(reland) media: Use platform specific folders for CDMs

This is a reland of commit e13213d846ff7bdd794588b7efd152c3b5080a8d with a minor fix in media_cdm.gypi where we use product_dir for clearkeycdm on all platforms except for Mac. On Mac, we use the default product_dir, and then copy the library to the platform specific folder.

Original CL Description:

* Purpose of this CL:

To support bundled CDM using DefaultCompnentInstaller, the folder structure of bundled CDMs should be the same as component updated CDMs.

For component CDMs, the folder structure is like:
    <DIR_USER_DATA>/WidevineCdm/<version>/_platform_specific/win_x64

For bundled CDM, the folder structure should be like:
    <DIR_COMPONENTS>/WidevineCdm/_platform_specific/win_x64
Note that the <version> folder is not needed in this case.

* What this CL does:

- Introduce cdm_paths.* to put CDMs in platform specific folders. On Win/Mac, we have something like WidevineCdm/_platform_specific/win_x64. On Linux/Cros, we don't use platform specific folders.

- On Mac, strip_save_dsym doesn't work with targets with "product_dir" (in gyp build). So we build to the default output dir first, then copy it over to the platform specific folder. See http://crbug.com/611990 for more details.

- Updated all tests to support platform specific folders.

- Update installer files to bundle the CDM (adapter) in the right folder.

[email protected],[email protected],[email protected],[email protected],
BUG=582622,611990
TEST=All tests pass. Tested on Mac and Linux.

Review-Url: https://codereview.chromium.org/2005703002
Cr-Commit-Position: refs/heads/master@{#395280}
diff --git a/chrome/BUILD.gn b/chrome/BUILD.gn
index d3e0352..c66526065 100644
--- a/chrome/BUILD.gn
+++ b/chrome/BUILD.gn
@@ -222,9 +222,10 @@
       # On Mac, internal plugins go inside the framework, so these
       # dependencies are on chrome.dll.
       "//third_party/adobe/flash:flapper_binaries",
-      "//third_party/widevine/cdm:widevinecdmadapter",
     ]
 
+    data_deps += [ "//third_party/widevine/cdm:widevinecdmadapter" ]
+
     if (is_multi_dll_chrome) {
       defines += [ "CHROME_MULTIPLE_DLL" ]
       data_deps += [ ":chrome_child" ]
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn
index e504c2b5..530b972 100644
--- a/chrome/browser/BUILD.gn
+++ b/chrome/browser/BUILD.gn
@@ -1289,6 +1289,14 @@
       "ui/app_list/test/test_app_list_controller_delegate.h",
     ]
   }
+
+  if (enable_pepper_cdms) {
+    sources += [
+      "media/pepper_cdm_test_helper.cc",
+      "media/pepper_cdm_test_helper.h",
+    ]
+    deps += [ "//media:cdm_paths" ]
+  }
 }
 
 # In GYP this is part of test_support_ui.
diff --git a/chrome/browser/DEPS b/chrome/browser/DEPS
index 7f19930..6a5f917 100644
--- a/chrome/browser/DEPS
+++ b/chrome/browser/DEPS
@@ -33,6 +33,7 @@
   "+jni",
   "+media/audio", # For media audio hang monitor.
   "+media/base",  # For media switches
+  "+media/cdm/cdm_paths.h",
   "+media/midi",  # For midi switches
   "+media/mojo",  # For mojo media services.
   "+mojo/converters",
diff --git a/chrome/browser/content_settings/content_settings_browsertest.cc b/chrome/browser/content_settings/content_settings_browsertest.cc
index c5a9934..5539dcf 100644
--- a/chrome/browser/content_settings/content_settings_browsertest.cc
+++ b/chrome/browser/content_settings/content_settings_browsertest.cc
@@ -326,14 +326,14 @@
 #if defined(ENABLE_PEPPER_CDMS)
     // Append the switch to register the External Clear Key CDM.
     base::FilePath::StringType pepper_plugins = BuildPepperCdmRegistration(
-        kClearKeyCdmAdapterFileName, kClearKeyCdmDisplayName,
-        kClearKeyCdmPepperMimeType);
+        kClearKeyCdmBaseDirectory, kClearKeyCdmAdapterFileName,
+        kClearKeyCdmDisplayName, kClearKeyCdmPepperMimeType);
 #if defined(WIDEVINE_CDM_AVAILABLE) && defined(WIDEVINE_CDM_IS_COMPONENT)
     // The CDM must be registered when it is a component.
     pepper_plugins.append(FILE_PATH_LITERAL(","));
     pepper_plugins.append(BuildPepperCdmRegistration(
-        kWidevineCdmAdapterFileName, kWidevineCdmDisplayName,
-        kWidevineCdmPluginMimeType));
+        kWidevineCdmBaseDirectory, kWidevineCdmAdapterFileName,
+        kWidevineCdmDisplayName, kWidevineCdmPluginMimeType));
 #endif  // defined(WIDEVINE_CDM_AVAILABLE) && defined(WIDEVINE_CDM_IS_COMPONENT)
     command_line->AppendSwitchNative(switches::kRegisterPepperPlugins,
                                      pepper_plugins);
diff --git a/chrome/browser/load_library_perf_test.cc b/chrome/browser/load_library_perf_test.cc
index 5b4fe125..6d30b2f 100644
--- a/chrome/browser/load_library_perf_test.cc
+++ b/chrome/browser/load_library_perf_test.cc
@@ -14,12 +14,24 @@
 #include "build/build_config.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "testing/perf/perf_test.h"
+
 #include "widevine_cdm_version.h"  //  In SHARED_INTERMEDIATE_DIR.
 
+#if defined(ENABLE_PEPPER_CDMS)
+#include "chrome/browser/media/pepper_cdm_test_helper.h"
+#include "media/cdm/cdm_paths.h"
+#endif
+
+namespace {
+
 // Measures the size (bytes) and time to load (sec) of a native library.
-void MeasureSizeAndTimeToLoadNativeLibrary(const base::FilePath& library_name) {
+// |library_relative_dir| is the relative path based on DIR_MODULE.
+void MeasureSizeAndTimeToLoadNativeLibrary(
+    const base::FilePath& library_relative_dir,
+    const base::FilePath& library_name) {
   base::FilePath output_dir;
   ASSERT_TRUE(PathService::Get(base::DIR_MODULE, &output_dir));
+  output_dir = output_dir.Append(library_relative_dir);
   base::FilePath library_path = output_dir.Append(library_name);
   ASSERT_TRUE(base::PathExists(library_path)) << library_path.value();
 
@@ -47,42 +59,48 @@
                          true);
 }
 
-// Use the base name of the library to dynamically get the platform specific
-// name. See base::GetNativeLibraryName() for details.
-void MeasureSizeAndTimeToLoadNativeLibraryByBaseName(
-    const std::string& base_library_name) {
-  MeasureSizeAndTimeToLoadNativeLibrary(base::FilePath::FromUTF16Unsafe(
-      base::GetNativeLibraryName(base::ASCIIToUTF16(base_library_name))));
+#if defined(ENABLE_PEPPER_CDMS)
+
+// File name of the ClearKey CDM on different platforms.
+// TODO(xhwang): Consolidate this with external_clear_key_test_helper.cc.
+const char kClearKeyCdmFileName[] =
+#if defined(OS_MACOSX)
+    "libclearkeycdm.dylib";
+#elif defined(OS_WIN)
+    "clearkeycdm.dll";
+#else  // OS_LINUX, etc.
+    "libclearkeycdm.so";
+#endif
+
+void MeasureSizeAndTimeToLoadCdm(const std::string& cdm_base_dir,
+                                 const std::string& cdm_name) {
+  MeasureSizeAndTimeToLoadNativeLibrary(
+      media::GetPlatformSpecificDirectory(cdm_base_dir),
+      base::FilePath::FromUTF8Unsafe(cdm_name));
 }
 
+#endif  // defined(ENABLE_PEPPER_CDMS)
+
+}  // namespace
+
 #if defined(ENABLE_PEPPER_CDMS)
 #if defined(WIDEVINE_CDM_AVAILABLE)
 TEST(LoadCDMPerfTest, Widevine) {
-  MeasureSizeAndTimeToLoadNativeLibrary(
-      base::FilePath::FromUTF8Unsafe(kWidevineCdmFileName));
+  MeasureSizeAndTimeToLoadCdm(kWidevineCdmBaseDirectory, kWidevineCdmFileName);
 }
 
 TEST(LoadCDMPerfTest, WidevineAdapter) {
-  MeasureSizeAndTimeToLoadNativeLibrary(
-      base::FilePath::FromUTF8Unsafe(kWidevineCdmAdapterFileName));
+  MeasureSizeAndTimeToLoadCdm(kWidevineCdmBaseDirectory,
+                              kWidevineCdmAdapterFileName);
 }
 #endif  // defined(WIDEVINE_CDM_AVAILABLE)
 
 TEST(LoadCDMPerfTest, ExternalClearKey) {
-#if defined(OS_MACOSX)
-  MeasureSizeAndTimeToLoadNativeLibrary(
-    base::FilePath::FromUTF8Unsafe("libclearkeycdm.dylib"));
-#else
-  MeasureSizeAndTimeToLoadNativeLibraryByBaseName("clearkeycdm");
-#endif  // defined(OS_MACOSX)
+  MeasureSizeAndTimeToLoadCdm(kClearKeyCdmBaseDirectory, kClearKeyCdmFileName);
 }
 
 TEST(LoadCDMPerfTest, ExternalClearKeyAdapter) {
-#if defined(OS_MACOSX)
-  MeasureSizeAndTimeToLoadNativeLibrary(
-    base::FilePath::FromUTF8Unsafe("clearkeycdmadapter.plugin"));
-#else
-  MeasureSizeAndTimeToLoadNativeLibraryByBaseName("clearkeycdmadapter");
-#endif  // defined(OS_MACOSX)
+  MeasureSizeAndTimeToLoadCdm(kClearKeyCdmBaseDirectory,
+                              kClearKeyCdmAdapterFileName);
 }
 #endif  // defined(ENABLE_PEPPER_CDMS)
diff --git a/chrome/browser/media/encrypted_media_browsertest.cc b/chrome/browser/media/encrypted_media_browsertest.cc
index 78cd3c8..c04916f 100644
--- a/chrome/browser/media/encrypted_media_browsertest.cc
+++ b/chrome/browser/media/encrypted_media_browsertest.cc
@@ -251,13 +251,15 @@
 
 #if defined(ENABLE_PEPPER_CDMS)
     if (IsExternalClearKey(key_system)) {
-      RegisterPepperCdm(command_line, kClearKeyCdmAdapterFileName,
-                        kClearKeyCdmDisplayName, kClearKeyCdmPepperMimeType);
+      RegisterPepperCdm(command_line, kClearKeyCdmBaseDirectory,
+                        kClearKeyCdmAdapterFileName, kClearKeyCdmDisplayName,
+                        kClearKeyCdmPepperMimeType);
     }
 #if defined(WIDEVINE_CDM_AVAILABLE) && defined(WIDEVINE_CDM_IS_COMPONENT)
     else if (IsWidevine(key_system)) {  // NOLINT
-      RegisterPepperCdm(command_line, kWidevineCdmAdapterFileName,
-                        kWidevineCdmDisplayName, kWidevineCdmPluginMimeType);
+      RegisterPepperCdm(command_line, kWidevineCdmBaseDirectory,
+                        kWidevineCdmAdapterFileName, kWidevineCdmDisplayName,
+                        kWidevineCdmPluginMimeType);
     }
 #endif  // defined(WIDEVINE_CDM_AVAILABLE) && defined(WIDEVINE_CDM_IS_COMPONENT)
 #endif  // defined(ENABLE_PEPPER_CDMS)
diff --git a/chrome/browser/media/encrypted_media_supported_types_browsertest.cc b/chrome/browser/media/encrypted_media_supported_types_browsertest.cc
index 97e6f29ad..65c6f9cf 100644
--- a/chrome/browser/media/encrypted_media_supported_types_browsertest.cc
+++ b/chrome/browser/media/encrypted_media_supported_types_browsertest.cc
@@ -258,8 +258,9 @@
  protected:
   void SetUpCommandLine(base::CommandLine* command_line) override {
     EncryptedMediaSupportedTypesTest::SetUpCommandLine(command_line);
-    RegisterPepperCdm(command_line, kClearKeyCdmAdapterFileName,
-                      kClearKeyCdmDisplayName, kClearKeyCdmPepperMimeType);
+    RegisterPepperCdm(command_line, kClearKeyCdmBaseDirectory,
+                      kClearKeyCdmAdapterFileName, kClearKeyCdmDisplayName,
+                      kClearKeyCdmPepperMimeType);
   }
 #endif  // defined(ENABLE_PEPPER_CDMS)
 };
@@ -278,7 +279,8 @@
  protected:
   void SetUpCommandLine(base::CommandLine* command_line) override {
     EncryptedMediaSupportedTypesTest::SetUpCommandLine(command_line);
-    RegisterPepperCdm(command_line, "clearkeycdmadapterwrongname.dll",
+    RegisterPepperCdm(command_line, kClearKeyCdmBaseDirectory,
+                      "clearkeycdmadapterwrongname.dll",
                       kClearKeyCdmDisplayName, kClearKeyCdmPepperMimeType,
                       false);
   }
@@ -290,7 +292,8 @@
  protected:
   void SetUpCommandLine(base::CommandLine* command_line) override {
     EncryptedMediaSupportedTypesTest::SetUpCommandLine(command_line);
-    RegisterPepperCdm(command_line, "widevinecdmadapterwrongname.dll",
+    RegisterPepperCdm(command_line, "WidevineCdm",
+                      "widevinecdmadapterwrongname.dll",
                       "Widevine Content Decryption Module",
                       "application/x-ppapi-widevine-cdm", false);
   }
diff --git a/chrome/browser/media/pepper_cdm_test_helper.cc b/chrome/browser/media/pepper_cdm_test_helper.cc
index 10731081..b4b85df 100644
--- a/chrome/browser/media/pepper_cdm_test_helper.cc
+++ b/chrome/browser/media/pepper_cdm_test_helper.cc
@@ -9,10 +9,11 @@
 #include "base/path_service.h"
 #include "base/strings/utf_string_conversions.h"
 #include "content/public/common/content_switches.h"
+#include "media/cdm/cdm_paths.h"
 
 #include "widevine_cdm_version.h"  //  In SHARED_INTERMEDIATE_DIR.
 
-const char kClearKeyCdmDisplayName[] = "Clear Key CDM";
+const char kClearKeyCdmBaseDirectory[] = "ClearKeyCdm";
 
 const char kClearKeyCdmAdapterFileName[] =
 #if defined(OS_MACOSX)
@@ -23,17 +24,23 @@
     "libclearkeycdmadapter.so";
 #endif
 
+const char kClearKeyCdmDisplayName[] = "Clear Key CDM";
+
 const char kClearKeyCdmPepperMimeType[] = "application/x-ppapi-clearkey-cdm";
 
 base::FilePath::StringType BuildPepperCdmRegistration(
+    const std::string& adapter_base_dir,
     const std::string& adapter_file_name,
     const std::string& display_name,
     const std::string& mime_type,
     bool expect_adapter_exists) {
   base::FilePath adapter_path;
   PathService::Get(base::DIR_MODULE, &adapter_path);
+  adapter_path = adapter_path.Append(
+      media::GetPlatformSpecificDirectory(adapter_base_dir));
   adapter_path = adapter_path.AppendASCII(adapter_file_name);
-  DCHECK_EQ(expect_adapter_exists, base::PathExists(adapter_path));
+  DCHECK_EQ(expect_adapter_exists, base::PathExists(adapter_path))
+      << adapter_path.MaybeAsASCII();
 
   base::FilePath::StringType pepper_cdm_registration = adapter_path.value();
 
@@ -52,12 +59,14 @@
 }
 
 void RegisterPepperCdm(base::CommandLine* command_line,
+                       const std::string& adapter_base_dir,
                        const std::string& adapter_file_name,
                        const std::string& display_name,
                        const std::string& mime_type,
                        bool expect_adapter_exists) {
   base::FilePath::StringType pepper_cdm_registration =
-      BuildPepperCdmRegistration(adapter_file_name, display_name, mime_type,
+      BuildPepperCdmRegistration(adapter_base_dir, adapter_file_name,
+                                 display_name, mime_type,
                                  expect_adapter_exists);
 
   // Append the switch to register the CDM Adapter.
diff --git a/chrome/browser/media/pepper_cdm_test_helper.h b/chrome/browser/media/pepper_cdm_test_helper.h
index d5ff9b4..87e766ff 100644
--- a/chrome/browser/media/pepper_cdm_test_helper.h
+++ b/chrome/browser/media/pepper_cdm_test_helper.h
@@ -13,12 +13,15 @@
 class CommandLine;
 }
 
-// Display name for Clear Key CDM.
-extern const char kClearKeyCdmDisplayName[];
+// Base path for Clear Key CDM (relative to the chrome executable).
+extern const char kClearKeyCdmBaseDirectory[];
 
 // Platform-specific filename relative to kClearKeyCdmBaseDirectory.
 extern const char kClearKeyCdmAdapterFileName[];
 
+// Display name for Clear Key CDM.
+extern const char kClearKeyCdmDisplayName[];
+
 // Pepper type for Clear Key CDM.
 extern const char kClearKeyCdmPepperMimeType[];
 
@@ -27,6 +30,7 @@
 // Multiple results may be passed to kRegisterPepperPlugins, separated by ",".
 // The CDM adapter should be located in DIR_MODULE.
 base::FilePath::StringType BuildPepperCdmRegistration(
+    const std::string& adapter_base_dir,
     const std::string& adapter_file_name,
     const std::string& display_name,
     const std::string& mime_type,
@@ -34,6 +38,7 @@
 
 // Registers pepper CDM in |command_line|.
 void RegisterPepperCdm(base::CommandLine* command_line,
+                       const std::string& adapter_base_dir,
                        const std::string& adapter_file_name,
                        const std::string& display_name,
                        const std::string& mime_type,
diff --git a/chrome/browser_tests.isolate b/chrome/browser_tests.isolate
index 0cc86ee3..8bdd048 100644
--- a/chrome/browser_tests.isolate
+++ b/chrome/browser_tests.isolate
@@ -181,20 +181,27 @@
     ['OS=="mac"', {
       'variables': {
         'files': [
-          '<(PRODUCT_DIR)/clearkeycdmadapter.plugin',
           '<(PRODUCT_DIR)/content_shell.pak',
-          '<(PRODUCT_DIR)/libclearkeycdm.dylib',
           '<(PRODUCT_DIR)/osmesa.so',
           '<(PRODUCT_DIR)/power_saver_test_plugin.plugin/Contents/MacOS/power_saver_test_plugin',
           '<(PRODUCT_DIR)/ppapi_tests.plugin/Contents/MacOS/ppapi_tests',
         ],
       },
     }],
-    ['OS=="mac" and branding=="Chrome" and enable_pepper_cdms==1', {
+    # We don't support ia32 target for mac. Still check arch for completeness.
+    ['OS=="mac" and target_arch=="x64"', {
       'variables': {
         'files': [
-          '<(PRODUCT_DIR)/libwidevinecdm.dylib',
-          '<(PRODUCT_DIR)/widevinecdmadapter.plugin',
+          '<(PRODUCT_DIR)/ClearKeyCdm/_platform_specific/mac_x64/clearkeycdmadapter.plugin',
+          '<(PRODUCT_DIR)/ClearKeyCdm/_platform_specific/mac_x64/libclearkeycdm.dylib',
+        ],
+      },
+    }],
+    ['OS=="mac" and target_arch=="x64" and branding=="Chrome" and enable_pepper_cdms==1', {
+      'variables': {
+        'files': [
+          '<(PRODUCT_DIR)/WidevineCdm/_platform_specific/mac_x64/libwidevinecdm.dylib',
+          '<(PRODUCT_DIR)/WidevineCdm/_platform_specific/mac_x64/widevinecdmadapter.plugin',
         ],
       },
     }],
@@ -203,8 +210,6 @@
         'files': [
           '../native_client/build/build_nexe.py',
           '<(PRODUCT_DIR)/chrome_elf.dll',
-          '<(PRODUCT_DIR)/clearkeycdm.dll',
-          '<(PRODUCT_DIR)/clearkeycdmadapter.dll',
           '<(PRODUCT_DIR)/crashpad_handler.exe',
           '<(PRODUCT_DIR)/power_saver_test_plugin.dll',
           '<(PRODUCT_DIR)/ppapi_tests.dll',
@@ -212,11 +217,35 @@
         ],
       },
     }],
-    ['OS=="win" and branding=="Chrome" and enable_pepper_cdms==1', {
+    ['OS=="win" and target_arch=="ia32"', {
       'variables': {
         'files': [
-          '<(PRODUCT_DIR)/widevinecdm.dll',
-          '<(PRODUCT_DIR)/widevinecdmadapter.dll',
+          '<(PRODUCT_DIR)/ClearKeyCdm/_platform_specific/win_x86/clearkeycdm.dll',
+          '<(PRODUCT_DIR)/ClearKeyCdm/_platform_specific/win_x86/clearkeycdmadapter.dll',
+        ],
+      },
+    }],
+    ['OS=="win" and target_arch=="x64"', {
+      'variables': {
+        'files': [
+          '<(PRODUCT_DIR)/ClearKeyCdm/_platform_specific/win_x64/clearkeycdm.dll',
+          '<(PRODUCT_DIR)/ClearKeyCdm/_platform_specific/win_x64/clearkeycdmadapter.dll',
+        ],
+      },
+    }],
+    ['OS=="win" and target_arch=="ia32" and branding=="Chrome" and enable_pepper_cdms==1', {
+      'variables': {
+        'files': [
+          '<(PRODUCT_DIR)/WidevineCdm/_platform_specific/win_x86/clearkeycdm.dll',
+          '<(PRODUCT_DIR)/WidevineCdm/_platform_specific/win_x86/clearkeycdmadapter.dll',
+        ],
+      },
+    }],
+    ['OS=="win" and target_arch=="x64" and branding=="Chrome" and enable_pepper_cdms==1', {
+      'variables': {
+        'files': [
+          '<(PRODUCT_DIR)/WidevineCdm/_platform_specific/win_x64/clearkeycdm.dll',
+          '<(PRODUCT_DIR)/WidevineCdm/_platform_specific/win_x64/clearkeycdmadapter.dll',
         ],
       },
     }],
diff --git a/chrome/chrome_dll_bundle.gypi b/chrome/chrome_dll_bundle.gypi
index 157d4e2d..61d64238 100644
--- a/chrome/chrome_dll_bundle.gypi
+++ b/chrome/chrome_dll_bundle.gypi
@@ -40,6 +40,7 @@
   },
   'includes': [
     'chrome_nibs.gypi',
+    '../media/cdm_paths.gypi',
   ],
   # TODO(mark): Come up with a fancier way to do this.  It should
   # only be necessary to list framework-Info.plist once, not the
@@ -135,12 +136,12 @@
     {
       # The adapter is not a complete library on its own. It needs the Widevine
       # CDM to work.
-      'destination': '<(PRODUCT_DIR)/$(CONTENTS_FOLDER_PATH)/Libraries/',
+      'destination': '<(PRODUCT_DIR)/$(CONTENTS_FOLDER_PATH)/Libraries/<(widevine_cdm_path)',
       'files': [],
       'conditions': [
         ['branding == "Chrome"', {
           'files': [
-            '<(PRODUCT_DIR)/widevinecdmadapter.plugin',
+            '<(PRODUCT_DIR)/<(widevine_cdm_path)/widevinecdmadapter.plugin',
           ],
         }],
       ],
diff --git a/chrome/chrome_installer.gypi b/chrome/chrome_installer.gypi
index 325f0b3..19c79f6d 100644
--- a/chrome/chrome_installer.gypi
+++ b/chrome/chrome_installer.gypi
@@ -3,6 +3,9 @@
 # found in the LICENSE file.
 
 {
+  'includes': [
+    '../media/cdm_paths.gypi',
+  ],
   'variables': {
     'lastchange_path': '../build/util/LASTCHANGE',
     'branding_dir': 'app/theme/<(branding_path_component)',
@@ -525,8 +528,8 @@
             'rpm_arch': 'i386',
             'packaging_files_binaries': [
               '<(PRODUCT_DIR)/nacl_irt_x86_32.nexe',
-              '<(PRODUCT_DIR)/libwidevinecdmadapter.so',
-              '<(PRODUCT_DIR)/libwidevinecdm.so',
+              '<(PRODUCT_DIR)/<(widevine_cdm_path)/libwidevinecdmadapter.so',
+              '<(PRODUCT_DIR)/<(widevine_cdm_path)/libwidevinecdm.so',
             ],
             'packaging_files_common': [
               '<(DEPTH)/build/linux/bin/eu-strip',
@@ -537,8 +540,8 @@
             'rpm_arch': 'x86_64',
             'packaging_files_binaries': [
               '<(PRODUCT_DIR)/nacl_irt_x86_64.nexe',
-              '<(PRODUCT_DIR)/libwidevinecdmadapter.so',
-              '<(PRODUCT_DIR)/libwidevinecdm.so',
+              '<(PRODUCT_DIR)/<(widevine_cdm_path)/libwidevinecdmadapter.so',
+              '<(PRODUCT_DIR)/<(widevine_cdm_path)/libwidevinecdm.so',
             ],
             'packaging_files_common': [
               '<!(which eu-strip)',
diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi
index ccc14dd..57f46a2c 100644
--- a/chrome/chrome_tests.gypi
+++ b/chrome/chrome_tests.gypi
@@ -2673,14 +2673,10 @@
           'sources': [ '<@(chrome_browser_tests_supervised_user_sources)' ],
         }],
         ['enable_pepper_cdms==1', {
-          'sources' : [
-            'browser/media/pepper_cdm_test_helper.cc',
-            'browser/media/pepper_cdm_test_helper.h',
-          ],
           'dependencies': [
             # Runtime dependencies.
-            '../third_party/widevine/cdm/widevine_cdm.gyp:widevinecdmadapter',
             '../media/media.gyp:clearkeycdmadapter',
+            '../third_party/widevine/cdm/widevine_cdm.gyp:widevinecdmadapter',
           ],
         }],
         ['enable_print_preview==0', {
@@ -3162,6 +3158,8 @@
       'conditions': [
         ['enable_pepper_cdms==1', {
           'dependencies': [
+            'test_support_common',
+            '../media/media.gyp:cdm_paths',
             # Runtime dependencies.
             '../media/media.gyp:clearkeycdmadapter',
             '../third_party/widevine/cdm/widevine_cdm.gyp:widevinecdmadapter',
diff --git a/chrome/chrome_tests_unit.gypi b/chrome/chrome_tests_unit.gypi
index f14bd89..963dbe05 100644
--- a/chrome/chrome_tests_unit.gypi
+++ b/chrome/chrome_tests_unit.gypi
@@ -2160,6 +2160,15 @@
             '../ui/views/views.gyp:views',
           ],
         }],
+        ['enable_pepper_cdms==1', {
+          'sources' : [
+            'browser/media/pepper_cdm_test_helper.cc',
+            'browser/media/pepper_cdm_test_helper.h',
+          ],
+          'dependencies': [
+            '../media/media.gyp:cdm_paths',
+          ],
+        }],
       ],
     },
     {
diff --git a/chrome/common/BUILD.gn b/chrome/common/BUILD.gn
index d2499a1..33a686e 100644
--- a/chrome/common/BUILD.gn
+++ b/chrome/common/BUILD.gn
@@ -353,6 +353,7 @@
     "//base/third_party/dynamic_annotations",
     "//components/bookmarks/common",
     "//components/nacl/common:switches",
+    "//media:cdm_paths",  # Needed by chrome_paths.cc.
     "//third_party/widevine/cdm:version_h",
   ]
 
diff --git a/chrome/common/chrome_paths.cc b/chrome/common/chrome_paths.cc
index f4e119db..accbe55 100644
--- a/chrome/common/chrome_paths.cc
+++ b/chrome/common/chrome_paths.cc
@@ -16,6 +16,7 @@
 #include "build/build_config.h"
 #include "chrome/common/chrome_constants.h"
 #include "chrome/common/chrome_paths_internal.h"
+#include "media/cdm/cdm_paths.h"
 
 #if defined(OS_ANDROID)
 #include "base/android/path_utils.h"
@@ -368,7 +369,7 @@
     case chrome::DIR_COMPONENT_WIDEVINE_CDM:
       if (!PathService::Get(chrome::DIR_USER_DATA, &cur))
         return false;
-      cur = cur.Append(FILE_PATH_LITERAL("WidevineCDM"));
+      cur = cur.AppendASCII(kWidevineCdmBaseDirectory);
       break;
 #endif  // defined(WIDEVINE_CDM_IS_COMPONENT)
     // TODO(xhwang): FILE_WIDEVINE_CDM_ADAPTER has different meanings.
@@ -377,6 +378,8 @@
     case chrome::FILE_WIDEVINE_CDM_ADAPTER:
       if (!GetComponentDirectory(&cur))
         return false;
+      cur = cur.Append(
+          media::GetPlatformSpecificDirectory(kWidevineCdmBaseDirectory));
       cur = cur.AppendASCII(kWidevineCdmAdapterFileName);
       break;
 #endif  // defined(WIDEVINE_CDM_AVAILABLE) && defined(ENABLE_PEPPER_CDMS)
diff --git a/chrome/common_constants.gyp b/chrome/common_constants.gyp
index cf315ca..95d0018 100644
--- a/chrome/common_constants.gyp
+++ b/chrome/common_constants.gyp
@@ -87,6 +87,7 @@
         '../base/base.gyp:base',
         '../base/third_party/dynamic_annotations/dynamic_annotations.gyp:dynamic_annotations',
         '../components/components.gyp:bookmarks_common',
+        '../media/media.gyp:cdm_paths',  # Needed by chrome_paths.cc.
         '../third_party/widevine/cdm/widevine_cdm.gyp:widevine_cdm_version_h',
       ],
       'target_conditions': [
diff --git a/chrome/installer/linux/BUILD.gn b/chrome/installer/linux/BUILD.gn
index 9f1422a..c30993b 100644
--- a/chrome/installer/linux/BUILD.gn
+++ b/chrome/installer/linux/BUILD.gn
@@ -8,6 +8,10 @@
 import("//build/util/version.gni")
 import("//chrome/version.gni")
 
+if (current_cpu == "x86" || current_cpu == "x64") {
+  import("//media/cdm/ppapi/cdm_paths.gni")
+}
+
 assert(is_linux && is_chrome_branded)
 
 # This target builds all "normal" Linux installers.
@@ -220,14 +224,14 @@
   if (current_cpu == "x86") {
     packaging_files_binaries += [
       "$root_out_dir/nacl_irt_x86_32.nexe",
-      "$root_out_dir/libwidevinecdmadapter.so",
-      "$root_out_dir/libwidevinecdm.so",
+      "$root_out_dir/$widevine_cdm_path/libwidevinecdmadapter.so",
+      "$root_out_dir/$widevine_cdm_path/libwidevinecdm.so",
     ]
   } else if (current_cpu == "x64") {
     packaging_files_binaries += [
       "$root_out_dir/nacl_irt_x86_64.nexe",
-      "$root_out_dir/libwidevinecdmadapter.so",
-      "$root_out_dir/libwidevinecdm.so",
+      "$root_out_dir/$widevine_cdm_path/libwidevinecdmadapter.so",
+      "$root_out_dir/$widevine_cdm_path/libwidevinecdm.so",
     ]
   } else if (current_cpu == "arm") {
     packaging_files_binaries += [ "$root_out_dir/nacl_irt_arm.nexe" ]
diff --git a/chrome/installer/mini_installer/chrome.release b/chrome/installer/mini_installer/chrome.release
index 4f39d897..1275e0c 100644
--- a/chrome/installer/mini_installer/chrome.release
+++ b/chrome/installer/mini_installer/chrome.release
@@ -53,7 +53,11 @@
 
 [GOOGLE_CHROME]
 SecondaryTile.png: %(VersionDir)s\
-widevinecdmadapter.dll: %(VersionDir)s\
+#
+# Widevine CDM sub-dir
+#
+WidevineCdm\_platform_specific\win_x86\widevinecdmadapter.dll: %(VersionDir)s\WidevineCdm\_platform_specific\win_x86\
+WidevineCdm\_platform_specific\win_x64\widevinecdmadapter.dll: %(VersionDir)s\WidevineCdm\_platform_specific\win_x64\
 #
 # Pepper Flash sub-dir.
 #
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn
index c8bce0f..086c09b8 100644
--- a/chrome/test/BUILD.gn
+++ b/chrome/test/BUILD.gn
@@ -1351,11 +1351,6 @@
               "//chrome")
     }
     if (enable_pepper_cdms) {
-      sources += [
-        "../browser/media/pepper_cdm_test_helper.cc",
-        "../browser/media/pepper_cdm_test_helper.h",
-      ]
-
       # Runtime dependencies.
       data_deps += [
         "//media/cdm/ppapi:clearkeycdmadapter",
@@ -1609,6 +1604,10 @@
     ]
 
     if (enable_pepper_cdms) {
+      deps += [
+        ":test_support",
+        "//media:cdm_paths",
+      ]
       data_deps = [
         "//media/cdm/ppapi:clearkeycdmadapter",
         "//third_party/widevine/cdm:widevinecdmadapter",
diff --git a/chrome/tools/build/win/FILES.cfg b/chrome/tools/build/win/FILES.cfg
index 6b334cd1..342337e6 100644
--- a/chrome/tools/build/win/FILES.cfg
+++ b/chrome/tools/build/win/FILES.cfg
@@ -341,7 +341,13 @@
   },
   # Widevine CDM adapter files:
   {
-    'filename': 'widevinecdmadapter.dll',
+    'filename': 'WidevineCdm/_platform_specific/win_x86/widevinecdmadapter.dll',
+    'arch': ['32bit'],
+    'buildtype': ['official'],
+  },
+  {
+    'filename': 'WidevineCdm/_platform_specific/win_x64/widevinecdmadapter.dll',
+    'arch': ['64bit'],
     'buildtype': ['official'],
   },
   # ANGLE files: