| 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/ui/app_list/app_list_service_mac.h" | 5 #include "chrome/browser/ui/app_list/app_list_service_mac.h" |
| 6 | 6 |
| 7 #include "apps/app_launcher.h" |
| 7 #include "base/bind.h" | 8 #include "base/bind.h" |
| 9 #include "base/command_line.h" |
| 10 #include "base/file_util.h" |
| 8 #include "base/lazy_instance.h" | 11 #include "base/lazy_instance.h" |
| 9 #include "base/memory/scoped_nsobject.h" | 12 #include "base/memory/scoped_nsobject.h" |
| 10 #include "base/memory/singleton.h" | 13 #include "base/memory/singleton.h" |
| 11 #include "base/message_loop.h" | 14 #include "base/message_loop.h" |
| 15 #include "base/observer_list.h" |
| 16 #include "base/utf_string_conversions.h" |
| 17 #include "content/public/browser/browser_thread.h" |
| 18 #include "chrome/browser/browser_process.h" |
| 19 #include "chrome/browser/profiles/profile_manager.h" |
| 20 #include "chrome/browser/shell_integration.h" |
| 21 #include "chrome/browser/ui/app_list/app_list_dismiss_observer_mac.h" |
| 12 #include "chrome/browser/ui/app_list/app_list_service_impl.h" | 22 #include "chrome/browser/ui/app_list/app_list_service_impl.h" |
| 13 #include "chrome/browser/ui/app_list/app_list_service_mac.h" | 23 #include "chrome/browser/ui/app_list/app_list_service_mac.h" |
| 14 #include "chrome/browser/ui/app_list/app_list_controller_delegate.h" | 24 #include "chrome/browser/ui/app_list/app_list_controller_delegate.h" |
| 15 #include "chrome/browser/ui/app_list/app_list_view_delegate.h" | 25 #include "chrome/browser/ui/app_list/app_list_view_delegate.h" |
| 16 #include "chrome/browser/ui/extensions/application_launch.h" | 26 #include "chrome/browser/ui/extensions/application_launch.h" |
| 27 #include "chrome/browser/web_applications/web_app.h" |
| 28 #include "chrome/common/chrome_switches.h" |
| 29 #include "chrome/common/chrome_version_info.h" |
| 30 #include "chrome/common/mac/app_mode_common.h" |
| 31 #include "chrome/common/url_constants.h" |
| 32 #include "chrome/common/web_apps.h" |
| 33 #include "grit/chrome_unscaled_resources.h" |
| 34 #include "grit/google_chrome_strings.h" |
| 17 #import "ui/app_list/cocoa/app_list_view_controller.h" | 35 #import "ui/app_list/cocoa/app_list_view_controller.h" |
| 18 #import "ui/app_list/cocoa/app_list_window_controller.h" | 36 #import "ui/app_list/cocoa/app_list_window_controller.h" |
| 37 #include "ui/base/l10n/l10n_util.h" |
| 38 #include "ui/base/resource/resource_bundle.h" |
| 19 | 39 |
| 20 namespace gfx { | 40 namespace gfx { |
| 21 class ImageSkia; | 41 class ImageSkia; |
| 22 } | 42 } |
| 23 | 43 |
| 24 namespace { | 44 namespace { |
| 25 | 45 |
| 26 // AppListServiceMac manages global resources needed for the app list to | 46 // AppListServiceMac manages global resources needed for the app list to |
| 27 // operate, and controls when the app list is opened and closed. | 47 // operate, and controls when the app list is opened and closed. |
| 28 class AppListServiceMac : public AppListServiceImpl { | 48 class AppListServiceMac : public AppListServiceImpl { |
| 29 public: | 49 public: |
| 30 virtual ~AppListServiceMac() {} | 50 virtual ~AppListServiceMac() {} |
| 31 | 51 |
| 32 static AppListServiceMac* GetInstance() { | 52 static AppListServiceMac* GetInstance() { |
| 33 return Singleton<AppListServiceMac, | 53 return Singleton<AppListServiceMac, |
| 34 LeakySingletonTraits<AppListServiceMac> >::get(); | 54 LeakySingletonTraits<AppListServiceMac> >::get(); |
| 35 } | 55 } |
| 36 | 56 |
| 37 void CreateAppList(Profile* profile); | 57 void CreateAppList(Profile* profile); |
| 38 NSWindow* GetNativeWindow(); | 58 NSWindow* GetNativeWindow(); |
| 39 | 59 |
| 60 void AddObserver(chrome::AppListDismissObserverMac* observer); |
| 61 void RemoveObserver(chrome::AppListDismissObserverMac* observer); |
| 62 |
| 40 // AppListService overrides: | 63 // AppListService overrides: |
| 64 virtual void Init(Profile* initial_profile) OVERRIDE; |
| 41 virtual void ShowAppList(Profile* requested_profile) OVERRIDE; | 65 virtual void ShowAppList(Profile* requested_profile) OVERRIDE; |
| 42 virtual void DismissAppList() OVERRIDE; | 66 virtual void DismissAppList() OVERRIDE; |
| 43 virtual bool IsAppListVisible() const OVERRIDE; | 67 virtual bool IsAppListVisible() const OVERRIDE; |
| 44 | 68 |
| 45 private: | 69 private: |
| 46 friend struct DefaultSingletonTraits<AppListServiceMac>; | 70 friend struct DefaultSingletonTraits<AppListServiceMac>; |
| 47 | 71 |
| 48 AppListServiceMac() {} | 72 AppListServiceMac() {} |
| 49 | 73 |
| 50 scoped_nsobject<AppListWindowController> window_controller_; | 74 scoped_nsobject<AppListWindowController> window_controller_; |
| 75 ObserverList<chrome::AppListDismissObserverMac> observers_; |
| 51 | 76 |
| 52 DISALLOW_COPY_AND_ASSIGN(AppListServiceMac); | 77 DISALLOW_COPY_AND_ASSIGN(AppListServiceMac); |
| 53 }; | 78 }; |
| 54 | 79 |
| 55 class AppListControllerDelegateCocoa : public AppListControllerDelegate { | 80 class AppListControllerDelegateCocoa : public AppListControllerDelegate { |
| 56 public: | 81 public: |
| 57 AppListControllerDelegateCocoa(); | 82 AppListControllerDelegateCocoa(); |
| 58 virtual ~AppListControllerDelegateCocoa(); | 83 virtual ~AppListControllerDelegateCocoa(); |
| 59 | 84 |
| 60 private: | 85 private: |
| 61 // AppListControllerDelegate overrides: | 86 // AppListControllerDelegate overrides: |
| 62 virtual void DismissView() OVERRIDE; | 87 virtual void DismissView() OVERRIDE; |
| 63 virtual gfx::NativeWindow GetAppListWindow() OVERRIDE; | 88 virtual gfx::NativeWindow GetAppListWindow() OVERRIDE; |
| 64 virtual bool CanPin() OVERRIDE; | 89 virtual bool CanPin() OVERRIDE; |
| 65 virtual bool CanShowCreateShortcutsDialog() OVERRIDE; | 90 virtual bool CanShowCreateShortcutsDialog() OVERRIDE; |
| 66 virtual void ActivateApp(Profile* profile, | 91 virtual void ActivateApp(Profile* profile, |
| 67 const extensions::Extension* extension, | 92 const extensions::Extension* extension, |
| 68 int event_flags) OVERRIDE; | 93 int event_flags) OVERRIDE; |
| 69 virtual void LaunchApp(Profile* profile, | 94 virtual void LaunchApp(Profile* profile, |
| 70 const extensions::Extension* extension, | 95 const extensions::Extension* extension, |
| 71 int event_flags) OVERRIDE; | 96 int event_flags) OVERRIDE; |
| 72 | 97 |
| 73 DISALLOW_COPY_AND_ASSIGN(AppListControllerDelegateCocoa); | 98 DISALLOW_COPY_AND_ASSIGN(AppListControllerDelegateCocoa); |
| 74 }; | 99 }; |
| 75 | 100 |
| 101 ShellIntegration::ShortcutInfo GetAppListShortcutInfo( |
| 102 const base::FilePath& profile_path) { |
| 103 ShellIntegration::ShortcutInfo shortcut_info; |
| 104 |
| 105 |
| 106 chrome::VersionInfo::Channel channel = chrome::VersionInfo::GetChannel(); |
| 107 if (channel == chrome::VersionInfo::CHANNEL_CANARY) { |
| 108 shortcut_info.title = |
| 109 l10n_util::GetStringUTF16(IDS_APP_LIST_SHORTCUT_NAME_CANARY); |
| 110 } else { |
| 111 shortcut_info.title = l10n_util::GetStringUTF16(IDS_APP_LIST_SHORTCUT_NAME); |
| 112 } |
| 113 |
| 114 shortcut_info.url = GURL(chrome::kChromeUIAppsURL); |
| 115 shortcut_info.extension_id = app_mode::kAppListModeId; |
| 116 shortcut_info.description = shortcut_info.title; |
| 117 shortcut_info.profile_path = profile_path; |
| 118 |
| 119 return shortcut_info; |
| 120 } |
| 121 |
| 122 void CreateAppListShim(const base::FilePath& profile_path) { |
| 123 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
| 124 |
| 125 WebApplicationInfo web_app_info; |
| 126 ShellIntegration::ShortcutInfo shortcut_info = |
| 127 GetAppListShortcutInfo(profile_path); |
| 128 |
| 129 ResourceBundle& resource_bundle = ResourceBundle::GetSharedInstance(); |
| 130 // TODO(tapted): Add more icon sizes when CreateShortcuts for mac will |
| 131 // actually make use of them. |
| 132 shortcut_info.favicon.Add( |
| 133 *resource_bundle.GetImageSkiaNamed(IDR_APP_LIST_128)); |
| 134 |
| 135 // TODO(tapted): Create a dock icon using chrome/browser/mac/dock.h . |
| 136 web_app::CreateShortcuts(shortcut_info, |
| 137 ShellIntegration::ShortcutLocations()); |
| 138 } |
| 139 |
| 140 // Check that there is an app list shim. If not, make one. |
| 141 void CheckAppListShimOnFileThread(const base::FilePath& profile_path) { |
| 142 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE)); |
| 143 base::FilePath install_path = web_app::internals::GetAppInstallPath( |
| 144 GetAppListShortcutInfo(profile_path)); |
| 145 DLOG(INFO) << install_path.value(); |
| 146 if (file_util::PathExists(install_path)) |
| 147 return; |
| 148 |
| 149 content::BrowserThread::PostTask( |
| 150 content::BrowserThread::UI, FROM_HERE, |
| 151 base::Bind(&CreateAppListShim, profile_path)); |
| 152 } |
| 153 |
| 76 AppListControllerDelegateCocoa::AppListControllerDelegateCocoa() {} | 154 AppListControllerDelegateCocoa::AppListControllerDelegateCocoa() {} |
| 77 | 155 |
| 78 AppListControllerDelegateCocoa::~AppListControllerDelegateCocoa() {} | 156 AppListControllerDelegateCocoa::~AppListControllerDelegateCocoa() {} |
| 79 | 157 |
| 80 void AppListControllerDelegateCocoa::DismissView() { | 158 void AppListControllerDelegateCocoa::DismissView() { |
| 81 AppListServiceMac::GetInstance()->DismissAppList(); | 159 AppListServiceMac::GetInstance()->DismissAppList(); |
| 82 } | 160 } |
| 83 | 161 |
| 84 gfx::NativeWindow AppListControllerDelegateCocoa::GetAppListWindow() { | 162 gfx::NativeWindow AppListControllerDelegateCocoa::GetAppListWindow() { |
| 85 return AppListServiceMac::GetInstance()->GetNativeWindow(); | 163 return AppListServiceMac::GetInstance()->GetNativeWindow(); |
| (...skipping 23 matching lines...) Expand all Loading... |
| 109 if (profile() == requested_profile) | 187 if (profile() == requested_profile) |
| 110 return; | 188 return; |
| 111 | 189 |
| 112 SetProfile(requested_profile); | 190 SetProfile(requested_profile); |
| 113 scoped_ptr<app_list::AppListViewDelegate> delegate( | 191 scoped_ptr<app_list::AppListViewDelegate> delegate( |
| 114 new AppListViewDelegate(new AppListControllerDelegateCocoa(), profile())); | 192 new AppListViewDelegate(new AppListControllerDelegateCocoa(), profile())); |
| 115 window_controller_.reset([[AppListWindowController alloc] init]); | 193 window_controller_.reset([[AppListWindowController alloc] init]); |
| 116 [[window_controller_ appListViewController] setDelegate:delegate.Pass()]; | 194 [[window_controller_ appListViewController] setDelegate:delegate.Pass()]; |
| 117 } | 195 } |
| 118 | 196 |
| 197 void AppListServiceMac::Init(Profile* initial_profile) { |
| 198 static bool checked_shim = false; |
| 199 if (checked_shim) |
| 200 return; |
| 201 |
| 202 checked_shim = true; |
| 203 if (!CommandLine::ForCurrentProcess()->HasSwitch(switches::kShowAppList)) |
| 204 return; |
| 205 |
| 206 // Delay, so that startup is not impacted. |
| 207 const int kCreateShimDelay = 5; |
| 208 content::BrowserThread::PostDelayedTask( |
| 209 content::BrowserThread::FILE, FROM_HERE, |
| 210 base::Bind(&CheckAppListShimOnFileThread, initial_profile->GetPath()), |
| 211 base::TimeDelta::FromSeconds(kCreateShimDelay)); |
| 212 } |
| 213 |
| 119 void AppListServiceMac::ShowAppList(Profile* requested_profile) { | 214 void AppListServiceMac::ShowAppList(Profile* requested_profile) { |
| 120 InvalidatePendingProfileLoads(); | 215 InvalidatePendingProfileLoads(); |
| 121 | 216 |
| 122 if (IsAppListVisible() && (requested_profile == profile())) { | 217 if (IsAppListVisible() && (requested_profile == profile())) { |
| 123 DCHECK(window_controller_); | 218 DCHECK(window_controller_); |
| 124 [[window_controller_ window] makeKeyAndOrderFront:nil]; | 219 [[window_controller_ window] makeKeyAndOrderFront:nil]; |
| 125 [NSApp activateIgnoringOtherApps:YES]; | 220 [NSApp activateIgnoringOtherApps:YES]; |
| 126 return; | 221 return; |
| 127 } | 222 } |
| 128 | 223 |
| 129 SaveProfilePathToLocalState(requested_profile->GetPath()); | 224 SaveProfilePathToLocalState(requested_profile->GetPath()); |
| 130 | 225 |
| 131 DismissAppList(); | 226 DismissAppList(); |
| 132 CreateAppList(requested_profile); | 227 CreateAppList(requested_profile); |
| 133 | 228 |
| 134 DCHECK(window_controller_); | 229 DCHECK(window_controller_); |
| 135 [[window_controller_ window] makeKeyAndOrderFront:nil]; | 230 [[window_controller_ window] makeKeyAndOrderFront:nil]; |
| 136 [NSApp activateIgnoringOtherApps:YES]; | 231 [NSApp activateIgnoringOtherApps:YES]; |
| 137 } | 232 } |
| 138 | 233 |
| 139 void AppListServiceMac::DismissAppList() { | 234 void AppListServiceMac::DismissAppList() { |
| 140 if (!window_controller_) | 235 if (!IsAppListVisible()) |
| 141 return; | 236 return; |
| 142 | 237 |
| 143 [[window_controller_ window] close]; | 238 [[window_controller_ window] close]; |
| 239 |
| 240 FOR_EACH_OBSERVER(chrome::AppListDismissObserverMac, |
| 241 observers_, |
| 242 OnAppListDismissed()); |
| 144 } | 243 } |
| 145 | 244 |
| 146 bool AppListServiceMac::IsAppListVisible() const { | 245 bool AppListServiceMac::IsAppListVisible() const { |
| 147 return [[window_controller_ window] isVisible]; | 246 return [[window_controller_ window] isVisible]; |
| 148 } | 247 } |
| 149 | 248 |
| 150 NSWindow* AppListServiceMac::GetNativeWindow() { | 249 NSWindow* AppListServiceMac::GetNativeWindow() { |
| 151 return [window_controller_ window]; | 250 return [window_controller_ window]; |
| 152 } | 251 } |
| 153 | 252 |
| 253 void AppListServiceMac::AddObserver( |
| 254 chrome::AppListDismissObserverMac* observer) { |
| 255 observers_.AddObserver(observer); |
| 256 } |
| 257 |
| 258 void AppListServiceMac::RemoveObserver( |
| 259 chrome::AppListDismissObserverMac* observer) { |
| 260 observers_.RemoveObserver(observer); |
| 261 } |
| 262 |
| 154 } // namespace | 263 } // namespace |
| 155 | 264 |
| 156 namespace chrome { | 265 namespace chrome { |
| 157 | 266 |
| 158 AppListService* GetAppListServiceMac() { | 267 AppListService* GetAppListServiceMac() { |
| 159 return AppListServiceMac::GetInstance(); | 268 return AppListServiceMac::GetInstance(); |
| 160 } | 269 } |
| 161 | 270 |
| 271 void AddAppListDismissObserver(AppListDismissObserverMac* observer) { |
| 272 AppListServiceMac::GetInstance()->AddObserver(observer); |
| 273 } |
| 274 |
| 275 void RemoveAppListDismissObserver(AppListDismissObserverMac* observer) { |
| 276 AppListServiceMac::GetInstance()->RemoveObserver(observer); |
| 277 } |
| 278 |
| 162 } // namespace chrome | 279 } // namespace chrome |
| OLD | NEW |