| OLD | NEW | 
|---|
| (Empty) |  | 
|  | 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/android/dev_tools_manager_delegate_android.h" | 
|  | 6 | 
|  | 7 #include "base/basictypes.h" | 
|  | 8 #include "base/compiler_specific.h" | 
|  | 9 #include "base/strings/string_number_conversions.h" | 
|  | 10 #include "base/strings/utf_string_conversions.h" | 
|  | 11 #include "chrome/browser/android/tab_android.h" | 
|  | 12 #include "chrome/browser/browser_process.h" | 
|  | 13 #include "chrome/browser/history/top_sites.h" | 
|  | 14 #include "chrome/browser/profiles/profile_manager.h" | 
|  | 15 #include "chrome/browser/ui/android/tab_model/tab_model.h" | 
|  | 16 #include "chrome/browser/ui/android/tab_model/tab_model_list.h" | 
|  | 17 #include "content/public/browser/devtools_agent_host.h" | 
|  | 18 #include "content/public/browser/devtools_target.h" | 
|  | 19 #include "content/public/browser/favicon_status.h" | 
|  | 20 #include "content/public/browser/navigation_entry.h" | 
|  | 21 #include "content/public/browser/web_contents.h" | 
|  | 22 | 
|  | 23 using content::DevToolsAgentHost; | 
|  | 24 using content::WebContents; | 
|  | 25 | 
|  | 26 namespace { | 
|  | 27 | 
|  | 28 const char kTargetTypePage[] = "page"; | 
|  | 29 const char kTargetTypeServiceWorker[] = "service_worker"; | 
|  | 30 const char kTargetTypeOther[] = "other"; | 
|  | 31 | 
|  | 32 GURL GetFaviconURLForContents(WebContents* web_contents) { | 
|  | 33   content::NavigationController& controller = web_contents->GetController(); | 
|  | 34   content::NavigationEntry* entry = controller.GetActiveEntry(); | 
|  | 35   if (entry != NULL && entry->GetURL().is_valid()) | 
|  | 36     return entry->GetFavicon().url; | 
|  | 37   return GURL(); | 
|  | 38 } | 
|  | 39 | 
|  | 40 GURL GetFaviconURLForAgentHost( | 
|  | 41     scoped_refptr<DevToolsAgentHost> agent_host) { | 
|  | 42   if (WebContents* web_contents = agent_host->GetWebContents()) | 
|  | 43     return GetFaviconURLForContents(web_contents); | 
|  | 44   return GURL(); | 
|  | 45 } | 
|  | 46 | 
|  | 47 base::TimeTicks GetLastActiveTimeForAgentHost( | 
|  | 48     scoped_refptr<DevToolsAgentHost> agent_host) { | 
|  | 49   if (WebContents* web_contents = agent_host->GetWebContents()) | 
|  | 50     return web_contents->GetLastActiveTime(); | 
|  | 51   return base::TimeTicks(); | 
|  | 52 } | 
|  | 53 | 
|  | 54 class TargetBase : public content::DevToolsTarget { | 
|  | 55  public: | 
|  | 56   // content::DevToolsTarget implementation: | 
|  | 57   virtual std::string GetParentId() const OVERRIDE { return std::string(); } | 
|  | 58 | 
|  | 59   virtual std::string GetTitle() const OVERRIDE { return title_; } | 
|  | 60 | 
|  | 61   virtual std::string GetDescription() const OVERRIDE { return std::string(); } | 
|  | 62 | 
|  | 63   virtual GURL GetURL() const OVERRIDE { return url_; } | 
|  | 64 | 
|  | 65   virtual GURL GetFaviconURL() const OVERRIDE { return favicon_url_; } | 
|  | 66 | 
|  | 67   virtual base::TimeTicks GetLastActivityTime() const OVERRIDE { | 
|  | 68     return last_activity_time_; | 
|  | 69   } | 
|  | 70 | 
|  | 71  protected: | 
|  | 72   explicit TargetBase(WebContents* web_contents) | 
|  | 73       : title_(base::UTF16ToUTF8(web_contents->GetTitle())), | 
|  | 74         url_(web_contents->GetURL()), | 
|  | 75         favicon_url_(GetFaviconURLForContents(web_contents)), | 
|  | 76         last_activity_time_(web_contents->GetLastActiveTime()) { | 
|  | 77   } | 
|  | 78 | 
|  | 79   explicit TargetBase(scoped_refptr<DevToolsAgentHost> agent_host) | 
|  | 80       : title_(agent_host->GetTitle()), | 
|  | 81         url_(agent_host->GetURL()), | 
|  | 82         favicon_url_(GetFaviconURLForAgentHost(agent_host)), | 
|  | 83         last_activity_time_(GetLastActiveTimeForAgentHost(agent_host)) { | 
|  | 84   } | 
|  | 85 | 
|  | 86   TargetBase(const std::string& title, const GURL& url) | 
|  | 87       : title_(title), | 
|  | 88         url_(url) { | 
|  | 89   } | 
|  | 90 | 
|  | 91  private: | 
|  | 92   const std::string title_; | 
|  | 93   const GURL url_; | 
|  | 94   const GURL favicon_url_; | 
|  | 95   const base::TimeTicks last_activity_time_; | 
|  | 96 }; | 
|  | 97 | 
|  | 98 class TabTarget : public TargetBase { | 
|  | 99  public: | 
|  | 100   static TabTarget* CreateForWebContents(int tab_id, | 
|  | 101                                          WebContents* web_contents) { | 
|  | 102     return new TabTarget(tab_id, web_contents); | 
|  | 103   } | 
|  | 104 | 
|  | 105   static TabTarget* CreateForUnloadedTab(int tab_id, | 
|  | 106                                          const base::string16& title, | 
|  | 107                                          const GURL& url) { | 
|  | 108     return new TabTarget(tab_id, title, url); | 
|  | 109   } | 
|  | 110 | 
|  | 111   // content::DevToolsTarget implementation: | 
|  | 112   virtual std::string GetId() const OVERRIDE { | 
|  | 113     return base::IntToString(tab_id_); | 
|  | 114   } | 
|  | 115 | 
|  | 116   virtual std::string GetType() const OVERRIDE { | 
|  | 117     return kTargetTypePage; | 
|  | 118   } | 
|  | 119 | 
|  | 120   virtual bool IsAttached() const OVERRIDE { | 
|  | 121     TabModel* model; | 
|  | 122     int index; | 
|  | 123     if (!FindTab(&model, &index)) | 
|  | 124       return false; | 
|  | 125     WebContents* web_contents = model->GetWebContentsAt(index); | 
|  | 126     if (!web_contents) | 
|  | 127       return false; | 
|  | 128     return DevToolsAgentHost::IsDebuggerAttached(web_contents); | 
|  | 129   } | 
|  | 130 | 
|  | 131   virtual scoped_refptr<DevToolsAgentHost> GetAgentHost() const OVERRIDE { | 
|  | 132     TabModel* model; | 
|  | 133     int index; | 
|  | 134     if (!FindTab(&model, &index)) | 
|  | 135       return NULL; | 
|  | 136     WebContents* web_contents = model->GetWebContentsAt(index); | 
|  | 137     if (!web_contents) { | 
|  | 138       // The tab has been pushed out of memory, pull it back. | 
|  | 139       TabAndroid* tab = model->GetTabAt(index); | 
|  | 140       if (!tab) | 
|  | 141         return NULL; | 
|  | 142 | 
|  | 143       tab->LoadIfNeeded(); | 
|  | 144       web_contents = model->GetWebContentsAt(index); | 
|  | 145       if (!web_contents) | 
|  | 146         return NULL; | 
|  | 147     } | 
|  | 148     return DevToolsAgentHost::GetOrCreateFor(web_contents); | 
|  | 149   } | 
|  | 150 | 
|  | 151   virtual bool Activate() const OVERRIDE { | 
|  | 152     TabModel* model; | 
|  | 153     int index; | 
|  | 154     if (!FindTab(&model, &index)) | 
|  | 155       return false; | 
|  | 156     model->SetActiveIndex(index); | 
|  | 157     return true; | 
|  | 158   } | 
|  | 159 | 
|  | 160   virtual bool Close() const OVERRIDE { | 
|  | 161     TabModel* model; | 
|  | 162     int index; | 
|  | 163     if (!FindTab(&model, &index)) | 
|  | 164       return false; | 
|  | 165     model->CloseTabAt(index); | 
|  | 166     return true; | 
|  | 167   } | 
|  | 168 | 
|  | 169  private: | 
|  | 170   TabTarget(int tab_id, WebContents* web_contents) | 
|  | 171       : TargetBase(web_contents), | 
|  | 172         tab_id_(tab_id) { | 
|  | 173   } | 
|  | 174 | 
|  | 175   TabTarget(int tab_id, const base::string16& title, const GURL& url) | 
|  | 176       : TargetBase(base::UTF16ToUTF8(title), url), | 
|  | 177         tab_id_(tab_id) { | 
|  | 178   } | 
|  | 179 | 
|  | 180   bool FindTab(TabModel** model_result, int* index_result) const { | 
|  | 181     for (TabModelList::const_iterator iter = TabModelList::begin(); | 
|  | 182         iter != TabModelList::end(); ++iter) { | 
|  | 183       TabModel* model = *iter; | 
|  | 184       for (int i = 0; i < model->GetTabCount(); ++i) { | 
|  | 185         TabAndroid* tab = model->GetTabAt(i); | 
|  | 186         if (tab && tab->GetAndroidId() == tab_id_) { | 
|  | 187           *model_result = model; | 
|  | 188           *index_result = i; | 
|  | 189           return true; | 
|  | 190         } | 
|  | 191       } | 
|  | 192     } | 
|  | 193     return false; | 
|  | 194   } | 
|  | 195 | 
|  | 196   const int tab_id_; | 
|  | 197 }; | 
|  | 198 | 
|  | 199 class NonTabTarget : public TargetBase { | 
|  | 200  public: | 
|  | 201   explicit NonTabTarget(scoped_refptr<DevToolsAgentHost> agent_host) | 
|  | 202       : TargetBase(agent_host), | 
|  | 203         agent_host_(agent_host) { | 
|  | 204   } | 
|  | 205 | 
|  | 206   // content::DevToolsTarget implementation: | 
|  | 207   virtual std::string GetId() const OVERRIDE { | 
|  | 208     return agent_host_->GetId(); | 
|  | 209   } | 
|  | 210 | 
|  | 211   virtual std::string GetType() const OVERRIDE { | 
|  | 212     switch (agent_host_->GetType()) { | 
|  | 213       case DevToolsAgentHost::TYPE_WEB_CONTENTS: | 
|  | 214         if (TabModelList::begin() == TabModelList::end()) { | 
|  | 215           // If there are no tab models we must be running in ChromeShell. | 
|  | 216           // Return the 'page' target type for backwards compatibility. | 
|  | 217           return kTargetTypePage; | 
|  | 218         } | 
|  | 219         break; | 
|  | 220       case DevToolsAgentHost::TYPE_SERVICE_WORKER: | 
|  | 221         return kTargetTypeServiceWorker; | 
|  | 222       default: | 
|  | 223         break; | 
|  | 224     } | 
|  | 225     return kTargetTypeOther; | 
|  | 226   } | 
|  | 227 | 
|  | 228   virtual bool IsAttached() const OVERRIDE { | 
|  | 229     return agent_host_->IsAttached(); | 
|  | 230   } | 
|  | 231 | 
|  | 232   virtual scoped_refptr<DevToolsAgentHost> GetAgentHost() const OVERRIDE { | 
|  | 233     return agent_host_; | 
|  | 234   } | 
|  | 235 | 
|  | 236   virtual bool Activate() const OVERRIDE { | 
|  | 237     return agent_host_->Activate(); | 
|  | 238   } | 
|  | 239 | 
|  | 240   virtual bool Close() const OVERRIDE { | 
|  | 241     return agent_host_->Close(); | 
|  | 242   } | 
|  | 243 | 
|  | 244  private: | 
|  | 245   scoped_refptr<DevToolsAgentHost> agent_host_; | 
|  | 246 }; | 
|  | 247 | 
|  | 248 }  // namespace | 
|  | 249 | 
|  | 250 DevToolsManagerDelegateAndroid::DevToolsManagerDelegateAndroid() | 
|  | 251     : network_protocol_handler_(new DevToolsNetworkProtocolHandler()) { | 
|  | 252 } | 
|  | 253 | 
|  | 254 DevToolsManagerDelegateAndroid::~DevToolsManagerDelegateAndroid() { | 
|  | 255 } | 
|  | 256 | 
|  | 257 void DevToolsManagerDelegateAndroid::Inspect( | 
|  | 258     content::BrowserContext* browser_context, | 
|  | 259     content::DevToolsAgentHost* agent_host) { | 
|  | 260 } | 
|  | 261 | 
|  | 262 base::DictionaryValue* DevToolsManagerDelegateAndroid::HandleCommand( | 
|  | 263     content::DevToolsAgentHost* agent_host, | 
|  | 264     base::DictionaryValue* command_dict) { | 
|  | 265   return network_protocol_handler_->HandleCommand(agent_host, command_dict); | 
|  | 266 } | 
|  | 267 | 
|  | 268 void DevToolsManagerDelegateAndroid::DevToolsAgentStateChanged( | 
|  | 269     content::DevToolsAgentHost* agent_host, | 
|  | 270     bool attached) { | 
|  | 271   network_protocol_handler_->DevToolsAgentStateChanged(agent_host, attached); | 
|  | 272 } | 
|  | 273 | 
|  | 274 scoped_ptr<content::DevToolsTarget> | 
|  | 275     DevToolsManagerDelegateAndroid::CreateNewTarget(const GURL& url) { | 
|  | 276   if (TabModelList::empty()) | 
|  | 277     return scoped_ptr<content::DevToolsTarget>(); | 
|  | 278 | 
|  | 279   TabModel* tab_model = TabModelList::get(0); | 
|  | 280   if (!tab_model) | 
|  | 281     return scoped_ptr<content::DevToolsTarget>(); | 
|  | 282 | 
|  | 283   WebContents* web_contents = tab_model->CreateNewTabForDevTools(url); | 
|  | 284   if (!web_contents) | 
|  | 285     return scoped_ptr<content::DevToolsTarget>(); | 
|  | 286 | 
|  | 287   TabAndroid* tab = TabAndroid::FromWebContents(web_contents); | 
|  | 288   if (!tab) | 
|  | 289     return scoped_ptr<content::DevToolsTarget>(); | 
|  | 290 | 
|  | 291   return scoped_ptr<content::DevToolsTarget>( | 
|  | 292       TabTarget::CreateForWebContents(tab->GetAndroidId(), web_contents)); | 
|  | 293 } | 
|  | 294 | 
|  | 295 void DevToolsManagerDelegateAndroid::EnumerateTargets(TargetCallback callback) { | 
|  | 296   TargetList targets; | 
|  | 297 | 
|  | 298   // Enumerate existing tabs, including the ones with no WebContents. | 
|  | 299   std::set<WebContents*> tab_web_contents; | 
|  | 300   for (TabModelList::const_iterator iter = TabModelList::begin(); | 
|  | 301       iter != TabModelList::end(); ++iter) { | 
|  | 302     TabModel* model = *iter; | 
|  | 303     for (int i = 0; i < model->GetTabCount(); ++i) { | 
|  | 304       TabAndroid* tab = model->GetTabAt(i); | 
|  | 305       if (!tab) | 
|  | 306         continue; | 
|  | 307 | 
|  | 308       WebContents* web_contents = model->GetWebContentsAt(i); | 
|  | 309       if (web_contents) { | 
|  | 310         tab_web_contents.insert(web_contents); | 
|  | 311         targets.push_back(TabTarget::CreateForWebContents(tab->GetAndroidId(), | 
|  | 312                                                           web_contents)); | 
|  | 313       } else { | 
|  | 314         targets.push_back(TabTarget::CreateForUnloadedTab(tab->GetAndroidId(), | 
|  | 315                                                           tab->GetTitle(), | 
|  | 316                                                           tab->GetURL())); | 
|  | 317       } | 
|  | 318     } | 
|  | 319   } | 
|  | 320 | 
|  | 321   // Add targets for WebContents not associated with any tabs. | 
|  | 322   DevToolsAgentHost::List agents = DevToolsAgentHost::GetOrCreateAll(); | 
|  | 323   for (DevToolsAgentHost::List::iterator it = agents.begin(); | 
|  | 324        it != agents.end(); ++it) { | 
|  | 325     if (WebContents* web_contents = (*it)->GetWebContents()) { | 
|  | 326       if (tab_web_contents.find(web_contents) != tab_web_contents.end()) | 
|  | 327         continue; | 
|  | 328     } | 
|  | 329     targets.push_back(new NonTabTarget(*it)); | 
|  | 330   } | 
|  | 331 | 
|  | 332   callback.Run(targets); | 
|  | 333 } | 
|  | 334 | 
|  | 335 std::string DevToolsManagerDelegateAndroid::GetPageThumbnailData( | 
|  | 336     const GURL& url) { | 
|  | 337   Profile* profile = ProfileManager::GetLastUsedProfile()->GetOriginalProfile(); | 
|  | 338   history::TopSites* top_sites = profile->GetTopSites(); | 
|  | 339   if (top_sites) { | 
|  | 340     scoped_refptr<base::RefCountedMemory> data; | 
|  | 341     if (top_sites->GetPageThumbnail(url, false, &data)) | 
|  | 342       return std::string(data->front_as<char>(), data->size()); | 
|  | 343   } | 
|  | 344   return std::string(); | 
|  | 345 } | 
| OLD | NEW | 
|---|