Chromium Code Reviews| Index: chrome/browser/devtools/devtools_targets_ui.cc |
| diff --git a/chrome/browser/devtools/devtools_targets_ui.cc b/chrome/browser/devtools/devtools_targets_ui.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..0130f49d2b2ad76a8bfd31f67666072c36e0087c |
| --- /dev/null |
| +++ b/chrome/browser/devtools/devtools_targets_ui.cc |
| @@ -0,0 +1,557 @@ |
| +// Copyright (c) 2012 The Chromium Authors. All rights reserved. |
|
vsevik
2013/11/12 14:24:07
ditto
Vladislav Kaznacheev
2013/11/13 16:02:33
Done.
|
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +#include "chrome/browser/devtools/devtools_targets_ui.h" |
| + |
| +#include "base/stl_util.h" |
| +#include "base/strings/stringprintf.h" |
| +#include "base/values.h" |
| +#include "chrome/browser/devtools/devtools_adb_bridge.h" |
| +#include "chrome/browser/devtools/devtools_target_impl.h" |
| +#include "chrome/browser/devtools/port_forwarding_controller.h" |
| +#include "content/public/browser/browser_child_process_observer.h" |
| +#include "content/public/browser/browser_thread.h" |
| +#include "content/public/browser/child_process_data.h" |
| +#include "content/public/browser/notification_observer.h" |
| +#include "content/public/browser/notification_registrar.h" |
| +#include "content/public/browser/notification_service.h" |
| +#include "content/public/browser/notification_source.h" |
| +#include "content/public/browser/notification_types.h" |
| +#include "content/public/browser/render_process_host.h" |
| +#include "content/public/browser/render_view_host.h" |
| +#include "content/public/browser/web_contents.h" |
| +#include "content/public/browser/worker_service.h" |
| +#include "content/public/browser/worker_service_observer.h" |
| +#include "content/public/common/process_type.h" |
| +#include "net/base/escape.h" |
| + |
| +using content::BrowserThread; |
| +using content::WebContents; |
| + |
| +namespace { |
| + |
| +const char kTargetSourceField[] = "source"; |
| +const char kTargetSourceRenderer[] = "renderers"; |
| +const char kTargetSourceWorker[] = "workers"; |
| +const char kTargetSourceAdb[] = "adb"; |
| + |
| +const char kTargetIdField[] = "id"; |
| +const char kTargetTypeField[] = "type"; |
| +const char kAttachedField[] = "attached"; |
| +const char kUrlField[] = "url"; |
| +const char kNameField[] = "name"; |
| +const char kFaviconUrlField[] = "faviconUrl"; |
| +const char kDescriptionField[] = "description"; |
| + |
| +const char kGuestList[] = "guests"; |
| + |
| +const char kAdbModelField[] = "adbModel"; |
| +const char kAdbConnectedField[] = "adbConnected"; |
| +const char kAdbSerialField[] = "adbSerial"; |
| +const char kAdbPortStatus[] = "adbPortStatus"; |
| +const char kAdbBrowsersList[] = "browsers"; |
| + |
| +const char kAdbBrowserNameField[] = "adbBrowserName"; |
| +const char kAdbBrowserVersionField[] = "adbBrowserVersion"; |
| +const char kAdbBrowserChromeVersionField[] = "adbBrowserChromeVersion"; |
| +const char kAdbPagesList[] = "pages"; |
| +const char kAdbPackagesList[] = "packages"; |
| + |
| +const char kAdbScreenWidthField[] = "adbScreenWidth"; |
| +const char kAdbScreenHeightField[] = "adbScreenHeight"; |
| +const char kAdbAttachedForeignField[] = "adbAttachedForeign"; |
| + |
| +// RenderViewHostTargetsUIHandler --------------------------------------------- |
| + |
| +class RenderViewHostTargetsUIHandler |
| + : public DevToolsTargetsUIHandler, |
| + public content::NotificationObserver { |
| + public: |
| + explicit RenderViewHostTargetsUIHandler(Callback callback); |
| + virtual ~RenderViewHostTargetsUIHandler(); |
| + private: |
| + // content::NotificationObserver overrides. |
| + virtual void Observe(int type, |
| + const content::NotificationSource& source, |
| + const content::NotificationDetails& details) OVERRIDE; |
| + |
| + void UpdateTargets(); |
| + |
| + content::NotificationRegistrar notification_registrar_; |
| +}; |
| + |
| +RenderViewHostTargetsUIHandler::RenderViewHostTargetsUIHandler( |
| + Callback callback) |
| + : DevToolsTargetsUIHandler(kTargetSourceRenderer, callback) { |
| + notification_registrar_.Add(this, |
| + content::NOTIFICATION_WEB_CONTENTS_CONNECTED, |
| + content::NotificationService::AllSources()); |
| + notification_registrar_.Add(this, |
| + content::NOTIFICATION_WEB_CONTENTS_DISCONNECTED, |
| + content::NotificationService::AllSources()); |
| + notification_registrar_.Add(this, |
| + content::NOTIFICATION_WEB_CONTENTS_DESTROYED, |
| + content::NotificationService::AllSources()); |
| + UpdateTargets(); |
| +} |
| + |
| +RenderViewHostTargetsUIHandler::~RenderViewHostTargetsUIHandler() { |
| + notification_registrar_.RemoveAll(); |
| +} |
| + |
| +void RenderViewHostTargetsUIHandler::Observe( |
| + int type, |
| + const content::NotificationSource& source, |
| + const content::NotificationDetails& details) { |
| + UpdateTargets(); |
| +} |
| + |
| +void RenderViewHostTargetsUIHandler::UpdateTargets() { |
| + scoped_ptr<ListValue> list_value(new ListValue()); |
| + |
| + std::map<WebContents*, DictionaryValue*> web_contents_to_descriptor_; |
| + std::vector<DevToolsTargetImpl*> guest_targets; |
| + |
| + DevToolsTargetImpl::List targets = |
| + DevToolsTargetImpl::EnumerateRenderViewHostTargets(); |
| + |
| + STLDeleteValues(&targets_); |
| + for (DevToolsTargetImpl::List::iterator it = targets.begin(); |
| + it != targets.end(); ++it) { |
| + scoped_ptr<DevToolsTargetImpl> target(*it); |
| + content::RenderViewHost* rvh = target->GetRenderViewHost(); |
| + if (!rvh) |
| + continue; |
| + WebContents* web_contents = WebContents::FromRenderViewHost(rvh); |
| + if (!web_contents) |
| + continue; |
| + |
| + DevToolsTargetImpl* target_ptr = target.get(); |
| + targets_[target_ptr->GetId()] = target.release(); |
| + if (rvh->GetProcess()->IsGuest()) { |
| + guest_targets.push_back(target_ptr); |
| + } else { |
| + DictionaryValue* descriptor = Serialize(*target_ptr); |
| + list_value->Append(descriptor); |
| + web_contents_to_descriptor_[web_contents] = descriptor; |
| + } |
| + } |
| + |
| + // Add the list of guest-views to each of its embedders. |
| + for (std::vector<DevToolsTargetImpl*>::iterator it(guest_targets.begin()); |
| + it != guest_targets.end(); ++it) { |
| + DevToolsTargetImpl* guest = (*it); |
| + WebContents* guest_web_contents = |
| + WebContents::FromRenderViewHost(guest->GetRenderViewHost()); |
| + WebContents* embedder = guest_web_contents->GetEmbedderWebContents(); |
| + if (embedder && web_contents_to_descriptor_.count(embedder) > 0) { |
| + DictionaryValue* parent = web_contents_to_descriptor_[embedder]; |
| + ListValue* guests = NULL; |
| + if (!parent->GetList(kGuestList, &guests)) { |
| + guests = new ListValue(); |
| + parent->Set(kGuestList, guests); |
| + } |
| + guests->Append(Serialize(*guest)); |
| + } |
| + } |
| + |
| + SendSerializedTargets(list_value.Pass()); |
| +} |
| + |
| +// WorkerObserver ------------------------------------------------------------- |
| + |
| +class WorkerObserver |
| + : public content::WorkerServiceObserver, |
| + public base::RefCountedThreadSafe<WorkerObserver> { |
| + public: |
| + WorkerObserver() {} |
| + |
| + void Start(DevToolsTargetImpl::Callback callback) { |
| + DCHECK(callback_.is_null()); |
| + DCHECK(!callback.is_null()); |
| + callback_ = callback; |
| + BrowserThread::PostTask( |
| + BrowserThread::IO, FROM_HERE, |
| + base::Bind(&WorkerObserver::StartOnIOThread, this)); |
| + } |
| + |
| + void Stop() { |
| + DCHECK(!callback_.is_null()); |
| + callback_ = DevToolsTargetImpl::Callback(); |
| + BrowserThread::PostTask( |
| + BrowserThread::IO, FROM_HERE, |
| + base::Bind(&WorkerObserver::StopOnIOThread, this)); |
| + } |
| + |
| + void Enumerate() { |
| + BrowserThread::PostTask( |
| + BrowserThread::IO, FROM_HERE, |
| + base::Bind(&WorkerObserver::EnumerateOnUIThread, |
| + this)); |
| + } |
| + |
| + private: |
| + friend class base::RefCountedThreadSafe<WorkerObserver>; |
| + virtual ~WorkerObserver() {} |
| + |
| + // content::WorkerServiceObserver overrides: |
| + virtual void WorkerCreated( |
| + const GURL& url, |
| + const string16& name, |
| + int process_id, |
| + int route_id) OVERRIDE { |
| + EnumerateOnUIThread(); |
| + } |
| + |
| + virtual void WorkerDestroyed(int process_id, int route_id) OVERRIDE { |
| + EnumerateOnUIThread(); |
| + } |
| + |
| + void StartOnIOThread() { |
| + content::WorkerService::GetInstance()->AddObserver(this); |
| + EnumerateOnUIThread(); |
| + } |
| + |
| + void StopOnIOThread() { |
| + content::WorkerService::GetInstance()->RemoveObserver(this); |
| + } |
| + |
| + void EnumerateOnUIThread() { |
|
vsevik
2013/11/12 14:24:07
Seeing a method with a name that ends with "OnUITh
Vladislav Kaznacheev
2013/11/13 16:02:33
Oops. What was I thinking. Done.
|
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| + DevToolsTargetImpl::EnumerateWorkerTargets( |
| + base::Bind(&WorkerObserver::RespondOnUIThread, this)); |
| + } |
| + |
| + void RespondOnUIThread(const DevToolsTargetImpl::List& targets) { |
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| + if (callback_.is_null()) |
| + return; |
| + callback_.Run(targets); |
| + } |
| + |
| + DevToolsTargetImpl::Callback callback_; |
| +}; |
| + |
| +// WorkerTargetsUIHandler ----------------------------------------------------- |
| + |
| +class WorkerTargetsUIHandler |
| + : public DevToolsTargetsUIHandler, |
| + public content::BrowserChildProcessObserver { |
| + public: |
| + explicit WorkerTargetsUIHandler(Callback callback); |
| + virtual ~WorkerTargetsUIHandler(); |
| + |
| + private: |
| + // content::BrowserChildProcessObserver overrides. |
| + virtual void BrowserChildProcessHostConnected( |
| + const content::ChildProcessData& data) OVERRIDE; |
| + virtual void BrowserChildProcessHostDisconnected( |
| + const content::ChildProcessData& data) OVERRIDE; |
| + |
| + void UpdateTargets(const DevToolsTargetImpl::List& targets); |
| + |
| + scoped_refptr<WorkerObserver> observer_; |
| +}; |
| + |
| +WorkerTargetsUIHandler::WorkerTargetsUIHandler(Callback callback) |
| + : DevToolsTargetsUIHandler(kTargetSourceWorker, callback), |
| + observer_(new WorkerObserver()) { |
| + observer_->Start(base::Bind(&WorkerTargetsUIHandler::UpdateTargets, |
| + base::Unretained(this))); |
| + BrowserChildProcessObserver::Add(this); |
| +} |
| + |
| +WorkerTargetsUIHandler::~WorkerTargetsUIHandler() { |
| + BrowserChildProcessObserver::Remove(this); |
| + observer_->Stop(); |
| +} |
| + |
| +void WorkerTargetsUIHandler::BrowserChildProcessHostConnected( |
| + const content::ChildProcessData& data) { |
| + if (data.process_type == content::PROCESS_TYPE_WORKER) |
| + observer_->Enumerate(); |
| +} |
| + |
| +void WorkerTargetsUIHandler::BrowserChildProcessHostDisconnected( |
| + const content::ChildProcessData& data) { |
| + if (data.process_type == content::PROCESS_TYPE_WORKER) |
| + observer_->Enumerate(); |
| +} |
| + |
| +void WorkerTargetsUIHandler::UpdateTargets( |
| + const DevToolsTargetImpl::List& targets) { |
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| + scoped_ptr<ListValue> list_value(new ListValue()); |
| + STLDeleteValues(&targets_); |
| + for (DevToolsTargetImpl::List::const_iterator it = targets.begin(); |
| + it != targets.end(); ++it) { |
| + DevToolsTargetImpl* target = *it; |
| + list_value->Append(Serialize(*target)); |
| + targets_[target->GetId()] = target; |
| + } |
| + SendSerializedTargets(list_value.Pass()); |
| +} |
| + |
| +// AdbTargetsUIHandler -------------------------------------------------------- |
| + |
| +class AdbTargetsUIHandler |
| + : public DevToolsRemoteTargetsUIHandler, |
| + public DevToolsAdbBridge::Listener { |
| + public: |
| + AdbTargetsUIHandler(Callback callback, Profile* profile); |
| + virtual ~AdbTargetsUIHandler(); |
| + |
| + virtual void Open(const std::string& browser_id, |
| + const std::string& url) OVERRIDE; |
| + virtual void Launch(const std::string& package_id) OVERRIDE; |
| + |
| + private: |
| + // DevToolsAdbBridge::Listener overrides. |
| + virtual void RemoteDevicesChanged( |
| + DevToolsAdbBridge::RemoteDevices* devices) OVERRIDE; |
| + |
| + Profile* profile_; |
| + |
| + typedef std::map<std::string, |
| + scoped_refptr<DevToolsAdbBridge::RemoteBrowser> > RemoteBrowsers; |
| + RemoteBrowsers remote_browsers_; |
| + |
| + typedef std::map<std::string, |
| + scoped_refptr<DevToolsAdbBridge::RemotePackage> > RemotePackages; |
| + RemotePackages remote_packages_; |
| +}; |
| + |
| +AdbTargetsUIHandler::AdbTargetsUIHandler(Callback callback, Profile* profile) |
| + : DevToolsRemoteTargetsUIHandler(kTargetSourceAdb, callback), |
| + profile_(profile) { |
| + DevToolsAdbBridge* adb_bridge = |
| + DevToolsAdbBridge::Factory::GetForProfile(profile_); |
| + if (adb_bridge) |
| + adb_bridge->AddListener(this); |
| +} |
| + |
| +AdbTargetsUIHandler::~AdbTargetsUIHandler() { |
| + DevToolsAdbBridge* adb_bridge = |
| + DevToolsAdbBridge::Factory::GetForProfile(profile_); |
| + if (adb_bridge) |
| + adb_bridge->RemoveListener(this); |
| +} |
| + |
| +void AdbTargetsUIHandler::Open(const std::string& browser_id, |
| + const std::string& url) { |
| + RemoteBrowsers::iterator it = remote_browsers_.find(browser_id); |
| + if (it != remote_browsers_.end()) |
| + it->second->Open(url); |
| +} |
| + |
| +void AdbTargetsUIHandler::Launch(const std::string& package_id) { |
| + RemotePackages::iterator it = remote_packages_.find(package_id); |
| + if (it != remote_packages_.end()) |
| + it->second->Launch(); |
| +} |
| + |
| +void AdbTargetsUIHandler::RemoteDevicesChanged( |
| + DevToolsAdbBridge::RemoteDevices* devices) { |
| + PortForwardingController* port_forwarding_controller = |
| + PortForwardingController::Factory::GetForProfile(profile_); |
| + PortForwardingController::DevicesStatus port_forwarding_status; |
| + if (port_forwarding_controller) |
| + port_forwarding_status = |
| + port_forwarding_controller->UpdateDeviceList(*devices); |
| + |
| + remote_browsers_.clear(); |
| + remote_packages_.clear(); |
| + STLDeleteValues(&targets_); |
| + |
| + scoped_ptr<ListValue> device_list(new ListValue()); |
| + for (DevToolsAdbBridge::RemoteDevices::iterator dit = devices->begin(); |
| + dit != devices->end(); ++dit) { |
| + DevToolsAdbBridge::RemoteDevice* device = dit->get(); |
| + DictionaryValue* device_data = new DictionaryValue(); |
| + device_data->SetString(kAdbModelField, device->GetModel()); |
| + device_data->SetString(kAdbSerialField, device->GetSerial()); |
| + device_data->SetBoolean(kAdbConnectedField, device->IsConnected()); |
| + std::string device_id = base::StringPrintf( |
| + "device:%s", |
| + device->GetSerial().c_str()); |
| + device_data->SetString(kTargetIdField, device_id); |
| + ListValue* browser_list = new ListValue(); |
| + device_data->Set(kAdbBrowsersList, browser_list); |
| + |
| + DevToolsAdbBridge::RemoteBrowsers& browsers = device->browsers(); |
| + for (DevToolsAdbBridge::RemoteBrowsers::iterator bit = |
| + browsers.begin(); bit != browsers.end(); ++bit) { |
| + DevToolsAdbBridge::RemoteBrowser* browser = bit->get(); |
| + DictionaryValue* browser_data = new DictionaryValue(); |
| + browser_data->SetString(kAdbBrowserNameField, browser->display_name()); |
| + browser_data->SetString(kAdbBrowserVersionField, browser->version()); |
| + DevToolsAdbBridge::RemoteBrowser::ParsedVersion parsed = |
| + browser->GetParsedVersion(); |
| + browser_data->SetInteger( |
| + kAdbBrowserChromeVersionField, |
| + browser->IsChrome() && !parsed.empty() ? parsed[0] : 0); |
| + std::string browser_id = base::StringPrintf( |
| + "browser:%s:%s:%s:%s", |
| + device->GetSerial().c_str(), // Ensure uniqueness across devices. |
| + browser->display_name().c_str(), // Sort by display name. |
| + browser->version().c_str(), // Then by version. |
| + browser->socket().c_str()); // Ensure uniqueness on the device. |
| + browser_data->SetString(kTargetIdField, browser_id); |
| + browser_data->SetString(kTargetSourceField, source_id()); |
| + remote_browsers_[browser_id] = browser; |
| + ListValue* page_list = new ListValue(); |
| + browser_data->Set(kAdbPagesList, page_list); |
| + |
| + DevToolsTargetImpl::List pages = browser->CreatePageTargets(); |
| + for (DevToolsTargetImpl::List::iterator it = |
| + pages.begin(); it != pages.end(); ++it) { |
| + DevToolsTargetImpl* target = *it; |
| + DictionaryValue* target_data = Serialize(*target); |
| + target_data->SetBoolean( |
| + kAdbAttachedForeignField, |
| + target->IsAttached() && |
| + !DevToolsAdbBridge::HasDevToolsWindow(target->GetId())); |
| + // Pass the screen size in the target object to make sure that |
| + // the caching logic does not prevent the target item from updating |
| + // when the screen size changes. |
| + gfx::Size screen_size = device->screen_size(); |
| + target_data->SetInteger(kAdbScreenWidthField, screen_size.width()); |
| + target_data->SetInteger(kAdbScreenHeightField, screen_size.height()); |
| + targets_[target->GetId()] = target; |
| + page_list->Append(target_data); |
| + } |
| + browser_list->Append(browser_data); |
| + } |
| + |
| + ListValue* package_list = new ListValue(); |
| + device_data->Set(kAdbPackagesList, package_list); |
| + |
| + DevToolsAdbBridge::RemotePackages& packages = device->packages(); |
| + for (DevToolsAdbBridge::RemotePackages::iterator pit = packages.begin(); |
| + pit != packages.end(); ++pit) { |
| + DevToolsAdbBridge::RemotePackage* package = pit->get(); |
| + DictionaryValue* package_data = new DictionaryValue(); |
| + package_data->SetString(kAdbBrowserNameField, package->display_name()); |
| + std::string package_id = base::StringPrintf( |
| + "package:%s:%s", |
| + device->GetSerial().c_str(), // Ensure uniqueness across devices. |
| + package->package_name().c_str()); // Ensure uniqueness on the device. |
| + package_data->SetString(kTargetIdField, package_id); |
| + package_data->SetString(kTargetSourceField, source_id()); |
| + remote_packages_[package_id] = package; |
| + package_list->Append(package_data); |
| + } |
| + |
| + if (port_forwarding_controller) { |
| + PortForwardingController::DevicesStatus::iterator sit = |
| + port_forwarding_status.find(device->GetSerial()); |
| + if (sit != port_forwarding_status.end()) { |
| + DictionaryValue* port_status_dict = new DictionaryValue(); |
| + typedef PortForwardingController::PortStatusMap StatusMap; |
| + const StatusMap& port_status = sit->second; |
| + for (StatusMap::const_iterator it = port_status.begin(); |
| + it != port_status.end(); ++it) { |
| + port_status_dict->SetInteger( |
| + base::StringPrintf("%d", it->first), it->second); |
| + } |
| + device_data->Set(kAdbPortStatus, port_status_dict); |
| + } |
| + } |
| + |
| + device_list->Append(device_data); |
| + } |
| + SendSerializedTargets(device_list.Pass()); |
| +} |
| + |
| +} // namespace |
| + |
| +// DevToolsTargetsUIHandler --------------------------------------------------- |
| + |
| +DevToolsTargetsUIHandler::DevToolsTargetsUIHandler( |
| + const std::string& source_id, |
| + Callback callback) |
| + : source_id_(source_id), |
| + callback_(callback) { |
| +} |
| + |
| +DevToolsTargetsUIHandler::~DevToolsTargetsUIHandler() { |
| + STLDeleteValues(&targets_); |
| +} |
| + |
| +// static |
| +scoped_ptr<DevToolsTargetsUIHandler> |
| +DevToolsTargetsUIHandler::CreateForRenderers( |
| + DevToolsTargetsUIHandler::Callback callback) { |
| + return scoped_ptr<DevToolsTargetsUIHandler>( |
| + new RenderViewHostTargetsUIHandler(callback)); |
| +} |
| + |
| +// static |
| +scoped_ptr<DevToolsTargetsUIHandler> |
| +DevToolsTargetsUIHandler::CreateForWorkers( |
| + DevToolsTargetsUIHandler::Callback callback) { |
| + return scoped_ptr<DevToolsTargetsUIHandler>( |
| + new WorkerTargetsUIHandler(callback)); |
| +} |
| + |
| +void DevToolsTargetsUIHandler::Inspect(const std::string& target_id, |
| + Profile* profile) { |
| + TargetMap::iterator it = targets_.find(target_id); |
| + if (it != targets_.end()) |
| + it->second->Inspect(profile); |
| +} |
| + |
| +void DevToolsTargetsUIHandler::Activate(const std::string& target_id) { |
| + TargetMap::iterator it = targets_.find(target_id); |
| + if (it != targets_.end()) |
| + it->second->Activate(); |
| +} |
| + |
| +void DevToolsTargetsUIHandler::Close(const std::string& target_id) { |
| + TargetMap::iterator it = targets_.find(target_id); |
| + if (it != targets_.end()) |
| + it->second->Close(); |
| +} |
| + |
| +void DevToolsTargetsUIHandler::Reload(const std::string& target_id) { |
| + TargetMap::iterator it = targets_.find(target_id); |
| + if (it != targets_.end()) |
| + it->second->Reload(); |
| +} |
| + |
| +base::DictionaryValue* |
| +DevToolsTargetsUIHandler::Serialize( |
| + const DevToolsTargetImpl& target) { |
| + DictionaryValue* target_data = new DictionaryValue(); |
| + target_data->SetString(kTargetSourceField, source_id_); |
| + target_data->SetString(kTargetIdField, target.GetId()); |
| + target_data->SetString(kTargetTypeField, target.GetType()); |
| + target_data->SetBoolean(kAttachedField, target.IsAttached()); |
| + target_data->SetString(kUrlField, target.GetUrl().spec()); |
| + target_data->SetString(kNameField, net::EscapeForHTML(target.GetTitle())); |
| + target_data->SetString(kFaviconUrlField, target.GetFaviconUrl().spec()); |
| + target_data->SetString(kDescriptionField, target.GetDescription()); |
| + return target_data; |
| +} |
| + |
| +void DevToolsTargetsUIHandler::SendSerializedTargets( |
| + scoped_ptr<ListValue> list) { |
| + callback_.Run(source_id_, list.Pass()); |
| +} |
| + |
| +// DevToolsRemoteTargetsUIHandler --------------------------------------------- |
| + |
| +DevToolsRemoteTargetsUIHandler::DevToolsRemoteTargetsUIHandler( |
| + const std::string& source_id, |
| + Callback callback) |
| + : DevToolsTargetsUIHandler(source_id, callback) { |
| +} |
| + |
| +// static |
| +scoped_ptr<DevToolsRemoteTargetsUIHandler> |
| +DevToolsRemoteTargetsUIHandler::CreateForAdb( |
| + DevToolsTargetsUIHandler::Callback callback, Profile* profile) { |
| + return scoped_ptr<DevToolsRemoteTargetsUIHandler>( |
| + new AdbTargetsUIHandler(callback, profile)); |
| +} |