Commit 13b46f47 authored by rpaquay@chromium.org's avatar rpaquay@chromium.org

Initial implementation of music manager private API.

MacOS and Linux are currently not supported. This will come in a later CL.

BUG=242540

Review URL: https://chromiumcodereview.appspot.com/15738013

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@202929 0039d316-1c4b-4281-b951-d872f2087c98
parent 9c18dbcb
// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/extensions/api/music_manager_private/device_id.h"
#include "base/base64.h"
#include "base/file_util.h"
#include "base/files/file_path.h"
#include "base/logging.h"
#if defined(OS_CHROMEOS)
#include "chromeos/cryptohome/cryptohome_library.h"
#endif
#include "crypto/hmac.h"
#if defined(ENABLE_RLZ)
#include "rlz/lib/machine_id.h"
#endif
namespace {
// Return a unique identifier for the machine/device. Currently, this is only
// supported on Windows (with RLZ enabled) and ChromeOS.
std::string GetMachineID() {
#if defined(OS_WIN) && defined(ENABLE_RLZ)
std::string result;
rlz_lib::GetMachineId(&result);
return result;
#elif defined(OS_CHROMEOS)
chromeos::CryptohomeLibrary* c_home = chromeos::CryptohomeLibrary::Get();
return c_home->GetSystemSalt();
#else
// Not implemented for other platforms.
return "";
#endif
}
// Compute HMAC-SHA256(|key|, |text|) as a string.
bool ComputeHmacSha256(const std::string& key,
const std::string& text,
std::string* signature_return) {
crypto::HMAC hmac(crypto::HMAC::SHA256);
const size_t digest_length = hmac.DigestLength();
std::vector<uint8> digest(digest_length);
bool result = hmac.Init(key) &&
hmac.Sign(text, &digest[0], digest.size()) &&
base::Base64Encode(std::string(reinterpret_cast<char*>(&digest[0]),
digest.size()),
signature_return);
return result;
}
}
namespace device_id {
std::string GetDeviceID(const std::string& salt) {
CHECK(!salt.empty());
std::string machine_id = GetMachineID();
if (machine_id.empty()) {
DLOG(WARNING) << "API is not supported on current platform.";
return "";
}
std::string device_id;
if (!ComputeHmacSha256(machine_id, salt, &device_id)) {
DLOG(ERROR) << "Error while computing HMAC-SHA256 of device id.";
return "";
}
return device_id;
}
} // namespace device_id
// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_EXTENSIONS_API_MUSIC_MANAGER_PRIVATE_DEVICE_ID_H_
#define CHROME_BROWSER_EXTENSIONS_API_MUSIC_MANAGER_PRIVATE_DEVICE_ID_H_
#include <string>
namespace device_id {
// Return a "device" identifier with the following characteristics:
// 1. The id is shared across users of a device.
// 2. The id is resilient to device reboots.
// 3. There is *some* way for the identifier to be reset (e.g. it can *not* be
// the MAC address of the device's network card).
// The specific implementation varies across platforms, but is currently
// fast enough that it can be run on the UI thread.
// The returned value is HMAC_SHA256(device_id, |salt|), so that the actual
// device identifier value is not exposed directly to the caller.
std::string GetDeviceID(const std::string& salt);
} // namespace device_id
#endif // CHROME_BROWSER_EXTENSIONS_API_MUSIC_MANAGER_PRIVATE_DEVICE_ID_H_
// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/extensions/api/music_manager_private/music_manager_private_api.h"
#include "chrome/browser/extensions/api/music_manager_private/device_id.h"
using content::BrowserThread;
namespace {
const char kDeviceIDNotSupported[] =
"Device ID API is not supported on this platform.";
}
namespace extensions {
namespace api {
MusicManagerPrivateGetDeviceIdFunction::
MusicManagerPrivateGetDeviceIdFunction() {
}
MusicManagerPrivateGetDeviceIdFunction::
~MusicManagerPrivateGetDeviceIdFunction() {
}
bool MusicManagerPrivateGetDeviceIdFunction::RunImpl() {
std::string salt = this->extension_id();
std::string result = device_id::GetDeviceID(salt);
bool response;
if (result.empty()) {
SetError(kDeviceIDNotSupported);
response = false;
} else {
SetResult(Value::CreateStringValue(result));
response = true;
}
SendResponse(response);
return response;
}
} // namespace api
} // namespace extensions
// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_EXTENSIONS_API_MUSIC_MANAGER_PRIVATE_MUSIC_MANAGER_PRIVATE_API_H_
#define CHROME_BROWSER_EXTENSIONS_API_MUSIC_MANAGER_PRIVATE_MUSIC_MANAGER_PRIVATE_API_H_
#include "chrome/browser/extensions/extension_function.h"
namespace extensions {
namespace api {
class MusicManagerPrivateGetDeviceIdFunction : public SyncExtensionFunction {
public:
DECLARE_EXTENSION_FUNCTION("musicManagerPrivate.getDeviceId",
MUSICMANAGERPRIVATE_GETDEVICEID)
MusicManagerPrivateGetDeviceIdFunction();
protected:
virtual ~MusicManagerPrivateGetDeviceIdFunction();
// ExtensionFunction:
virtual bool RunImpl() OVERRIDE;
};
} // namespace api
} // namespace extensions
#endif // CHROME_BROWSER_EXTENSIONS_API_MUSIC_MANAGER_PRIVATE_MUSIC_MANAGER_PRIVATE_API_H_
// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/extensions/extension_test_message_listener.h"
#include "chrome/browser/extensions/platform_app_browsertest_util.h"
// This API is supported only on a subset of platforms.
#if defined(OS_CHROMEOS) || \
(defined(OS_WIN) && defined(ENABLE_RLZ))
class MusicManagerPrivateTest : public extensions::PlatformAppBrowserTest {
};
IN_PROC_BROWSER_TEST_F(MusicManagerPrivateTest, DeviceIdValueReturned) {
ASSERT_TRUE(RunPlatformAppTest(
"platform_apps/music_manager_private/device_id_value_returned"))
<< message_;
}
#endif
...@@ -537,6 +537,7 @@ enum HistogramValue { ...@@ -537,6 +537,7 @@ enum HistogramValue {
FILESYSTEM_RESTOREENTRY, FILESYSTEM_RESTOREENTRY,
RUNTIME_SETUNINSTALLURL, RUNTIME_SETUNINSTALLURL,
INPUTMETHODPRIVATE_STARTIME, INPUTMETHODPRIVATE_STARTIME,
MUSICMANAGERPRIVATE_GETDEVICEID,
ENUM_BOUNDARY // Last entry: Add new entries above. ENUM_BOUNDARY // Last entry: Add new entries above.
}; };
......
...@@ -298,6 +298,10 @@ ...@@ -298,6 +298,10 @@
'browser/extensions/api/metrics_private/metrics_private_api.h', 'browser/extensions/api/metrics_private/metrics_private_api.h',
'browser/extensions/api/module/module.cc', 'browser/extensions/api/module/module.cc',
'browser/extensions/api/module/module.h', 'browser/extensions/api/module/module.h',
'browser/extensions/api/music_manager_private/device_id.cc',
'browser/extensions/api/music_manager_private/device_id.h',
'browser/extensions/api/music_manager_private/music_manager_private_api.cc',
'browser/extensions/api/music_manager_private/music_manager_private_api.h',
'browser/extensions/api/notifications/notifications_api.cc', 'browser/extensions/api/notifications/notifications_api.cc',
'browser/extensions/api/notifications/notifications_api.h', 'browser/extensions/api/notifications/notifications_api.h',
'browser/extensions/api/omnibox/omnibox_api.cc', 'browser/extensions/api/omnibox/omnibox_api.cc',
......
...@@ -1343,6 +1343,7 @@ ...@@ -1343,6 +1343,7 @@
'browser/extensions/api/messaging/native_messaging_apitest.cc', 'browser/extensions/api/messaging/native_messaging_apitest.cc',
'browser/extensions/api/metrics_private/metrics_apitest.cc', 'browser/extensions/api/metrics_private/metrics_apitest.cc',
'browser/extensions/api/module/module_apitest.cc', 'browser/extensions/api/module/module_apitest.cc',
'browser/extensions/api/music_manager_private/music_manager_private_browsertest.cc',
'browser/extensions/api/notifications/notifications_apitest.cc', 'browser/extensions/api/notifications/notifications_apitest.cc',
'browser/extensions/api/omnibox/omnibox_api_browsertest.cc', 'browser/extensions/api/omnibox/omnibox_api_browsertest.cc',
'browser/extensions/api/page_capture/page_capture_apitest.cc', 'browser/extensions/api/page_capture/page_capture_apitest.cc',
......
...@@ -346,6 +346,14 @@ ...@@ -346,6 +346,14 @@
"iejldcgjigodajhjecapkeiggcncflph" // Google Now dev "iejldcgjigodajhjecapkeiggcncflph" // Google Now dev
] ]
}, },
"musicManagerPrivate": {
"channel": "dev",
"extension_types": ["platform_app"],
"whitelist": [
"4B1D0E19C6C43C008C44A8278C8B5BFE15ABEB3C", // Music Manager
"B8F61FD1B25DE03706DBB8906A73261E4DBB992A" // Test
]
},
"nativeMessaging": [ "nativeMessaging": [
{ {
"channel": "beta", "channel": "beta",
......
...@@ -71,6 +71,7 @@ ...@@ -71,6 +71,7 @@
'media_galleries_private.idl', 'media_galleries_private.idl',
'media_player_private.json', 'media_player_private.json',
'metrics_private.json', 'metrics_private.json',
'music_manager_private.idl',
'networking_private.json', 'networking_private.json',
'notifications.idl', 'notifications.idl',
'omnibox.json', 'omnibox.json',
......
// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
[nodoc] namespace musicManagerPrivate {
callback GetDeviceIdCallback = void (DOMString device_id);
interface Functions {
// Returns an identifier stable across users and reboots.
//
// |callback| : Called with the stable identifier value.
static void getDeviceId(GetDeviceIdCallback callback);
};
};
...@@ -92,6 +92,7 @@ class APIPermission { ...@@ -92,6 +92,7 @@ class APIPermission {
kMediaGalleriesPrivate, kMediaGalleriesPrivate,
kMediaPlayerPrivate, kMediaPlayerPrivate,
kMetricsPrivate, kMetricsPrivate,
kMusicManagerPrivate,
kNativeMessaging, kNativeMessaging,
kNetworkingPrivate, kNetworkingPrivate,
kNotification, kNotification,
......
...@@ -151,6 +151,8 @@ std::vector<APIPermissionInfo*> ChromeAPIPermissions::GetAllPermissions() ...@@ -151,6 +151,8 @@ std::vector<APIPermissionInfo*> ChromeAPIPermissions::GetAllPermissions()
APIPermissionInfo::kFlagCannotBeOptional }, APIPermissionInfo::kFlagCannotBeOptional },
{ APIPermission::kMetricsPrivate, "metricsPrivate", { APIPermission::kMetricsPrivate, "metricsPrivate",
APIPermissionInfo::kFlagCannotBeOptional }, APIPermissionInfo::kFlagCannotBeOptional },
{ APIPermission::kMusicManagerPrivate, "musicManagerPrivate",
APIPermissionInfo::kFlagCannotBeOptional },
{ APIPermission::kSystemPrivate, "systemPrivate", { APIPermission::kSystemPrivate, "systemPrivate",
APIPermissionInfo::kFlagCannotBeOptional }, APIPermissionInfo::kFlagCannotBeOptional },
{ APIPermission::kCloudPrintPrivate, "cloudPrintPrivate", { APIPermission::kCloudPrintPrivate, "cloudPrintPrivate",
......
...@@ -695,6 +695,7 @@ TEST(PermissionsTest, PermissionMessages) { ...@@ -695,6 +695,7 @@ TEST(PermissionsTest, PermissionMessages) {
skip.insert(APIPermission::kMediaGalleriesPrivate); skip.insert(APIPermission::kMediaGalleriesPrivate);
skip.insert(APIPermission::kMediaPlayerPrivate); skip.insert(APIPermission::kMediaPlayerPrivate);
skip.insert(APIPermission::kMetricsPrivate); skip.insert(APIPermission::kMetricsPrivate);
skip.insert(APIPermission::kMusicManagerPrivate);
skip.insert(APIPermission::kNetworkingPrivate); skip.insert(APIPermission::kNetworkingPrivate);
skip.insert(APIPermission::kRtcPrivate); skip.insert(APIPermission::kRtcPrivate);
skip.insert(APIPermission::kStreamsPrivate); skip.insert(APIPermission::kStreamsPrivate);
......
// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
function runTests() {
chrome.test.runTests([
function test() {
chrome.musicManagerPrivate.getDeviceId(function(id) {
console.log("Device ID=" + id);
chrome.test.assertEq("string", typeof id);
chrome.test.assertTrue(id.length >= 8);
chrome.test.succeed();
});
}
]);
}
window.onload = function() {
chrome.test.getConfig(function(config) {
runTests();
});
}
<!--
* Copyright 2013 The Chromium Authors. All rights reserved. Use of this
* source code is governed by a BSD-style license that can be found in the
* LICENSE file.
-->
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>&lt;Music Manager Private&gt; Sample</title>
<script src="chrometest.js"></script>
</head>
<body>
</body>
</html>
// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* Listens for the app launching then creates the window
*
* @see http://developer.chrome.com/trunk/apps/app.runtime.html
* @see http://developer.chrome.com/trunk/apps/app.window.html
*/
chrome.app.runtime.onLaunched.addListener(function() {
chrome.app.window.create('index.html',
{top:0, left: 0, width: 900, height: 800});
});
{
"key": "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC61/45N9NLV2RJed0+RTsio6gyrcYKCaIz5dPjNrOvvLa6LMSbMCsXwecHkXR8ohd26AmgOjYlkSFl4JSzNybDcVPO1p/EfkF/o5k/GC6IPtS2PBFBsjjktz2hdAwSlY04QSW0X0TsDKxCPg69CaudH0cbCFxxJ3ml7R4xfDPXxwIDAQAB",
"manifest_version": 2,
"name": "Music Manager Private Sample",
"version": "0.1",
"minimum_chrome_version": "28",
"app": {
"background": {
"scripts": ["main.js"]
}
},
"permissions": [
"musicManagerPrivate"
]
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment