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/android/tab_model/tab_model.h" 6 7 #include "base/logging.h" 8 #include "chrome/browser/browser_process.h" 9 #include "chrome/browser/chrome_notification_types.h" 10 #include "chrome/browser/profiles/profile.h" 11 #include "chrome/browser/sync/glue/synced_window_delegate_android.h" 12 #include "chrome/browser/ui/toolbar/toolbar_model_impl.h" 13 #include "content/public/browser/notification_service.h" 14 15 using content::NotificationService; 16 17 TabModel::TabModel(Profile* profile) 18 : profile_(profile), 19 synced_window_delegate_( 20 new browser_sync::SyncedWindowDelegateAndroid(this)) { 21 22 if (profile) { 23 // A normal Profile creates an OTR profile if it does not exist when 24 // GetOffTheRecordProfile() is called, so we guard it with 25 // HasOffTheRecordProfile(). An OTR profile returns itself when you call 26 // GetOffTheRecordProfile(). 27 is_off_the_record_ = (profile->HasOffTheRecordProfile() && 28 profile == profile->GetOffTheRecordProfile()); 29 30 // A profile can be destroyed, for example in the case of closing all 31 // incognito tabs. We therefore must listen for when this happens, and 32 // remove our pointer to the profile accordingly. 33 registrar_.Add(this, chrome::NOTIFICATION_PROFILE_DESTROYED, 34 content::Source<Profile>(profile_)); 35 registrar_.Add(this, chrome::NOTIFICATION_PROFILE_CREATED, 36 content::NotificationService::AllSources()); 37 } else { 38 is_off_the_record_ = false; 39 } 40 } 41 42 TabModel::~TabModel() { 43 } 44 45 Profile* TabModel::GetProfile() const { 46 return profile_; 47 } 48 49 bool TabModel::IsOffTheRecord() const { 50 return is_off_the_record_; 51 } 52 53 browser_sync::SyncedWindowDelegate* TabModel::GetSyncedWindowDelegate() const { 54 return synced_window_delegate_.get(); 55 } 56 57 SessionID::id_type TabModel::GetSessionId() const { 58 return session_id_.id(); 59 } 60 61 void TabModel::BroadcastSessionRestoreComplete() { 62 if (profile_) { 63 NotificationService::current()->Notify( 64 chrome::NOTIFICATION_SESSION_RESTORE_COMPLETE, 65 content::Source<Profile>(profile_), 66 NotificationService::NoDetails()); 67 } else { 68 // TODO(nyquist): Uncomment this once downstream Android uses new 69 // constructor that takes a Profile* argument. See crbug.com/159704. 70 // NOTREACHED(); 71 } 72 } 73 74 void TabModel::Observe( 75 int type, 76 const content::NotificationSource& source, 77 const content::NotificationDetails& details) { 78 switch (type) { 79 case chrome::NOTIFICATION_PROFILE_DESTROYED: 80 // Our profile just got destroyed, so we delete our pointer to it. 81 profile_ = NULL; 82 break; 83 case chrome::NOTIFICATION_PROFILE_CREATED: 84 // Our incognito tab model out lives the profile, so we need to recapture 85 // the pointer if ours was previously deleted. 86 // NOTIFICATION_PROFILE_DESTROYED is not sent for every destruction, so 87 // we overwrite the pointer regardless of whether it's NULL. 88 if (is_off_the_record_) { 89 Profile* profile = content::Source<Profile>(source).ptr(); 90 if (profile && profile->IsOffTheRecord()) 91 profile_ = profile; 92 } 93 break; 94 default: 95 NOTREACHED(); 96 } 97 } 98