summaryrefslogtreecommitdiffstats
path: root/src/com/android/contacts/util/AccountPromptUtils.java
blob: cdefda0b794c5e0f2545115b943e8141ac3c52b5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
/*
 * Copyright (C) 2011 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.contacts.util;

import android.accounts.AccountManager;
import android.accounts.AccountManagerCallback;
import android.accounts.AccountManagerFuture;
import android.accounts.AuthenticatorDescription;
import android.accounts.AuthenticatorException;
import android.accounts.OperationCanceledException;
import android.app.Activity;
import android.content.Context;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.util.Log;

import com.android.contacts.R;
import com.android.contacts.model.account.GoogleAccountType;

import java.io.IOException;

/**
 * Utility class for controlling whether the standard "no account" prompt on launch is shown.
 */
public class AccountPromptUtils {

    private static final String TAG = AccountPromptUtils.class.getSimpleName();

    /** {@link SharedPreferences} key for whether or not the "no account" prompt should be shown. */
    private static final String KEY_SHOW_ACCOUNT_PROMPT = "settings.showAccountPrompt";

    /**
     * The following intent keys are understood by the {@link AccountManager} and should not be
     * changed unless the API changes.
     */
    private static final String KEY_INTRO_MESSAGE = "introMessage";
    private static final String KEY_ALLOW_SKIP_ACCOUNT_SETUP = "allowSkip";
    private static final String KEY_USER_SKIPPED_ACCOUNT_SETUP = "setupSkipped";

    private static SharedPreferences getSharedPreferences(Context context) {
        return PreferenceManager.getDefaultSharedPreferences(context);
    }

    /**
     * Returns true if the "no account" prompt should be shown
     * (according to {@link SharedPreferences}), otherwise return false. Since this prompt is
     * Google-specific for the time being, this method will also return false if the Google
     * account type is not available from the {@link AccountManager}.
     */
    public static boolean shouldShowAccountPrompt(Context context) {
        // TODO: Remove the filtering of account types once there is an API in
        // {@link AccountManager} to show a similar account prompt
        // (see {@link AccountManager#addAccount()} in {@link #launchAccountPrompt()}
        // for any type of account. Bug: 5375902
        AuthenticatorDescription[] allTypes =
                AccountManager.get(context).getAuthenticatorTypes();
        for (AuthenticatorDescription authenticatorType : allTypes) {
            if (GoogleAccountType.ACCOUNT_TYPE.equals(authenticatorType.type)) {
                return getSharedPreferences(context).getBoolean(KEY_SHOW_ACCOUNT_PROMPT, true);
            }
        }
        return false;
    }

    /**
     * Remember to never show the "no account" prompt again by saving this to
     * {@link SharedPreferences}.
     */
    public static void neverShowAccountPromptAgain(Context context) {
        getSharedPreferences(context).edit()
                .putBoolean(KEY_SHOW_ACCOUNT_PROMPT, false)
                .apply();
    }

    /**
     * Launch the "no account" prompt. (We assume the caller has already verified that the prompt
     * can be shown, so checking the {@link #KEY_SHOW_ACCOUNT_PROMPT} value in
     * {@link SharedPreferences} will not be done in this method).
     */
    public static void launchAccountPrompt(Activity activity) {
        Bundle options = new Bundle();
        options.putCharSequence(KEY_INTRO_MESSAGE, activity.getString(R.string.no_account_prompt));
        options.putBoolean(KEY_ALLOW_SKIP_ACCOUNT_SETUP, true);
        AccountManager.get(activity).addAccount(GoogleAccountType.ACCOUNT_TYPE, null, null, options,
                activity, getAccountManagerCallback(activity), null);
    }

    private static AccountManagerCallback<Bundle> getAccountManagerCallback(
            final Activity activity) {
        return new AccountManagerCallback<Bundle>() {
            @Override
            public void run(AccountManagerFuture<Bundle> future) {
                if (future.isCancelled()) {
                    // The account creation process was canceled
                    activity.finish();
                    return;
                }
                try {
                    Bundle result = future.getResult();
                    if (result.getBoolean(KEY_USER_SKIPPED_ACCOUNT_SETUP)) {
                        AccountPromptUtils.neverShowAccountPromptAgain(activity);
                    }
                } catch (OperationCanceledException ignore) {
                    Log.e(TAG, "Account setup error: account creation process canceled");
                } catch (IOException ignore) {
                    Log.e(TAG, "Account setup error: No authenticator was registered for this"
                            + "account type or the authenticator failed to respond");
                } catch (AuthenticatorException ignore) {
                    Log.e(TAG, "Account setup error: Authenticator experienced an I/O problem");
                }
            }
        };
    }
}