OLD | NEW |
---|---|
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 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 | 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 package org.chromium.chrome.browser.signin; | 5 package org.chromium.chrome.browser.signin; |
6 | 6 |
7 import android.accounts.Account; | |
7 import android.content.Context; | 8 import android.content.Context; |
8 import android.os.AsyncTask; | 9 import android.os.AsyncTask; |
9 | 10 |
10 import org.chromium.base.Log; | 11 import org.chromium.base.Log; |
11 import org.chromium.base.ObserverList; | 12 import org.chromium.base.ObserverList; |
12 import org.chromium.base.ThreadUtils; | 13 import org.chromium.base.ThreadUtils; |
13 import org.chromium.base.VisibleForTesting; | 14 import org.chromium.base.VisibleForTesting; |
15 import org.chromium.base.annotations.JNINamespace; | |
16 import org.chromium.sync.signin.AccountManagerDelegate.Callback; | |
14 import org.chromium.sync.signin.AccountManagerHelper; | 17 import org.chromium.sync.signin.AccountManagerHelper; |
15 | 18 |
16 import java.util.List; | |
17 | |
18 /** | 19 /** |
19 * Android wrapper of AccountTrackerService which provides access from the java l ayer. | 20 * Android wrapper of AccountTrackerService which provides access from the java l ayer. |
20 * It offers the capability of fetching and seeding system accounts into AccountT rackerService in C++ | 21 * It offers the capability of fetching and seeding system accounts into AccountT rackerService in C++ |
21 * layer, and notifies observers when it is complete. | 22 * layer, and notifies observers when it is complete. |
22 */ | 23 */ |
24 @JNINamespace("signin::android") | |
23 public class AccountTrackerService { | 25 public class AccountTrackerService { |
24 private static final String TAG = "cr.AccountService"; | 26 private static final String TAG = "AccountService"; |
25 private static AccountTrackerService sAccountTrackerService; | 27 private static AccountTrackerService sAccountTrackerService; |
26 private static AccountIdProvider sAccountIdProvider; | |
27 private SystemAccountsSeedingStatus mSystemAccountsSeedingStatus = | 28 private SystemAccountsSeedingStatus mSystemAccountsSeedingStatus = |
28 SystemAccountsSeedingStatus.SEEDING_NOT_STARTED; | 29 SystemAccountsSeedingStatus.SEEDING_NOT_STARTED; |
29 private boolean mForceRefresh; | 30 private boolean mForceRefresh; |
30 private boolean mSyncForceRefreshedForTest; | 31 private boolean mSyncForceRefreshedForTest; |
31 | 32 |
32 private final Context mContext; | 33 private final Context mContext; |
33 private final long mNativeAccountTrackerService; | |
34 | 34 |
35 private enum SystemAccountsSeedingStatus { | 35 private enum SystemAccountsSeedingStatus { |
36 SEEDING_NOT_STARTED, | 36 SEEDING_NOT_STARTED, |
37 SEEDING_IN_PROGRESS, | 37 SEEDING_IN_PROGRESS, |
38 SEEDING_DONE | 38 SEEDING_DONE |
39 } | 39 } |
40 | 40 |
41 /** | 41 /** |
42 * Classes that want to listen for system accounts fetching and seeding shoul d implement | 42 * Classes that want to listen for system accounts fetching and seeding shoul d implement |
43 * this interface and register with {@link #addSystemAccountsSeededListener}. | 43 * this interface and register with {@link #addSystemAccountsSeededListener}. |
44 */ | 44 */ |
45 public interface OnSystemAccountsSeededListener { | 45 public interface OnSystemAccountsSeededListener { |
46 // Called at the end of seedSystemAccounts(). | 46 // Called at the end of seedSystemAccounts(). |
47 void onSystemAccountsSeedingComplete(); | 47 void onSystemAccountsSeedingComplete(); |
48 // Called at the beginning of system accounts being force refreshed. | 48 // Called at the beginning of system accounts being force refreshed. |
49 void onSystemAccountsForceRefreshed(); | 49 void onSystemAccountsForceRefreshed(); |
50 } | 50 } |
51 | 51 |
52 private final ObserverList<OnSystemAccountsSeededListener> mSystemAccountsSe edingObservers = | 52 private final ObserverList<OnSystemAccountsSeededListener> mSystemAccountsSe edingObservers = |
53 new ObserverList<>(); | 53 new ObserverList<>(); |
54 | 54 |
55 public static AccountTrackerService get(Context context) { | 55 public static AccountTrackerService get(Context context) { |
56 ThreadUtils.assertOnUiThread(); | 56 ThreadUtils.assertOnUiThread(); |
57 if (sAccountTrackerService == null) { | 57 if (sAccountTrackerService == null) { |
58 sAccountTrackerService = new AccountTrackerService(context); | 58 sAccountTrackerService = new AccountTrackerService(context); |
59 sAccountIdProvider = AccountIdProvider.getInstance(); | |
60 } | 59 } |
61 return sAccountTrackerService; | 60 return sAccountTrackerService; |
62 } | 61 } |
63 | 62 |
64 private AccountTrackerService(Context context) { | 63 private AccountTrackerService(Context context) { |
65 mContext = context; | 64 mContext = context; |
66 mNativeAccountTrackerService = nativeInit(); | |
67 } | 65 } |
68 | 66 |
69 /** | 67 /** |
70 * Check whether system accounts have been seeded into AccountTrackerService in C++ layer. | 68 * Check whether system accounts have been seeded into AccountTrackerService in C++ layer. |
71 */ | 69 */ |
72 public boolean isSystemAccountsSeeded() { | 70 public boolean isSystemAccountsSeeded() { |
73 ThreadUtils.assertOnUiThread(); | 71 ThreadUtils.assertOnUiThread(); |
74 if (mSystemAccountsSeedingStatus == SystemAccountsSeedingStatus.SEEDING_ DONE) { | 72 if (mSystemAccountsSeedingStatus == SystemAccountsSeedingStatus.SEEDING_ DONE |
73 && nativeAreAllAccountsSeeded()) { | |
gogerald1
2015/10/13 16:34:53
seedSystemAccounts is called on UI thread and Seed
| |
75 return true; | 74 return true; |
76 } | 75 } |
77 | |
78 if (mSystemAccountsSeedingStatus == SystemAccountsSeedingStatus.SEEDING_ NOT_STARTED) { | 76 if (mSystemAccountsSeedingStatus == SystemAccountsSeedingStatus.SEEDING_ NOT_STARTED) { |
79 seedSystemAccounts(); | 77 seedSystemAccounts(); |
80 } | 78 } |
81 | |
82 return false; | 79 return false; |
83 } | 80 } |
84 | 81 |
85 /** | 82 /** |
86 * Register an |observer| to observe system accounts seeding status. | 83 * Register an |observer| to observe system accounts seeding status. |
87 */ | 84 */ |
88 public void addSystemAccountsSeededListener(OnSystemAccountsSeededListener o bserver) { | 85 public void addSystemAccountsSeededListener(OnSystemAccountsSeededListener o bserver) { |
89 ThreadUtils.assertOnUiThread(); | 86 ThreadUtils.assertOnUiThread(); |
90 mSystemAccountsSeedingObservers.addObserver(observer); | 87 mSystemAccountsSeedingObservers.addObserver(observer); |
91 if (mSystemAccountsSeedingStatus == SystemAccountsSeedingStatus.SEEDING_ DONE) { | 88 if (mSystemAccountsSeedingStatus == SystemAccountsSeedingStatus.SEEDING_ DONE) { |
92 observer.onSystemAccountsSeedingComplete(); | 89 observer.onSystemAccountsSeedingComplete(); |
93 } | 90 } |
94 } | 91 } |
95 | 92 |
96 private void seedSystemAccounts() { | 93 private void seedSystemAccounts() { |
97 ThreadUtils.assertOnUiThread(); | 94 ThreadUtils.assertOnUiThread(); |
98 mSystemAccountsSeedingStatus = SystemAccountsSeedingStatus.SEEDING_IN_PR OGRESS; | |
99 mForceRefresh = false; | 95 mForceRefresh = false; |
100 mSyncForceRefreshedForTest = false; | 96 mSyncForceRefreshedForTest = false; |
101 AccountManagerHelper accountManagerHelper = AccountManagerHelper.get(mCo ntext); | 97 final AccountIdProvider accountIdProvider = AccountIdProvider.getInstanc e(); |
102 List<String> accountNamesList = accountManagerHelper.getGoogleAccountNam es(); | 98 if (accountIdProvider.canBeUsed(mContext, null)) { |
103 final String[] accountNames = accountNamesList.toArray(new String[accoun tNamesList.size()]); | 99 mSystemAccountsSeedingStatus = SystemAccountsSeedingStatus.SEEDING_I N_PROGRESS; |
104 new AsyncTask<Void, Void, String[]>() { | 100 } else { |
101 mSystemAccountsSeedingStatus = SystemAccountsSeedingStatus.SEEDING_N OT_STARTED; | |
102 notifyObserversOnForceRefreshed(); | |
103 return; | |
104 } | |
105 AccountManagerHelper.get(mContext).getGoogleAccounts(new Callback<Accoun t[]>() { | |
105 @Override | 106 @Override |
106 public String[] doInBackground(Void... params) { | 107 public void gotResult(final Account[] accounts) { |
107 Log.d(TAG, "Getting id/email mapping"); | 108 new AsyncTask<Void, Void, String[][]>() { |
108 String[] accountIds = new String[accountNames.length]; | 109 @Override |
109 for (int i = 0; i < accountIds.length; ++i) { | 110 public String[][] doInBackground(Void... params) { |
110 accountIds[i] = sAccountIdProvider.getAccountId(mContext, ac countNames[i]); | 111 Log.d(TAG, "Getting id/email mapping"); |
111 } | 112 String[][] accountIdNameMap = new String[2][accounts.len gth]; |
112 return accountIds; | 113 for (int i = 0; i < accounts.length; ++i) { |
114 accountIdNameMap[0][i] = | |
115 accountIdProvider.getAccountId(mContext, acc ounts[i].name); | |
116 accountIdNameMap[1][i] = accounts[i].name; | |
117 } | |
118 return accountIdNameMap; | |
119 } | |
120 @Override | |
121 public void onPostExecute(String[][] accountIdNameMap) { | |
122 if (mSyncForceRefreshedForTest) return; | |
123 if (mForceRefresh) { | |
124 seedSystemAccounts(); | |
125 return; | |
126 } | |
127 if (areAccountIdsValid(accountIdNameMap[0])) { | |
128 nativeSeedAccountsInfo(accountIdNameMap[0], accountI dNameMap[1]); | |
129 mSystemAccountsSeedingStatus = SystemAccountsSeeding Status.SEEDING_DONE; | |
130 notifyObserversOnSeedingComplete(); | |
131 } else { | |
132 Log.w(TAG, "Invalid mapping of id/email"); | |
133 seedSystemAccounts(); | |
134 } | |
135 } | |
136 }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); | |
113 } | 137 } |
114 @Override | 138 }); |
115 public void onPostExecute(String[] accountIds) { | |
116 if (mSyncForceRefreshedForTest) return; | |
117 if (mForceRefresh) { | |
118 seedSystemAccounts(); | |
119 return; | |
120 } | |
121 if (areAccountIdsValid(accountIds)) { | |
122 nativeSeedAccountsInfo(mNativeAccountTrackerService, account Ids, accountNames); | |
123 mSystemAccountsSeedingStatus = SystemAccountsSeedingStatus.S EEDING_DONE; | |
124 notifyObserversOnSeedingComplete(); | |
125 } else { | |
126 Log.w(TAG, "Invalid mapping of id/email"); | |
127 if (sAccountIdProvider.canBeUsed(mContext, null)) { | |
128 seedSystemAccounts(); | |
129 return; | |
130 } | |
131 mSystemAccountsSeedingStatus = SystemAccountsSeedingStatus.S EEDING_NOT_STARTED; | |
132 notifyObserversOnForceRefreshed(); | |
133 } | |
134 } | |
135 }.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR); | |
136 } | 139 } |
137 | 140 |
138 private boolean areAccountIdsValid(String[] accountIds) { | 141 private boolean areAccountIdsValid(String[] accountIds) { |
139 for (int i = 0; i < accountIds.length; ++i) { | 142 for (int i = 0; i < accountIds.length; ++i) { |
140 if (accountIds[i] == null) return false; | 143 if (accountIds[i] == null) return false; |
141 } | 144 } |
142 return true; | 145 return true; |
143 } | 146 } |
144 | 147 |
145 private void notifyObserversOnSeedingComplete() { | 148 private void notifyObserversOnSeedingComplete() { |
146 for (OnSystemAccountsSeededListener observer : mSystemAccountsSeedingObs ervers) { | 149 for (OnSystemAccountsSeededListener observer : mSystemAccountsSeedingObs ervers) { |
147 observer.onSystemAccountsSeedingComplete(); | 150 observer.onSystemAccountsSeedingComplete(); |
148 } | 151 } |
149 } | 152 } |
150 | 153 |
151 /** | 154 /** |
152 * Seed system accounts into AccountTrackerService synchronously for test pur pose. | 155 * Seed system accounts into AccountTrackerService synchronously for test pur pose. |
153 */ | 156 */ |
154 @VisibleForTesting | 157 @VisibleForTesting |
155 public void syncForceRefreshForTest(String[] accountIds, String[] accountNam es) { | 158 public void syncForceRefreshForTest(String[] accountIds, String[] accountNam es) { |
156 ThreadUtils.assertOnUiThread(); | 159 ThreadUtils.assertOnUiThread(); |
157 mSystemAccountsSeedingStatus = SystemAccountsSeedingStatus.SEEDING_IN_PR OGRESS; | 160 mSystemAccountsSeedingStatus = SystemAccountsSeedingStatus.SEEDING_IN_PR OGRESS; |
158 mForceRefresh = false; | 161 mForceRefresh = false; |
159 mSyncForceRefreshedForTest = true; | 162 mSyncForceRefreshedForTest = true; |
160 nativeSeedAccountsInfo(mNativeAccountTrackerService, accountIds, account Names); | 163 nativeSeedAccountsInfo(accountIds, accountNames); |
161 mSystemAccountsSeedingStatus = SystemAccountsSeedingStatus.SEEDING_DONE; | 164 mSystemAccountsSeedingStatus = SystemAccountsSeedingStatus.SEEDING_DONE; |
162 } | 165 } |
163 | 166 |
164 /** | 167 /** |
165 * Force AccountTrackerService refresh/update systems accounts. | 168 * Force AccountTrackerService refresh/update systems accounts. |
166 */ | 169 */ |
167 public void forceRefresh() { | 170 public void forceRefresh() { |
168 ThreadUtils.assertOnUiThread(); | 171 ThreadUtils.assertOnUiThread(); |
169 mForceRefresh = true; | 172 mForceRefresh = true; |
170 notifyObserversOnForceRefreshed(); | 173 notifyObserversOnForceRefreshed(); |
171 if (mSystemAccountsSeedingStatus != SystemAccountsSeedingStatus.SEEDING_ IN_PROGRESS) { | 174 if (mSystemAccountsSeedingStatus != SystemAccountsSeedingStatus.SEEDING_ IN_PROGRESS) { |
172 seedSystemAccounts(); | 175 seedSystemAccounts(); |
173 } | 176 } |
174 } | 177 } |
175 | 178 |
176 private void notifyObserversOnForceRefreshed() { | 179 private void notifyObserversOnForceRefreshed() { |
177 for (OnSystemAccountsSeededListener observer : mSystemAccountsSeedingObs ervers) { | 180 for (OnSystemAccountsSeededListener observer : mSystemAccountsSeedingObs ervers) { |
178 observer.onSystemAccountsForceRefreshed(); | 181 observer.onSystemAccountsForceRefreshed(); |
179 } | 182 } |
180 } | 183 } |
181 | 184 |
182 // Native methods. | 185 private static native boolean nativeAreAllAccountsSeeded(); |
183 private native long nativeInit(); | 186 private static native void nativeSeedAccountsInfo(String[] gaiaIds, String[] accountNames); |
184 private native void nativeSeedAccountsInfo( | |
185 long nativeAccountTrackerServiceAndroid, String[] gaiaIds, String[] accountNames); | |
186 } | 187 } |
OLD | NEW |