Home | History | Annotate | Download | only in signin
      1 // Copyright 2013 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 package org.chromium.sync.signin;
      6 
      7 import android.accounts.Account;
      8 import android.content.Context;
      9 import android.os.AsyncTask;
     10 import android.preference.PreferenceManager;
     11 import android.util.Log;
     12 
     13 import com.google.ipc.invalidation.external.client.contrib.MultiplexingGcmListener;
     14 
     15 import org.chromium.base.CommandLine;
     16 import org.chromium.base.ObserverList;
     17 import org.chromium.base.VisibleForTesting;
     18 import org.chromium.sync.SyncSwitches;
     19 
     20 public class ChromeSigninController {
     21     public interface Listener {
     22         /**
     23          * Called when the user signs out of Chrome.
     24          */
     25         void onClearSignedInUser();
     26     }
     27 
     28     public static final String TAG = "ChromeSigninController";
     29 
     30     @VisibleForTesting
     31     public static final String SIGNED_IN_ACCOUNT_KEY = "google.services.username";
     32 
     33     private static final Object LOCK = new Object();
     34 
     35     private static ChromeSigninController sChromeSigninController;
     36 
     37     private final Context mApplicationContext;
     38 
     39     private final ObserverList<Listener> mListeners = new ObserverList<Listener>();
     40 
     41     private boolean mGcmInitialized;
     42 
     43     private ChromeSigninController(Context context) {
     44         mApplicationContext = context.getApplicationContext();
     45     }
     46 
     47     /**
     48      * A factory method for the ChromeSigninController.
     49      *
     50      * @param context the ApplicationContext is retrieved from the context used as an argument.
     51      * @return a singleton instance of the ChromeSigninController
     52      */
     53     public static ChromeSigninController get(Context context) {
     54         synchronized (LOCK) {
     55             if (sChromeSigninController == null) {
     56                 sChromeSigninController = new ChromeSigninController(context);
     57             }
     58         }
     59         return sChromeSigninController;
     60     }
     61 
     62     public Account getSignedInUser() {
     63         String syncAccountName = getSignedInAccountName();
     64         if (syncAccountName == null) {
     65             return null;
     66         }
     67         return AccountManagerHelper.createAccountFromName(syncAccountName);
     68     }
     69 
     70     public boolean isSignedIn() {
     71         return getSignedInAccountName() != null;
     72     }
     73 
     74     public void setSignedInAccountName(String accountName) {
     75         PreferenceManager.getDefaultSharedPreferences(mApplicationContext).edit()
     76                 .putString(SIGNED_IN_ACCOUNT_KEY, accountName)
     77                 .apply();
     78     }
     79 
     80     public void clearSignedInUser() {
     81         Log.d(TAG, "Clearing user signed in to Chrome");
     82         setSignedInAccountName(null);
     83 
     84         for (Listener listener : mListeners) {
     85             listener.onClearSignedInUser();
     86         }
     87     }
     88 
     89     public String getSignedInAccountName() {
     90         return PreferenceManager.getDefaultSharedPreferences(mApplicationContext)
     91                 .getString(SIGNED_IN_ACCOUNT_KEY, null);
     92     }
     93 
     94     /**
     95      * Adds a Listener.
     96      * @param listener Listener to add.
     97      */
     98     public void addListener(Listener listener) {
     99         mListeners.addObserver(listener);
    100     }
    101 
    102     /**
    103      * Removes a Listener.
    104      * @param listener Listener to remove from the list.
    105      */
    106     public void removeListener(Listener listener) {
    107         mListeners.removeObserver(listener);
    108     }
    109 
    110     /**
    111      * Registers for Google Cloud Messaging (GCM) if there is no existing registration.
    112      */
    113     public void ensureGcmIsInitialized() {
    114         if (mGcmInitialized) return;
    115         mGcmInitialized = true;
    116         new AsyncTask<Void, Void, Void>() {
    117             @Override
    118             protected Void doInBackground(Void... arg0) {
    119                 if (CommandLine.getInstance().hasSwitch(
    120                         SyncSwitches.DISABLE_SYNC_GCM_IN_ORDER_TO_TRY_PUSH_API)) {
    121                     Log.w(TAG, "Sync GCM notifications disabled in order to try Push API!");
    122                     return null;
    123                 }
    124                 try {
    125                     String regId = MultiplexingGcmListener.initializeGcm(mApplicationContext);
    126                     if (!regId.isEmpty())
    127                         Log.d(TAG, "Already registered with GCM");
    128                 } catch (IllegalStateException exception) {
    129                     Log.w(TAG, "Application manifest does not correctly configure GCM; "
    130                             + "sync notifications will not work", exception);
    131                 } catch (UnsupportedOperationException exception) {
    132                     Log.w(TAG, "Device does not support GCM; sync notifications will not work",
    133                             exception);
    134                 }
    135                 return null;
    136             }
    137         }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
    138     }
    139 }
    140