Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(128)

Side by Side Diff: chrome/browser/ui/ash/launcher/chrome_launcher_controller_impl.cc

Issue 2052013002: Adding ChromeLauncherController interface. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@chrome_launcher_smaller_api
Patch Set: Rebase Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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/ash/launcher/chrome_launcher_controller.h" 5 #include "chrome/browser/ui/ash/launcher/chrome_launcher_controller_impl.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 8
9 #include <vector> 9 #include <vector>
10 10
11 #include "ash/ash_switches.h" 11 #include "ash/ash_switches.h"
12 #include "ash/common/shelf/shelf_item_delegate_manager.h" 12 #include "ash/common/shelf/shelf_item_delegate_manager.h"
13 #include "ash/common/shelf/shelf_model.h" 13 #include "ash/common/shelf/shelf_model.h"
14 #include "ash/common/system/tray/system_tray_delegate.h" 14 #include "ash/common/system/tray/system_tray_delegate.h"
15 #include "ash/common/wm_shell.h" 15 #include "ash/common/wm_shell.h"
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
98 #include "ui/base/window_open_disposition.h" 98 #include "ui/base/window_open_disposition.h"
99 #include "ui/keyboard/keyboard_util.h" 99 #include "ui/keyboard/keyboard_util.h"
100 #include "ui/resources/grit/ui_resources.h" 100 #include "ui/resources/grit/ui_resources.h"
101 #include "ui/wm/core/window_animations.h" 101 #include "ui/wm/core/window_animations.h"
102 102
103 using extensions::Extension; 103 using extensions::Extension;
104 using extensions::UnloadedExtensionInfo; 104 using extensions::UnloadedExtensionInfo;
105 using extension_misc::kGmailAppId; 105 using extension_misc::kGmailAppId;
106 using content::WebContents; 106 using content::WebContents;
107 107
108 // static
109 ChromeLauncherController* ChromeLauncherController::instance_ = NULL;
110
111 namespace { 108 namespace {
112 109
113 int64_t GetDisplayIDForShelf(ash::Shelf* shelf) { 110 int64_t GetDisplayIDForShelf(ash::Shelf* shelf) {
114 aura::Window* root_window = 111 aura::Window* root_window =
115 shelf->shelf_widget()->GetNativeWindow()->GetRootWindow(); 112 shelf->shelf_widget()->GetNativeWindow()->GetRootWindow();
116 display::Display display = 113 display::Display display =
117 display::Screen::GetScreen()->GetDisplayNearestWindow(root_window); 114 display::Screen::GetScreen()->GetDisplayNearestWindow(root_window);
118 DCHECK(display.is_valid()); 115 DCHECK(display.is_valid());
119 return display.id(); 116 return display.id();
120 } 117 }
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
174 const size_t kPinProhibitedExtensionIdsLength = 171 const size_t kPinProhibitedExtensionIdsLength =
175 arraysize(kPinProhibitedExtensionIds); 172 arraysize(kPinProhibitedExtensionIds);
176 173
177 } // namespace 174 } // namespace
178 175
179 // A class to get events from ChromeOS when a user gets changed or added. 176 // A class to get events from ChromeOS when a user gets changed or added.
180 class ChromeLauncherControllerUserSwitchObserver 177 class ChromeLauncherControllerUserSwitchObserver
181 : public user_manager::UserManager::UserSessionStateObserver { 178 : public user_manager::UserManager::UserSessionStateObserver {
182 public: 179 public:
183 ChromeLauncherControllerUserSwitchObserver( 180 ChromeLauncherControllerUserSwitchObserver(
184 ChromeLauncherController* controller) 181 ChromeLauncherControllerImpl* controller)
185 : controller_(controller) { 182 : controller_(controller) {
186 DCHECK(user_manager::UserManager::IsInitialized()); 183 DCHECK(user_manager::UserManager::IsInitialized());
187 user_manager::UserManager::Get()->AddSessionStateObserver(this); 184 user_manager::UserManager::Get()->AddSessionStateObserver(this);
188 } 185 }
189 ~ChromeLauncherControllerUserSwitchObserver() override { 186 ~ChromeLauncherControllerUserSwitchObserver() override {
190 user_manager::UserManager::Get()->RemoveSessionStateObserver(this); 187 user_manager::UserManager::Get()->RemoveSessionStateObserver(this);
191 } 188 }
192 189
193 // user_manager::UserManager::UserSessionStateObserver overrides: 190 // user_manager::UserManager::UserSessionStateObserver overrides:
194 void UserAddedToSession(const user_manager::User* added_user) override; 191 void UserAddedToSession(const user_manager::User* added_user) override;
195 192
196 // ChromeLauncherControllerUserSwitchObserver: 193 // ChromeLauncherControllerUserSwitchObserver:
197 void OnUserProfileReadyToSwitch(Profile* profile); 194 void OnUserProfileReadyToSwitch(Profile* profile);
198 195
199 private: 196 private:
200 // Add a user to the session. 197 // Add a user to the session.
201 void AddUser(Profile* profile); 198 void AddUser(Profile* profile);
202 199
203 // The owning ChromeLauncherController. 200 // The owning ChromeLauncherControllerImpl.
204 ChromeLauncherController* controller_; 201 ChromeLauncherControllerImpl* controller_;
205 202
206 // Users which were just added to the system, but which profiles were not yet 203 // Users which were just added to the system, but which profiles were not yet
207 // (fully) loaded. 204 // (fully) loaded.
208 std::set<std::string> added_user_ids_waiting_for_profiles_; 205 std::set<std::string> added_user_ids_waiting_for_profiles_;
209 206
210 DISALLOW_COPY_AND_ASSIGN(ChromeLauncherControllerUserSwitchObserver); 207 DISALLOW_COPY_AND_ASSIGN(ChromeLauncherControllerUserSwitchObserver);
211 }; 208 };
212 209
213 void ChromeLauncherControllerUserSwitchObserver::UserAddedToSession( 210 void ChromeLauncherControllerUserSwitchObserver::UserAddedToSession(
214 const user_manager::User* active_user) { 211 const user_manager::User* active_user) {
215 Profile* profile = 212 Profile* profile =
216 multi_user_util::GetProfileFromAccountId(active_user->GetAccountId()); 213 multi_user_util::GetProfileFromAccountId(active_user->GetAccountId());
217 // If we do not have a profile yet, we postpone forwarding the notification 214 // If we do not have a profile yet, we postpone forwarding the notification
218 // until it is loaded. 215 // until it is loaded.
219 if (!profile) 216 if (!profile)
220 added_user_ids_waiting_for_profiles_.insert(active_user->email()); 217 added_user_ids_waiting_for_profiles_.insert(active_user->email());
221 else 218 else
222 AddUser(profile); 219 AddUser(profile);
223 } 220 }
224 221
225 void ChromeLauncherControllerUserSwitchObserver::OnUserProfileReadyToSwitch( 222 void ChromeLauncherControllerUserSwitchObserver::OnUserProfileReadyToSwitch(
226 Profile* profile) { 223 Profile* profile) {
227 if (!added_user_ids_waiting_for_profiles_.empty()) { 224 if (!added_user_ids_waiting_for_profiles_.empty()) {
228 // Check if the profile is from a user which was on the waiting list. 225 // Check if the profile is from a user which was on the waiting list.
229 std::string user_id = 226 std::string user_id =
230 multi_user_util::GetAccountIdFromProfile(profile).GetUserEmail(); 227 multi_user_util::GetAccountIdFromProfile(profile).GetUserEmail();
231 std::set<std::string>::iterator it = std::find( 228 std::set<std::string>::iterator it =
232 added_user_ids_waiting_for_profiles_.begin(), 229 std::find(added_user_ids_waiting_for_profiles_.begin(),
233 added_user_ids_waiting_for_profiles_.end(), 230 added_user_ids_waiting_for_profiles_.end(), user_id);
234 user_id);
235 if (it != added_user_ids_waiting_for_profiles_.end()) { 231 if (it != added_user_ids_waiting_for_profiles_.end()) {
236 added_user_ids_waiting_for_profiles_.erase(it); 232 added_user_ids_waiting_for_profiles_.erase(it);
237 AddUser(profile->GetOriginalProfile()); 233 AddUser(profile->GetOriginalProfile());
238 } 234 }
239 } 235 }
240 } 236 }
241 237
242 void ChromeLauncherControllerUserSwitchObserver::AddUser(Profile* profile) { 238 void ChromeLauncherControllerUserSwitchObserver::AddUser(Profile* profile) {
243 if (chrome::MultiUserWindowManager::GetMultiProfileMode() == 239 if (chrome::MultiUserWindowManager::GetMultiProfileMode() ==
244 chrome::MultiUserWindowManager::MULTI_PROFILE_MODE_SEPARATED) 240 chrome::MultiUserWindowManager::MULTI_PROFILE_MODE_SEPARATED)
245 chrome::MultiUserWindowManager::GetInstance()->AddUser(profile); 241 chrome::MultiUserWindowManager::GetInstance()->AddUser(profile);
246 controller_->AdditionalUserAddedToSession(profile->GetOriginalProfile()); 242 controller_->AdditionalUserAddedToSession(profile->GetOriginalProfile());
247 } 243 }
248 244
249 ChromeLauncherController::ChromeLauncherController(Profile* profile, 245 ChromeLauncherControllerImpl::ChromeLauncherControllerImpl(
250 ash::ShelfModel* model) 246 Profile* profile,
247 ash::ShelfModel* model)
251 : model_(model), 248 : model_(model),
252 item_delegate_manager_(NULL), 249 item_delegate_manager_(NULL),
253 profile_(profile), 250 profile_(profile),
254 app_sync_ui_state_(NULL), 251 app_sync_ui_state_(NULL),
255 ignore_persist_pinned_state_change_(false) { 252 ignore_persist_pinned_state_change_(false) {
256 if (!profile_) { 253 if (!profile_) {
257 // If no profile was passed, we take the currently active profile and use it 254 // If no profile was passed, we take the currently active profile and use it
258 // as the owner of the current desktop. 255 // as the owner of the current desktop.
259 // Use the original profile as on chromeos we may get a temporary off the 256 // Use the original profile as on chromeos we may get a temporary off the
260 // record profile, unless in guest session (where off the record profile is 257 // record profile, unless in guest session (where off the record profile is
(...skipping 15 matching lines...) Expand all
276 AttachProfile(profile_); 273 AttachProfile(profile_);
277 model_->AddObserver(this); 274 model_->AddObserver(this);
278 275
279 // In multi profile mode we might have a window manager. We try to create it 276 // In multi profile mode we might have a window manager. We try to create it
280 // here. If the instantiation fails, the manager is not needed. 277 // here. If the instantiation fails, the manager is not needed.
281 chrome::MultiUserWindowManager::CreateInstance(); 278 chrome::MultiUserWindowManager::CreateInstance();
282 279
283 // On Chrome OS using multi profile we want to switch the content of the shelf 280 // On Chrome OS using multi profile we want to switch the content of the shelf
284 // with a user change. Note that for unit tests the instance can be NULL. 281 // with a user change. Note that for unit tests the instance can be NULL.
285 if (chrome::MultiUserWindowManager::GetMultiProfileMode() != 282 if (chrome::MultiUserWindowManager::GetMultiProfileMode() !=
286 chrome::MultiUserWindowManager::MULTI_PROFILE_MODE_OFF) { 283 chrome::MultiUserWindowManager::MULTI_PROFILE_MODE_OFF) {
287 user_switch_observer_.reset( 284 user_switch_observer_.reset(
288 new ChromeLauncherControllerUserSwitchObserver(this)); 285 new ChromeLauncherControllerUserSwitchObserver(this));
289 } 286 }
290 287
291 std::unique_ptr<AppWindowLauncherController> extension_app_window_controller; 288 std::unique_ptr<AppWindowLauncherController> extension_app_window_controller;
292 // Create our v1/v2 application / browser monitors which will inform the 289 // Create our v1/v2 application / browser monitors which will inform the
293 // launcher of status changes. 290 // launcher of status changes.
294 if (chrome::MultiUserWindowManager::GetMultiProfileMode() == 291 if (chrome::MultiUserWindowManager::GetMultiProfileMode() ==
295 chrome::MultiUserWindowManager::MULTI_PROFILE_MODE_SEPARATED) { 292 chrome::MultiUserWindowManager::MULTI_PROFILE_MODE_SEPARATED) {
296 // If running in separated destkop mode, we create the multi profile version 293 // If running in separated destkop mode, we create the multi profile version
297 // of status monitor. 294 // of status monitor.
298 browser_status_monitor_.reset(new MultiProfileBrowserStatusMonitor(this)); 295 browser_status_monitor_.reset(new MultiProfileBrowserStatusMonitor(this));
299 extension_app_window_controller.reset( 296 extension_app_window_controller.reset(
300 new MultiProfileAppWindowLauncherController(this)); 297 new MultiProfileAppWindowLauncherController(this));
301 } else { 298 } else {
302 // Create our v1/v2 application / browser monitors which will inform the 299 // Create our v1/v2 application / browser monitors which will inform the
303 // launcher of status changes. 300 // launcher of status changes.
304 browser_status_monitor_.reset(new BrowserStatusMonitor(this)); 301 browser_status_monitor_.reset(new BrowserStatusMonitor(this));
305 extension_app_window_controller.reset( 302 extension_app_window_controller.reset(
306 new ExtensionAppWindowLauncherController(this)); 303 new ExtensionAppWindowLauncherController(this));
307 } 304 }
308 app_window_controllers_.push_back(std::move(extension_app_window_controller)); 305 app_window_controllers_.push_back(std::move(extension_app_window_controller));
309 306
310 std::unique_ptr<AppWindowLauncherController> arc_app_window_controller; 307 std::unique_ptr<AppWindowLauncherController> arc_app_window_controller;
311 arc_app_window_controller.reset(new ArcAppWindowLauncherController(this)); 308 arc_app_window_controller.reset(
309 new ArcAppWindowLauncherController(this, this));
312 app_window_controllers_.push_back(std::move(arc_app_window_controller)); 310 app_window_controllers_.push_back(std::move(arc_app_window_controller));
313 311
314 // Right now ash::Shell isn't created for tests. 312 // Right now ash::Shell isn't created for tests.
315 // TODO(mukai): Allows it to observe display change and write tests. 313 // TODO(mukai): Allows it to observe display change and write tests.
316 if (ash::Shell::HasInstance()) { 314 if (ash::Shell::HasInstance()) {
317 ash::Shell::GetInstance()->window_tree_host_manager()->AddObserver(this); 315 ash::Shell::GetInstance()->window_tree_host_manager()->AddObserver(this);
318 // If it got already set, we remove the observer first again and swap the 316 // If it got already set, we remove the observer first again and swap the
319 // ItemDelegateManager. 317 // ItemDelegateManager.
320 if (item_delegate_manager_) 318 if (item_delegate_manager_)
321 item_delegate_manager_->RemoveObserver(this); 319 item_delegate_manager_->RemoveObserver(this);
322 item_delegate_manager_ = 320 item_delegate_manager_ =
323 ash::Shell::GetInstance()->shelf_item_delegate_manager(); 321 ash::Shell::GetInstance()->shelf_item_delegate_manager();
324 item_delegate_manager_->AddObserver(this); 322 item_delegate_manager_->AddObserver(this);
325 } 323 }
326 } 324 }
327 325
328 ChromeLauncherController::~ChromeLauncherController() { 326 ChromeLauncherControllerImpl::~ChromeLauncherControllerImpl() {
329 if (item_delegate_manager_) 327 if (item_delegate_manager_)
330 item_delegate_manager_->RemoveObserver(this); 328 item_delegate_manager_->RemoveObserver(this);
331 329
332 // Reset the BrowserStatusMonitor as it has a weak pointer to this. 330 // Reset the BrowserStatusMonitor as it has a weak pointer to this.
333 browser_status_monitor_.reset(); 331 browser_status_monitor_.reset();
334 332
335 // Reset the app window controllers here since it has a weak pointer to this. 333 // Reset the app window controllers here since it has a weak pointer to this.
336 app_window_controllers_.clear(); 334 app_window_controllers_.clear();
337 335
338 model_->RemoveObserver(this); 336 model_->RemoveObserver(this);
339 if (ash::Shell::HasInstance()) 337 if (ash::Shell::HasInstance())
340 ash::Shell::GetInstance()->window_tree_host_manager()->RemoveObserver(this); 338 ash::Shell::GetInstance()->window_tree_host_manager()->RemoveObserver(this);
341 for (IDToItemControllerMap::iterator i = id_to_item_controller_map_.begin(); 339 for (IDToItemControllerMap::iterator i = id_to_item_controller_map_.begin();
342 i != id_to_item_controller_map_.end(); ++i) { 340 i != id_to_item_controller_map_.end(); ++i) {
343 int index = model_->ItemIndexByID(i->first); 341 int index = model_->ItemIndexByID(i->first);
344 // A "browser proxy" is not known to the model and this removal does 342 // A "browser proxy" is not known to the model and this removal does
345 // therefore not need to be propagated to the model. 343 // therefore not need to be propagated to the model.
346 if (index != -1 && 344 if (index != -1 &&
347 model_->items()[index].type != ash::TYPE_BROWSER_SHORTCUT) 345 model_->items()[index].type != ash::TYPE_BROWSER_SHORTCUT)
348 model_->RemoveItemAt(index); 346 model_->RemoveItemAt(index);
349 } 347 }
350 348
351 // Release all profile dependent resources. 349 // Release all profile dependent resources.
352 ReleaseProfile(); 350 ReleaseProfile();
353 if (instance_ == this)
354 instance_ = NULL;
355 351
356 // Get rid of the multi user window manager instance. 352 // Get rid of the multi user window manager instance.
357 chrome::MultiUserWindowManager::DeleteInstance(); 353 chrome::MultiUserWindowManager::DeleteInstance();
358 } 354 }
359 355
360 // static 356 // static
361 ChromeLauncherController* ChromeLauncherController::CreateInstance( 357 ChromeLauncherControllerImpl* ChromeLauncherControllerImpl::CreateInstance(
362 Profile* profile, 358 Profile* profile,
363 ash::ShelfModel* model) { 359 ash::ShelfModel* model) {
364 // We do not check here for re-creation of the ChromeLauncherController since 360 // We do not check here for re-creation of the ChromeLauncherControllerImpl
365 // it appears that it might be intentional that the ChromeLauncherController 361 // since it appears that it might be intentional that
366 // can be re-created. 362 // ChromeLauncherControllerImpl can be re-created.
367 instance_ = new ChromeLauncherController(profile, model); 363 ChromeLauncherControllerImpl* instance =
368 return instance_; 364 new ChromeLauncherControllerImpl(profile, model);
365 ChromeLauncherController::set_instance(instance);
366 return instance;
369 } 367 }
370 368
371 void ChromeLauncherController::Init() { 369 void ChromeLauncherControllerImpl::Init() {
372 CreateBrowserShortcutLauncherItem(); 370 CreateBrowserShortcutLauncherItem();
373 UpdateAppLaunchersFromPref(); 371 UpdateAppLaunchersFromPref();
374 372
375 // TODO(sky): update unit test so that this test isn't necessary. 373 // TODO(sky): update unit test so that this test isn't necessary.
376 if (ash::Shell::HasInstance()) 374 if (ash::Shell::HasInstance())
377 SetVirtualKeyboardBehaviorFromPrefs(); 375 SetVirtualKeyboardBehaviorFromPrefs();
378 376
379 prefs_observer_ = 377 prefs_observer_ =
380 ash::ChromeLauncherPrefsObserver::CreateIfNecessary(profile_); 378 ash::ChromeLauncherPrefsObserver::CreateIfNecessary(profile_);
381 } 379 }
382 380
383 ash::ShelfID ChromeLauncherController::CreateAppLauncherItem( 381 ash::ShelfID ChromeLauncherControllerImpl::CreateAppLauncherItem(
384 LauncherItemController* controller, 382 LauncherItemController* controller,
385 const std::string& app_id, 383 const std::string& app_id,
386 ash::ShelfItemStatus status) { 384 ash::ShelfItemStatus status) {
387 CHECK(controller); 385 CHECK(controller);
388 int index = 0; 386 int index = 0;
389 // Panels are inserted on the left so as not to push all existing panels over. 387 // Panels are inserted on the left so as not to push all existing panels over.
390 if (controller->GetShelfItemType() != ash::TYPE_APP_PANEL) 388 if (controller->GetShelfItemType() != ash::TYPE_APP_PANEL)
391 index = model_->item_count(); 389 index = model_->item_count();
392 return InsertAppLauncherItem(controller, 390 return InsertAppLauncherItem(controller, app_id, status, index,
393 app_id,
394 status,
395 index,
396 controller->GetShelfItemType()); 391 controller->GetShelfItemType());
397 } 392 }
398 393
399 void ChromeLauncherController::SetItemStatus(ash::ShelfID id, 394 void ChromeLauncherControllerImpl::SetItemStatus(ash::ShelfID id,
400 ash::ShelfItemStatus status) { 395 ash::ShelfItemStatus status) {
401 int index = model_->ItemIndexByID(id); 396 int index = model_->ItemIndexByID(id);
402 ash::ShelfItemStatus old_status = model_->items()[index].status; 397 ash::ShelfItemStatus old_status = model_->items()[index].status;
403 // Since ordinary browser windows are not registered, we might get a negative 398 // Since ordinary browser windows are not registered, we might get a negative
404 // index here. 399 // index here.
405 if (index >= 0 && old_status != status) { 400 if (index >= 0 && old_status != status) {
406 ash::ShelfItem item = model_->items()[index]; 401 ash::ShelfItem item = model_->items()[index];
407 item.status = status; 402 item.status = status;
408 model_->Set(index, item); 403 model_->Set(index, item);
409 } 404 }
410 } 405 }
411 406
412 void ChromeLauncherController::SetItemController( 407 void ChromeLauncherControllerImpl::SetItemController(
413 ash::ShelfID id, 408 ash::ShelfID id,
414 LauncherItemController* controller) { 409 LauncherItemController* controller) {
415 CHECK(controller); 410 CHECK(controller);
416 IDToItemControllerMap::iterator iter = id_to_item_controller_map_.find(id); 411 IDToItemControllerMap::iterator iter = id_to_item_controller_map_.find(id);
417 CHECK(iter != id_to_item_controller_map_.end()); 412 CHECK(iter != id_to_item_controller_map_.end());
418 controller->set_shelf_id(id); 413 controller->set_shelf_id(id);
419 iter->second = controller; 414 iter->second = controller;
420 // Existing controller is destroyed and replaced by registering again. 415 // Existing controller is destroyed and replaced by registering again.
421 SetShelfItemDelegate(id, controller); 416 SetShelfItemDelegate(id, controller);
422 } 417 }
423 418
424 void ChromeLauncherController::CloseLauncherItem(ash::ShelfID id) { 419 void ChromeLauncherControllerImpl::CloseLauncherItem(ash::ShelfID id) {
425 CHECK(id); 420 CHECK(id);
426 if (IsPinned(id)) { 421 if (IsPinned(id)) {
427 // Create a new shortcut controller. 422 // Create a new shortcut controller.
428 IDToItemControllerMap::iterator iter = id_to_item_controller_map_.find(id); 423 IDToItemControllerMap::iterator iter = id_to_item_controller_map_.find(id);
429 CHECK(iter != id_to_item_controller_map_.end()); 424 CHECK(iter != id_to_item_controller_map_.end());
430 SetItemStatus(id, ash::STATUS_CLOSED); 425 SetItemStatus(id, ash::STATUS_CLOSED);
431 std::string app_id = iter->second->app_id(); 426 std::string app_id = iter->second->app_id();
432 iter->second = AppShortcutLauncherItemController::Create(app_id, this); 427 iter->second = AppShortcutLauncherItemController::Create(app_id, this);
433 iter->second->set_shelf_id(id); 428 iter->second->set_shelf_id(id);
434 // Existing controller is destroyed and replaced by registering again. 429 // Existing controller is destroyed and replaced by registering again.
435 SetShelfItemDelegate(id, iter->second); 430 SetShelfItemDelegate(id, iter->second);
436 } else { 431 } else {
437 LauncherItemClosed(id); 432 LauncherItemClosed(id);
438 } 433 }
439 } 434 }
440 435
441 AppListControllerDelegate::Pinnable ChromeLauncherController::GetPinnable( 436 AppListControllerDelegate::Pinnable ChromeLauncherControllerImpl::GetPinnable(
442 const std::string& app_id) { 437 const std::string& app_id) {
443 for (size_t i = 0; i < kPinProhibitedExtensionIdsLength; ++i) { 438 for (size_t i = 0; i < kPinProhibitedExtensionIdsLength; ++i) {
444 if (kPinProhibitedExtensionIds[i] == app_id) 439 if (kPinProhibitedExtensionIds[i] == app_id)
445 return AppListControllerDelegate::NO_PIN; 440 return AppListControllerDelegate::NO_PIN;
446 } 441 }
447 442
448 const base::ListValue* pref = 443 const base::ListValue* pref =
449 profile_->GetPrefs()->GetList(prefs::kPolicyPinnedLauncherApps); 444 profile_->GetPrefs()->GetList(prefs::kPolicyPinnedLauncherApps);
450 if (!pref) 445 if (!pref)
451 return AppListControllerDelegate::PIN_EDITABLE; 446 return AppListControllerDelegate::PIN_EDITABLE;
452 447
453 // Pinned ARC apps policy defines the package name of the apps, that must 448 // Pinned ARC apps policy defines the package name of the apps, that must
454 // be pinned. All the launch activities of any package in policy are pinned. 449 // be pinned. All the launch activities of any package in policy are pinned.
455 // In turn the input parameter to this function is app_id, which 450 // In turn the input parameter to this function is app_id, which
456 // is 32 chars hash. In case of ARC app this is a hash of 451 // is 32 chars hash. In case of ARC app this is a hash of
457 // (package name + activity). This means that we must identify the package 452 // (package name + activity). This means that we must identify the package
458 // from the hash, and check if this package is pinned by policy. 453 // from the hash, and check if this package is pinned by policy.
459 const ArcAppListPrefs* const arc_prefs = ArcAppListPrefs::Get(profile()); 454 const ArcAppListPrefs* const arc_prefs = ArcAppListPrefs::Get(GetProfile());
460 std::string arc_app_packege_name; 455 std::string arc_app_packege_name;
461 if (arc_prefs) { 456 if (arc_prefs) {
462 std::unique_ptr<ArcAppListPrefs::AppInfo> app_info = 457 std::unique_ptr<ArcAppListPrefs::AppInfo> app_info =
463 arc_prefs->GetApp(app_id); 458 arc_prefs->GetApp(app_id);
464 if (app_info) 459 if (app_info)
465 arc_app_packege_name = app_info->package_name; 460 arc_app_packege_name = app_info->package_name;
466 } 461 }
467 462
468 for (size_t index = 0; index < pref->GetSize(); ++index) { 463 for (size_t index = 0; index < pref->GetSize(); ++index) {
469 const base::DictionaryValue* app = nullptr; 464 const base::DictionaryValue* app = nullptr;
470 std::string app_id_or_package; 465 std::string app_id_or_package;
471 if (pref->GetDictionary(index, &app) && 466 if (pref->GetDictionary(index, &app) &&
472 app->GetString(ash::kPinnedAppsPrefAppIDPath, &app_id_or_package) && 467 app->GetString(ash::kPinnedAppsPrefAppIDPath, &app_id_or_package) &&
473 (app_id == app_id_or_package || 468 (app_id == app_id_or_package ||
474 arc_app_packege_name == app_id_or_package)) { 469 arc_app_packege_name == app_id_or_package)) {
475 return AppListControllerDelegate::PIN_FIXED; 470 return AppListControllerDelegate::PIN_FIXED;
476 } 471 }
477 } 472 }
478 return AppListControllerDelegate::PIN_EDITABLE; 473 return AppListControllerDelegate::PIN_EDITABLE;
479 } 474 }
480 475
481 void ChromeLauncherController::Pin(ash::ShelfID id) { 476 void ChromeLauncherControllerImpl::Pin(ash::ShelfID id) {
482 DCHECK(HasShelfIDToAppIDMapping(id)); 477 DCHECK(HasShelfIDToAppIDMapping(id));
483 478
484 int index = model_->ItemIndexByID(id); 479 int index = model_->ItemIndexByID(id);
485 DCHECK_GE(index, 0); 480 DCHECK_GE(index, 0);
486 481
487 ash::ShelfItem item = model_->items()[index]; 482 ash::ShelfItem item = model_->items()[index];
488 483
489 if (item.type == ash::TYPE_PLATFORM_APP || 484 if (item.type == ash::TYPE_PLATFORM_APP ||
490 item.type == ash::TYPE_WINDOWED_APP) { 485 item.type == ash::TYPE_WINDOWED_APP) {
491 item.type = ash::TYPE_APP_SHORTCUT; 486 item.type = ash::TYPE_APP_SHORTCUT;
492 model_->Set(index, item); 487 model_->Set(index, item);
493 } else if (item.type != ash::TYPE_APP_SHORTCUT) { 488 } else if (item.type != ash::TYPE_APP_SHORTCUT) {
494 return; 489 return;
495 } 490 }
496 491
497 if (GetLauncherItemController(id)->CanPin()) 492 if (GetLauncherItemController(id)->CanPin())
498 PersistPinnedState(); 493 PersistPinnedState();
499 } 494 }
500 495
501 void ChromeLauncherController::Unpin(ash::ShelfID id) { 496 void ChromeLauncherControllerImpl::Unpin(ash::ShelfID id) {
502 LauncherItemController* controller = GetLauncherItemController(id); 497 LauncherItemController* controller = GetLauncherItemController(id);
503 CHECK(controller); 498 CHECK(controller);
504 const bool can_pin = controller->CanPin(); 499 const bool can_pin = controller->CanPin();
505 500
506 if (controller->type() == LauncherItemController::TYPE_APP || 501 if (controller->type() == LauncherItemController::TYPE_APP ||
507 controller->locked()) { 502 controller->locked()) {
508 UnpinRunningAppInternal(model_->ItemIndexByID(id)); 503 UnpinRunningAppInternal(model_->ItemIndexByID(id));
509 } else { 504 } else {
510 LauncherItemClosed(id); 505 LauncherItemClosed(id);
511 } 506 }
512 if (can_pin) 507 if (can_pin)
513 PersistPinnedState(); 508 PersistPinnedState();
514 } 509 }
515 510
516 bool ChromeLauncherController::IsPinned(ash::ShelfID id) { 511 bool ChromeLauncherControllerImpl::IsPinned(ash::ShelfID id) {
517 int index = model_->ItemIndexByID(id); 512 int index = model_->ItemIndexByID(id);
518 if (index < 0) 513 if (index < 0)
519 return false; 514 return false;
520 ash::ShelfItemType type = model_->items()[index].type; 515 ash::ShelfItemType type = model_->items()[index].type;
521 return (type == ash::TYPE_APP_SHORTCUT || type == ash::TYPE_BROWSER_SHORTCUT); 516 return (type == ash::TYPE_APP_SHORTCUT || type == ash::TYPE_BROWSER_SHORTCUT);
522 } 517 }
523 518
524 void ChromeLauncherController::TogglePinned(ash::ShelfID id) { 519 void ChromeLauncherControllerImpl::TogglePinned(ash::ShelfID id) {
525 if (!HasShelfIDToAppIDMapping(id)) 520 if (!HasShelfIDToAppIDMapping(id))
526 return; // May happen if item closed with menu open. 521 return; // May happen if item closed with menu open.
527 522
528 if (IsPinned(id)) 523 if (IsPinned(id))
529 Unpin(id); 524 Unpin(id);
530 else 525 else
531 Pin(id); 526 Pin(id);
532 } 527 }
533 528
534 bool ChromeLauncherController::IsPinnable(ash::ShelfID id) const { 529 bool ChromeLauncherControllerImpl::IsPinnable(ash::ShelfID id) const {
535 int index = model_->ItemIndexByID(id); 530 int index = model_->ItemIndexByID(id);
536 if (index == -1) 531 if (index == -1)
537 return false; 532 return false;
538 533
539 ash::ShelfItemType type = model_->items()[index].type; 534 ash::ShelfItemType type = model_->items()[index].type;
540 std::string app_id; 535 std::string app_id;
541 return ((type == ash::TYPE_APP_SHORTCUT || type == ash::TYPE_PLATFORM_APP || 536 return ((type == ash::TYPE_APP_SHORTCUT || type == ash::TYPE_PLATFORM_APP ||
542 type == ash::TYPE_WINDOWED_APP) && 537 type == ash::TYPE_WINDOWED_APP) &&
543 item_delegate_manager_->GetShelfItemDelegate(id)->CanPin()); 538 item_delegate_manager_->GetShelfItemDelegate(id)->CanPin());
544 } 539 }
545 540
546 void ChromeLauncherController::LockV1AppWithID(const std::string& app_id) { 541 void ChromeLauncherControllerImpl::LockV1AppWithID(const std::string& app_id) {
547 ash::ShelfID id = GetShelfIDForAppID(app_id); 542 ash::ShelfID id = GetShelfIDForAppID(app_id);
548 if (!IsPinned(id) && !IsWindowedAppInLauncher(app_id)) { 543 if (!IsPinned(id) && !IsWindowedAppInLauncher(app_id)) {
549 CreateAppShortcutLauncherItemWithType(app_id, 544 CreateAppShortcutLauncherItemWithType(app_id, model_->item_count(),
550 model_->item_count(),
551 ash::TYPE_WINDOWED_APP); 545 ash::TYPE_WINDOWED_APP);
552 id = GetShelfIDForAppID(app_id); 546 id = GetShelfIDForAppID(app_id);
553 } 547 }
554 CHECK(id); 548 CHECK(id);
555 id_to_item_controller_map_[id]->lock(); 549 id_to_item_controller_map_[id]->lock();
556 } 550 }
557 551
558 void ChromeLauncherController::UnlockV1AppWithID(const std::string& app_id) { 552 void ChromeLauncherControllerImpl::UnlockV1AppWithID(
553 const std::string& app_id) {
559 ash::ShelfID id = GetShelfIDForAppID(app_id); 554 ash::ShelfID id = GetShelfIDForAppID(app_id);
560 CHECK(id); 555 CHECK(id);
561 CHECK(IsPinned(id) || IsWindowedAppInLauncher(app_id)); 556 CHECK(IsPinned(id) || IsWindowedAppInLauncher(app_id));
562 LauncherItemController* controller = id_to_item_controller_map_[id]; 557 LauncherItemController* controller = id_to_item_controller_map_[id];
563 controller->unlock(); 558 controller->unlock();
564 if (!controller->locked() && !IsPinned(id)) 559 if (!controller->locked() && !IsPinned(id))
565 CloseLauncherItem(id); 560 CloseLauncherItem(id);
566 } 561 }
567 562
568 void ChromeLauncherController::Launch(ash::ShelfID id, int event_flags) { 563 void ChromeLauncherControllerImpl::Launch(ash::ShelfID id, int event_flags) {
569 LauncherItemController* controller = GetLauncherItemController(id); 564 LauncherItemController* controller = GetLauncherItemController(id);
570 if (!controller) 565 if (!controller)
571 return; // In case invoked from menu and item closed while menu up. 566 return; // In case invoked from menu and item closed while menu up.
572 controller->Launch(ash::LAUNCH_FROM_UNKNOWN, event_flags); 567 controller->Launch(ash::LAUNCH_FROM_UNKNOWN, event_flags);
573 } 568 }
574 569
575 void ChromeLauncherController::Close(ash::ShelfID id) { 570 void ChromeLauncherControllerImpl::Close(ash::ShelfID id) {
576 LauncherItemController* controller = GetLauncherItemController(id); 571 LauncherItemController* controller = GetLauncherItemController(id);
577 if (!controller) 572 if (!controller)
578 return; // May happen if menu closed. 573 return; // May happen if menu closed.
579 controller->Close(); 574 controller->Close();
580 } 575 }
581 576
582 bool ChromeLauncherController::IsOpen(ash::ShelfID id) { 577 bool ChromeLauncherControllerImpl::IsOpen(ash::ShelfID id) {
583 LauncherItemController* controller = GetLauncherItemController(id); 578 LauncherItemController* controller = GetLauncherItemController(id);
584 if (!controller) 579 if (!controller)
585 return false; 580 return false;
586 return controller->IsOpen(); 581 return controller->IsOpen();
587 } 582 }
588 583
589 bool ChromeLauncherController::IsPlatformApp(ash::ShelfID id) { 584 bool ChromeLauncherControllerImpl::IsPlatformApp(ash::ShelfID id) {
590 if (!HasShelfIDToAppIDMapping(id)) 585 if (!HasShelfIDToAppIDMapping(id))
591 return false; 586 return false;
592 587
593 std::string app_id = GetAppIDForShelfID(id); 588 std::string app_id = GetAppIDForShelfID(id);
594 const Extension* extension = GetExtensionForAppID(app_id); 589 const Extension* extension = GetExtensionForAppID(app_id);
595 // An extension can be synced / updated at any time and therefore not be 590 // An extension can be synced / updated at any time and therefore not be
596 // available. 591 // available.
597 return extension ? extension->is_platform_app() : false; 592 return extension ? extension->is_platform_app() : false;
598 } 593 }
599 594
600 void ChromeLauncherController::LaunchApp(const std::string& app_id, 595 void ChromeLauncherControllerImpl::LaunchApp(const std::string& app_id,
601 ash::LaunchSource source, 596 ash::LaunchSource source,
602 int event_flags) { 597 int event_flags) {
603 launcher_controller_helper_->LaunchApp(app_id, source, event_flags); 598 launcher_controller_helper_->LaunchApp(app_id, source, event_flags);
604 } 599 }
605 600
606 void ChromeLauncherController::ActivateApp(const std::string& app_id, 601 void ChromeLauncherControllerImpl::ActivateApp(const std::string& app_id,
607 ash::LaunchSource source, 602 ash::LaunchSource source,
608 int event_flags) { 603 int event_flags) {
609 // If there is an existing non-shortcut controller for this app, open it. 604 // If there is an existing non-shortcut controller for this app, open it.
610 ash::ShelfID id = GetShelfIDForAppID(app_id); 605 ash::ShelfID id = GetShelfIDForAppID(app_id);
611 if (id) { 606 if (id) {
612 LauncherItemController* controller = GetLauncherItemController(id); 607 LauncherItemController* controller = GetLauncherItemController(id);
613 controller->Activate(source); 608 controller->Activate(source);
614 return; 609 return;
615 } 610 }
616 611
617 // Create a temporary application launcher item and use it to see if there are 612 // Create a temporary application launcher item and use it to see if there are
618 // running instances. 613 // running instances.
619 std::unique_ptr<AppShortcutLauncherItemController> app_controller( 614 std::unique_ptr<AppShortcutLauncherItemController> app_controller(
620 AppShortcutLauncherItemController::Create(app_id, this)); 615 AppShortcutLauncherItemController::Create(app_id, this));
621 if (!app_controller->GetRunningApplications().empty()) 616 if (!app_controller->GetRunningApplications().empty())
622 app_controller->Activate(source); 617 app_controller->Activate(source);
623 else 618 else
624 LaunchApp(app_id, source, event_flags); 619 LaunchApp(app_id, source, event_flags);
625 } 620 }
626 621
627 extensions::LaunchType ChromeLauncherController::GetLaunchType( 622 extensions::LaunchType ChromeLauncherControllerImpl::GetLaunchType(
628 ash::ShelfID id) { 623 ash::ShelfID id) {
629 const Extension* extension = GetExtensionForAppID(GetAppIDForShelfID(id)); 624 const Extension* extension = GetExtensionForAppID(GetAppIDForShelfID(id));
630 625
631 // An extension can be unloaded/updated/unavailable at any time. 626 // An extension can be unloaded/updated/unavailable at any time.
632 if (!extension) 627 if (!extension)
633 return extensions::LAUNCH_TYPE_DEFAULT; 628 return extensions::LAUNCH_TYPE_DEFAULT;
634 629
635 return extensions::GetLaunchType(extensions::ExtensionPrefs::Get(profile_), 630 return extensions::GetLaunchType(extensions::ExtensionPrefs::Get(profile_),
636 extension); 631 extension);
637 } 632 }
638 633
639 ash::ShelfID ChromeLauncherController::GetShelfIDForAppID( 634 ash::ShelfID ChromeLauncherControllerImpl::GetShelfIDForAppID(
640 const std::string& app_id) { 635 const std::string& app_id) {
641 for (IDToItemControllerMap::const_iterator i = 636 for (IDToItemControllerMap::const_iterator i =
642 id_to_item_controller_map_.begin(); 637 id_to_item_controller_map_.begin();
643 i != id_to_item_controller_map_.end(); ++i) { 638 i != id_to_item_controller_map_.end(); ++i) {
644 if (i->second->type() == LauncherItemController::TYPE_APP_PANEL) 639 if (i->second->type() == LauncherItemController::TYPE_APP_PANEL)
645 continue; // Don't include panels 640 continue; // Don't include panels
646 if (i->second->app_id() == app_id) 641 if (i->second->app_id() == app_id)
647 return i->first; 642 return i->first;
648 } 643 }
649 return 0; 644 return 0;
650 } 645 }
651 646
652 bool ChromeLauncherController::HasShelfIDToAppIDMapping(ash::ShelfID id) const { 647 bool ChromeLauncherControllerImpl::HasShelfIDToAppIDMapping(
648 ash::ShelfID id) const {
653 return id_to_item_controller_map_.find(id) != 649 return id_to_item_controller_map_.find(id) !=
654 id_to_item_controller_map_.end(); 650 id_to_item_controller_map_.end();
655 } 651 }
656 652
657 const std::string& ChromeLauncherController::GetAppIDForShelfID( 653 const std::string& ChromeLauncherControllerImpl::GetAppIDForShelfID(
658 ash::ShelfID id) { 654 ash::ShelfID id) {
659 LauncherItemController* controller = GetLauncherItemController(id); 655 LauncherItemController* controller = GetLauncherItemController(id);
660 return controller ? controller->app_id() : base::EmptyString(); 656 return controller ? controller->app_id() : base::EmptyString();
661 } 657 }
662 658
663 void ChromeLauncherController::OnAppImageUpdated(const std::string& id, 659 void ChromeLauncherControllerImpl::OnAppImageUpdated(
664 const gfx::ImageSkia& image) { 660 const std::string& id,
661 const gfx::ImageSkia& image) {
665 // TODO: need to get this working for shortcuts. 662 // TODO: need to get this working for shortcuts.
666 for (IDToItemControllerMap::const_iterator i = 663 for (IDToItemControllerMap::const_iterator i =
667 id_to_item_controller_map_.begin(); 664 id_to_item_controller_map_.begin();
668 i != id_to_item_controller_map_.end(); ++i) { 665 i != id_to_item_controller_map_.end(); ++i) {
669 LauncherItemController* controller = i->second; 666 LauncherItemController* controller = i->second;
670 if (controller->app_id() != id) 667 if (controller->app_id() != id)
671 continue; 668 continue;
672 if (controller->image_set_by_controller()) 669 if (controller->image_set_by_controller())
673 continue; 670 continue;
674 int index = model_->ItemIndexByID(i->first); 671 int index = model_->ItemIndexByID(i->first);
675 if (index == -1) 672 if (index == -1)
676 continue; 673 continue;
677 ash::ShelfItem item = model_->items()[index]; 674 ash::ShelfItem item = model_->items()[index];
678 item.image = image; 675 item.image = image;
679 model_->Set(index, item); 676 model_->Set(index, item);
680 // It's possible we're waiting on more than one item, so don't break. 677 // It's possible we're waiting on more than one item, so don't break.
681 } 678 }
682 } 679 }
683 680
684 void ChromeLauncherController::SetLauncherItemImage( 681 void ChromeLauncherControllerImpl::SetLauncherItemImage(
685 ash::ShelfID shelf_id, 682 ash::ShelfID shelf_id,
686 const gfx::ImageSkia& image) { 683 const gfx::ImageSkia& image) {
687 int index = model_->ItemIndexByID(shelf_id); 684 int index = model_->ItemIndexByID(shelf_id);
688 if (index == -1) 685 if (index == -1)
689 return; 686 return;
690 ash::ShelfItem item = model_->items()[index]; 687 ash::ShelfItem item = model_->items()[index];
691 item.image = image; 688 item.image = image;
692 model_->Set(index, item); 689 model_->Set(index, item);
693 } 690 }
694 691
695 bool ChromeLauncherController::IsAppPinned(const std::string& app_id) { 692 bool ChromeLauncherControllerImpl::IsAppPinned(const std::string& app_id) {
696 for (IDToItemControllerMap::const_iterator i = 693 for (IDToItemControllerMap::const_iterator i =
697 id_to_item_controller_map_.begin(); 694 id_to_item_controller_map_.begin();
698 i != id_to_item_controller_map_.end(); ++i) { 695 i != id_to_item_controller_map_.end(); ++i) {
699 if (IsPinned(i->first) && i->second->app_id() == app_id) 696 if (IsPinned(i->first) && i->second->app_id() == app_id)
700 return true; 697 return true;
701 } 698 }
702 return false; 699 return false;
703 } 700 }
704 701
705 bool ChromeLauncherController::IsWindowedAppInLauncher( 702 bool ChromeLauncherControllerImpl::IsWindowedAppInLauncher(
706 const std::string& app_id) { 703 const std::string& app_id) {
707 int index = model_->ItemIndexByID(GetShelfIDForAppID(app_id)); 704 int index = model_->ItemIndexByID(GetShelfIDForAppID(app_id));
708 if (index < 0) 705 if (index < 0)
709 return false; 706 return false;
710 707
711 ash::ShelfItemType type = model_->items()[index].type; 708 ash::ShelfItemType type = model_->items()[index].type;
712 return type == ash::TYPE_WINDOWED_APP; 709 return type == ash::TYPE_WINDOWED_APP;
713 } 710 }
714 711
715 void ChromeLauncherController::PinAppWithID(const std::string& app_id) { 712 void ChromeLauncherControllerImpl::PinAppWithID(const std::string& app_id) {
716 if (GetPinnable(app_id) == AppListControllerDelegate::PIN_EDITABLE) 713 if (GetPinnable(app_id) == AppListControllerDelegate::PIN_EDITABLE)
717 DoPinAppWithID(app_id); 714 DoPinAppWithID(app_id);
718 else 715 else
719 NOTREACHED(); 716 NOTREACHED();
720 } 717 }
721 718
722 void ChromeLauncherController::SetLaunchType( 719 void ChromeLauncherControllerImpl::SetLaunchType(
723 ash::ShelfID id, 720 ash::ShelfID id,
724 extensions::LaunchType launch_type) { 721 extensions::LaunchType launch_type) {
725 LauncherItemController* controller = GetLauncherItemController(id); 722 LauncherItemController* controller = GetLauncherItemController(id);
726 if (!controller) 723 if (!controller)
727 return; 724 return;
728 725
729 extensions::SetLaunchType(profile_, controller->app_id(), launch_type); 726 extensions::SetLaunchType(profile_, controller->app_id(), launch_type);
730 } 727 }
731 728
732 void ChromeLauncherController::UnpinAppWithID(const std::string& app_id) { 729 void ChromeLauncherControllerImpl::UnpinAppWithID(const std::string& app_id) {
733 if (GetPinnable(app_id) == AppListControllerDelegate::PIN_EDITABLE) 730 if (GetPinnable(app_id) == AppListControllerDelegate::PIN_EDITABLE)
734 DoUnpinAppWithID(app_id); 731 DoUnpinAppWithID(app_id);
735 else 732 else
736 NOTREACHED(); 733 NOTREACHED();
737 } 734 }
738 735
739 void ChromeLauncherController::OnSetShelfItemDelegate( 736 void ChromeLauncherControllerImpl::OnSetShelfItemDelegate(
740 ash::ShelfID id, 737 ash::ShelfID id,
741 ash::ShelfItemDelegate* item_delegate) { 738 ash::ShelfItemDelegate* item_delegate) {
742 // TODO(skuhne): This fixes crbug.com/429870, but it does not answer why we 739 // TODO(skuhne): This fixes crbug.com/429870, but it does not answer why we
743 // get into this state in the first place. 740 // get into this state in the first place.
744 IDToItemControllerMap::iterator iter = id_to_item_controller_map_.find(id); 741 IDToItemControllerMap::iterator iter = id_to_item_controller_map_.find(id);
745 if (iter == id_to_item_controller_map_.end() || item_delegate == iter->second) 742 if (iter == id_to_item_controller_map_.end() || item_delegate == iter->second)
746 return; 743 return;
747 LOG(ERROR) << "Unexpected change of shelf item id: " << id; 744 LOG(ERROR) << "Unexpected change of shelf item id: " << id;
748 id_to_item_controller_map_.erase(iter); 745 id_to_item_controller_map_.erase(iter);
749 } 746 }
750 747
751 void ChromeLauncherController::PersistPinnedState() { 748 void ChromeLauncherControllerImpl::PersistPinnedState() {
752 if (ignore_persist_pinned_state_change_) 749 if (ignore_persist_pinned_state_change_)
753 return; 750 return;
754 // It is a coding error to call PersistPinnedState() if the pinned apps are 751 // It is a coding error to call PersistPinnedState() if the pinned apps are
755 // not user-editable. The code should check earlier and not perform any 752 // not user-editable. The code should check earlier and not perform any
756 // modification actions that trigger persisting the state. 753 // modification actions that trigger persisting the state.
757 // Mutating kPinnedLauncherApps is going to notify us and trigger us to 754 // Mutating kPinnedLauncherApps is going to notify us and trigger us to
758 // process the change. We don't want that to happen so remove ourselves as a 755 // process the change. We don't want that to happen so remove ourselves as a
759 // listener. 756 // listener.
760 pref_change_registrar_.Remove(prefs::kPinnedLauncherApps); 757 pref_change_registrar_.Remove(prefs::kPinnedLauncherApps);
761 { 758 {
762 std::unique_ptr<const base::ListValue> pinned_apps_pref = 759 std::unique_ptr<const base::ListValue> pinned_apps_pref =
763 profile_->GetPrefs() 760 profile_->GetPrefs()
764 ->GetList(prefs::kPinnedLauncherApps) 761 ->GetList(prefs::kPinnedLauncherApps)
765 ->CreateDeepCopy(); 762 ->CreateDeepCopy();
766 763
767 const base::ListValue* policy_pinned_apps_pref = 764 const base::ListValue* policy_pinned_apps_pref =
768 profile_->GetPrefs()->GetList(prefs::kPolicyPinnedLauncherApps); 765 profile_->GetPrefs()->GetList(prefs::kPolicyPinnedLauncherApps);
769 766
770 ListPrefUpdate updater(profile_->GetPrefs(), prefs::kPinnedLauncherApps); 767 ListPrefUpdate updater(profile_->GetPrefs(), prefs::kPinnedLauncherApps);
771 updater->Clear(); 768 updater->Clear();
772 for (size_t i = 0; i < model_->items().size(); ++i) { 769 for (size_t i = 0; i < model_->items().size(); ++i) {
773 if (model_->items()[i].type == ash::TYPE_APP_SHORTCUT) { 770 if (model_->items()[i].type == ash::TYPE_APP_SHORTCUT) {
774 ash::ShelfID id = model_->items()[i].id; 771 ash::ShelfID id = model_->items()[i].id;
775 LauncherItemController* controller = GetLauncherItemController(id); 772 LauncherItemController* controller = GetLauncherItemController(id);
776 // Don't persist pinning state for apps that are handled internally and 773 // Don't persist pinning state for apps that are handled internally and
777 // have pinnable state AppListControllerDelegate::NO_PIN. 774 // have pinnable state AppListControllerDelegate::NO_PIN.
778 if (controller && IsPinned(id) && 775 if (controller && IsPinned(id) &&
779 GetPinnable(controller->app_id()) != 776 GetPinnable(controller->app_id()) !=
780 AppListControllerDelegate::NO_PIN) { 777 AppListControllerDelegate::NO_PIN) {
781 base::DictionaryValue* app_value = ash::CreateAppDict( 778 base::DictionaryValue* app_value =
782 controller->app_id()); 779 ash::CreateAppDict(controller->app_id());
783 if (app_value) { 780 if (app_value) {
784 if (!IsAppForUserPinned(controller->app_id(), 781 if (!IsAppForUserPinned(controller->app_id(),
785 pinned_apps_pref.get(), 782 pinned_apps_pref.get(),
786 policy_pinned_apps_pref)) 783 policy_pinned_apps_pref))
787 app_value->SetBoolean(ash::kPinnedAppsPrefPinnedByPolicy, true); 784 app_value->SetBoolean(ash::kPinnedAppsPrefPinnedByPolicy, true);
788 updater->Append(app_value); 785 updater->Append(app_value);
789 } 786 }
790 } 787 }
791 } else if (model_->items()[i].type == ash::TYPE_BROWSER_SHORTCUT) { 788 } else if (model_->items()[i].type == ash::TYPE_BROWSER_SHORTCUT) {
792 PersistChromeItemIndex(i); 789 PersistChromeItemIndex(i);
793 } else if (model_->items()[i].type == ash::TYPE_APP_LIST) { 790 } else if (model_->items()[i].type == ash::TYPE_APP_LIST) {
794 base::DictionaryValue* app_value = 791 base::DictionaryValue* app_value =
795 ash::CreateAppDict(ash::kPinnedAppsPlaceholder); 792 ash::CreateAppDict(ash::kPinnedAppsPlaceholder);
796 if (app_value) 793 if (app_value)
797 updater->Append(app_value); 794 updater->Append(app_value);
798 } 795 }
799 } 796 }
800 } 797 }
801 pref_change_registrar_.Add( 798 pref_change_registrar_.Add(
802 prefs::kPinnedLauncherApps, 799 prefs::kPinnedLauncherApps,
803 base::Bind(&ChromeLauncherController::UpdateAppLaunchersFromPref, 800 base::Bind(&ChromeLauncherControllerImpl::UpdateAppLaunchersFromPref,
804 base::Unretained(this))); 801 base::Unretained(this)));
805 } 802 }
806 803
807 Profile* ChromeLauncherController::profile() { 804 Profile* ChromeLauncherControllerImpl::GetProfile() {
808 return profile_; 805 return profile_;
809 } 806 }
810 807
811 void ChromeLauncherController::UpdateAppState(content::WebContents* contents, 808 void ChromeLauncherControllerImpl::UpdateAppState(
812 AppState app_state) { 809 content::WebContents* contents,
810 AppState app_state) {
813 std::string app_id = launcher_controller_helper_->GetAppID(contents); 811 std::string app_id = launcher_controller_helper_->GetAppID(contents);
814 812
815 // Check if the gMail app is loaded and it matches the given content. 813 // Check if the gMail app is loaded and it matches the given content.
816 // This special treatment is needed to address crbug.com/234268. 814 // This special treatment is needed to address crbug.com/234268.
817 if (app_id.empty() && ContentCanBeHandledByGmailApp(contents)) 815 if (app_id.empty() && ContentCanBeHandledByGmailApp(contents))
818 app_id = kGmailAppId; 816 app_id = kGmailAppId;
819 817
820 // Check the old |app_id| for a tab. If the contents has changed we need to 818 // Check the old |app_id| for a tab. If the contents has changed we need to
821 // remove it from the previous app. 819 // remove it from the previous app.
822 if (web_contents_to_app_id_.find(contents) != web_contents_to_app_id_.end()) { 820 if (web_contents_to_app_id_.find(contents) != web_contents_to_app_id_.end()) {
(...skipping 10 matching lines...) Expand all
833 } 831 }
834 832
835 if (app_state == APP_STATE_REMOVED) 833 if (app_state == APP_STATE_REMOVED)
836 web_contents_to_app_id_.erase(contents); 834 web_contents_to_app_id_.erase(contents);
837 else 835 else
838 web_contents_to_app_id_[contents] = app_id; 836 web_contents_to_app_id_[contents] = app_id;
839 837
840 ash::ShelfID id = GetShelfIDForAppID(app_id); 838 ash::ShelfID id = GetShelfIDForAppID(app_id);
841 if (id) { 839 if (id) {
842 SetItemStatus(id, (app_state == APP_STATE_WINDOW_ACTIVE || 840 SetItemStatus(id, (app_state == APP_STATE_WINDOW_ACTIVE ||
843 app_state == APP_STATE_ACTIVE) ? ash::STATUS_ACTIVE : 841 app_state == APP_STATE_ACTIVE)
844 GetAppState(app_id)); 842 ? ash::STATUS_ACTIVE
843 : GetAppState(app_id));
845 } 844 }
846 } 845 }
847 846
848 ash::ShelfID ChromeLauncherController::GetShelfIDForWebContents( 847 ash::ShelfID ChromeLauncherControllerImpl::GetShelfIDForWebContents(
849 content::WebContents* contents) { 848 content::WebContents* contents) {
850 DCHECK(contents); 849 DCHECK(contents);
851 850
852 std::string app_id = launcher_controller_helper_->GetAppID(contents); 851 std::string app_id = launcher_controller_helper_->GetAppID(contents);
853 852
854 if (app_id.empty() && ContentCanBeHandledByGmailApp(contents)) 853 if (app_id.empty() && ContentCanBeHandledByGmailApp(contents))
855 app_id = kGmailAppId; 854 app_id = kGmailAppId;
856 855
857 ash::ShelfID id = GetShelfIDForAppID(app_id); 856 ash::ShelfID id = GetShelfIDForAppID(app_id);
858 857
859 if (app_id.empty() || !id) { 858 if (app_id.empty() || !id) {
860 int browser_index = model_->GetItemIndexForType(ash::TYPE_BROWSER_SHORTCUT); 859 int browser_index = model_->GetItemIndexForType(ash::TYPE_BROWSER_SHORTCUT);
861 return model_->items()[browser_index].id; 860 return model_->items()[browser_index].id;
862 } 861 }
863 862
864 return id; 863 return id;
865 } 864 }
866 865
867 void ChromeLauncherController::SetRefocusURLPatternForTest(ash::ShelfID id, 866 void ChromeLauncherControllerImpl::SetRefocusURLPatternForTest(
868 const GURL& url) { 867 ash::ShelfID id,
868 const GURL& url) {
869 LauncherItemController* controller = GetLauncherItemController(id); 869 LauncherItemController* controller = GetLauncherItemController(id);
870 DCHECK(controller); 870 DCHECK(controller);
871 871
872 int index = model_->ItemIndexByID(id); 872 int index = model_->ItemIndexByID(id);
873 if (index == -1) { 873 if (index == -1) {
874 NOTREACHED() << "Invalid launcher id"; 874 NOTREACHED() << "Invalid launcher id";
875 return; 875 return;
876 } 876 }
877 877
878 ash::ShelfItemType type = model_->items()[index].type; 878 ash::ShelfItemType type = model_->items()[index].type;
879 if (type == ash::TYPE_APP_SHORTCUT || type == ash::TYPE_WINDOWED_APP) { 879 if (type == ash::TYPE_APP_SHORTCUT || type == ash::TYPE_WINDOWED_APP) {
880 AppShortcutLauncherItemController* app_controller = 880 AppShortcutLauncherItemController* app_controller =
881 static_cast<AppShortcutLauncherItemController*>(controller); 881 static_cast<AppShortcutLauncherItemController*>(controller);
882 app_controller->set_refocus_url(url); 882 app_controller->set_refocus_url(url);
883 } else { 883 } else {
884 NOTREACHED() << "Invalid launcher type"; 884 NOTREACHED() << "Invalid launcher type";
885 } 885 }
886 } 886 }
887 887
888 const Extension* ChromeLauncherController::GetExtensionForAppID( 888 const Extension* ChromeLauncherControllerImpl::GetExtensionForAppID(
889 const std::string& app_id) const { 889 const std::string& app_id) const {
890 return extensions::ExtensionRegistry::Get(profile_)->GetExtensionById( 890 return extensions::ExtensionRegistry::Get(profile_)->GetExtensionById(
891 app_id, extensions::ExtensionRegistry::EVERYTHING); 891 app_id, extensions::ExtensionRegistry::EVERYTHING);
892 } 892 }
893 893
894 ash::ShelfItemDelegate::PerformedAction 894 ash::ShelfItemDelegate::PerformedAction
895 ChromeLauncherController::ActivateWindowOrMinimizeIfActive( 895 ChromeLauncherControllerImpl::ActivateWindowOrMinimizeIfActive(
896 ui::BaseWindow* window, 896 ui::BaseWindow* window,
897 bool allow_minimize) { 897 bool allow_minimize) {
898 // In separated desktop mode we might have to teleport a window back to the 898 // In separated desktop mode we might have to teleport a window back to the
899 // current user. 899 // current user.
900 if (chrome::MultiUserWindowManager::GetMultiProfileMode() == 900 if (chrome::MultiUserWindowManager::GetMultiProfileMode() ==
901 chrome::MultiUserWindowManager::MULTI_PROFILE_MODE_SEPARATED) { 901 chrome::MultiUserWindowManager::MULTI_PROFILE_MODE_SEPARATED) {
902 aura::Window* native_window = window->GetNativeWindow(); 902 aura::Window* native_window = window->GetNativeWindow();
903 const AccountId& current_account_id = 903 const AccountId& current_account_id =
904 multi_user_util::GetAccountIdFromProfile(profile()); 904 multi_user_util::GetAccountIdFromProfile(GetProfile());
905 chrome::MultiUserWindowManager* manager = 905 chrome::MultiUserWindowManager* manager =
906 chrome::MultiUserWindowManager::GetInstance(); 906 chrome::MultiUserWindowManager::GetInstance();
907 if (!manager->IsWindowOnDesktopOfUser(native_window, current_account_id)) { 907 if (!manager->IsWindowOnDesktopOfUser(native_window, current_account_id)) {
908 ash::MultiProfileUMA::RecordTeleportAction( 908 ash::MultiProfileUMA::RecordTeleportAction(
909 ash::MultiProfileUMA::TELEPORT_WINDOW_RETURN_BY_LAUNCHER); 909 ash::MultiProfileUMA::TELEPORT_WINDOW_RETURN_BY_LAUNCHER);
910 manager->ShowWindowForUser(native_window, current_account_id); 910 manager->ShowWindowForUser(native_window, current_account_id);
911 window->Activate(); 911 window->Activate();
912 return ash::ShelfItemDelegate::kExistingWindowActivated; 912 return ash::ShelfItemDelegate::kExistingWindowActivated;
913 } 913 }
914 } 914 }
915 915
916 if (window->IsActive() && allow_minimize) { 916 if (window->IsActive() && allow_minimize) {
917 window->Minimize(); 917 window->Minimize();
918 return ash::ShelfItemDelegate::kNoAction; 918 return ash::ShelfItemDelegate::kNoAction;
919 } 919 }
920 920
921 window->Show(); 921 window->Show();
922 window->Activate(); 922 window->Activate();
923 return ash::ShelfItemDelegate::kExistingWindowActivated; 923 return ash::ShelfItemDelegate::kExistingWindowActivated;
924 } 924 }
925 925
926 void ChromeLauncherController::OnShelfCreated(ash::Shelf* shelf) { 926 ArcAppDeferredLauncherController*
927 ChromeLauncherControllerImpl::GetArcDeferredLauncher() {
928 return arc_deferred_launcher_.get();
929 }
930
931 void ChromeLauncherControllerImpl::OnShelfCreated(ash::Shelf* shelf) {
927 PrefService* prefs = profile_->GetPrefs(); 932 PrefService* prefs = profile_->GetPrefs();
928 const int64_t display = GetDisplayIDForShelf(shelf); 933 const int64_t display = GetDisplayIDForShelf(shelf);
929 934
930 shelf->SetAutoHideBehavior(ash::GetShelfAutoHideBehaviorPref(prefs, display)); 935 shelf->SetAutoHideBehavior(ash::GetShelfAutoHideBehaviorPref(prefs, display));
931 936
932 if (ash::ShelfWidget::ShelfAlignmentAllowed()) 937 if (ash::ShelfWidget::ShelfAlignmentAllowed())
933 shelf->SetAlignment(ash::GetShelfAlignmentPref(prefs, display)); 938 shelf->SetAlignment(ash::GetShelfAlignmentPref(prefs, display));
934 } 939 }
935 940
936 void ChromeLauncherController::OnShelfDestroyed(ash::Shelf* shelf) {} 941 void ChromeLauncherControllerImpl::OnShelfDestroyed(ash::Shelf* shelf) {}
937 942
938 void ChromeLauncherController::OnShelfAlignmentChanged(ash::Shelf* shelf) { 943 void ChromeLauncherControllerImpl::OnShelfAlignmentChanged(ash::Shelf* shelf) {
939 ash::SetShelfAlignmentPref(profile_->GetPrefs(), GetDisplayIDForShelf(shelf), 944 ash::SetShelfAlignmentPref(profile_->GetPrefs(), GetDisplayIDForShelf(shelf),
940 shelf->alignment()); 945 shelf->alignment());
941 } 946 }
942 947
943 void ChromeLauncherController::OnShelfAutoHideBehaviorChanged( 948 void ChromeLauncherControllerImpl::OnShelfAutoHideBehaviorChanged(
944 ash::Shelf* shelf) { 949 ash::Shelf* shelf) {
945 ash::SetShelfAutoHideBehaviorPref(profile_->GetPrefs(), 950 ash::SetShelfAutoHideBehaviorPref(profile_->GetPrefs(),
946 GetDisplayIDForShelf(shelf), 951 GetDisplayIDForShelf(shelf),
947 shelf->auto_hide_behavior()); 952 shelf->auto_hide_behavior());
948 } 953 }
949 954
950 void ChromeLauncherController::OnShelfAutoHideStateChanged(ash::Shelf* shelf) {} 955 void ChromeLauncherControllerImpl::OnShelfAutoHideStateChanged(
951
952 void ChromeLauncherController::OnShelfVisibilityStateChanged(
953 ash::Shelf* shelf) {} 956 ash::Shelf* shelf) {}
954 957
955 void ChromeLauncherController::ShelfItemAdded(int index) { 958 void ChromeLauncherControllerImpl::OnShelfVisibilityStateChanged(
959 ash::Shelf* shelf) {}
960
961 void ChromeLauncherControllerImpl::ShelfItemAdded(int index) {
956 // The app list launcher can get added to the shelf after we applied the 962 // The app list launcher can get added to the shelf after we applied the
957 // preferences. In that case the item might be at the wrong spot. As such we 963 // preferences. In that case the item might be at the wrong spot. As such we
958 // call the function again. 964 // call the function again.
959 if (model_->items()[index].type == ash::TYPE_APP_LIST) 965 if (model_->items()[index].type == ash::TYPE_APP_LIST)
960 UpdateAppLaunchersFromPref(); 966 UpdateAppLaunchersFromPref();
961 } 967 }
962 968
963 void ChromeLauncherController::ShelfItemRemoved(int index, ash::ShelfID id) { 969 void ChromeLauncherControllerImpl::ShelfItemRemoved(int index,
970 ash::ShelfID id) {
964 // TODO(skuhne): This fixes crbug.com/429870, but it does not answer why we 971 // TODO(skuhne): This fixes crbug.com/429870, but it does not answer why we
965 // get into this state in the first place. 972 // get into this state in the first place.
966 IDToItemControllerMap::iterator iter = id_to_item_controller_map_.find(id); 973 IDToItemControllerMap::iterator iter = id_to_item_controller_map_.find(id);
967 if (iter == id_to_item_controller_map_.end()) 974 if (iter == id_to_item_controller_map_.end())
968 return; 975 return;
969 976
970 LOG(ERROR) << "Unexpected change of shelf item id: " << id; 977 LOG(ERROR) << "Unexpected change of shelf item id: " << id;
971 978
972 id_to_item_controller_map_.erase(iter); 979 id_to_item_controller_map_.erase(iter);
973 } 980 }
974 981
975 void ChromeLauncherController::ShelfItemMoved(int start_index, 982 void ChromeLauncherControllerImpl::ShelfItemMoved(int start_index,
976 int target_index) { 983 int target_index) {
977 const ash::ShelfItem& item = model_->items()[target_index]; 984 const ash::ShelfItem& item = model_->items()[target_index];
978 // We remember the moved item position if it is either pinnable or 985 // We remember the moved item position if it is either pinnable or
979 // it is the app list with the alternate shelf layout. 986 // it is the app list with the alternate shelf layout.
980 if ((HasShelfIDToAppIDMapping(item.id) && IsPinned(item.id)) || 987 if ((HasShelfIDToAppIDMapping(item.id) && IsPinned(item.id)) ||
981 item.type == ash::TYPE_APP_LIST) 988 item.type == ash::TYPE_APP_LIST)
982 PersistPinnedState(); 989 PersistPinnedState();
983 } 990 }
984 991
985 void ChromeLauncherController::ShelfItemChanged( 992 void ChromeLauncherControllerImpl::ShelfItemChanged(
986 int index, 993 int index,
987 const ash::ShelfItem& old_item) {} 994 const ash::ShelfItem& old_item) {}
988 995
989 void ChromeLauncherController::ActiveUserChanged( 996 void ChromeLauncherControllerImpl::ActiveUserChanged(
990 const std::string& user_email) { 997 const std::string& user_email) {
991 // Store the order of running applications for the user which gets inactive. 998 // Store the order of running applications for the user which gets inactive.
992 RememberUnpinnedRunningApplicationOrder(); 999 RememberUnpinnedRunningApplicationOrder();
993 // Coming here the default profile is already switched. All profile specific 1000 // Coming here the default profile is already switched. All profile specific
994 // resources get released and the new profile gets attached instead. 1001 // resources get released and the new profile gets attached instead.
995 ReleaseProfile(); 1002 ReleaseProfile();
996 // When coming here, the active user has already be changed so that we can 1003 // When coming here, the active user has already be changed so that we can
997 // set it as active. 1004 // set it as active.
998 AttachProfile(ProfileManager::GetActiveUserProfile()); 1005 AttachProfile(ProfileManager::GetActiveUserProfile());
999 // Update the V1 applications. 1006 // Update the V1 applications.
1000 browser_status_monitor_->ActiveUserChanged(user_email); 1007 browser_status_monitor_->ActiveUserChanged(user_email);
1001 // Switch the running applications to the new user. 1008 // Switch the running applications to the new user.
1002 for (auto& controller : app_window_controllers_) 1009 for (auto& controller : app_window_controllers_)
1003 controller->ActiveUserChanged(user_email); 1010 controller->ActiveUserChanged(user_email);
1004 // Update the user specific shell properties from the new user profile. 1011 // Update the user specific shell properties from the new user profile.
1005 UpdateAppLaunchersFromPref(); 1012 UpdateAppLaunchersFromPref();
1006 SetShelfBehaviorsFromPrefs(); 1013 SetShelfBehaviorsFromPrefs();
1007 SetVirtualKeyboardBehaviorFromPrefs(); 1014 SetVirtualKeyboardBehaviorFromPrefs();
1008 1015
1009 // Restore the order of running, but unpinned applications for the activated 1016 // Restore the order of running, but unpinned applications for the activated
1010 // user. 1017 // user.
1011 RestoreUnpinnedRunningApplicationOrder(user_email); 1018 RestoreUnpinnedRunningApplicationOrder(user_email);
1012 // Inform the system tray of the change. 1019 // Inform the system tray of the change.
1013 ash::WmShell::Get()->system_tray_delegate()->ActiveUserWasChanged(); 1020 ash::WmShell::Get()->system_tray_delegate()->ActiveUserWasChanged();
1014 // Force on-screen keyboard to reset. 1021 // Force on-screen keyboard to reset.
1015 if (keyboard::IsKeyboardEnabled()) 1022 if (keyboard::IsKeyboardEnabled())
1016 ash::Shell::GetInstance()->CreateKeyboard(); 1023 ash::Shell::GetInstance()->CreateKeyboard();
1017 } 1024 }
1018 1025
1019 void ChromeLauncherController::AdditionalUserAddedToSession(Profile* profile) { 1026 void ChromeLauncherControllerImpl::AdditionalUserAddedToSession(
1027 Profile* profile) {
1020 // Switch the running applications to the new user. 1028 // Switch the running applications to the new user.
1021 for (auto& controller : app_window_controllers_) 1029 for (auto& controller : app_window_controllers_)
1022 controller->AdditionalUserAddedToSession(profile); 1030 controller->AdditionalUserAddedToSession(profile);
1023 } 1031 }
1024 1032
1025 void ChromeLauncherController::OnAppInstalled( 1033 void ChromeLauncherControllerImpl::OnAppInstalled(
1026 content::BrowserContext* browser_context, 1034 content::BrowserContext* browser_context,
1027 const std::string& app_id) { 1035 const std::string& app_id) {
1028 if (IsAppPinned(app_id)) { 1036 if (IsAppPinned(app_id)) {
1029 // Clear and re-fetch to ensure icon is up-to-date. 1037 // Clear and re-fetch to ensure icon is up-to-date.
1030 AppIconLoader* app_icon_loader = GetAppIconLoaderForApp(app_id); 1038 AppIconLoader* app_icon_loader = GetAppIconLoaderForApp(app_id);
1031 if (app_icon_loader) { 1039 if (app_icon_loader) {
1032 app_icon_loader->ClearImage(app_id); 1040 app_icon_loader->ClearImage(app_id);
1033 app_icon_loader->FetchImage(app_id); 1041 app_icon_loader->FetchImage(app_id);
1034 } 1042 }
1035 } 1043 }
1036 1044
1037 UpdateAppLaunchersFromPref(); 1045 UpdateAppLaunchersFromPref();
1038 } 1046 }
1039 1047
1040 void ChromeLauncherController::OnAppUpdated( 1048 void ChromeLauncherControllerImpl::OnAppUpdated(
1041 content::BrowserContext* browser_context, 1049 content::BrowserContext* browser_context,
1042 const std::string& app_id) { 1050 const std::string& app_id) {
1043 AppIconLoader* app_icon_loader = GetAppIconLoaderForApp(app_id); 1051 AppIconLoader* app_icon_loader = GetAppIconLoaderForApp(app_id);
1044 if (app_icon_loader) 1052 if (app_icon_loader)
1045 app_icon_loader->UpdateImage(app_id); 1053 app_icon_loader->UpdateImage(app_id);
1046 } 1054 }
1047 1055
1048 void ChromeLauncherController::OnAppUninstalled( 1056 void ChromeLauncherControllerImpl::OnAppUninstalled(
1049 content::BrowserContext* browser_context, 1057 content::BrowserContext* browser_context,
1050 const std::string& app_id) { 1058 const std::string& app_id) {
1051 // Since we might have windowed apps of this type which might have 1059 // Since we might have windowed apps of this type which might have
1052 // outstanding locks which needs to be removed. 1060 // outstanding locks which needs to be removed.
1053 const Profile* profile = Profile::FromBrowserContext(browser_context); 1061 const Profile* profile = Profile::FromBrowserContext(browser_context);
1054 if (GetShelfIDForAppID(app_id)) 1062 if (GetShelfIDForAppID(app_id))
1055 CloseWindowedAppsFromRemovedExtension(app_id, profile); 1063 CloseWindowedAppsFromRemovedExtension(app_id, profile);
1056 1064
1057 if (IsAppPinned(app_id)) { 1065 if (IsAppPinned(app_id)) {
1058 if (profile == profile_) 1066 if (profile == profile_)
1059 DoUnpinAppWithID(app_id); 1067 DoUnpinAppWithID(app_id);
1060 AppIconLoader* app_icon_loader = GetAppIconLoaderForApp(app_id); 1068 AppIconLoader* app_icon_loader = GetAppIconLoaderForApp(app_id);
1061 if (app_icon_loader) 1069 if (app_icon_loader)
1062 app_icon_loader->ClearImage(app_id); 1070 app_icon_loader->ClearImage(app_id);
1063 } 1071 }
1064 } 1072 }
1065 1073
1066 void ChromeLauncherController::OnDisplayConfigurationChanged() { 1074 void ChromeLauncherControllerImpl::OnDisplayConfigurationChanged() {
1067 SetShelfBehaviorsFromPrefs(); 1075 SetShelfBehaviorsFromPrefs();
1068 } 1076 }
1069 1077
1070 void ChromeLauncherController::OnAppSyncUIStatusChanged() { 1078 void ChromeLauncherControllerImpl::OnAppSyncUIStatusChanged() {
1071 if (app_sync_ui_state_->status() == AppSyncUIState::STATUS_SYNCING) 1079 if (app_sync_ui_state_->status() == AppSyncUIState::STATUS_SYNCING)
1072 model_->set_status(ash::ShelfModel::STATUS_LOADING); 1080 model_->set_status(ash::ShelfModel::STATUS_LOADING);
1073 else 1081 else
1074 model_->set_status(ash::ShelfModel::STATUS_NORMAL); 1082 model_->set_status(ash::ShelfModel::STATUS_NORMAL);
1075 } 1083 }
1076 1084
1077 ChromeLauncherAppMenuItems ChromeLauncherController::GetApplicationList( 1085 ChromeLauncherAppMenuItems ChromeLauncherControllerImpl::GetApplicationList(
1078 const ash::ShelfItem& item, 1086 const ash::ShelfItem& item,
1079 int event_flags) { 1087 int event_flags) {
1080 // Make sure that there is a controller associated with the id and that the 1088 // Make sure that there is a controller associated with the id and that the
1081 // extension itself is a valid application and not a panel. 1089 // extension itself is a valid application and not a panel.
1082 LauncherItemController* controller = GetLauncherItemController(item.id); 1090 LauncherItemController* controller = GetLauncherItemController(item.id);
1083 if (!controller || !GetShelfIDForAppID(controller->app_id())) 1091 if (!controller || !GetShelfIDForAppID(controller->app_id()))
1084 return ChromeLauncherAppMenuItems(); 1092 return ChromeLauncherAppMenuItems();
1085 1093
1086 return controller->GetApplicationList(event_flags); 1094 return controller->GetApplicationList(event_flags);
1087 } 1095 }
1088 1096
1089 std::vector<content::WebContents*> 1097 std::vector<content::WebContents*>
1090 ChromeLauncherController::GetV1ApplicationsFromAppId( 1098 ChromeLauncherControllerImpl::GetV1ApplicationsFromAppId(
1091 const std::string& app_id) { 1099 const std::string& app_id) {
1092 ash::ShelfID id = GetShelfIDForAppID(app_id); 1100 ash::ShelfID id = GetShelfIDForAppID(app_id);
1093 1101
1094 // If there is no such an item pinned to the launcher, no menu gets created. 1102 // If there is no such an item pinned to the launcher, no menu gets created.
1095 if (id) { 1103 if (id) {
1096 LauncherItemController* controller = GetLauncherItemController(id); 1104 LauncherItemController* controller = GetLauncherItemController(id);
1097 DCHECK(controller); 1105 DCHECK(controller);
1098 if (controller->type() == LauncherItemController::TYPE_SHORTCUT) 1106 if (controller->type() == LauncherItemController::TYPE_SHORTCUT)
1099 return GetV1ApplicationsFromController(controller); 1107 return GetV1ApplicationsFromController(controller);
1100 } 1108 }
1101 return std::vector<content::WebContents*>(); 1109 return std::vector<content::WebContents*>();
1102 } 1110 }
1103 1111
1104 void ChromeLauncherController::ActivateShellApp(const std::string& app_id, 1112 void ChromeLauncherControllerImpl::ActivateShellApp(const std::string& app_id,
1105 int index) { 1113 int index) {
1106 ash::ShelfID id = GetShelfIDForAppID(app_id); 1114 ash::ShelfID id = GetShelfIDForAppID(app_id);
1107 if (id) { 1115 if (id) {
1108 LauncherItemController* controller = GetLauncherItemController(id); 1116 LauncherItemController* controller = GetLauncherItemController(id);
1109 if (controller && controller->type() == LauncherItemController::TYPE_APP) { 1117 if (controller && controller->type() == LauncherItemController::TYPE_APP) {
1110 AppWindowLauncherItemController* app_window_controller = 1118 AppWindowLauncherItemController* app_window_controller =
1111 static_cast<AppWindowLauncherItemController*>(controller); 1119 static_cast<AppWindowLauncherItemController*>(controller);
1112 app_window_controller->ActivateIndexedApp(index); 1120 app_window_controller->ActivateIndexedApp(index);
1113 } 1121 }
1114 } 1122 }
1115 } 1123 }
1116 1124
1117 bool ChromeLauncherController::IsWebContentHandledByApplication( 1125 bool ChromeLauncherControllerImpl::IsWebContentHandledByApplication(
1118 content::WebContents* web_contents, 1126 content::WebContents* web_contents,
1119 const std::string& app_id) { 1127 const std::string& app_id) {
1120 if ((web_contents_to_app_id_.find(web_contents) != 1128 if ((web_contents_to_app_id_.find(web_contents) !=
1121 web_contents_to_app_id_.end()) && 1129 web_contents_to_app_id_.end()) &&
1122 (web_contents_to_app_id_[web_contents] == app_id)) 1130 (web_contents_to_app_id_[web_contents] == app_id))
1123 return true; 1131 return true;
1124 return (app_id == kGmailAppId && ContentCanBeHandledByGmailApp(web_contents)); 1132 return (app_id == kGmailAppId && ContentCanBeHandledByGmailApp(web_contents));
1125 } 1133 }
1126 1134
1127 bool ChromeLauncherController::ContentCanBeHandledByGmailApp( 1135 bool ChromeLauncherControllerImpl::ContentCanBeHandledByGmailApp(
1128 content::WebContents* web_contents) { 1136 content::WebContents* web_contents) {
1129 ash::ShelfID id = GetShelfIDForAppID(kGmailAppId); 1137 ash::ShelfID id = GetShelfIDForAppID(kGmailAppId);
1130 if (id) { 1138 if (id) {
1131 const GURL url = web_contents->GetURL(); 1139 const GURL url = web_contents->GetURL();
1132 // We need to extend the application matching for the gMail app beyond the 1140 // We need to extend the application matching for the gMail app beyond the
1133 // manifest file's specification. This is required because of the namespace 1141 // manifest file's specification. This is required because of the namespace
1134 // overlap with the offline app ("/mail/mu/"). 1142 // overlap with the offline app ("/mail/mu/").
1135 if (!base::MatchPattern(url.path(), "/mail/mu/*") && 1143 if (!base::MatchPattern(url.path(), "/mail/mu/*") &&
1136 base::MatchPattern(url.path(), "/mail/*") && 1144 base::MatchPattern(url.path(), "/mail/*") &&
1137 GetExtensionForAppID(kGmailAppId) && 1145 GetExtensionForAppID(kGmailAppId) &&
1138 GetExtensionForAppID(kGmailAppId)->OverlapsWithOrigin(url)) 1146 GetExtensionForAppID(kGmailAppId)->OverlapsWithOrigin(url))
1139 return true; 1147 return true;
1140 } 1148 }
1141 return false; 1149 return false;
1142 } 1150 }
1143 1151
1144 gfx::Image ChromeLauncherController::GetAppListIcon( 1152 gfx::Image ChromeLauncherControllerImpl::GetAppListIcon(
1145 content::WebContents* web_contents) const { 1153 content::WebContents* web_contents) const {
1146 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); 1154 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
1147 if (IsIncognito(web_contents)) 1155 if (IsIncognito(web_contents))
1148 return rb.GetImageNamed(IDR_ASH_SHELF_LIST_INCOGNITO_BROWSER); 1156 return rb.GetImageNamed(IDR_ASH_SHELF_LIST_INCOGNITO_BROWSER);
1149 favicon::FaviconDriver* favicon_driver = 1157 favicon::FaviconDriver* favicon_driver =
1150 favicon::ContentFaviconDriver::FromWebContents(web_contents); 1158 favicon::ContentFaviconDriver::FromWebContents(web_contents);
1151 gfx::Image result = favicon_driver->GetFavicon(); 1159 gfx::Image result = favicon_driver->GetFavicon();
1152 if (result.IsEmpty()) 1160 if (result.IsEmpty())
1153 return rb.GetImageNamed(IDR_DEFAULT_FAVICON); 1161 return rb.GetImageNamed(IDR_DEFAULT_FAVICON);
1154 return result; 1162 return result;
1155 } 1163 }
1156 1164
1157 base::string16 ChromeLauncherController::GetAppListTitle( 1165 base::string16 ChromeLauncherControllerImpl::GetAppListTitle(
1158 content::WebContents* web_contents) const { 1166 content::WebContents* web_contents) const {
1159 base::string16 title = web_contents->GetTitle(); 1167 base::string16 title = web_contents->GetTitle();
1160 if (!title.empty()) 1168 if (!title.empty())
1161 return title; 1169 return title;
1162 WebContentsToAppIDMap::const_iterator iter = 1170 WebContentsToAppIDMap::const_iterator iter =
1163 web_contents_to_app_id_.find(web_contents); 1171 web_contents_to_app_id_.find(web_contents);
1164 if (iter != web_contents_to_app_id_.end()) { 1172 if (iter != web_contents_to_app_id_.end()) {
1165 std::string app_id = iter->second; 1173 std::string app_id = iter->second;
1166 const extensions::Extension* extension = GetExtensionForAppID(app_id); 1174 const extensions::Extension* extension = GetExtensionForAppID(app_id);
1167 if (extension) 1175 if (extension)
1168 return base::UTF8ToUTF16(extension->name()); 1176 return base::UTF8ToUTF16(extension->name());
1169 } 1177 }
1170 return l10n_util::GetStringUTF16(IDS_NEW_TAB_TITLE); 1178 return l10n_util::GetStringUTF16(IDS_NEW_TAB_TITLE);
1171 } 1179 }
1172 1180
1173 ash::ShelfID ChromeLauncherController::CreateAppShortcutLauncherItem( 1181 ash::ShelfID ChromeLauncherControllerImpl::CreateAppShortcutLauncherItem(
1174 const std::string& app_id, 1182 const std::string& app_id,
1175 int index) { 1183 int index) {
1176 return CreateAppShortcutLauncherItemWithType(app_id, 1184 return CreateAppShortcutLauncherItemWithType(app_id, index,
1177 index,
1178 ash::TYPE_APP_SHORTCUT); 1185 ash::TYPE_APP_SHORTCUT);
1179 } 1186 }
1180 1187
1181 void ChromeLauncherController::SetLauncherControllerHelperForTest( 1188 void ChromeLauncherControllerImpl::SetLauncherControllerHelperForTest(
1182 LauncherControllerHelper* helper) { 1189 LauncherControllerHelper* helper) {
1183 launcher_controller_helper_.reset(helper); 1190 launcher_controller_helper_.reset(helper);
1184 } 1191 }
1185 1192
1186 void ChromeLauncherController::SetAppIconLoadersForTest( 1193 void ChromeLauncherControllerImpl::SetAppIconLoadersForTest(
1187 std::vector<std::unique_ptr<AppIconLoader>>& loaders) { 1194 std::vector<std::unique_ptr<AppIconLoader>>& loaders) {
1188 app_icon_loaders_.clear(); 1195 app_icon_loaders_.clear();
1189 for (auto& loader : loaders) 1196 for (auto& loader : loaders)
1190 app_icon_loaders_.push_back(std::move(loader)); 1197 app_icon_loaders_.push_back(std::move(loader));
1191 } 1198 }
1192 1199
1193 const std::string& ChromeLauncherController::GetAppIdFromShelfIdForTest( 1200 const std::string& ChromeLauncherControllerImpl::GetAppIdFromShelfIdForTest(
1194 ash::ShelfID id) { 1201 ash::ShelfID id) {
1195 return id_to_item_controller_map_[id]->app_id(); 1202 return id_to_item_controller_map_[id]->app_id();
1196 } 1203 }
1197 1204
1198 bool ChromeLauncherController::GetAppIDForShelfIDConst( 1205 bool ChromeLauncherControllerImpl::GetAppIDForShelfIDConst(
1199 ash::ShelfID id, 1206 ash::ShelfID id,
1200 std::string* app_id) const { 1207 std::string* app_id) const {
1201 auto app = id_to_item_controller_map_.find(id); 1208 auto app = id_to_item_controller_map_.find(id);
1202 if (app == id_to_item_controller_map_.end()) { 1209 if (app == id_to_item_controller_map_.end()) {
1203 return false; 1210 return false;
1204 } else { 1211 } else {
1205 *app_id = app->second->app_id(); 1212 *app_id = app->second->app_id();
1206 return true; 1213 return true;
1207 } 1214 }
1208 } 1215 }
1209 1216
1210 void ChromeLauncherController::SetShelfItemDelegateManagerForTest( 1217 void ChromeLauncherControllerImpl::SetShelfItemDelegateManagerForTest(
1211 ash::ShelfItemDelegateManager* manager) { 1218 ash::ShelfItemDelegateManager* manager) {
1212 if (item_delegate_manager_) 1219 if (item_delegate_manager_)
1213 item_delegate_manager_->RemoveObserver(this); 1220 item_delegate_manager_->RemoveObserver(this);
1214 1221
1215 item_delegate_manager_ = manager; 1222 item_delegate_manager_ = manager;
1216 1223
1217 if (item_delegate_manager_) 1224 if (item_delegate_manager_)
1218 item_delegate_manager_->AddObserver(this); 1225 item_delegate_manager_->AddObserver(this);
1219 } 1226 }
1220 1227
1221 void ChromeLauncherController::RememberUnpinnedRunningApplicationOrder() { 1228 void ChromeLauncherControllerImpl::RememberUnpinnedRunningApplicationOrder() {
1222 RunningAppListIds list; 1229 RunningAppListIds list;
1223 for (int i = 0; i < model_->item_count(); i++) { 1230 for (int i = 0; i < model_->item_count(); i++) {
1224 ash::ShelfItemType type = model_->items()[i].type; 1231 ash::ShelfItemType type = model_->items()[i].type;
1225 if (type == ash::TYPE_WINDOWED_APP || type == ash::TYPE_PLATFORM_APP) 1232 if (type == ash::TYPE_WINDOWED_APP || type == ash::TYPE_PLATFORM_APP)
1226 list.push_back(GetAppIDForShelfID(model_->items()[i].id)); 1233 list.push_back(GetAppIDForShelfID(model_->items()[i].id));
1227 } 1234 }
1228 const std::string user_email = 1235 const std::string user_email =
1229 multi_user_util::GetAccountIdFromProfile(profile_).GetUserEmail(); 1236 multi_user_util::GetAccountIdFromProfile(profile_).GetUserEmail();
1230 last_used_running_application_order_[user_email] = list; 1237 last_used_running_application_order_[user_email] = list;
1231 } 1238 }
1232 1239
1233 void ChromeLauncherController::RestoreUnpinnedRunningApplicationOrder( 1240 void ChromeLauncherControllerImpl::RestoreUnpinnedRunningApplicationOrder(
1234 const std::string& user_id) { 1241 const std::string& user_id) {
1235 const RunningAppListIdMap::iterator app_id_list = 1242 const RunningAppListIdMap::iterator app_id_list =
1236 last_used_running_application_order_.find(user_id); 1243 last_used_running_application_order_.find(user_id);
1237 if (app_id_list == last_used_running_application_order_.end()) 1244 if (app_id_list == last_used_running_application_order_.end())
1238 return; 1245 return;
1239 1246
1240 // Find the first insertion point for running applications. 1247 // Find the first insertion point for running applications.
1241 int running_index = model_->FirstRunningAppIndex(); 1248 int running_index = model_->FirstRunningAppIndex();
1242 for (RunningAppListIds::iterator app_id = app_id_list->second.begin(); 1249 for (RunningAppListIds::iterator app_id = app_id_list->second.begin();
1243 app_id != app_id_list->second.end(); ++app_id) { 1250 app_id != app_id_list->second.end(); ++app_id) {
1244 ash::ShelfID shelf_id = GetShelfIDForAppID(*app_id); 1251 ash::ShelfID shelf_id = GetShelfIDForAppID(*app_id);
1245 if (shelf_id) { 1252 if (shelf_id) {
1246 int app_index = model_->ItemIndexByID(shelf_id); 1253 int app_index = model_->ItemIndexByID(shelf_id);
1247 DCHECK_GE(app_index, 0); 1254 DCHECK_GE(app_index, 0);
1248 ash::ShelfItemType type = model_->items()[app_index].type; 1255 ash::ShelfItemType type = model_->items()[app_index].type;
1249 if (type == ash::TYPE_WINDOWED_APP || type == ash::TYPE_PLATFORM_APP) { 1256 if (type == ash::TYPE_WINDOWED_APP || type == ash::TYPE_PLATFORM_APP) {
1250 if (running_index != app_index) 1257 if (running_index != app_index)
1251 model_->Move(running_index, app_index); 1258 model_->Move(running_index, app_index);
1252 running_index++; 1259 running_index++;
1253 } 1260 }
1254 } 1261 }
1255 } 1262 }
1256 } 1263 }
1257 1264
1258 ash::ShelfID ChromeLauncherController::CreateAppShortcutLauncherItemWithType( 1265 ash::ShelfID
1266 ChromeLauncherControllerImpl::CreateAppShortcutLauncherItemWithType(
1259 const std::string& app_id, 1267 const std::string& app_id,
1260 int index, 1268 int index,
1261 ash::ShelfItemType shelf_item_type) { 1269 ash::ShelfItemType shelf_item_type) {
1262 AppShortcutLauncherItemController* controller = 1270 AppShortcutLauncherItemController* controller =
1263 AppShortcutLauncherItemController::Create(app_id, this); 1271 AppShortcutLauncherItemController::Create(app_id, this);
1264 ash::ShelfID shelf_id = InsertAppLauncherItem( 1272 ash::ShelfID shelf_id = InsertAppLauncherItem(
1265 controller, app_id, ash::STATUS_CLOSED, index, shelf_item_type); 1273 controller, app_id, ash::STATUS_CLOSED, index, shelf_item_type);
1266 return shelf_id; 1274 return shelf_id;
1267 } 1275 }
1268 1276
1269 LauncherItemController* ChromeLauncherController::GetLauncherItemController( 1277 LauncherItemController* ChromeLauncherControllerImpl::GetLauncherItemController(
1270 const ash::ShelfID id) { 1278 const ash::ShelfID id) {
1271 if (!HasShelfIDToAppIDMapping(id)) 1279 if (!HasShelfIDToAppIDMapping(id))
1272 return NULL; 1280 return NULL;
1273 return id_to_item_controller_map_[id]; 1281 return id_to_item_controller_map_[id];
1274 } 1282 }
1275 1283
1276 bool ChromeLauncherController::IsBrowserFromActiveUser(Browser* browser) { 1284 bool ChromeLauncherControllerImpl::IsBrowserFromActiveUser(Browser* browser) {
1277 // If running multi user mode with separate desktops, we have to check if the 1285 // If running multi user mode with separate desktops, we have to check if the
1278 // browser is from the active user. 1286 // browser is from the active user.
1279 if (chrome::MultiUserWindowManager::GetMultiProfileMode() != 1287 if (chrome::MultiUserWindowManager::GetMultiProfileMode() !=
1280 chrome::MultiUserWindowManager::MULTI_PROFILE_MODE_SEPARATED) 1288 chrome::MultiUserWindowManager::MULTI_PROFILE_MODE_SEPARATED)
1281 return true; 1289 return true;
1282 return multi_user_util::IsProfileFromActiveUser(browser->profile()); 1290 return multi_user_util::IsProfileFromActiveUser(browser->profile());
1283 } 1291 }
1284 1292
1285 bool ChromeLauncherController::ShelfBoundsChangesProbablyWithUser( 1293 bool ChromeLauncherControllerImpl::ShelfBoundsChangesProbablyWithUser(
1286 ash::Shelf* shelf, 1294 ash::Shelf* shelf,
1287 const std::string& user_id) const { 1295 const std::string& user_id) const {
1288 Profile* other_profile = multi_user_util::GetProfileFromAccountId( 1296 Profile* other_profile = multi_user_util::GetProfileFromAccountId(
1289 AccountId::FromUserEmail(user_id)); 1297 AccountId::FromUserEmail(user_id));
1290 if (other_profile == profile_) 1298 if (other_profile == profile_)
1291 return false; 1299 return false;
1292 1300
1293 // Note: The Auto hide state from preferences is not the same as the actual 1301 // Note: The Auto hide state from preferences is not the same as the actual
1294 // visibility of the shelf. Depending on all the various states (full screen, 1302 // visibility of the shelf. Depending on all the various states (full screen,
1295 // no window on desktop, multi user, ..) the shelf could be shown - or not. 1303 // no window on desktop, multi user, ..) the shelf could be shown - or not.
1296 PrefService* prefs = profile_->GetPrefs(); 1304 PrefService* prefs = profile_->GetPrefs();
1297 PrefService* other_prefs = other_profile->GetPrefs(); 1305 PrefService* other_prefs = other_profile->GetPrefs();
1298 const int64_t display = GetDisplayIDForShelf(shelf); 1306 const int64_t display = GetDisplayIDForShelf(shelf);
1299 bool currently_shown = ash::SHELF_AUTO_HIDE_BEHAVIOR_NEVER == 1307 bool currently_shown = ash::SHELF_AUTO_HIDE_BEHAVIOR_NEVER ==
1300 ash::GetShelfAutoHideBehaviorPref(prefs, display); 1308 ash::GetShelfAutoHideBehaviorPref(prefs, display);
1301 bool other_shown = ash::SHELF_AUTO_HIDE_BEHAVIOR_NEVER == 1309 bool other_shown = ash::SHELF_AUTO_HIDE_BEHAVIOR_NEVER ==
1302 ash::GetShelfAutoHideBehaviorPref(other_prefs, display); 1310 ash::GetShelfAutoHideBehaviorPref(other_prefs, display);
1303 1311
1304 return currently_shown != other_shown || 1312 return currently_shown != other_shown ||
1305 ash::GetShelfAlignmentPref(prefs, display) != 1313 ash::GetShelfAlignmentPref(prefs, display) !=
1306 ash::GetShelfAlignmentPref(other_prefs, display); 1314 ash::GetShelfAlignmentPref(other_prefs, display);
1307 } 1315 }
1308 1316
1309 void ChromeLauncherController::OnUserProfileReadyToSwitch(Profile* profile) { 1317 void ChromeLauncherControllerImpl::OnUserProfileReadyToSwitch(
1318 Profile* profile) {
1310 if (user_switch_observer_.get()) 1319 if (user_switch_observer_.get())
1311 user_switch_observer_->OnUserProfileReadyToSwitch(profile); 1320 user_switch_observer_->OnUserProfileReadyToSwitch(profile);
1312 } 1321 }
1313 1322
1314 void ChromeLauncherController::LauncherItemClosed(ash::ShelfID id) { 1323 void ChromeLauncherControllerImpl::LauncherItemClosed(ash::ShelfID id) {
1315 IDToItemControllerMap::iterator iter = id_to_item_controller_map_.find(id); 1324 IDToItemControllerMap::iterator iter = id_to_item_controller_map_.find(id);
1316 CHECK(iter != id_to_item_controller_map_.end()); 1325 CHECK(iter != id_to_item_controller_map_.end());
1317 CHECK(iter->second); 1326 CHECK(iter->second);
1318 const std::string& app_id = iter->second->app_id(); 1327 const std::string& app_id = iter->second->app_id();
1319 AppIconLoader* app_icon_loader = GetAppIconLoaderForApp(app_id); 1328 AppIconLoader* app_icon_loader = GetAppIconLoaderForApp(app_id);
1320 if (app_icon_loader) 1329 if (app_icon_loader)
1321 app_icon_loader->ClearImage(app_id); 1330 app_icon_loader->ClearImage(app_id);
1322 id_to_item_controller_map_.erase(iter); 1331 id_to_item_controller_map_.erase(iter);
1323 int index = model_->ItemIndexByID(id); 1332 int index = model_->ItemIndexByID(id);
1324 // A "browser proxy" is not known to the model and this removal does 1333 // A "browser proxy" is not known to the model and this removal does
1325 // therefore not need to be propagated to the model. 1334 // therefore not need to be propagated to the model.
1326 if (index != -1) 1335 if (index != -1)
1327 model_->RemoveItemAt(index); 1336 model_->RemoveItemAt(index);
1328 } 1337 }
1329 1338
1330 void ChromeLauncherController::DoPinAppWithID(const std::string& app_id) { 1339 void ChromeLauncherControllerImpl::DoPinAppWithID(const std::string& app_id) {
1331 // If there is an item, do nothing and return. 1340 // If there is an item, do nothing and return.
1332 if (IsAppPinned(app_id)) 1341 if (IsAppPinned(app_id))
1333 return; 1342 return;
1334 1343
1335 ash::ShelfID shelf_id = GetShelfIDForAppID(app_id); 1344 ash::ShelfID shelf_id = GetShelfIDForAppID(app_id);
1336 if (shelf_id) { 1345 if (shelf_id) {
1337 // App item exists, pin it 1346 // App item exists, pin it
1338 Pin(shelf_id); 1347 Pin(shelf_id);
1339 } else { 1348 } else {
1340 // Otherwise, create a shortcut item for it. 1349 // Otherwise, create a shortcut item for it.
1341 shelf_id = CreateAppShortcutLauncherItem(app_id, model_->item_count()); 1350 shelf_id = CreateAppShortcutLauncherItem(app_id, model_->item_count());
1342 if (GetPinnable(app_id) == AppListControllerDelegate::PIN_EDITABLE) 1351 if (GetPinnable(app_id) == AppListControllerDelegate::PIN_EDITABLE)
1343 PersistPinnedState(); 1352 PersistPinnedState();
1344 } 1353 }
1345 } 1354 }
1346 1355
1347 void ChromeLauncherController::DoUnpinAppWithID(const std::string& app_id) { 1356 void ChromeLauncherControllerImpl::DoUnpinAppWithID(const std::string& app_id) {
1348 ash::ShelfID shelf_id = GetShelfIDForAppID(app_id); 1357 ash::ShelfID shelf_id = GetShelfIDForAppID(app_id);
1349 if (shelf_id && IsPinned(shelf_id)) 1358 if (shelf_id && IsPinned(shelf_id))
1350 Unpin(shelf_id); 1359 Unpin(shelf_id);
1351 } 1360 }
1352 1361
1353 int ChromeLauncherController::PinRunningAppInternal(int index, 1362 int ChromeLauncherControllerImpl::PinRunningAppInternal(int index,
1354 ash::ShelfID shelf_id) { 1363 ash::ShelfID shelf_id) {
1355 int running_index = model_->ItemIndexByID(shelf_id); 1364 int running_index = model_->ItemIndexByID(shelf_id);
1356 ash::ShelfItem item = model_->items()[running_index]; 1365 ash::ShelfItem item = model_->items()[running_index];
1357 DCHECK(item.type == ash::TYPE_WINDOWED_APP || 1366 DCHECK(item.type == ash::TYPE_WINDOWED_APP ||
1358 item.type == ash::TYPE_PLATFORM_APP); 1367 item.type == ash::TYPE_PLATFORM_APP);
1359 item.type = ash::TYPE_APP_SHORTCUT; 1368 item.type = ash::TYPE_APP_SHORTCUT;
1360 model_->Set(running_index, item); 1369 model_->Set(running_index, item);
1361 // The |ShelfModel|'s weight system might reposition the item to a 1370 // The |ShelfModel|'s weight system might reposition the item to a
1362 // new index, so we get the index again. 1371 // new index, so we get the index again.
1363 running_index = model_->ItemIndexByID(shelf_id); 1372 running_index = model_->ItemIndexByID(shelf_id);
1364 if (running_index < index) 1373 if (running_index < index)
1365 --index; 1374 --index;
1366 if (running_index != index) 1375 if (running_index != index)
1367 model_->Move(running_index, index); 1376 model_->Move(running_index, index);
1368 return index; 1377 return index;
1369 } 1378 }
1370 1379
1371 void ChromeLauncherController::UnpinRunningAppInternal(int index) { 1380 void ChromeLauncherControllerImpl::UnpinRunningAppInternal(int index) {
1372 DCHECK_GE(index, 0); 1381 DCHECK_GE(index, 0);
1373 ash::ShelfItem item = model_->items()[index]; 1382 ash::ShelfItem item = model_->items()[index];
1374 DCHECK_EQ(item.type, ash::TYPE_APP_SHORTCUT); 1383 DCHECK_EQ(item.type, ash::TYPE_APP_SHORTCUT);
1375 item.type = ash::TYPE_WINDOWED_APP; 1384 item.type = ash::TYPE_WINDOWED_APP;
1376 // A platform app and a windowed app are sharing TYPE_APP_SHORTCUT. As such 1385 // A platform app and a windowed app are sharing TYPE_APP_SHORTCUT. As such
1377 // we have to check here what this was before it got a shortcut. 1386 // we have to check here what this was before it got a shortcut.
1378 LauncherItemController* controller = GetLauncherItemController(item.id); 1387 LauncherItemController* controller = GetLauncherItemController(item.id);
1379 if (controller && controller->type() == LauncherItemController::TYPE_APP) 1388 if (controller && controller->type() == LauncherItemController::TYPE_APP)
1380 item.type = ash::TYPE_PLATFORM_APP; 1389 item.type = ash::TYPE_PLATFORM_APP;
1381 model_->Set(index, item); 1390 model_->Set(index, item);
1382 } 1391 }
1383 1392
1384 void ChromeLauncherController::UpdateAppLaunchersFromPref() { 1393 void ChromeLauncherControllerImpl::UpdateAppLaunchersFromPref() {
1385 // There are various functions which will trigger a |PersistPinnedState| call 1394 // There are various functions which will trigger a |PersistPinnedState| call
1386 // like a direct call to |DoPinAppWithID|, or an indirect call to the menu 1395 // like a direct call to |DoPinAppWithID|, or an indirect call to the menu
1387 // model which will use weights to re-arrange the icons to new positions. 1396 // model which will use weights to re-arrange the icons to new positions.
1388 // Since this function is meant to synchronize the "is state" with the 1397 // Since this function is meant to synchronize the "is state" with the
1389 // "sync state", it makes no sense to store any changes by this function back 1398 // "sync state", it makes no sense to store any changes by this function back
1390 // into the pref state. Therefore we tell |persistPinnedState| to ignore any 1399 // into the pref state. Therefore we tell |persistPinnedState| to ignore any
1391 // invocations while we are running. 1400 // invocations while we are running.
1392 base::AutoReset<bool> auto_reset(&ignore_persist_pinned_state_change_, true); 1401 base::AutoReset<bool> auto_reset(&ignore_persist_pinned_state_change_, true);
1393 std::vector<std::string> pinned_apps = ash::GetPinnedAppsFromPrefs( 1402 std::vector<std::string> pinned_apps = ash::GetPinnedAppsFromPrefs(
1394 profile_->GetPrefs(), launcher_controller_helper_.get()); 1403 profile_->GetPrefs(), launcher_controller_helper_.get());
(...skipping 19 matching lines...) Expand all
1414 const ash::ShelfItem& item(model_->items()[index]); 1423 const ash::ShelfItem& item(model_->items()[index]);
1415 bool is_app_list = item.type == ash::TYPE_APP_LIST; 1424 bool is_app_list = item.type == ash::TYPE_APP_LIST;
1416 bool is_chrome = item.type == ash::TYPE_BROWSER_SHORTCUT; 1425 bool is_chrome = item.type == ash::TYPE_BROWSER_SHORTCUT;
1417 if (item.type != ash::TYPE_APP_SHORTCUT && !is_app_list && !is_chrome) 1426 if (item.type != ash::TYPE_APP_SHORTCUT && !is_app_list && !is_chrome)
1418 continue; 1427 continue;
1419 LauncherItemController* controller = GetLauncherItemController(item.id); 1428 LauncherItemController* controller = GetLauncherItemController(item.id);
1420 if ((ash::kPinnedAppsPlaceholder == *pref_app_id && is_app_list) || 1429 if ((ash::kPinnedAppsPlaceholder == *pref_app_id && is_app_list) ||
1421 (extension_misc::kChromeAppId == *pref_app_id && is_chrome) || 1430 (extension_misc::kChromeAppId == *pref_app_id && is_chrome) ||
1422 (controller && controller->app_id() == *pref_app_id)) { 1431 (controller && controller->app_id() == *pref_app_id)) {
1423 // Check if an item needs to be moved here. 1432 // Check if an item needs to be moved here.
1424 MoveChromeOrApplistToFinalPosition( 1433 MoveChromeOrApplistToFinalPosition(is_chrome, is_app_list, index,
1425 is_chrome, is_app_list, index, &chrome_index, &app_list_index); 1434 &chrome_index, &app_list_index);
1426 ++pref_app_id; 1435 ++pref_app_id;
1427 break; 1436 break;
1428 } else { 1437 } else {
1429 if (is_chrome || is_app_list) { 1438 if (is_chrome || is_app_list) {
1430 // We cannot delete any of these shortcuts. As such we remember 1439 // We cannot delete any of these shortcuts. As such we remember
1431 // their positions and move them later where they belong. 1440 // their positions and move them later where they belong.
1432 if (is_chrome) 1441 if (is_chrome)
1433 chrome_index = index; 1442 chrome_index = index;
1434 else 1443 else
1435 app_list_index = index; 1444 app_list_index = index;
1436 // And skip the item - or exit the loop if end is reached (note that 1445 // And skip the item - or exit the loop if end is reached (note that
1437 // in that case we will reduce the index again by one and this only 1446 // in that case we will reduce the index again by one and this only
1438 // compensates for it). 1447 // compensates for it).
1439 if (index >= max_index - 1) 1448 if (index >= max_index - 1)
1440 break; 1449 break;
1441 ++index; 1450 ++index;
1442 } else { 1451 } else {
1443 // Check if this is a platform or a windowed app. 1452 // Check if this is a platform or a windowed app.
1444 if (item.type == ash::TYPE_APP_SHORTCUT && 1453 if (item.type == ash::TYPE_APP_SHORTCUT && controller &&
1445 controller &&
1446 (controller->locked() || 1454 (controller->locked() ||
1447 controller->type() == LauncherItemController::TYPE_APP)) { 1455 controller->type() == LauncherItemController::TYPE_APP)) {
1448 // Note: This will not change the amount of items (|max_index|). 1456 // Note: This will not change the amount of items (|max_index|).
1449 // Even changes to the actual |index| due to item weighting 1457 // Even changes to the actual |index| due to item weighting
1450 // changes should be fine. 1458 // changes should be fine.
1451 UnpinRunningAppInternal(index); 1459 UnpinRunningAppInternal(index);
1452 } else { 1460 } else {
1453 if (controller) 1461 if (controller)
1454 LauncherItemClosed(item.id); 1462 LauncherItemClosed(item.id);
1455 --max_index; 1463 --max_index;
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
1515 int source_index = model_->ItemIndexByID(id); 1523 int source_index = model_->ItemIndexByID(id);
1516 if (source_index != target_index) 1524 if (source_index != target_index)
1517 model_->Move(source_index, target_index); 1525 model_->Move(source_index, target_index);
1518 1526
1519 // Needed for the old layout - the weight might force it to be lower in 1527 // Needed for the old layout - the weight might force it to be lower in
1520 // rank. 1528 // rank.
1521 if (app_list_index != -1 && target_index <= app_list_index) 1529 if (app_list_index != -1 && target_index <= app_list_index)
1522 ++app_list_index; 1530 ++app_list_index;
1523 } else { 1531 } else {
1524 int target_index = FindInsertionPoint(is_app_list); 1532 int target_index = FindInsertionPoint(is_app_list);
1525 MoveChromeOrApplistToFinalPosition( 1533 MoveChromeOrApplistToFinalPosition(is_chrome, is_app_list, target_index,
1526 is_chrome, is_app_list, target_index, &chrome_index, &app_list_index); 1534 &chrome_index, &app_list_index);
1527 } 1535 }
1528 } 1536 }
1529 } 1537 }
1530 1538
1531 void ChromeLauncherController::SetShelfAutoHideBehaviorFromPrefs() { 1539 void ChromeLauncherControllerImpl::SetShelfAutoHideBehaviorFromPrefs() {
1532 for (auto* window : ash::Shell::GetAllRootWindows()) { 1540 for (auto* window : ash::Shell::GetAllRootWindows()) {
1533 ash::Shelf* shelf = ash::Shelf::ForWindow(window); 1541 ash::Shelf* shelf = ash::Shelf::ForWindow(window);
1534 if (shelf) { 1542 if (shelf) {
1535 shelf->SetAutoHideBehavior(ash::GetShelfAutoHideBehaviorPref( 1543 shelf->SetAutoHideBehavior(ash::GetShelfAutoHideBehaviorPref(
1536 profile_->GetPrefs(), GetDisplayIDForShelf(shelf))); 1544 profile_->GetPrefs(), GetDisplayIDForShelf(shelf)));
1537 } 1545 }
1538 } 1546 }
1539 } 1547 }
1540 1548
1541 void ChromeLauncherController::SetShelfAlignmentFromPrefs() { 1549 void ChromeLauncherControllerImpl::SetShelfAlignmentFromPrefs() {
1542 if (!ash::ShelfWidget::ShelfAlignmentAllowed()) 1550 if (!ash::ShelfWidget::ShelfAlignmentAllowed())
1543 return; 1551 return;
1544 1552
1545 for (auto* window : ash::Shell::GetAllRootWindows()) { 1553 for (auto* window : ash::Shell::GetAllRootWindows()) {
1546 ash::Shelf* shelf = ash::Shelf::ForWindow(window); 1554 ash::Shelf* shelf = ash::Shelf::ForWindow(window);
1547 if (shelf) { 1555 if (shelf) {
1548 shelf->SetAlignment(ash::GetShelfAlignmentPref( 1556 shelf->SetAlignment(ash::GetShelfAlignmentPref(
1549 profile_->GetPrefs(), GetDisplayIDForShelf(shelf))); 1557 profile_->GetPrefs(), GetDisplayIDForShelf(shelf)));
1550 } 1558 }
1551 } 1559 }
1552 } 1560 }
1553 1561
1554 void ChromeLauncherController::SetShelfBehaviorsFromPrefs() { 1562 void ChromeLauncherControllerImpl::SetShelfBehaviorsFromPrefs() {
1555 SetShelfAutoHideBehaviorFromPrefs(); 1563 SetShelfAutoHideBehaviorFromPrefs();
1556 SetShelfAlignmentFromPrefs(); 1564 SetShelfAlignmentFromPrefs();
1557 } 1565 }
1558 1566
1559 void ChromeLauncherController::SetVirtualKeyboardBehaviorFromPrefs() { 1567 void ChromeLauncherControllerImpl::SetVirtualKeyboardBehaviorFromPrefs() {
1560 const PrefService* service = profile_->GetPrefs(); 1568 const PrefService* service = profile_->GetPrefs();
1561 const bool was_enabled = keyboard::IsKeyboardEnabled(); 1569 const bool was_enabled = keyboard::IsKeyboardEnabled();
1562 if (!service->HasPrefPath(prefs::kTouchVirtualKeyboardEnabled)) { 1570 if (!service->HasPrefPath(prefs::kTouchVirtualKeyboardEnabled)) {
1563 keyboard::SetKeyboardShowOverride(keyboard::KEYBOARD_SHOW_OVERRIDE_NONE); 1571 keyboard::SetKeyboardShowOverride(keyboard::KEYBOARD_SHOW_OVERRIDE_NONE);
1564 } else { 1572 } else {
1565 const bool enable = service->GetBoolean( 1573 const bool enable =
1566 prefs::kTouchVirtualKeyboardEnabled); 1574 service->GetBoolean(prefs::kTouchVirtualKeyboardEnabled);
1567 keyboard::SetKeyboardShowOverride( 1575 keyboard::SetKeyboardShowOverride(
1568 enable ? keyboard::KEYBOARD_SHOW_OVERRIDE_ENABLED 1576 enable ? keyboard::KEYBOARD_SHOW_OVERRIDE_ENABLED
1569 : keyboard::KEYBOARD_SHOW_OVERRIDE_DISABLED); 1577 : keyboard::KEYBOARD_SHOW_OVERRIDE_DISABLED);
1570 } 1578 }
1571 const bool is_enabled = keyboard::IsKeyboardEnabled(); 1579 const bool is_enabled = keyboard::IsKeyboardEnabled();
1572 if (was_enabled && !is_enabled) 1580 if (was_enabled && !is_enabled)
1573 ash::Shell::GetInstance()->DeactivateKeyboard(); 1581 ash::Shell::GetInstance()->DeactivateKeyboard();
1574 else if (is_enabled && !was_enabled) 1582 else if (is_enabled && !was_enabled)
1575 ash::Shell::GetInstance()->CreateKeyboard(); 1583 ash::Shell::GetInstance()->CreateKeyboard();
1576 } 1584 }
1577 1585
1578 ash::ShelfItemStatus ChromeLauncherController::GetAppState( 1586 ash::ShelfItemStatus ChromeLauncherControllerImpl::GetAppState(
1579 const std::string& app_id) { 1587 const std::string& app_id) {
1580 ash::ShelfItemStatus status = ash::STATUS_CLOSED; 1588 ash::ShelfItemStatus status = ash::STATUS_CLOSED;
1581 for (WebContentsToAppIDMap::iterator it = web_contents_to_app_id_.begin(); 1589 for (WebContentsToAppIDMap::iterator it = web_contents_to_app_id_.begin();
1582 it != web_contents_to_app_id_.end(); 1590 it != web_contents_to_app_id_.end(); ++it) {
1583 ++it) {
1584 if (it->second == app_id) { 1591 if (it->second == app_id) {
1585 Browser* browser = chrome::FindBrowserWithWebContents(it->first); 1592 Browser* browser = chrome::FindBrowserWithWebContents(it->first);
1586 // Usually there should never be an item in our |web_contents_to_app_id_| 1593 // Usually there should never be an item in our |web_contents_to_app_id_|
1587 // list which got deleted already. However - in some situations e.g. 1594 // list which got deleted already. However - in some situations e.g.
1588 // Browser::SwapTabContent there is temporarily no associated browser. 1595 // Browser::SwapTabContent there is temporarily no associated browser.
1589 if (!browser) 1596 if (!browser)
1590 continue; 1597 continue;
1591 if (browser->window()->IsActive()) { 1598 if (browser->window()->IsActive()) {
1592 return browser->tab_strip_model()->GetActiveWebContents() == it->first ? 1599 return browser->tab_strip_model()->GetActiveWebContents() == it->first
1593 ash::STATUS_ACTIVE : ash::STATUS_RUNNING; 1600 ? ash::STATUS_ACTIVE
1601 : ash::STATUS_RUNNING;
1594 } else { 1602 } else {
1595 status = ash::STATUS_RUNNING; 1603 status = ash::STATUS_RUNNING;
1596 } 1604 }
1597 } 1605 }
1598 } 1606 }
1599 return status; 1607 return status;
1600 } 1608 }
1601 1609
1602 ash::ShelfID ChromeLauncherController::InsertAppLauncherItem( 1610 ash::ShelfID ChromeLauncherControllerImpl::InsertAppLauncherItem(
1603 LauncherItemController* controller, 1611 LauncherItemController* controller,
1604 const std::string& app_id, 1612 const std::string& app_id,
1605 ash::ShelfItemStatus status, 1613 ash::ShelfItemStatus status,
1606 int index, 1614 int index,
1607 ash::ShelfItemType shelf_item_type) { 1615 ash::ShelfItemType shelf_item_type) {
1608 ash::ShelfID id = model_->next_id(); 1616 ash::ShelfID id = model_->next_id();
1609 CHECK(!HasShelfIDToAppIDMapping(id)); 1617 CHECK(!HasShelfIDToAppIDMapping(id));
1610 CHECK(controller); 1618 CHECK(controller);
1611 id_to_item_controller_map_[id] = controller; 1619 id_to_item_controller_map_[id] = controller;
1612 controller->set_shelf_id(id); 1620 controller->set_shelf_id(id);
(...skipping 15 matching lines...) Expand all
1628 app_icon_loader->FetchImage(app_id); 1636 app_icon_loader->FetchImage(app_id);
1629 app_icon_loader->UpdateImage(app_id); 1637 app_icon_loader->UpdateImage(app_id);
1630 } 1638 }
1631 1639
1632 SetShelfItemDelegate(id, controller); 1640 SetShelfItemDelegate(id, controller);
1633 1641
1634 return id; 1642 return id;
1635 } 1643 }
1636 1644
1637 std::vector<content::WebContents*> 1645 std::vector<content::WebContents*>
1638 ChromeLauncherController::GetV1ApplicationsFromController( 1646 ChromeLauncherControllerImpl::GetV1ApplicationsFromController(
1639 LauncherItemController* controller) { 1647 LauncherItemController* controller) {
1640 DCHECK(controller->type() == LauncherItemController::TYPE_SHORTCUT); 1648 DCHECK(controller->type() == LauncherItemController::TYPE_SHORTCUT);
1641 AppShortcutLauncherItemController* app_controller = 1649 AppShortcutLauncherItemController* app_controller =
1642 static_cast<AppShortcutLauncherItemController*>(controller); 1650 static_cast<AppShortcutLauncherItemController*>(controller);
1643 return app_controller->GetRunningApplications(); 1651 return app_controller->GetRunningApplications();
1644 } 1652 }
1645 1653
1646 BrowserShortcutLauncherItemController* 1654 BrowserShortcutLauncherItemController*
1647 ChromeLauncherController::GetBrowserShortcutLauncherItemController() { 1655 ChromeLauncherControllerImpl::GetBrowserShortcutLauncherItemController() {
1648 for (IDToItemControllerMap::iterator i = id_to_item_controller_map_.begin(); 1656 for (IDToItemControllerMap::iterator i = id_to_item_controller_map_.begin();
1649 i != id_to_item_controller_map_.end(); ++i) { 1657 i != id_to_item_controller_map_.end(); ++i) {
1650 int index = model_->ItemIndexByID(i->first); 1658 int index = model_->ItemIndexByID(i->first);
1651 const ash::ShelfItem& item = model_->items()[index]; 1659 const ash::ShelfItem& item = model_->items()[index];
1652 if (item.type == ash::TYPE_BROWSER_SHORTCUT) 1660 if (item.type == ash::TYPE_BROWSER_SHORTCUT)
1653 return static_cast<BrowserShortcutLauncherItemController*>(i->second); 1661 return static_cast<BrowserShortcutLauncherItemController*>(i->second);
1654 } 1662 }
1655 NOTREACHED() 1663 NOTREACHED()
1656 << "There should be always be a BrowserShortcutLauncherItemController."; 1664 << "There should be always be a BrowserShortcutLauncherItemController.";
1657 return nullptr; 1665 return nullptr;
1658 } 1666 }
1659 1667
1660 ash::ShelfID ChromeLauncherController::CreateBrowserShortcutLauncherItem() { 1668 ash::ShelfID ChromeLauncherControllerImpl::CreateBrowserShortcutLauncherItem() {
1661 ash::ShelfItem browser_shortcut; 1669 ash::ShelfItem browser_shortcut;
1662 browser_shortcut.type = ash::TYPE_BROWSER_SHORTCUT; 1670 browser_shortcut.type = ash::TYPE_BROWSER_SHORTCUT;
1663 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); 1671 ResourceBundle& rb = ResourceBundle::GetSharedInstance();
1664 browser_shortcut.image = *rb.GetImageSkiaNamed(IDR_PRODUCT_LOGO_32); 1672 browser_shortcut.image = *rb.GetImageSkiaNamed(IDR_PRODUCT_LOGO_32);
1665 ash::ShelfID id = model_->next_id(); 1673 ash::ShelfID id = model_->next_id();
1666 size_t index = GetChromeIconIndexForCreation(); 1674 size_t index = GetChromeIconIndexForCreation();
1667 model_->AddAt(index, browser_shortcut); 1675 model_->AddAt(index, browser_shortcut);
1668 id_to_item_controller_map_[id] = 1676 id_to_item_controller_map_[id] =
1669 new BrowserShortcutLauncherItemController(this, model_); 1677 new BrowserShortcutLauncherItemController(this, model_);
1670 id_to_item_controller_map_[id]->set_shelf_id(id); 1678 id_to_item_controller_map_[id]->set_shelf_id(id);
1671 // ShelfItemDelegateManager owns BrowserShortcutLauncherItemController. 1679 // ShelfItemDelegateManager owns BrowserShortcutLauncherItemController.
1672 SetShelfItemDelegate(id, id_to_item_controller_map_[id]); 1680 SetShelfItemDelegate(id, id_to_item_controller_map_[id]);
1673 return id; 1681 return id;
1674 } 1682 }
1675 1683
1676 void ChromeLauncherController::PersistChromeItemIndex(int index) { 1684 void ChromeLauncherControllerImpl::PersistChromeItemIndex(int index) {
1677 profile_->GetPrefs()->SetInteger(prefs::kShelfChromeIconIndex, index); 1685 profile_->GetPrefs()->SetInteger(prefs::kShelfChromeIconIndex, index);
1678 } 1686 }
1679 1687
1680 void ChromeLauncherController::MoveChromeOrApplistToFinalPosition( 1688 void ChromeLauncherControllerImpl::MoveChromeOrApplistToFinalPosition(
1681 bool is_chrome, 1689 bool is_chrome,
1682 bool is_app_list, 1690 bool is_app_list,
1683 int target_index, 1691 int target_index,
1684 int* chrome_index, 1692 int* chrome_index,
1685 int* app_list_index) { 1693 int* app_list_index) {
1686 if (is_chrome && *chrome_index != -1) { 1694 if (is_chrome && *chrome_index != -1) {
1687 model_->Move(*chrome_index, target_index); 1695 model_->Move(*chrome_index, target_index);
1688 if (*app_list_index != -1 && 1696 if (*app_list_index != -1 && *chrome_index < *app_list_index &&
1689 *chrome_index < *app_list_index &&
1690 target_index > *app_list_index) 1697 target_index > *app_list_index)
1691 --(*app_list_index); 1698 --(*app_list_index);
1692 *chrome_index = -1; 1699 *chrome_index = -1;
1693 } else if (is_app_list && *app_list_index != -1) { 1700 } else if (is_app_list && *app_list_index != -1) {
1694 model_->Move(*app_list_index, target_index); 1701 model_->Move(*app_list_index, target_index);
1695 if (*chrome_index != -1 && 1702 if (*chrome_index != -1 && *app_list_index < *chrome_index &&
1696 *app_list_index < *chrome_index &&
1697 target_index > *chrome_index) 1703 target_index > *chrome_index)
1698 --(*chrome_index); 1704 --(*chrome_index);
1699 *app_list_index = -1; 1705 *app_list_index = -1;
1700 } 1706 }
1701 } 1707 }
1702 1708
1703 int ChromeLauncherController::FindInsertionPoint(bool is_app_list) { 1709 int ChromeLauncherControllerImpl::FindInsertionPoint(bool is_app_list) {
1704 // Keeping this change small to backport to M33&32 (see crbug.com/329597). 1710 // Keeping this change small to backport to M33&32 (see crbug.com/329597).
1705 // TODO(skuhne): With the removal of the legacy shelf layout we should remove 1711 // TODO(skuhne): With the removal of the legacy shelf layout we should remove
1706 // the ability to move the app list item since this was never used. We should 1712 // the ability to move the app list item since this was never used. We should
1707 // instead ask the ShelfModel::ValidateInsertionIndex or similir for an index. 1713 // instead ask the ShelfModel::ValidateInsertionIndex or similir for an index.
1708 if (is_app_list) 1714 if (is_app_list)
1709 return 0; 1715 return 0;
1710 1716
1711 for (int i = model_->item_count() - 1; i > 0; --i) { 1717 for (int i = model_->item_count() - 1; i > 0; --i) {
1712 ash::ShelfItemType type = model_->items()[i].type; 1718 ash::ShelfItemType type = model_->items()[i].type;
1713 if (type == ash::TYPE_APP_SHORTCUT || 1719 if (type == ash::TYPE_APP_SHORTCUT ||
1714 (is_app_list && type == ash::TYPE_APP_LIST) || 1720 (is_app_list && type == ash::TYPE_APP_LIST) ||
1715 type == ash::TYPE_BROWSER_SHORTCUT) { 1721 type == ash::TYPE_BROWSER_SHORTCUT) {
1716 return i; 1722 return i;
1717 } 1723 }
1718 } 1724 }
1719 return 0; 1725 return 0;
1720 } 1726 }
1721 1727
1722 int ChromeLauncherController::GetChromeIconIndexForCreation() { 1728 int ChromeLauncherControllerImpl::GetChromeIconIndexForCreation() {
1723 // We get the list of pinned apps as they currently would get pinned. 1729 // We get the list of pinned apps as they currently would get pinned.
1724 // Within this list the chrome icon will be the correct location. 1730 // Within this list the chrome icon will be the correct location.
1725 std::vector<std::string> pinned_apps = ash::GetPinnedAppsFromPrefs( 1731 std::vector<std::string> pinned_apps = ash::GetPinnedAppsFromPrefs(
1726 profile_->GetPrefs(), launcher_controller_helper_.get()); 1732 profile_->GetPrefs(), launcher_controller_helper_.get());
1727 1733
1728 std::vector<std::string>::iterator it = 1734 std::vector<std::string>::iterator it =
1729 std::find(pinned_apps.begin(), 1735 std::find(pinned_apps.begin(), pinned_apps.end(),
1730 pinned_apps.end(),
1731 std::string(extension_misc::kChromeAppId)); 1736 std::string(extension_misc::kChromeAppId));
1732 DCHECK(it != pinned_apps.end()); 1737 DCHECK(it != pinned_apps.end());
1733 int index = it - pinned_apps.begin(); 1738 int index = it - pinned_apps.begin();
1734 1739
1735 // We should do here a comparison between the is state and the "want to be" 1740 // We should do here a comparison between the is state and the "want to be"
1736 // state since some apps might be able to pin but are not yet. Instead - for 1741 // state since some apps might be able to pin but are not yet. Instead - for
1737 // the time being we clamp against the amount of known items and wait for the 1742 // the time being we clamp against the amount of known items and wait for the
1738 // next |UpdateAppLaunchersFromPref()| call to correct it - it will come since 1743 // next |UpdateAppLaunchersFromPref()| call to correct it - it will come since
1739 // the pinning will be done then. 1744 // the pinning will be done then.
1740 return std::min(model_->item_count(), index); 1745 return std::min(model_->item_count(), index);
1741 } 1746 }
1742 1747
1743 bool ChromeLauncherController::IsIncognito( 1748 bool ChromeLauncherControllerImpl::IsIncognito(
1744 const content::WebContents* web_contents) const { 1749 const content::WebContents* web_contents) const {
1745 const Profile* profile = 1750 const Profile* profile =
1746 Profile::FromBrowserContext(web_contents->GetBrowserContext()); 1751 Profile::FromBrowserContext(web_contents->GetBrowserContext());
1747 return profile->IsOffTheRecord() && !profile->IsGuestSession() && 1752 return profile->IsOffTheRecord() && !profile->IsGuestSession() &&
1748 !profile->IsSystemProfile(); 1753 !profile->IsSystemProfile();
1749 } 1754 }
1750 1755
1751 void ChromeLauncherController::CloseWindowedAppsFromRemovedExtension( 1756 void ChromeLauncherControllerImpl::CloseWindowedAppsFromRemovedExtension(
1752 const std::string& app_id, 1757 const std::string& app_id,
1753 const Profile* profile) { 1758 const Profile* profile) {
1754 // This function cannot rely on the controller's enumeration functionality 1759 // This function cannot rely on the controller's enumeration functionality
1755 // since the extension has already be unloaded. 1760 // since the extension has already be unloaded.
1756 const BrowserList* browser_list = BrowserList::GetInstance(); 1761 const BrowserList* browser_list = BrowserList::GetInstance();
1757 std::vector<Browser*> browser_to_close; 1762 std::vector<Browser*> browser_to_close;
1758 for (BrowserList::const_reverse_iterator it = 1763 for (BrowserList::const_reverse_iterator it =
1759 browser_list->begin_last_active(); 1764 browser_list->begin_last_active();
1760 it != browser_list->end_last_active(); ++it) { 1765 it != browser_list->end_last_active(); ++it) {
1761 Browser* browser = *it; 1766 Browser* browser = *it;
1762 if (!browser->is_type_tabbed() && browser->is_type_popup() && 1767 if (!browser->is_type_tabbed() && browser->is_type_popup() &&
1763 browser->is_app() && 1768 browser->is_app() &&
1764 app_id == 1769 app_id ==
1765 web_app::GetExtensionIdFromApplicationName(browser->app_name()) && 1770 web_app::GetExtensionIdFromApplicationName(browser->app_name()) &&
1766 profile == browser->profile()) { 1771 profile == browser->profile()) {
1767 browser_to_close.push_back(browser); 1772 browser_to_close.push_back(browser);
1768 } 1773 }
1769 } 1774 }
1770 while (!browser_to_close.empty()) { 1775 while (!browser_to_close.empty()) {
1771 TabStripModel* tab_strip = browser_to_close.back()->tab_strip_model(); 1776 TabStripModel* tab_strip = browser_to_close.back()->tab_strip_model();
1772 tab_strip->CloseWebContentsAt(0, TabStripModel::CLOSE_NONE); 1777 tab_strip->CloseWebContentsAt(0, TabStripModel::CLOSE_NONE);
1773 browser_to_close.pop_back(); 1778 browser_to_close.pop_back();
1774 } 1779 }
1775 } 1780 }
1776 1781
1777 void ChromeLauncherController::SetShelfItemDelegate( 1782 void ChromeLauncherControllerImpl::SetShelfItemDelegate(
1778 ash::ShelfID id, 1783 ash::ShelfID id,
1779 ash::ShelfItemDelegate* item_delegate) { 1784 ash::ShelfItemDelegate* item_delegate) {
1780 DCHECK_GT(id, 0); 1785 DCHECK_GT(id, 0);
1781 DCHECK(item_delegate); 1786 DCHECK(item_delegate);
1782 DCHECK(item_delegate_manager_); 1787 DCHECK(item_delegate_manager_);
1783 item_delegate_manager_->SetShelfItemDelegate( 1788 item_delegate_manager_->SetShelfItemDelegate(
1784 id, std::unique_ptr<ash::ShelfItemDelegate>(item_delegate)); 1789 id, std::unique_ptr<ash::ShelfItemDelegate>(item_delegate));
1785 } 1790 }
1786 1791
1787 void ChromeLauncherController::AttachProfile(Profile* profile) { 1792 void ChromeLauncherControllerImpl::AttachProfile(Profile* profile) {
1788 profile_ = profile; 1793 profile_ = profile;
1789 // Either add the profile to the list of known profiles and make it the active 1794 // Either add the profile to the list of known profiles and make it the active
1790 // one for some functions of LauncherControllerHelper or create a new one. 1795 // one for some functions of LauncherControllerHelper or create a new one.
1791 if (!launcher_controller_helper_.get()) 1796 if (!launcher_controller_helper_.get())
1792 launcher_controller_helper_.reset(new LauncherControllerHelper(profile_)); 1797 launcher_controller_helper_.reset(new LauncherControllerHelper(profile_));
1793 else 1798 else
1794 launcher_controller_helper_->SetCurrentUser(profile_); 1799 launcher_controller_helper_->SetCurrentUser(profile_);
1795 // TODO(skuhne): The AppIconLoaderImpl has the same problem. Each loaded 1800 // TODO(skuhne): The AppIconLoaderImpl has the same problem. Each loaded
1796 // image is associated with a profile (its loader requires the profile). 1801 // image is associated with a profile (its loader requires the profile).
1797 // Since icon size changes are possible, the icon could be requested to be 1802 // Since icon size changes are possible, the icon could be requested to be
1798 // reloaded. However - having it not multi profile aware would cause problems 1803 // reloaded. However - having it not multi profile aware would cause problems
1799 // if the icon cache gets deleted upon user switch. 1804 // if the icon cache gets deleted upon user switch.
1800 std::unique_ptr<AppIconLoader> extension_app_icon_loader( 1805 std::unique_ptr<AppIconLoader> extension_app_icon_loader(
1801 new extensions::ExtensionAppIconLoader( 1806 new extensions::ExtensionAppIconLoader(
1802 profile_, extension_misc::EXTENSION_ICON_SMALL, this)); 1807 profile_, extension_misc::EXTENSION_ICON_SMALL, this));
1803 app_icon_loaders_.push_back(std::move(extension_app_icon_loader)); 1808 app_icon_loaders_.push_back(std::move(extension_app_icon_loader));
1804 1809
1805 if (arc::ArcAuthService::IsAllowedForProfile(profile_)) { 1810 if (arc::ArcAuthService::IsAllowedForProfile(profile_)) {
1806 DCHECK(arc_deferred_launcher()); 1811 DCHECK(arc_deferred_launcher_.get());
1807 std::unique_ptr<AppIconLoader> arc_app_icon_loader( 1812 std::unique_ptr<AppIconLoader> arc_app_icon_loader(
1808 new ArcAppIconLoader(profile_, extension_misc::EXTENSION_ICON_SMALL, 1813 new ArcAppIconLoader(profile_, extension_misc::EXTENSION_ICON_SMALL,
1809 arc_deferred_launcher(), this)); 1814 arc_deferred_launcher_.get(), this));
1810 app_icon_loaders_.push_back(std::move(arc_app_icon_loader)); 1815 app_icon_loaders_.push_back(std::move(arc_app_icon_loader));
1811 } 1816 }
1812 1817
1813 pref_change_registrar_.Init(profile_->GetPrefs()); 1818 pref_change_registrar_.Init(profile_->GetPrefs());
1814 pref_change_registrar_.Add( 1819 pref_change_registrar_.Add(
1815 prefs::kPinnedLauncherApps, 1820 prefs::kPinnedLauncherApps,
1816 base::Bind(&ChromeLauncherController::UpdateAppLaunchersFromPref, 1821 base::Bind(&ChromeLauncherControllerImpl::UpdateAppLaunchersFromPref,
1817 base::Unretained(this))); 1822 base::Unretained(this)));
1818 pref_change_registrar_.Add( 1823 pref_change_registrar_.Add(
1819 prefs::kPolicyPinnedLauncherApps, 1824 prefs::kPolicyPinnedLauncherApps,
1820 base::Bind(&ChromeLauncherController::UpdateAppLaunchersFromPref, 1825 base::Bind(&ChromeLauncherControllerImpl::UpdateAppLaunchersFromPref,
1821 base::Unretained(this))); 1826 base::Unretained(this)));
1822 pref_change_registrar_.Add( 1827 pref_change_registrar_.Add(
1823 prefs::kShelfAlignmentLocal, 1828 prefs::kShelfAlignmentLocal,
1824 base::Bind(&ChromeLauncherController::SetShelfAlignmentFromPrefs, 1829 base::Bind(&ChromeLauncherControllerImpl::SetShelfAlignmentFromPrefs,
1825 base::Unretained(this))); 1830 base::Unretained(this)));
1826 pref_change_registrar_.Add( 1831 pref_change_registrar_.Add(
1827 prefs::kShelfAutoHideBehaviorLocal, 1832 prefs::kShelfAutoHideBehaviorLocal,
1828 base::Bind(&ChromeLauncherController:: 1833 base::Bind(
1829 SetShelfAutoHideBehaviorFromPrefs, 1834 &ChromeLauncherControllerImpl::SetShelfAutoHideBehaviorFromPrefs,
1830 base::Unretained(this))); 1835 base::Unretained(this)));
1831 pref_change_registrar_.Add( 1836 pref_change_registrar_.Add(
1832 prefs::kShelfPreferences, 1837 prefs::kShelfPreferences,
1833 base::Bind(&ChromeLauncherController::SetShelfBehaviorsFromPrefs, 1838 base::Bind(&ChromeLauncherControllerImpl::SetShelfBehaviorsFromPrefs,
1834 base::Unretained(this))); 1839 base::Unretained(this)));
1835 pref_change_registrar_.Add( 1840 pref_change_registrar_.Add(
1836 prefs::kTouchVirtualKeyboardEnabled, 1841 prefs::kTouchVirtualKeyboardEnabled,
1837 base::Bind(&ChromeLauncherController::SetVirtualKeyboardBehaviorFromPrefs, 1842 base::Bind(
1838 base::Unretained(this))); 1843 &ChromeLauncherControllerImpl::SetVirtualKeyboardBehaviorFromPrefs,
1844 base::Unretained(this)));
1839 1845
1840 std::unique_ptr<LauncherAppUpdater> extension_app_updater( 1846 std::unique_ptr<LauncherAppUpdater> extension_app_updater(
1841 new LauncherExtensionAppUpdater(this, profile_)); 1847 new LauncherExtensionAppUpdater(this, profile_));
1842 app_updaters_.push_back(std::move(extension_app_updater)); 1848 app_updaters_.push_back(std::move(extension_app_updater));
1843 1849
1844 if (arc::ArcAuthService::IsAllowedForProfile(profile_)) { 1850 if (arc::ArcAuthService::IsAllowedForProfile(profile_)) {
1845 std::unique_ptr<LauncherAppUpdater> arc_app_updater( 1851 std::unique_ptr<LauncherAppUpdater> arc_app_updater(
1846 new LauncherArcAppUpdater(this, profile_)); 1852 new LauncherArcAppUpdater(this, profile_));
1847 app_updaters_.push_back(std::move(arc_app_updater)); 1853 app_updaters_.push_back(std::move(arc_app_updater));
1848 } 1854 }
1849 } 1855 }
1850 1856
1851 void ChromeLauncherController::ReleaseProfile() { 1857 void ChromeLauncherControllerImpl::ReleaseProfile() {
1852 if (app_sync_ui_state_) 1858 if (app_sync_ui_state_)
1853 app_sync_ui_state_->RemoveObserver(this); 1859 app_sync_ui_state_->RemoveObserver(this);
1854 1860
1855 app_updaters_.clear(); 1861 app_updaters_.clear();
1856 1862
1857 prefs_observer_.reset(); 1863 prefs_observer_.reset();
1858 1864
1859 pref_change_registrar_.RemoveAll(); 1865 pref_change_registrar_.RemoveAll();
1860 } 1866 }
1861 1867
1862 AppIconLoader* ChromeLauncherController::GetAppIconLoaderForApp( 1868 AppIconLoader* ChromeLauncherControllerImpl::GetAppIconLoaderForApp(
1863 const std::string& app_id) { 1869 const std::string& app_id) {
1864 for (const auto& app_icon_loader : app_icon_loaders_) { 1870 for (const auto& app_icon_loader : app_icon_loaders_) {
1865 if (app_icon_loader->CanLoadImageForApp(app_id)) 1871 if (app_icon_loader->CanLoadImageForApp(app_id))
1866 return app_icon_loader.get(); 1872 return app_icon_loader.get();
1867 } 1873 }
1868 1874
1869 return nullptr; 1875 return nullptr;
1870 } 1876 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698