12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file. 42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)package org.chromium.sync.signin; 62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)import android.accounts.Account; 82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)import android.content.Context; 93551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)import android.os.AsyncTask; 102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)import android.preference.PreferenceManager; 112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)import android.util.Log; 122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)import com.google.common.annotations.VisibleForTesting; 143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)import com.google.ipc.invalidation.external.client.contrib.MultiplexingGcmListener; 152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 16f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)import org.chromium.base.CommandLine; 172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)import org.chromium.base.ObserverList; 18f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)import org.chromium.sync.SyncSwitches; 192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)public class ChromeSigninController { 212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public interface Listener { 222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) /** 232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * Called when the user signs out of Chrome. 242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) */ 252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void onClearSignedInUser(); 262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 289ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch public static final String TAG = "ChromeSigninController"; 292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) @VisibleForTesting 312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public static final String SIGNED_IN_ACCOUNT_KEY = "google.services.username"; 322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private static final Object LOCK = new Object(); 342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private static ChromeSigninController sChromeSigninController; 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private final Context mApplicationContext; 382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private final ObserverList<Listener> mListeners = new ObserverList<Listener>(); 402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) private boolean mGcmInitialized; 423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private ChromeSigninController(Context context) { 442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) mApplicationContext = context.getApplicationContext(); 452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) /** 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * A factory method for the ChromeSigninController. 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @param context the ApplicationContext is retrieved from the context used as an argument. 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @return a singleton instance of the ChromeSigninController 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) */ 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public static ChromeSigninController get(Context context) { 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) synchronized (LOCK) { 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (sChromeSigninController == null) { 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) sChromeSigninController = new ChromeSigninController(context); 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return sChromeSigninController; 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public Account getSignedInUser() { 632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) String syncAccountName = getSignedInAccountName(); 642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (syncAccountName == null) { 652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return null; 662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return AccountManagerHelper.createAccountFromName(syncAccountName); 682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public boolean isSignedIn() { 712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return getSignedInAccountName() != null; 722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public void setSignedInAccountName(String accountName) { 752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PreferenceManager.getDefaultSharedPreferences(mApplicationContext).edit() 762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) .putString(SIGNED_IN_ACCOUNT_KEY, accountName) 772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) .apply(); 782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public void clearSignedInUser() { 812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Log.d(TAG, "Clearing user signed in to Chrome"); 822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) setSignedInAccountName(null); 832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (Listener listener : mListeners) { 852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) listener.onClearSignedInUser(); 862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public String getSignedInAccountName() { 902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return PreferenceManager.getDefaultSharedPreferences(mApplicationContext) 912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) .getString(SIGNED_IN_ACCOUNT_KEY, null); 922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) /** 952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * Adds a Listener. 962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @param listener Listener to add. 972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) */ 982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public void addListener(Listener listener) { 992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) mListeners.addObserver(listener); 1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) /** 1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * Removes a Listener. 1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @param listener Listener to remove from the list. 1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) */ 1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public void removeListener(Listener listener) { 1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) mListeners.removeObserver(listener); 1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) /** 1113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) * Registers for Google Cloud Messaging (GCM) if there is no existing registration. 1123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) */ 1133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) public void ensureGcmIsInitialized() { 1143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (mGcmInitialized) return; 1153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) mGcmInitialized = true; 1163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) new AsyncTask<Void, Void, Void>() { 1173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) @Override 1183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) protected Void doInBackground(Void... arg0) { 119f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (CommandLine.getInstance().hasSwitch( 120f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) SyncSwitches.DISABLE_SYNC_GCM_IN_ORDER_TO_TRY_PUSH_API)) { 121f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) Log.w(TAG, "Sync GCM notifications disabled in order to try Push API!"); 122f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return null; 123f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 1243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) try { 1253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) String regId = MultiplexingGcmListener.initializeGcm(mApplicationContext); 1263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (!regId.isEmpty()) 1273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) Log.d(TAG, "Already registered with GCM"); 1283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } catch (IllegalStateException exception) { 1293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) Log.w(TAG, "Application manifest does not correctly configure GCM; " 1303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) + "sync notifications will not work", exception); 1313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } catch (UnsupportedOperationException exception) { 1323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) Log.w(TAG, "Device does not support GCM; sync notifications will not work", 1333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) exception); 1343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 1353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return null; 1363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 1373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); 1383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 140