Add ICU message format support
[chromium-blink-merge.git] / ios / web / browsing_data_partition_impl.mm
blob224a92430c94020a454d6a8e2c95266314171f2e
1 // Copyright 2015 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.
5 #import "ios/web/browsing_data_partition_impl.h"
7 #include "base/logging.h"
8 #include "ios/web/public/browser_state.h"
9 #include "ios/web/public/browsing_data_partition_client.h"
10 #import "ios/web/public/crw_browsing_data_store.h"
11 #include "ios/web/public/web_thread.h"
13 // A class that observes the |mode| changes in a CRWBrowsingDataStore using KVO.
14 // Maintains a count of all the CRWBrowsingDataStores whose mode is out of sync
15 // with their corresponding ActiveStateManager's active state.
16 @interface CRWBrowsingDataStoreModeObserver : NSObject
18 // The total count of the CRWBrowsingDataStores -- that are being observed --
19 // whose mode is out of sync with their associated ActiveStateManager's active
20 // state.
21 @property(nonatomic, assign) NSUInteger outOfSyncStoreCount;
23 // Adds |browsingDataStore| to the list of the CRWBrowsingDataStores that are
24 // being observed for KVO changes in the |mode| value. |browserState| cannot be
25 // null and the |browserState|'s associated CRWBrowsingDataStore must be
26 // |browsingDataStore|.
27 // The |browsingDataStore|'s mode must not already be |CHANGING|.
28 - (void)startObservingBrowsingDataStore:(CRWBrowsingDataStore*)browsingDataStore
29                            browserState:(web::BrowserState*)browserState;
31 // Stops observing |browsingDataStore| for its |mode| change.
32 // The |browsingDataStore|'s mode must not be |CHANGING|.
33 - (void)stopObservingBrowsingDataStore:(CRWBrowsingDataStore*)browsingDataStore;
34 @end
36 @implementation CRWBrowsingDataStoreModeObserver
38 @synthesize outOfSyncStoreCount = _outOfSyncStoreCount;
40 - (void)startObservingBrowsingDataStore:(CRWBrowsingDataStore*)browsingDataStore
41                            browserState:(web::BrowserState*)browserState {
42   web::BrowsingDataPartition* browsing_data_partition =
43       web::BrowserState::GetBrowsingDataPartition(browserState);
44   DCHECK(browsing_data_partition);
45   DCHECK_EQ(browsing_data_partition->GetBrowsingDataStore(), browsingDataStore);
46   DCHECK_NE(web::CHANGING, browsingDataStore.mode);
48   [browsingDataStore addObserver:self
49                       forKeyPath:@"mode"
50                          options:0
51                          context:browserState];
54 - (void)stopObservingBrowsingDataStore:
55         (CRWBrowsingDataStore*)browsingDataStore {
56   DCHECK_NE(web::CHANGING, browsingDataStore.mode);
58   [browsingDataStore removeObserver:self forKeyPath:@"mode"];
61 - (void)observeValueForKeyPath:(NSString*)keyPath
62                       ofObject:(CRWBrowsingDataStore*)browsingDataStore
63                         change:(NSDictionary*)change
64                        context:(void*)context {
65   DCHECK([keyPath isEqual:@"mode"]);
66   DCHECK([browsingDataStore isKindOfClass:[CRWBrowsingDataStore class]]);
67   DCHECK(context);
69   if (browsingDataStore.mode == web::CHANGING) {
70     ++self.outOfSyncStoreCount;
71     return;
72   }
73   web::BrowserState* browserState = static_cast<web::BrowserState*>(context);
74   web::ActiveStateManager* activeStateManager =
75       web::BrowserState::GetActiveStateManager(browserState);
76   DCHECK(activeStateManager);
77   bool activeState = activeStateManager->IsActive();
78   // Check if the |browsingDataStore|'s associated ActiveStateManager's active
79   // state is still out of sync.
80   if (activeState && browsingDataStore.mode == web::INACTIVE) {
81     [browsingDataStore makeActiveWithCompletionHandler:nil];
82   } else if (!activeState && browsingDataStore.mode == web::ACTIVE) {
83     [browsingDataStore makeInactiveWithCompletionHandler:nil];
84   }
86   DCHECK_GE(self.outOfSyncStoreCount, 1U);
87   --self.outOfSyncStoreCount;
88   web::BrowsingDataPartitionClient* client =
89       web::GetBrowsingDataPartitionClient();
90   if (client) {
91     client->DidBecomeSynchronized();
92   }
95 @end
97 namespace web {
99 namespace {
100 // The global observer that tracks the number of CRWBrowsingDataStores whose
101 // modes are out of sync with their associated ActiveStateManager's active
102 // state.
103 CRWBrowsingDataStoreModeObserver* g_browsing_data_store_mode_observer = nil;
104 }  // namespace
106 BrowsingDataPartitionImpl::BrowsingDataPartitionImpl(
107     BrowserState* browser_state)
108     : browser_state_(browser_state) {
109   DCHECK_CURRENTLY_ON_WEB_THREAD(WebThread::UI);
110   DCHECK(browser_state);
112   active_state_manager_ = static_cast<ActiveStateManagerImpl*>(
113       BrowserState::GetActiveStateManager(browser_state));
114   DCHECK(active_state_manager_);
115   active_state_manager_->AddObserver(this);
118 BrowsingDataPartitionImpl::~BrowsingDataPartitionImpl() {
119   if (active_state_manager_) {
120     active_state_manager_->RemoveObserver(this);
121   }
122   DCHECK_NE(CHANGING, [browsing_data_store_ mode]);
123   [g_browsing_data_store_mode_observer
124       stopObservingBrowsingDataStore:browsing_data_store_];
127 // static
128 bool BrowsingDataPartition::IsSynchronized() {
129   return [g_browsing_data_store_mode_observer outOfSyncStoreCount] == 0U;
132 CRWBrowsingDataStore* BrowsingDataPartitionImpl::GetBrowsingDataStore() {
133   DCHECK_CURRENTLY_ON_WEB_THREAD(WebThread::UI);
135   if (!browsing_data_store_) {
136     browsing_data_store_.reset(
137         [[CRWBrowsingDataStore alloc] initWithBrowserState:browser_state_]);
138     if (!g_browsing_data_store_mode_observer) {
139       g_browsing_data_store_mode_observer =
140           [[CRWBrowsingDataStoreModeObserver alloc] init];
141     }
142     [g_browsing_data_store_mode_observer
143         startObservingBrowsingDataStore:browsing_data_store_
144                            browserState:browser_state_];
145   }
146   return browsing_data_store_;
149 void BrowsingDataPartitionImpl::OnActive() {
150   DCHECK_CURRENTLY_ON_WEB_THREAD(WebThread::UI);
152   [GetBrowsingDataStore() makeActiveWithCompletionHandler:nil];
155 void BrowsingDataPartitionImpl::OnInactive() {
156   DCHECK_CURRENTLY_ON_WEB_THREAD(WebThread::UI);
158   [GetBrowsingDataStore() makeInactiveWithCompletionHandler:nil];
161 void BrowsingDataPartitionImpl::WillBeDestroyed() {
162   DCHECK_CURRENTLY_ON_WEB_THREAD(WebThread::UI);
164   active_state_manager_->RemoveObserver(this);
165   active_state_manager_ = nullptr;
168 }  // namespace web