Home | History | Annotate | Download | only in media
      1 // Copyright 2014 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "chrome/browser/media/wv_test_license_server_config.h"
      6 
      7 #include "base/command_line.h"
      8 #include "base/environment.h"
      9 #include "base/files/file_util.h"
     10 #include "base/path_service.h"
     11 #include "base/rand_util.h"
     12 #include "base/strings/stringprintf.h"
     13 #include "net/base/net_errors.h"
     14 #include "net/socket/tcp_server_socket.h"
     15 #include "net/test/python_utils.h"
     16 
     17 
     18 const uint16 kMinPort = 17000;
     19 const uint16 kPortRangeSize = 1000;
     20 
     21 // Widevine license server configuration files.
     22 const base::FilePath::CharType kKeysFileName[] =
     23     FILE_PATH_LITERAL("keys.dat");
     24 const base::FilePath::CharType kPoliciesFileName[] =
     25     FILE_PATH_LITERAL("policies.dat");
     26 const base::FilePath::CharType kProfilesFileName[] =
     27     FILE_PATH_LITERAL("profiles.dat");
     28 
     29 // License server configuration files directory name relative to root.
     30 const base::FilePath::CharType kLicenseServerConfigDirName[] =
     31     FILE_PATH_LITERAL("config");
     32 
     33 WVTestLicenseServerConfig::WVTestLicenseServerConfig() {
     34 }
     35 
     36 WVTestLicenseServerConfig::~WVTestLicenseServerConfig() {
     37 }
     38 
     39 bool WVTestLicenseServerConfig::GetServerCommandLine(
     40     CommandLine* command_line) {
     41   if (!GetPythonCommand(command_line)) {
     42     LOG(ERROR) << "Could not get Python runtime command.";
     43     return false;
     44   }
     45 
     46   // Add the Python protocol buffers files directory to Python path.
     47   base::FilePath pyproto_dir;
     48   if (!GetPyProtoPath(&pyproto_dir)) {
     49     VLOG(0) << "Cannot find pyproto directory required by license server.";
     50     return false;
     51   }
     52   AppendToPythonPath(pyproto_dir);
     53 
     54   base::FilePath license_server_path;
     55   GetLicenseServerPath(&license_server_path);
     56   if (!base::PathExists(license_server_path)) {
     57     VLOG(0) << "Missing license server file at " << license_server_path.value();
     58     return false;
     59   }
     60 
     61   base::FilePath server_root;
     62   GetLicenseServerRootPath(&server_root);
     63   base::FilePath config_path = server_root.Append(kLicenseServerConfigDirName);
     64 
     65   if (!base::PathExists(config_path.Append(kKeysFileName)) ||
     66       !base::PathExists(config_path.Append(kPoliciesFileName)) ||
     67       !base::PathExists(config_path.Append(kProfilesFileName))) {
     68     VLOG(0) << "Missing license server configuration files.";
     69     return false;
     70   }
     71 
     72   if (!SelectServerPort())
     73     return false;
     74 
     75   // Needed to dynamically load .so libraries used by license server.
     76   // TODO(shadi): Remove need to set env variable once b/12932983 is fixed.
     77 #if defined(OS_LINUX)
     78   scoped_ptr<base::Environment> env(base::Environment::Create());
     79   const char kLibraryPathEnvVarName[] = "LD_LIBRARY_PATH";
     80   std::string library_paths(license_server_path.DirName().value());
     81   std::string old_path;
     82   if (env->GetVar(kLibraryPathEnvVarName, &old_path))
     83     library_paths.append(":").append(old_path);
     84   env->SetVar(kLibraryPathEnvVarName, library_paths);
     85 #endif  // defined(OS_LINUX)
     86 
     87   // Since it is a Python command line, we need to AppendArg instead of
     88   // AppendSwitch so that the arguments are passed to the Python server instead
     89   // of Python engine.
     90   command_line->AppendArgPath(license_server_path);
     91   command_line->AppendArg("-k");
     92   command_line->AppendArgPath(config_path.Append(kKeysFileName));
     93   command_line->AppendArg("-o");
     94   command_line->AppendArgPath(config_path.Append(kPoliciesFileName));
     95   command_line->AppendArg("-r");
     96   command_line->AppendArgPath(config_path.Append(kProfilesFileName));
     97   command_line->AppendArg(base::StringPrintf("--port=%u", port_));
     98   return true;
     99 }
    100 
    101 bool WVTestLicenseServerConfig::SelectServerPort() {
    102   // Try all ports within the range of kMinPort to (kMinPort + kPortRangeSize)
    103   // Instead of starting from kMinPort, use a random port within that range.
    104   net::IPAddressNumber address;
    105   net::ParseIPLiteralToNumber("127.0.0.1", &address);
    106   uint16 start_seed = base::RandInt(0, kPortRangeSize);
    107   uint16 try_port = 0;
    108   for (uint16 i = 0; i < kPortRangeSize; ++i) {
    109     try_port = kMinPort + (start_seed + i) % kPortRangeSize;
    110     net::NetLog::Source source;
    111     net::TCPServerSocket sock(NULL, source);
    112     if (sock.Listen(net::IPEndPoint(address, try_port), 1) == net::OK) {
    113       port_ = try_port;
    114       return true;
    115     }
    116   }
    117   VLOG(0) << "Could not find an open port in the range of " <<  kMinPort <<
    118              " to " << kMinPort + kPortRangeSize;
    119   return false;
    120 }
    121 
    122 bool WVTestLicenseServerConfig::IsPlatformSupported() {
    123 #if defined(OS_LINUX) && defined(ARCH_CPU_X86_64)
    124   return true;
    125 #else
    126   return false;
    127 #endif  // defined(OS_LINUX)
    128 }
    129 
    130 std::string WVTestLicenseServerConfig::GetServerURL() {
    131   return base::StringPrintf("http://localhost:%u/license_server", port_);
    132 }
    133 
    134 void WVTestLicenseServerConfig::GetLicenseServerPath(base::FilePath *path) {
    135   base::FilePath server_root;
    136   GetLicenseServerRootPath(&server_root);
    137   // Platform-specific license server binary path relative to root.
    138   *path =
    139 #if defined(OS_LINUX)
    140     server_root.Append(FILE_PATH_LITERAL("linux"))
    141                .Append(FILE_PATH_LITERAL("license_server.py"));
    142 #else
    143     server_root.Append(FILE_PATH_LITERAL("unsupported_platform"));
    144 #endif  // defined(OS_LINUX)
    145 }
    146 
    147 void WVTestLicenseServerConfig::GetLicenseServerRootPath(
    148     base::FilePath* path) {
    149   base::FilePath source_root;
    150   PathService::Get(base::DIR_SOURCE_ROOT, &source_root);
    151   *path = source_root.Append(FILE_PATH_LITERAL("third_party"))
    152                      .Append(FILE_PATH_LITERAL("widevine"))
    153                      .Append(FILE_PATH_LITERAL("test"))
    154                      .Append(FILE_PATH_LITERAL("license_server"));
    155 }
    156