| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/apps/shortcut_manager.h" | 5 #include "chrome/browser/apps/shortcut_manager.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/command_line.h" | 8 #include "base/command_line.h" |
| 9 #include "base/compiler_specific.h" | 9 #include "base/compiler_specific.h" |
| 10 #include "base/prefs/pref_service.h" | 10 #include "base/prefs/pref_service.h" |
| (...skipping 13 matching lines...) Expand all Loading... |
| 24 #include "content/public/browser/browser_thread.h" | 24 #include "content/public/browser/browser_thread.h" |
| 25 #include "extensions/browser/extension_registry.h" | 25 #include "extensions/browser/extension_registry.h" |
| 26 #include "extensions/browser/extension_system.h" | 26 #include "extensions/browser/extension_system.h" |
| 27 #include "extensions/common/extension_set.h" | 27 #include "extensions/common/extension_set.h" |
| 28 #include "extensions/common/one_shot_event.h" | 28 #include "extensions/common/one_shot_event.h" |
| 29 | 29 |
| 30 using extensions::Extension; | 30 using extensions::Extension; |
| 31 | 31 |
| 32 namespace { | 32 namespace { |
| 33 | 33 |
| 34 // This version number is stored in local prefs to check whether app shortcuts |
| 35 // need to be recreated. This might happen when we change various aspects of app |
| 36 // shortcuts like command-line flags or associated icons, binaries, etc. |
| 37 const int kCurrentAppShortcutsVersion = 0; |
| 38 |
| 39 // Delay in seconds before running UpdateShortcutsForAllApps. |
| 40 const int kUpdateShortcutsForAllAppsDelay = 10; |
| 41 |
| 34 // Creates a shortcut for an application in the applications menu, if there is | 42 // Creates a shortcut for an application in the applications menu, if there is |
| 35 // not already one present. | 43 // not already one present. |
| 36 void CreateShortcutsInApplicationsMenu(Profile* profile, | 44 void CreateShortcutsInApplicationsMenu(Profile* profile, |
| 37 const Extension* app) { | 45 const Extension* app) { |
| 38 web_app::ShortcutLocations creation_locations; | 46 web_app::ShortcutLocations creation_locations; |
| 39 // Create the shortcut in the Chrome Apps subdir. | 47 // Create the shortcut in the Chrome Apps subdir. |
| 40 creation_locations.applications_menu_location = | 48 creation_locations.applications_menu_location = |
| 41 web_app::APP_MENU_LOCATION_SUBDIR_CHROMEAPPS; | 49 web_app::APP_MENU_LOCATION_SUBDIR_CHROMEAPPS; |
| 42 web_app::CreateShortcuts( | 50 web_app::CreateShortcuts( |
| 43 web_app::SHORTCUT_CREATION_AUTOMATED, creation_locations, profile, app); | 51 web_app::SHORTCUT_CREATION_AUTOMATED, creation_locations, profile, app); |
| 44 } | 52 } |
| 45 | 53 |
| 46 bool ShouldCreateShortcutFor(Profile* profile, const Extension* extension) { | 54 void SetCurrentAppShortcutsVersion(PrefService* prefs) { |
| 47 return extension->is_platform_app() && | 55 prefs->SetInteger(prefs::kAppShortcutsVersion, kCurrentAppShortcutsVersion); |
| 48 extension->location() != extensions::Manifest::COMPONENT && | |
| 49 extensions::ui_util::ShouldDisplayInAppLauncher(extension, profile); | |
| 50 } | 56 } |
| 51 | 57 |
| 52 } // namespace | 58 } // namespace |
| 53 | 59 |
| 54 // static | 60 // static |
| 55 void AppShortcutManager::RegisterProfilePrefs( | 61 void AppShortcutManager::RegisterProfilePrefs( |
| 56 user_prefs::PrefRegistrySyncable* registry) { | 62 user_prefs::PrefRegistrySyncable* registry) { |
| 57 // Indicates whether app shortcuts have been created. | 63 // Indicates whether app shortcuts have been created. |
| 58 registry->RegisterBooleanPref( | 64 registry->RegisterIntegerPref( |
| 59 prefs::kAppShortcutsHaveBeenCreated, false, | 65 prefs::kAppShortcutsVersion, 0, |
| 60 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); | 66 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); |
| 61 } | 67 } |
| 62 | 68 |
| 63 AppShortcutManager::AppShortcutManager(Profile* profile) | 69 AppShortcutManager::AppShortcutManager(Profile* profile) |
| 64 : profile_(profile), | 70 : profile_(profile), |
| 65 is_profile_info_cache_observer_(false), | 71 is_profile_info_cache_observer_(false), |
| 66 prefs_(profile->GetPrefs()), | 72 prefs_(profile->GetPrefs()), |
| 67 extension_registry_observer_(this), | 73 extension_registry_observer_(this), |
| 68 weak_ptr_factory_(this) { | 74 weak_ptr_factory_(this) { |
| 69 // Use of g_browser_process requires that we are either on the UI thread, or | 75 // Use of g_browser_process requires that we are either on the UI thread, or |
| 70 // there are no threads initialized (such as in unit tests). | 76 // there are no threads initialized (such as in unit tests). |
| 71 DCHECK(!content::BrowserThread::IsThreadInitialized( | 77 DCHECK(!content::BrowserThread::IsThreadInitialized( |
| 72 content::BrowserThread::UI) || | 78 content::BrowserThread::UI) || |
| 73 content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | 79 content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
| 74 | 80 |
| 75 extension_registry_observer_.Add( | 81 extension_registry_observer_.Add( |
| 76 extensions::ExtensionRegistry::Get(profile_)); | 82 extensions::ExtensionRegistry::Get(profile_)); |
| 77 // Wait for extensions to be ready before running OnceOffCreateShortcuts. | 83 // Wait for extensions to be ready before running |
| 84 // UpdateShortcutsForAllAppsIfNeeded. |
| 78 extensions::ExtensionSystem::Get(profile)->ready().Post( | 85 extensions::ExtensionSystem::Get(profile)->ready().Post( |
| 79 FROM_HERE, | 86 FROM_HERE, |
| 80 base::Bind(&AppShortcutManager::OnceOffCreateShortcuts, | 87 base::Bind(&AppShortcutManager::UpdateShortcutsForAllAppsIfNeeded, |
| 81 weak_ptr_factory_.GetWeakPtr())); | 88 weak_ptr_factory_.GetWeakPtr())); |
| 82 | 89 |
| 83 ProfileManager* profile_manager = g_browser_process->profile_manager(); | 90 ProfileManager* profile_manager = g_browser_process->profile_manager(); |
| 84 // profile_manager might be NULL in testing environments. | 91 // profile_manager might be NULL in testing environments. |
| 85 if (profile_manager) { | 92 if (profile_manager) { |
| 86 profile_manager->GetProfileInfoCache().AddObserver(this); | 93 profile_manager->GetProfileInfoCache().AddObserver(this); |
| 87 is_profile_info_cache_observer_ = true; | 94 is_profile_info_cache_observer_ = true; |
| 88 } | 95 } |
| 89 } | 96 } |
| 90 | 97 |
| (...skipping 14 matching lines...) Expand all Loading... |
| 105 const std::string& old_name) { | 112 const std::string& old_name) { |
| 106 if (!extension->is_app()) | 113 if (!extension->is_app()) |
| 107 return; | 114 return; |
| 108 | 115 |
| 109 // If the app is being updated, update any existing shortcuts but do not | 116 // If the app is being updated, update any existing shortcuts but do not |
| 110 // create new ones. If it is being installed, automatically create a | 117 // create new ones. If it is being installed, automatically create a |
| 111 // shortcut in the applications menu (e.g., Start Menu). | 118 // shortcut in the applications menu (e.g., Start Menu). |
| 112 if (is_update && !from_ephemeral) { | 119 if (is_update && !from_ephemeral) { |
| 113 web_app::UpdateAllShortcuts( | 120 web_app::UpdateAllShortcuts( |
| 114 base::UTF8ToUTF16(old_name), profile_, extension); | 121 base::UTF8ToUTF16(old_name), profile_, extension); |
| 115 } else if (ShouldCreateShortcutFor(profile_, extension)) { | 122 } else { |
| 116 CreateShortcutsInApplicationsMenu(profile_, extension); | 123 CreateShortcutsInApplicationsMenu(profile_, extension); |
| 117 } | 124 } |
| 118 } | 125 } |
| 119 | 126 |
| 120 void AppShortcutManager::OnExtensionUninstalled( | 127 void AppShortcutManager::OnExtensionUninstalled( |
| 121 content::BrowserContext* browser_context, | 128 content::BrowserContext* browser_context, |
| 122 const Extension* extension) { | 129 const Extension* extension) { |
| 123 web_app::DeleteAllShortcuts(profile_, extension); | 130 web_app::DeleteAllShortcuts(profile_, extension); |
| 124 } | 131 } |
| 125 | 132 |
| 126 void AppShortcutManager::OnProfileWillBeRemoved( | 133 void AppShortcutManager::OnProfileWillBeRemoved( |
| 127 const base::FilePath& profile_path) { | 134 const base::FilePath& profile_path) { |
| 128 if (profile_path != profile_->GetPath()) | 135 if (profile_path != profile_->GetPath()) |
| 129 return; | 136 return; |
| 130 content::BrowserThread::PostTask( | 137 content::BrowserThread::PostTask( |
| 131 content::BrowserThread::FILE, FROM_HERE, | 138 content::BrowserThread::FILE, FROM_HERE, |
| 132 base::Bind(&web_app::internals::DeleteAllShortcutsForProfile, | 139 base::Bind(&web_app::internals::DeleteAllShortcutsForProfile, |
| 133 profile_path)); | 140 profile_path)); |
| 134 } | 141 } |
| 135 | 142 |
| 136 void AppShortcutManager::OnceOffCreateShortcuts() { | 143 void AppShortcutManager::UpdateShortcutsForAllAppsIfNeeded() { |
| 137 if (prefs_->GetBoolean(prefs::kAppShortcutsHaveBeenCreated)) | 144 int last_version = prefs_->GetInteger(prefs::kAppShortcutsVersion); |
| 145 if (last_version >= kCurrentAppShortcutsVersion) |
| 138 return; | 146 return; |
| 139 | 147 |
| 140 prefs_->SetBoolean(prefs::kAppShortcutsHaveBeenCreated, true); | 148 content::BrowserThread::PostDelayedTask( |
| 141 | 149 content::BrowserThread::UI, |
| 142 // Check if extension system/service are available. They might not be in | 150 FROM_HERE, |
| 143 // tests. | 151 base::Bind(&web_app::UpdateShortcutsForAllApps, |
| 144 extensions::ExtensionSystem* extension_system; | 152 profile_, |
| 145 ExtensionServiceInterface* extension_service; | 153 base::Bind(&SetCurrentAppShortcutsVersion, prefs_)), |
| 146 if (!(extension_system = extensions::ExtensionSystem::Get(profile_)) || | 154 base::TimeDelta::FromSeconds(kUpdateShortcutsForAllAppsDelay)); |
| 147 !(extension_service = extension_system->extension_service())) | |
| 148 return; | |
| 149 | |
| 150 // Create an applications menu shortcut for each app in this profile. | |
| 151 const extensions::ExtensionSet* apps = extension_service->extensions(); | |
| 152 for (extensions::ExtensionSet::const_iterator it = apps->begin(); | |
| 153 it != apps->end(); ++it) { | |
| 154 if (ShouldCreateShortcutFor(profile_, it->get())) | |
| 155 CreateShortcutsInApplicationsMenu(profile_, it->get()); | |
| 156 } | |
| 157 } | 155 } |
| OLD | NEW |