15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/ash/launcher/launcher_app_tab_helper.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
74e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include <vector>
84e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
94e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "chrome/browser/browser_process.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/extension_service.h"
111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "chrome/browser/extensions/extension_util.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/profiles/profile.h"
134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "chrome/browser/profiles/profile_manager.h"
14f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "chrome/browser/ui/browser_finder.h"
15a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "chrome/browser/web_applications/web_app.h"
165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/common/extensions/manifest_handlers/app_launch_info.h"
17f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "content/public/browser/navigation_entry.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/web_contents.h"
195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "extensions/browser/extension_registry.h"
20a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include "extensions/browser/extension_system.h"
21f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/common/extension.h"
22a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include "extensions/common/extension_set.h"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const extensions::Extension* GetExtensionForTab(Profile* profile,
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                content::WebContents* tab) {
28a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  ExtensionService* extension_service =
29a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      extensions::ExtensionSystem::Get(profile)->extension_service();
304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (!extension_service || !extension_service->extensions_enabled())
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NULL;
325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
33c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  // Note: It is possible to come here after a tab got removed form the browser
34c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  // before it gets destroyed, in which case there is no browser.
35f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  Browser* browser = chrome::FindBrowserWithWebContents(tab);
365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
37a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  extensions::ExtensionRegistry* registry =
38a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      extensions::ExtensionRegistry::Get(profile);
39a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
40a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Use the Browser's app name to determine the extension for app windows and
41a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // use the tab's url for app tabs.
42c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  if (browser && browser->is_app()) {
43a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    return registry->GetExtensionById(
44a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        web_app::GetExtensionIdFromApplicationName(browser->app_name()),
45a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        extensions::ExtensionRegistry::EVERYTHING);
46a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
47a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
48a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  const GURL url = tab->GetURL();
49a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  const extensions::ExtensionSet& extensions = registry->enabled_extensions();
50a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  const extensions::Extension* extension = extensions.GetAppByURL(url);
51a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  if (extension)
52a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    return extension;
535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
54a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Bookmark app windows should match their launch url extension despite
55a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // their web extents.
561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (extensions::util::IsStreamlinedHostedAppsEnabled()) {
57a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    for (extensions::ExtensionSet::const_iterator it = extensions.begin();
58a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)         it != extensions.end(); ++it) {
59a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      if (it->get()->from_bookmark() &&
60a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)          extensions::AppLaunchInfo::GetLaunchWebURL(it->get()) == url) {
61a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        return it->get();
625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      }
635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
65a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return NULL;
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const extensions::Extension* GetExtensionByID(Profile* profile,
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              const std::string& id) {
70116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  return extensions::ExtensionRegistry::Get(profile)->GetExtensionById(
71116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      id, extensions::ExtensionRegistry::EVERYTHING);
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)LauncherAppTabHelper::LauncherAppTabHelper(Profile* profile)
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : profile_(profile) {
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)LauncherAppTabHelper::~LauncherAppTabHelper() {
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)std::string LauncherAppTabHelper::GetAppID(content::WebContents* tab) {
844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ProfileManager* profile_manager = g_browser_process->profile_manager();
854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (profile_manager) {
864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    const std::vector<Profile*> profile_list =
874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        profile_manager->GetLoadedProfiles();
884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    if (profile_list.size() > 0) {
894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      for (std::vector<Profile*>::const_iterator it = profile_list.begin();
904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)           it != profile_list.end();
914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)           ++it) {
924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        const extensions::Extension* extension = GetExtensionForTab(*it, tab);
934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        if (extension)
944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)          return extension->id();
954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      }
964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      return std::string();
974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    }
984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // If there is no profile manager we only use the known profile.
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const extensions::Extension* extension = GetExtensionForTab(profile_, tab);
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return extension ? extension->id() : std::string();
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)bool LauncherAppTabHelper::IsValidIDForCurrentUser(const std::string& id) {
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return GetExtensionByID(profile_, id) != NULL;
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void LauncherAppTabHelper::SetCurrentUser(Profile* profile) {
1094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  profile_ = profile;
1104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
111