| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "chrome/browser/ui/views/aura/launcher/chrome_launcher_delegate.h" | |
| 6 | |
| 7 #include "ash/launcher/launcher_model.h" | |
| 8 #include "ash/launcher/launcher_types.h" | |
| 9 #include "ash/wm/window_util.h" | |
| 10 #include "base/command_line.h" | |
| 11 #include "base/utf_string_conversions.h" | |
| 12 #include "base/values.h" | |
| 13 #include "chrome/browser/defaults.h" | |
| 14 #include "chrome/browser/extensions/extension_service.h" | |
| 15 #include "chrome/browser/prefs/incognito_mode_prefs.h" | |
| 16 #include "chrome/browser/prefs/pref_service.h" | |
| 17 #include "chrome/browser/prefs/scoped_user_pref_update.h" | |
| 18 #include "chrome/browser/profiles/profile.h" | |
| 19 #include "chrome/browser/profiles/profile_manager.h" | |
| 20 #include "chrome/browser/tabs/tab_strip_model.h" | |
| 21 #include "chrome/browser/ui/browser.h" | |
| 22 #include "chrome/browser/ui/browser_window.h" | |
| 23 #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" | |
| 24 #include "chrome/browser/ui/views/aura/launcher/launcher_context_menu.h" | |
| 25 #include "chrome/browser/ui/views/aura/launcher/launcher_icon_loader.h" | |
| 26 #include "chrome/browser/ui/views/aura/launcher/launcher_updater.h" | |
| 27 #include "chrome/browser/web_applications/web_app.h" | |
| 28 #include "chrome/common/chrome_notification_types.h" | |
| 29 #include "chrome/common/extensions/extension.h" | |
| 30 #include "chrome/common/extensions/extension_resource.h" | |
| 31 #include "chrome/common/pref_names.h" | |
| 32 #include "content/public/browser/notification_service.h" | |
| 33 #include "content/public/browser/web_contents.h" | |
| 34 #include "grit/theme_resources.h" | |
| 35 #include "ui/aura/window.h" | |
| 36 #include "ui/views/widget/widget.h" | |
| 37 | |
| 38 namespace { | |
| 39 | |
| 40 // See description in PersistPinnedState(). | |
| 41 const char kAppIDPath[] = "id"; | |
| 42 const char kAppTypePath[] = "type"; | |
| 43 const char kAppTypeTab[] = "tab"; | |
| 44 const char kAppTypeWindow[] = "window"; | |
| 45 | |
| 46 } // namespace | |
| 47 | |
| 48 // ChromeLauncherDelegate::Item ------------------------------------------------ | |
| 49 | |
| 50 ChromeLauncherDelegate::Item::Item() | |
| 51 : item_type(TYPE_TABBED_BROWSER), | |
| 52 app_type(APP_TYPE_WINDOW), | |
| 53 updater(NULL), | |
| 54 pinned(false) { | |
| 55 } | |
| 56 | |
| 57 ChromeLauncherDelegate::Item::~Item() { | |
| 58 } | |
| 59 | |
| 60 // ChromeLauncherDelegate ------------------------------------------------------ | |
| 61 | |
| 62 // static | |
| 63 ChromeLauncherDelegate* ChromeLauncherDelegate::instance_ = NULL; | |
| 64 | |
| 65 ChromeLauncherDelegate::ChromeLauncherDelegate(Profile* profile, | |
| 66 ash::LauncherModel* model) | |
| 67 : model_(model), | |
| 68 profile_(profile) { | |
| 69 if (!profile_) { | |
| 70 // Use the original profile as on chromeos we may get a temporary off the | |
| 71 // record profile. | |
| 72 profile_ = ProfileManager::GetDefaultProfile()->GetOriginalProfile(); | |
| 73 } | |
| 74 instance_ = this; | |
| 75 model_->AddObserver(this); | |
| 76 app_icon_loader_.reset(new LauncherIconLoader(profile_, this)); | |
| 77 registrar_.Add(this, | |
| 78 chrome::NOTIFICATION_EXTENSION_UNLOADED, | |
| 79 content::Source<Profile>(profile_)); | |
| 80 } | |
| 81 | |
| 82 ChromeLauncherDelegate::~ChromeLauncherDelegate() { | |
| 83 model_->RemoveObserver(this); | |
| 84 for (IDToItemMap::iterator i = id_to_item_map_.begin(); | |
| 85 i != id_to_item_map_.end(); ++i) { | |
| 86 model_->RemoveItemAt(model_->ItemIndexByID(i->first)); | |
| 87 } | |
| 88 if (instance_ == this) | |
| 89 instance_ = NULL; | |
| 90 } | |
| 91 | |
| 92 void ChromeLauncherDelegate::Init() { | |
| 93 const base::ListValue* pinned_apps = | |
| 94 profile_->GetPrefs()->GetList(prefs::kPinnedLauncherApps); | |
| 95 for (size_t i = 0; i < pinned_apps->GetSize(); ++i) { | |
| 96 DictionaryValue* app = NULL; | |
| 97 if (pinned_apps->GetDictionary(i, &app)) { | |
| 98 std::string app_id, type_string; | |
| 99 if (app->GetString(kAppIDPath, &app_id) && | |
| 100 app->GetString(kAppTypePath, &type_string) && | |
| 101 app_icon_loader_->IsValidID(app_id)) { | |
| 102 AppType app_type = (type_string == kAppTypeWindow) ? | |
| 103 APP_TYPE_WINDOW : APP_TYPE_TAB; | |
| 104 CreateAppLauncherItem(NULL, app_id, app_type); | |
| 105 } | |
| 106 } | |
| 107 } | |
| 108 } | |
| 109 | |
| 110 // static | |
| 111 void ChromeLauncherDelegate::RegisterUserPrefs(PrefService* user_prefs) { | |
| 112 // TODO: If we want to support multiple profiles this will likely need to be | |
| 113 // pushed to local state and we'll need to track profile per item. | |
| 114 user_prefs->RegisterListPref(prefs::kPinnedLauncherApps, | |
| 115 PrefService::SYNCABLE_PREF); | |
| 116 } | |
| 117 | |
| 118 ash::LauncherID ChromeLauncherDelegate::CreateTabbedLauncherItem( | |
| 119 LauncherUpdater* updater) { | |
| 120 // Tabbed items always get a new item. Put the tabbed item before the app | |
| 121 // tabs. If there are no app tabs put it at the end. | |
| 122 int index = static_cast<int>(model_->items().size()); | |
| 123 for (IDToItemMap::const_iterator i = id_to_item_map_.begin(); | |
| 124 i != id_to_item_map_.end(); ++i) { | |
| 125 if (i->second.updater == updater) { | |
| 126 DCHECK_EQ(TYPE_APP, i->second.item_type); | |
| 127 index = std::min(index, model_->ItemIndexByID(i->first)); | |
| 128 } | |
| 129 } | |
| 130 ash::LauncherID id = model_->next_id(); | |
| 131 ash::LauncherItem item(ash::TYPE_TABBED); | |
| 132 model_->Add(index, item); | |
| 133 DCHECK(id_to_item_map_.find(id) == id_to_item_map_.end()); | |
| 134 id_to_item_map_[id].item_type = TYPE_TABBED_BROWSER; | |
| 135 id_to_item_map_[id].updater = updater; | |
| 136 return id; | |
| 137 } | |
| 138 | |
| 139 ash::LauncherID ChromeLauncherDelegate::CreateAppLauncherItem( | |
| 140 LauncherUpdater* updater, | |
| 141 const std::string& app_id, | |
| 142 AppType app_type) { | |
| 143 // See if we have a closed item that matches the app. | |
| 144 if (updater) { | |
| 145 for (IDToItemMap::iterator i = id_to_item_map_.begin(); | |
| 146 i != id_to_item_map_.end(); ++i) { | |
| 147 if (i->second.updater == NULL && i->second.app_id == app_id && | |
| 148 i->second.app_type == app_type) { | |
| 149 i->second.updater = updater; | |
| 150 return i->first; | |
| 151 } | |
| 152 } | |
| 153 } | |
| 154 | |
| 155 // Newly created apps go after all existing apps. If there are no apps put it | |
| 156 // at after the tabbed item, and if there is no tabbed item put it at the end. | |
| 157 int item_count = static_cast<int>(model_->items().size()); | |
| 158 int min_app_index = item_count; | |
| 159 int min_tab_index = min_app_index; | |
| 160 if (updater) { | |
| 161 for (IDToItemMap::const_iterator i = id_to_item_map_.begin(); | |
| 162 i != id_to_item_map_.end(); ++i) { | |
| 163 if (i->second.updater == updater) { | |
| 164 if (i->second.item_type == TYPE_APP) { | |
| 165 min_app_index = | |
| 166 std::min(min_app_index, model_->ItemIndexByID(i->first)); | |
| 167 } else { | |
| 168 min_tab_index = | |
| 169 std::min(min_app_index, model_->ItemIndexByID(i->first)); | |
| 170 } | |
| 171 } | |
| 172 } | |
| 173 } | |
| 174 int insert_index = min_app_index != item_count ? | |
| 175 min_app_index : std::min(item_count, min_tab_index + 1); | |
| 176 ash::LauncherID id = model_->next_id(); | |
| 177 ash::LauncherItem item(ash::TYPE_APP); | |
| 178 model_->Add(insert_index, item); | |
| 179 DCHECK(id_to_item_map_.find(id) == id_to_item_map_.end()); | |
| 180 id_to_item_map_[id].item_type = TYPE_APP; | |
| 181 id_to_item_map_[id].app_type = app_type; | |
| 182 id_to_item_map_[id].app_id = app_id; | |
| 183 id_to_item_map_[id].updater = updater; | |
| 184 id_to_item_map_[id].pinned = updater == NULL; | |
| 185 | |
| 186 app_icon_loader_->FetchImage(app_id); | |
| 187 return id; | |
| 188 } | |
| 189 | |
| 190 void ChromeLauncherDelegate::ConvertAppToTabbed(ash::LauncherID id) { | |
| 191 DCHECK(id_to_item_map_.find(id) != id_to_item_map_.end()); | |
| 192 DCHECK_EQ(TYPE_APP, id_to_item_map_[id].item_type); | |
| 193 DCHECK(!id_to_item_map_[id].pinned); | |
| 194 id_to_item_map_[id].item_type = TYPE_TABBED_BROWSER; | |
| 195 id_to_item_map_[id].app_id.clear(); | |
| 196 } | |
| 197 | |
| 198 void ChromeLauncherDelegate::ConvertTabbedToApp(ash::LauncherID id, | |
| 199 const std::string& app_id, | |
| 200 AppType app_type) { | |
| 201 DCHECK(id_to_item_map_.find(id) != id_to_item_map_.end()); | |
| 202 DCHECK_EQ(TYPE_TABBED_BROWSER, id_to_item_map_[id].item_type); | |
| 203 DCHECK(!id_to_item_map_[id].pinned); | |
| 204 id_to_item_map_[id].item_type = TYPE_APP; | |
| 205 id_to_item_map_[id].app_type = app_type; | |
| 206 id_to_item_map_[id].app_id = app_id; | |
| 207 | |
| 208 ash::LauncherItem item(ash::TYPE_APP); | |
| 209 item.id = id; | |
| 210 model_->Set(model_->ItemIndexByID(id), item); | |
| 211 | |
| 212 app_icon_loader_->FetchImage(app_id); | |
| 213 } | |
| 214 | |
| 215 void ChromeLauncherDelegate::LauncherItemClosed(ash::LauncherID id) { | |
| 216 DCHECK(id_to_item_map_.find(id) != id_to_item_map_.end()); | |
| 217 if (id_to_item_map_[id].pinned) { | |
| 218 // The item is pinned, leave it in the launcher. | |
| 219 id_to_item_map_[id].updater = NULL; | |
| 220 } else { | |
| 221 id_to_item_map_.erase(id); | |
| 222 model_->RemoveItemAt(model_->ItemIndexByID(id)); | |
| 223 } | |
| 224 } | |
| 225 | |
| 226 void ChromeLauncherDelegate::AppIDChanged(ash::LauncherID id, | |
| 227 const std::string& app_id) { | |
| 228 DCHECK(id_to_item_map_.find(id) != id_to_item_map_.end()); | |
| 229 id_to_item_map_[id].app_id = app_id; | |
| 230 PersistPinnedState(); | |
| 231 | |
| 232 app_icon_loader_->FetchImage(app_id); | |
| 233 } | |
| 234 | |
| 235 bool ChromeLauncherDelegate::HasClosedAppItem(const std::string& app_id, | |
| 236 AppType app_type) { | |
| 237 for (IDToItemMap::const_iterator i = id_to_item_map_.begin(); | |
| 238 i != id_to_item_map_.end(); ++i) { | |
| 239 if (!i->second.updater && i->second.item_type == TYPE_APP && | |
| 240 i->second.app_type == app_type && i->second.app_id == app_id) | |
| 241 return true; | |
| 242 } | |
| 243 return false; | |
| 244 } | |
| 245 | |
| 246 void ChromeLauncherDelegate::Pin(ash::LauncherID id) { | |
| 247 DCHECK(id_to_item_map_.find(id) != id_to_item_map_.end()); | |
| 248 id_to_item_map_[id].pinned = true; | |
| 249 PersistPinnedState(); | |
| 250 } | |
| 251 | |
| 252 void ChromeLauncherDelegate::Unpin(ash::LauncherID id) { | |
| 253 DCHECK(id_to_item_map_.find(id) != id_to_item_map_.end()); | |
| 254 id_to_item_map_[id].pinned = false; | |
| 255 if (!id_to_item_map_[id].updater) | |
| 256 LauncherItemClosed(id); | |
| 257 PersistPinnedState(); | |
| 258 } | |
| 259 | |
| 260 bool ChromeLauncherDelegate::IsPinned(ash::LauncherID id) { | |
| 261 DCHECK(id_to_item_map_.find(id) != id_to_item_map_.end()); | |
| 262 return id_to_item_map_[id].pinned; | |
| 263 } | |
| 264 | |
| 265 void ChromeLauncherDelegate::TogglePinned(ash::LauncherID id) { | |
| 266 if (id_to_item_map_.find(id) == id_to_item_map_.end()) | |
| 267 return; // May happen if item closed with menu open. | |
| 268 | |
| 269 if (IsPinned(id)) | |
| 270 Unpin(id); | |
| 271 else | |
| 272 Pin(id); | |
| 273 } | |
| 274 | |
| 275 bool ChromeLauncherDelegate::IsPinnable(ash::LauncherID id) { | |
| 276 return id_to_item_map_.find(id) != id_to_item_map_.end() && | |
| 277 id_to_item_map_[id].item_type == TYPE_APP; | |
| 278 } | |
| 279 | |
| 280 void ChromeLauncherDelegate::Open(ash::LauncherID id) { | |
| 281 if (id_to_item_map_.find(id) == id_to_item_map_.end()) | |
| 282 return; // In case invoked from menu and item closed while menu up. | |
| 283 | |
| 284 LauncherUpdater* updater = id_to_item_map_[id].updater; | |
| 285 if (updater) { | |
| 286 updater->window()->Show(); | |
| 287 ash::wm::ActivateWindow(updater->window()); | |
| 288 TabContentsWrapper* tab = updater->GetTab(id); | |
| 289 if (tab) { | |
| 290 updater->tab_model()->ActivateTabAt( | |
| 291 updater->tab_model()->GetIndexOfTabContents(tab), true); | |
| 292 } | |
| 293 } else { | |
| 294 DCHECK_EQ(TYPE_APP, id_to_item_map_[id].item_type); | |
| 295 if (id_to_item_map_[id].app_type == APP_TYPE_TAB) { | |
| 296 const Extension* extension = | |
| 297 profile_->GetExtensionService()->GetInstalledExtension( | |
| 298 id_to_item_map_[id].app_id); | |
| 299 DCHECK(extension); | |
| 300 Browser::OpenApplicationTab(GetProfileForNewWindows(), extension, GURL(), | |
| 301 NEW_FOREGROUND_TAB); | |
| 302 if (id_to_item_map_[id].updater) | |
| 303 id_to_item_map_[id].updater->window()->Show(); | |
| 304 } else { | |
| 305 std::string app_name = web_app::GenerateApplicationNameFromExtensionId( | |
| 306 id_to_item_map_[id].app_id); | |
| 307 Browser* browser = Browser::CreateForApp( | |
| 308 Browser::TYPE_POPUP, app_name, gfx::Rect(), | |
| 309 GetProfileForNewWindows()); | |
| 310 browser->window()->Show(); | |
| 311 } | |
| 312 } | |
| 313 } | |
| 314 | |
| 315 void ChromeLauncherDelegate::Close(ash::LauncherID id) { | |
| 316 if (id_to_item_map_.find(id) == id_to_item_map_.end()) | |
| 317 return; // May happen if menu closed. | |
| 318 | |
| 319 if (!id_to_item_map_[id].updater) | |
| 320 return; // TODO: maybe should treat as unpin? | |
| 321 | |
| 322 TabContentsWrapper* tab = id_to_item_map_[id].updater->GetTab(id); | |
| 323 if (tab) { | |
| 324 content::WebContentsDelegate* delegate = | |
| 325 tab->web_contents()->GetDelegate(); | |
| 326 if (delegate) | |
| 327 delegate->CloseContents(tab->web_contents()); | |
| 328 else | |
| 329 delete tab; | |
| 330 } else { | |
| 331 views::Widget* widget = views::Widget::GetWidgetForNativeView( | |
| 332 id_to_item_map_[id].updater->window()); | |
| 333 if (widget) | |
| 334 widget->Close(); | |
| 335 } | |
| 336 } | |
| 337 | |
| 338 bool ChromeLauncherDelegate::IsOpen(ash::LauncherID id) { | |
| 339 return id_to_item_map_.find(id) != id_to_item_map_.end() && | |
| 340 id_to_item_map_[id].updater != NULL; | |
| 341 } | |
| 342 | |
| 343 ChromeLauncherDelegate::AppType ChromeLauncherDelegate::GetAppType( | |
| 344 ash::LauncherID id) { | |
| 345 DCHECK(id_to_item_map_.find(id) != id_to_item_map_.end()); | |
| 346 return id_to_item_map_[id].app_type; | |
| 347 } | |
| 348 | |
| 349 std::string ChromeLauncherDelegate::GetAppID(TabContentsWrapper* tab) { | |
| 350 return app_icon_loader_->GetAppID(tab); | |
| 351 } | |
| 352 | |
| 353 void ChromeLauncherDelegate::SetAppImage(const std::string& id, | |
| 354 SkBitmap* image) { | |
| 355 for (IDToItemMap::const_iterator i = id_to_item_map_.begin(); | |
| 356 i != id_to_item_map_.end(); ++i) { | |
| 357 if (i->second.app_id == id) { | |
| 358 int index = model_->ItemIndexByID(i->first); | |
| 359 ash::LauncherItem item = model_->items()[index]; | |
| 360 item.image = image ? *image : Extension::GetDefaultIcon(true); | |
| 361 model_->Set(index, item); | |
| 362 // It's possible we're waiting on more than one item, so don't break. | |
| 363 } | |
| 364 } | |
| 365 } | |
| 366 | |
| 367 void ChromeLauncherDelegate::CreateNewWindow() { | |
| 368 Browser::OpenEmptyWindow(GetProfileForNewWindows()); | |
| 369 } | |
| 370 | |
| 371 void ChromeLauncherDelegate::ItemClicked(const ash::LauncherItem& item) { | |
| 372 DCHECK(id_to_item_map_.find(item.id) != id_to_item_map_.end()); | |
| 373 Open(item.id); | |
| 374 } | |
| 375 | |
| 376 int ChromeLauncherDelegate::GetBrowserShortcutResourceId() { | |
| 377 return IDR_PRODUCT_LOGO_32; | |
| 378 } | |
| 379 | |
| 380 string16 ChromeLauncherDelegate::GetTitle(const ash::LauncherItem& item) { | |
| 381 DCHECK(id_to_item_map_.find(item.id) != id_to_item_map_.end()); | |
| 382 LauncherUpdater* updater = id_to_item_map_[item.id].updater; | |
| 383 if (updater) { | |
| 384 if (id_to_item_map_[item.id].item_type == TYPE_TABBED_BROWSER) { | |
| 385 return updater->tab_model()->GetActiveTabContents() ? | |
| 386 updater->tab_model()->GetActiveTabContents()->web_contents()-> | |
| 387 GetTitle() : string16(); | |
| 388 } | |
| 389 // Fall through to get title from extension. | |
| 390 } | |
| 391 const Extension* extension = profile_->GetExtensionService()-> | |
| 392 GetInstalledExtension(id_to_item_map_[item.id].app_id); | |
| 393 return extension ? UTF8ToUTF16(extension->name()) : string16(); | |
| 394 } | |
| 395 | |
| 396 ui::MenuModel* ChromeLauncherDelegate::CreateContextMenu( | |
| 397 const ash::LauncherItem& item) { | |
| 398 return new LauncherContextMenu(this, item.id); | |
| 399 } | |
| 400 | |
| 401 void ChromeLauncherDelegate::LauncherItemAdded(int index) { | |
| 402 } | |
| 403 | |
| 404 void ChromeLauncherDelegate::LauncherItemRemoved(int index, | |
| 405 ash::LauncherID id) { | |
| 406 } | |
| 407 | |
| 408 void ChromeLauncherDelegate::LauncherItemMoved( | |
| 409 int start_index, | |
| 410 int target_index) { | |
| 411 ash::LauncherID id = model_->items()[target_index].id; | |
| 412 if (id_to_item_map_.find(id) != id_to_item_map_.end() && | |
| 413 id_to_item_map_[id].pinned) { | |
| 414 PersistPinnedState(); | |
| 415 } | |
| 416 } | |
| 417 | |
| 418 void ChromeLauncherDelegate::LauncherItemChanged( | |
| 419 int index, | |
| 420 const ash::LauncherItem& old_item) { | |
| 421 } | |
| 422 | |
| 423 void ChromeLauncherDelegate::LauncherItemWillChange(int index) { | |
| 424 } | |
| 425 | |
| 426 void ChromeLauncherDelegate::Observe( | |
| 427 int type, | |
| 428 const content::NotificationSource& source, | |
| 429 const content::NotificationDetails& details) { | |
| 430 DCHECK_EQ(type, chrome::NOTIFICATION_EXTENSION_UNLOADED); | |
| 431 const Extension* extension = | |
| 432 content::Details<UnloadedExtensionInfo>(details)->extension; | |
| 433 UnpinAppsWithID(extension->id()); | |
| 434 } | |
| 435 | |
| 436 void ChromeLauncherDelegate::PersistPinnedState() { | |
| 437 ListPrefUpdate updater(profile_->GetPrefs(), prefs::kPinnedLauncherApps); | |
| 438 updater.Get()->Clear(); | |
| 439 for (size_t i = 0; i < model_->items().size(); ++i) { | |
| 440 if (model_->items()[i].type == ash::TYPE_APP) { | |
| 441 ash::LauncherID id = model_->items()[i].id; | |
| 442 if (id_to_item_map_.find(id) != id_to_item_map_.end() && | |
| 443 id_to_item_map_[id].pinned) { | |
| 444 base::DictionaryValue* app_value = new base::DictionaryValue; | |
| 445 app_value->SetString(kAppIDPath, id_to_item_map_[id].app_id); | |
| 446 const char* app_type_string = | |
| 447 id_to_item_map_[id].app_type == APP_TYPE_WINDOW ? | |
| 448 kAppTypeWindow : kAppTypeTab; | |
| 449 app_value->SetString(kAppTypePath, app_type_string); | |
| 450 updater.Get()->Append(app_value); | |
| 451 } | |
| 452 } | |
| 453 } | |
| 454 } | |
| 455 | |
| 456 void ChromeLauncherDelegate::UnpinAppsWithID(const std::string& app_id) { | |
| 457 for (IDToItemMap::iterator i = id_to_item_map_.begin(); | |
| 458 i != id_to_item_map_.end(); ) { | |
| 459 IDToItemMap::iterator current(i); | |
| 460 ++i; | |
| 461 if (current->second.app_id == app_id && current->second.pinned) | |
| 462 Unpin(current->first); | |
| 463 } | |
| 464 } | |
| 465 | |
| 466 void ChromeLauncherDelegate::SetAppIconLoaderForTest(AppIconLoader* loader) { | |
| 467 app_icon_loader_.reset(loader); | |
| 468 } | |
| 469 | |
| 470 Profile* ChromeLauncherDelegate::GetProfileForNewWindows() { | |
| 471 Profile* profile = ProfileManager::GetDefaultProfile(); | |
| 472 if (browser_defaults::kAlwaysOpenIncognitoWindow && | |
| 473 IncognitoModePrefs::ShouldLaunchIncognito( | |
| 474 *CommandLine::ForCurrentProcess(), | |
| 475 profile->GetPrefs())) { | |
| 476 profile = profile->GetOffTheRecordProfile(); | |
| 477 } | |
| 478 return profile; | |
| 479 } | |
| OLD | NEW |