summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authornoamsml@chromium.org <noamsml@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-06-14 19:55:59 +0000
committernoamsml@chromium.org <noamsml@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-06-14 19:55:59 +0000
commit1862693823dcdcef50caf63325b5b9dbcbc75516 (patch)
tree5d9e92e08de34afc51467b7e15ae91687d6a088a
parent9d20d7d94e5e3ee442be84c3ed7290e57bcba75e (diff)
downloadchromium_src-1862693823dcdcef50caf63325b5b9dbcbc75516.zip
chromium_src-1862693823dcdcef50caf63325b5b9dbcbc75516.tar.gz
chromium_src-1862693823dcdcef50caf63325b5b9dbcbc75516.tar.bz2
Implementation for gcdPrivate.getCloudDeviceList plus tests.
Get cloud device list from Javascript API. BUG= Review URL: https://codereview.chromium.org/332483006 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@277258 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/extensions/api/gcd_private/gcd_private_api.cc119
-rw-r--r--chrome/browser/extensions/api/gcd_private/gcd_private_api.h33
-rw-r--r--chrome/browser/extensions/api/gcd_private/gcd_private_apitest.cc124
-rw-r--r--chrome/browser/local_discovery/gcd_constants.cc1
-rw-r--r--chrome/browser/local_discovery/gcd_constants.h1
-rw-r--r--chrome/chrome_tests.gypi1
-rw-r--r--chrome/test/data/extensions/api_test/gcd_private/api/get_cloud_list.html1
-rw-r--r--chrome/test/data/extensions/api_test/gcd_private/api/get_cloud_list.js37
-rw-r--r--chrome/test/data/extensions/api_test/gcd_private/api/manifest.json7
-rw-r--r--chrome/test/data/extensions/api_test/gcd_private/api/trun8
10 files changed, 327 insertions, 5 deletions
diff --git a/chrome/browser/extensions/api/gcd_private/gcd_private_api.cc b/chrome/browser/extensions/api/gcd_private/gcd_private_api.cc
index 38ddcb8..b17b984 100644
--- a/chrome/browser/extensions/api/gcd_private/gcd_private_api.cc
+++ b/chrome/browser/extensions/api/gcd_private/gcd_private_api.cc
@@ -6,14 +6,53 @@
#include "base/lazy_instance.h"
#include "base/memory/scoped_ptr.h"
+#include "chrome/browser/local_discovery/cloud_device_list.h"
+#include "chrome/browser/local_discovery/cloud_print_printer_list.h"
+#include "chrome/browser/local_discovery/gcd_constants.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
+#include "chrome/browser/signin/signin_manager_factory.h"
+#include "components/signin/core/browser/profile_oauth2_token_service.h"
+#include "components/signin/core/browser/signin_manager.h"
+#include "components/signin/core/browser/signin_manager_base.h"
namespace extensions {
+using extensions::api::gcd_private::GCDDevice;
+
namespace {
+
+const int kNumRequestsNeeded = 2;
+
+const char kIDPrefixCloudPrinter[] = "cloudprint:";
+const char kIDPrefixGcd[] = "gcd:";
+
+GcdPrivateAPI::GCDApiFlowFactoryForTests* g_gcd_api_flow_factory = NULL;
+
base::LazyInstance<BrowserContextKeyedAPIFactory<GcdPrivateAPI> > g_factory =
LAZY_INSTANCE_INITIALIZER;
+
+scoped_ptr<local_discovery::GCDApiFlow> MakeGCDApiFlow(Profile* profile) {
+ if (g_gcd_api_flow_factory) {
+ return g_gcd_api_flow_factory->CreateGCDApiFlow();
+ }
+
+ ProfileOAuth2TokenService* token_service =
+ ProfileOAuth2TokenServiceFactory::GetForProfile(profile);
+ if (!token_service)
+ return scoped_ptr<local_discovery::GCDApiFlow>();
+ SigninManagerBase* signin_manager =
+ SigninManagerFactory::GetInstance()->GetForProfile(profile);
+ if (!signin_manager)
+ return scoped_ptr<local_discovery::GCDApiFlow>();
+ return local_discovery::GCDApiFlow::Create(
+ profile->GetRequestContext(),
+ token_service,
+ signin_manager->GetAuthenticatedAccountId());
}
+} // namespace
+
GcdPrivateAPI::GcdPrivateAPI(content::BrowserContext* context)
: browser_context_(context) {
}
@@ -27,12 +66,86 @@ GcdPrivateAPI::GetFactoryInstance() {
return g_factory.Pointer();
}
+// static
+void GcdPrivateAPI::SetGCDApiFlowFactoryForTests(
+ GCDApiFlowFactoryForTests* factory) {
+ g_gcd_api_flow_factory = factory;
+}
+
+GcdPrivateGetCloudDeviceListFunction::GcdPrivateGetCloudDeviceListFunction() {
+}
+GcdPrivateGetCloudDeviceListFunction::~GcdPrivateGetCloudDeviceListFunction() {
+}
+
bool GcdPrivateGetCloudDeviceListFunction::RunAsync() {
- results_.reset(new base::ListValue);
- results_->Append(new base::ListValue);
+ requests_succeeded_ = 0;
+ requests_failed_ = 0;
+
+ printer_list_ = MakeGCDApiFlow(GetProfile());
+ device_list_ = MakeGCDApiFlow(GetProfile());
+
+ if (!printer_list_ || !device_list_)
+ return false;
+
+ // Balanced in CheckListingDone()
+ AddRef();
+
+ printer_list_->Start(make_scoped_ptr<local_discovery::GCDApiFlow::Request>(
+ new local_discovery::CloudPrintPrinterList(this)));
+ device_list_->Start(make_scoped_ptr<local_discovery::GCDApiFlow::Request>(
+ new local_discovery::CloudDeviceList(this)));
- SendResponse(true);
return true;
}
+void GcdPrivateGetCloudDeviceListFunction::OnDeviceListReady(
+ const DeviceList& devices) {
+ requests_succeeded_++;
+
+ devices_.insert(devices_.end(), devices.begin(), devices.end());
+
+ CheckListingDone();
+}
+
+void GcdPrivateGetCloudDeviceListFunction::OnDeviceListUnavailable() {
+ requests_failed_++;
+
+ CheckListingDone();
+}
+
+void GcdPrivateGetCloudDeviceListFunction::CheckListingDone() {
+ if (requests_failed_ + requests_succeeded_ != kNumRequestsNeeded)
+ return;
+
+ if (requests_succeeded_ == 0) {
+ SendResponse(false);
+ return;
+ }
+
+ std::vector<linked_ptr<GCDDevice> > devices;
+
+ for (DeviceList::iterator i = devices_.begin(); i != devices_.end(); i++) {
+ linked_ptr<GCDDevice> device(new GCDDevice);
+ device->setup_type = extensions::api::gcd_private::SETUP_TYPE_CLOUD;
+ if (i->type == local_discovery::kGCDTypePrinter) {
+ device->id_string = kIDPrefixCloudPrinter + i->id;
+ } else {
+ device->id_string = kIDPrefixGcd + i->id;
+ }
+
+ device->cloud_id.reset(new std::string(i->id));
+ device->device_type = i->type;
+ device->device_name = i->display_name;
+ device->device_description = i->description;
+
+ devices.push_back(device);
+ }
+
+ results_ = extensions::api::gcd_private::GetCloudDeviceList::Results::Create(
+ devices);
+
+ SendResponse(true);
+ Release();
+}
+
} // namespace extensions
diff --git a/chrome/browser/extensions/api/gcd_private/gcd_private_api.h b/chrome/browser/extensions/api/gcd_private/gcd_private_api.h
index dc7b680..d8c6f46 100644
--- a/chrome/browser/extensions/api/gcd_private/gcd_private_api.h
+++ b/chrome/browser/extensions/api/gcd_private/gcd_private_api.h
@@ -5,7 +5,10 @@
#ifndef CHROME_BROWSER_EXTENSIONS_API_GCD_PRIVATE_GCD_PRIVATE_API_H_
#define CHROME_BROWSER_EXTENSIONS_API_GCD_PRIVATE_GCD_PRIVATE_API_H_
+#include "base/memory/scoped_ptr.h"
#include "chrome/browser/extensions/chrome_extension_function.h"
+#include "chrome/browser/local_discovery/cloud_device_list_delegate.h"
+#include "chrome/browser/local_discovery/gcd_api_flow.h"
#include "chrome/common/extensions/api/gcd_private.h"
#include "extensions/browser/browser_context_keyed_api_factory.h"
@@ -13,9 +16,18 @@ namespace extensions {
class GcdPrivateAPI : public BrowserContextKeyedAPI {
public:
+ class GCDApiFlowFactoryForTests {
+ public:
+ virtual ~GCDApiFlowFactoryForTests() {}
+
+ virtual scoped_ptr<local_discovery::GCDApiFlow> CreateGCDApiFlow() = 0;
+ };
+
explicit GcdPrivateAPI(content::BrowserContext* context);
virtual ~GcdPrivateAPI();
+ static void SetGCDApiFlowFactoryForTests(GCDApiFlowFactoryForTests* factory);
+
// BrowserContextKeyedAPI implementation.
static BrowserContextKeyedAPIFactory<GcdPrivateAPI>* GetFactoryInstance();
@@ -29,16 +41,33 @@ class GcdPrivateAPI : public BrowserContextKeyedAPI {
};
class GcdPrivateGetCloudDeviceListFunction
- : public ChromeAsyncExtensionFunction {
+ : public ChromeAsyncExtensionFunction,
+ public local_discovery::CloudDeviceListDelegate {
public:
DECLARE_EXTENSION_FUNCTION("gcdPrivate.getCloudDeviceList",
FEEDBACKPRIVATE_GETSTRINGS)
+ GcdPrivateGetCloudDeviceListFunction();
+
protected:
- virtual ~GcdPrivateGetCloudDeviceListFunction() {}
+ virtual ~GcdPrivateGetCloudDeviceListFunction();
// SyncExtensionFunction overrides.
virtual bool RunAsync() OVERRIDE;
+
+ private:
+ // CloudDeviceListDelegate implementation
+ virtual void OnDeviceListReady(const DeviceList& devices) OVERRIDE;
+ virtual void OnDeviceListUnavailable() OVERRIDE;
+
+ void CheckListingDone();
+
+ int requests_succeeded_;
+ int requests_failed_;
+ DeviceList devices_;
+
+ scoped_ptr<local_discovery::GCDApiFlow> printer_list_;
+ scoped_ptr<local_discovery::GCDApiFlow> device_list_;
};
} // namespace extensions
diff --git a/chrome/browser/extensions/api/gcd_private/gcd_private_apitest.cc b/chrome/browser/extensions/api/gcd_private/gcd_private_apitest.cc
new file mode 100644
index 0000000..7e6ae8b
--- /dev/null
+++ b/chrome/browser/extensions/api/gcd_private/gcd_private_apitest.cc
@@ -0,0 +1,124 @@
+// Copyright 2014 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 "base/command_line.h"
+#include "base/json/json_reader.h"
+#include "chrome/browser/extensions/api/gcd_private/gcd_private_api.h"
+#include "chrome/browser/extensions/extension_apitest.h"
+#include "chrome/browser/extensions/extension_service.h"
+#include "chrome/common/extensions/api/mdns.h"
+#include "extensions/common/switches.h"
+#include "testing/gmock/include/gmock/gmock.h"
+
+namespace api = extensions::api;
+
+namespace {
+
+const char kCloudPrintResponse[] =
+ "{"
+ " \"success\": true,"
+ " \"printers\": ["
+ " {\"id\" : \"someCloudPrintID\","
+ " \"displayName\": \"someCloudPrintDisplayName\","
+ " \"description\": \"someCloudPrintDescription\"}"
+ " ]"
+ "}";
+
+const char kGCDResponse[] =
+ "{"
+ "\"kind\": \"clouddevices#devicesListResponse\","
+ "\"devices\": [{"
+ " \"kind\": \"clouddevices#device\","
+ " \"id\": \"someGCDID\","
+ " \"deviceKind\": \"someType\","
+ " \"creationTimeMs\": \"123\","
+ " \"systemName\": \"someGCDDisplayName\","
+ " \"owner\": \"user@domain.com\","
+ " \"description\": \"someGCDDescription\","
+ " \"state\": {"
+ " \"base\": {"
+ " \"connectionStatus\": \"offline\""
+ " }"
+ " },"
+ " \"channel\": {"
+ " \"supportedType\": \"xmpp\""
+ " },"
+ " \"personalizedInfo\": {"
+ " \"maxRole\": \"owner\""
+ " }}]}";
+
+// Sentinel value to signify the request should fail.
+const char kResponseValueFailure[] = "FAILURE";
+
+class FakeGCDApiFlowFactory
+ : public extensions::GcdPrivateAPI::GCDApiFlowFactoryForTests {
+ public:
+ FakeGCDApiFlowFactory() {
+ extensions::GcdPrivateAPI::SetGCDApiFlowFactoryForTests(this);
+ }
+
+ virtual ~FakeGCDApiFlowFactory() {
+ extensions::GcdPrivateAPI::SetGCDApiFlowFactoryForTests(NULL);
+ }
+
+ virtual scoped_ptr<local_discovery::GCDApiFlow> CreateGCDApiFlow() OVERRIDE {
+ return scoped_ptr<local_discovery::GCDApiFlow>(new FakeGCDApiFlow(this));
+ }
+
+ void SetResponse(const GURL& url, const std::string& response) {
+ responses_[url] = response;
+ }
+
+ private:
+ class FakeGCDApiFlow : public local_discovery::GCDApiFlow {
+ public:
+ explicit FakeGCDApiFlow(FakeGCDApiFlowFactory* factory)
+ : factory_(factory) {}
+
+ virtual ~FakeGCDApiFlow() {}
+
+ virtual void Start(scoped_ptr<Request> request) OVERRIDE {
+ std::string response_str = factory_->responses_[request->GetURL()];
+
+ if (response_str == kResponseValueFailure) {
+ request->OnGCDAPIFlowError(
+ local_discovery::GCDApiFlow::ERROR_MALFORMED_RESPONSE);
+ return;
+ }
+
+ scoped_ptr<base::Value> response(base::JSONReader::Read(response_str));
+ ASSERT_TRUE(response);
+
+ base::DictionaryValue* response_dict;
+ ASSERT_TRUE(response->GetAsDictionary(&response_dict));
+
+ request->OnGCDAPIFlowComplete(*response_dict);
+ }
+
+ private:
+ FakeGCDApiFlowFactory* factory_;
+ };
+
+ std::map<GURL /*request url*/, std::string /*response json*/> responses_;
+};
+
+class GcdPrivateAPITest : public ExtensionApiTest {
+ public:
+ GcdPrivateAPITest() {}
+
+ protected:
+ FakeGCDApiFlowFactory api_flow_factory_;
+};
+
+IN_PROC_BROWSER_TEST_F(GcdPrivateAPITest, GetCloudList) {
+ api_flow_factory_.SetResponse(
+ GURL("https://www.google.com/cloudprint/search"), kCloudPrintResponse);
+
+ api_flow_factory_.SetResponse(
+ GURL("https://www.googleapis.com/clouddevices/v1/devices"), kGCDResponse);
+
+ EXPECT_TRUE(RunExtensionSubtest("gcd_private/api", "get_cloud_list.html"));
+}
+
+} // namespace
diff --git a/chrome/browser/local_discovery/gcd_constants.cc b/chrome/browser/local_discovery/gcd_constants.cc
index b5b63cc..9c7e050 100644
--- a/chrome/browser/local_discovery/gcd_constants.cc
+++ b/chrome/browser/local_discovery/gcd_constants.cc
@@ -7,5 +7,6 @@
namespace local_discovery {
const char kGCDKeyKind[] = "kind";
+const char kGCDTypePrinter[] = "printer";
} // namespace local_discovery
diff --git a/chrome/browser/local_discovery/gcd_constants.h b/chrome/browser/local_discovery/gcd_constants.h
index c51d15e..542a0b7 100644
--- a/chrome/browser/local_discovery/gcd_constants.h
+++ b/chrome/browser/local_discovery/gcd_constants.h
@@ -8,6 +8,7 @@
namespace local_discovery {
extern const char kGCDKeyKind[];
+extern const char kGCDTypePrinter[];
} // namespace local_discovery
diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi
index 7ebd5e0..6f7c7f8 100644
--- a/chrome/chrome_tests.gypi
+++ b/chrome/chrome_tests.gypi
@@ -1089,6 +1089,7 @@
'browser/extensions/api/file_system/file_system_apitest_chromeos.cc',
'browser/extensions/api/font_settings/font_settings_apitest.cc',
'browser/extensions/api/gcm/gcm_apitest.cc',
+ 'browser/extensions/api/gcd_private/gcd_private_apitest.cc',
'browser/extensions/api/history/history_apitest.cc',
'browser/extensions/api/hotword_private/hotword_private_apitest.cc',
'browser/extensions/api/i18n/i18n_apitest.cc',
diff --git a/chrome/test/data/extensions/api_test/gcd_private/api/get_cloud_list.html b/chrome/test/data/extensions/api_test/gcd_private/api/get_cloud_list.html
new file mode 100644
index 0000000..c658bdd
--- /dev/null
+++ b/chrome/test/data/extensions/api_test/gcd_private/api/get_cloud_list.html
@@ -0,0 +1 @@
+<script src="get_cloud_list.js"></script>
diff --git a/chrome/test/data/extensions/api_test/gcd_private/api/get_cloud_list.js b/chrome/test/data/extensions/api_test/gcd_private/api/get_cloud_list.js
new file mode 100644
index 0000000..0ea069c
--- /dev/null
+++ b/chrome/test/data/extensions/api_test/gcd_private/api/get_cloud_list.js
@@ -0,0 +1,37 @@
+// Copyright 2014 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.
+
+onload = function() {
+ chrome.test.runTests([
+ function getCloudList() {
+ chrome.gcdPrivate.getCloudDeviceList(function(services) {
+ // Sort to avoid order dependence
+ services.sort(function(a,b) {
+ return a.idString.localeCompare(b.idString);
+ });
+
+ chrome.test.assertEq(2, services.length);
+
+ chrome.test.assertEq(services[0].setupType, "cloud");
+ chrome.test.assertEq(services[0].idString,
+ "cloudprint:someCloudPrintID");
+ chrome.test.assertEq(services[0].cloudId, "someCloudPrintID");
+ chrome.test.assertEq(services[0].deviceType, "printer");
+ chrome.test.assertEq(services[0].deviceName,
+ "someCloudPrintDisplayName");
+ chrome.test.assertEq(services[0].deviceDescription,
+ "someCloudPrintDescription");
+
+ chrome.test.assertEq(services[1].setupType, "cloud");
+ chrome.test.assertEq(services[1].idString, "gcd:someGCDID");
+ chrome.test.assertEq(services[1].cloudId, "someGCDID");
+ chrome.test.assertEq(services[1].deviceType, "someType");
+ chrome.test.assertEq(services[1].deviceName, "someGCDDisplayName");
+ chrome.test.assertEq(services[1].deviceDescription,
+ "someGCDDescription");
+
+ chrome.test.notifyPass();
+ })
+ }]);
+};
diff --git a/chrome/test/data/extensions/api_test/gcd_private/api/manifest.json b/chrome/test/data/extensions/api_test/gcd_private/api/manifest.json
new file mode 100644
index 0000000..9ada54d
--- /dev/null
+++ b/chrome/test/data/extensions/api_test/gcd_private/api/manifest.json
@@ -0,0 +1,7 @@
+ {
+ "manifest_version": 2,
+ "name": "GCD Extension",
+ "version": "1.0",
+ "description": "Test GCD Extension",
+ "permissions": ["gcdPrivate"]
+}
diff --git a/chrome/test/data/extensions/api_test/gcd_private/api/trun b/chrome/test/data/extensions/api_test/gcd_private/api/trun
new file mode 100644
index 0000000..96cfbed
--- /dev/null
+++ b/chrome/test/data/extensions/api_test/gcd_private/api/trun
@@ -0,0 +1,8 @@
+ {
+ "key": "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC8xv6iO+j4kzj1HiBL93+XVJH/CRyAQMUHS/Z0l8nCAzaAFkW/JsNwxJqQhrZspnxLqbQxNncXs6g6bsXAwKHiEs+LSs+bIv0Gc/2ycZdhXJ8GhEsSMakog5dpQd1681c2gLK/8CrAoewE/0GIKhaFcp7a2iZlGh4Am6fgMKy0iQIDAQAB",
+ "manifest_version": 2,
+ "name": "MDNS Extension",
+ "version": "1.0",
+ "description": "Test MDNS Extension",
+ "permissions": ["mdns"]
+}