• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.common.annotations.VisibleForTesting;
14 import com.google.ipc.invalidation.external.client.contrib.MultiplexingGcmListener;
15 
16 import org.chromium.base.CommandLine;
17 import org.chromium.base.ObserverList;
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          */
onClearSignedInUser()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 
ChromeSigninController(Context context)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      */
get(Context context)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 
getSignedInUser()62     public Account getSignedInUser() {
63         String syncAccountName = getSignedInAccountName();
64         if (syncAccountName == null) {
65             return null;
66         }
67         return AccountManagerHelper.createAccountFromName(syncAccountName);
68     }
69 
isSignedIn()70     public boolean isSignedIn() {
71         return getSignedInAccountName() != null;
72     }
73 
setSignedInAccountName(String accountName)74     public void setSignedInAccountName(String accountName) {
75         PreferenceManager.getDefaultSharedPreferences(mApplicationContext).edit()
76                 .putString(SIGNED_IN_ACCOUNT_KEY, accountName)
77                 .apply();
78     }
79 
clearSignedInUser()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 
getSignedInAccountName()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      */
addListener(Listener listener)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      */
removeListener(Listener listener)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      */
ensureGcmIsInitialized()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