Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 84185148 authored by Sandeep Siddhartha's avatar Sandeep Siddhartha
Browse files

Add account listing and preference integration for current account

Bug: 17464068
Change-Id: Idb68a6012b285d6bc4632414bb6d11131148cf67
parent 27bb70d6
Loading
Loading
Loading
Loading
+40 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2014 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.inputmethod.latin.utils;

import android.content.Context;

import javax.annotation.Nonnull;

/**
 * Utility class for retrieving accounts that may be used for login.
 */
public class LoginAccountUtils {
    private LoginAccountUtils() {
        // This utility class is not publicly instantiable.
    }

    /**
     * Get the accounts available for login.
     *
     * @return an array of accounts. Empty (never null) if no accounts are available for login.
     */
    @Nonnull
    public static String[] getAccountsForLogin(final Context context) {
        return new String[0];
    }
}
+4 −0
Original line number Diff line number Diff line
@@ -158,5 +158,9 @@
                <action android:name="android.intent.action.MAIN"/>
            </intent-filter>
        </activity>

        <!-- Unexported activity used for tests. -->
        <activity android:name=".settings.TestFragmentActivity"
                android:exported="false" />
    </application>
</manifest>
+8 −2
Original line number Diff line number Diff line
@@ -181,14 +181,20 @@

    <!-- Title of the preference item for switching accounts [CHAR LIMIT=30] -->
    <string name="switch_accounts">Switch accounts</string>

    <!-- Summary of the preference item for switching accounts when no accounts
         are selected [CHAR LIMIT=65] -->
    <string name="no_accounts_selected">No accounts selected</string>

    <!-- Summary of the preference item for switching accounts when an account
         is selected [CHAR LIMIT=65] -->
    <string name="account_selected">Currently using <xliff:g id="EMAIL_ADDRESS" example="someone@example.com">%1$s</xliff:g></string>
    <!-- Positive text for selecting an account -->
    <string name="account_select_ok">OK</string>
    <!-- Negative text for selecting an account -->
    <string name="account_select_cancel">Cancel</string>
    <!-- Text for signing out of an account -->
    <string name="account_select_sign_out">Sign out</string>
    <!-- Title of the account picker dialog for selecting an account [CHAR LIMIT=40] -->
    <string name="account_select_title">Select an account to use</string>

    <!-- Description for English (UK) keyboard subtype [CHAR LIMIT=25]
         (UK) should be an abbreviation of United Kingdom to fit in the CHAR LIMIT. -->
+117 −6
Original line number Diff line number Diff line
@@ -16,25 +16,41 @@

package com.android.inputmethod.latin.settings;

import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.SharedPreferences;
import android.content.res.Resources;
import android.os.Bundle;
import android.preference.Preference;
import android.preference.Preference.OnPreferenceClickListener;
import android.text.TextUtils;
import android.widget.ListView;
import android.widget.Toast;

import com.android.inputmethod.latin.R;
import com.android.inputmethod.latin.SubtypeSwitcher;
import com.android.inputmethod.latin.define.ProductionFlags;
import com.android.inputmethod.latin.utils.LoginAccountUtils;

import javax.annotation.Nullable;

/**
 * "Accounts & Privacy" settings sub screen.
 *
 * This settings sub screen handles the following preferences:
 * - TODO: Account selection/management for IME
 * - TODO: Sync preferences
 * - TODO: Privacy preferences
 * <li> Account selection/management for IME
 * <li> TODO: Sync preferences
 * <li> TODO: Privacy preferences
 */
public final class AccountsSettingsFragment extends SubScreenFragment {
    static final String PREF_ACCCOUNT_SWITCHER = "account_switcher";

    private final DialogInterface.OnClickListener mAccountSelectedListener =
            new AccountSelectedListener();
    private final DialogInterface.OnClickListener mAccountSignedOutListener =
            new AccountSignedOutListener();

    @Override
    public void onCreate(final Bundle icicle) {
        super.onCreate(icicle);
@@ -74,9 +90,104 @@ public final class AccountsSettingsFragment extends SubScreenFragment {
    }

    private void refreshAccountSelection() {
        // TODO: Fetch the currently selected account.
        // Set the summary for the account preference.
        // Depending on the account selection, enable/disable preferences that
        final String currentAccount = getCurrentlySelectedAccount();
        final Preference accountSwitcher = findPreference(PREF_ACCCOUNT_SWITCHER);
        if (currentAccount == null) {
            // No account is currently selected.
            accountSwitcher.setSummary(getString(R.string.no_accounts_selected));
        } else {
            // Set the currently selected account.
            accountSwitcher.setSummary(getString(R.string.account_selected, currentAccount));
        }
        final Context context = getActivity();
        final String[] accountsForLogin = LoginAccountUtils.getAccountsForLogin(context);
        accountSwitcher.setOnPreferenceClickListener(new OnPreferenceClickListener() {
            @Override
            public boolean onPreferenceClick(Preference preference) {
                if (accountsForLogin.length == 0) {
                    // TODO: Handle account addition.
                    Toast.makeText(getActivity(),
                            getString(R.string.account_select_cancel), Toast.LENGTH_SHORT).show();
                } else {
                    createAccountPicker(accountsForLogin, currentAccount).show();
                }
                return true;
            }
        });

        // TODO: Depending on the account selection, enable/disable preferences that
        // depend on an account.
    }

    @Nullable
    private String getCurrentlySelectedAccount() {
        return getSharedPreferences().getString(Settings.PREF_ACCOUNT_NAME, null);
    }

    /**
     * Creates an account picker dialog showing the given accounts in a list and selecting
     * the selected account by default.
     * The list of accounts must not be null/empty.
     *
     * Package-private for testing.
     */
    AlertDialog createAccountPicker(final String[] accounts,
            final String selectedAccount) {
        if (accounts == null || accounts.length == 0) {
            throw new IllegalArgumentException("List of accounts must not be empty");
        }

        // See if the currently selected account is in the list.
        // If it is, the entry is selected, and a sign-out button is provided.
        // If it isn't, select the 0th account by default which will get picked up
        // if the user presses OK.
        int index = 0;
        boolean isSignedIn = false;
        for (int i = 0;  i < accounts.length; i++) {
            if (TextUtils.equals(accounts[i], selectedAccount)) {
                index = i;
                isSignedIn = true;
                break;
            }
        }
        final AlertDialog.Builder builder = new AlertDialog.Builder(getActivity())
                .setTitle(R.string.account_select_title)
                .setSingleChoiceItems(accounts, index, null)
                .setPositiveButton(R.string.account_select_ok, mAccountSelectedListener)
                .setNegativeButton(R.string.account_select_cancel, null);
        if (isSignedIn) {
            builder.setNeutralButton(R.string.account_select_sign_out, mAccountSignedOutListener);
        }
        return builder.create();
    }

    /**
     * Listener for an account being selected from the picker.
     * Persists the account to shared preferences.
     */
    class AccountSelectedListener implements DialogInterface.OnClickListener {
        @Override
        public void onClick(DialogInterface dialog, int which) {
            final ListView lv = ((AlertDialog)dialog).getListView();
            final Object selectedItem = lv.getItemAtPosition(lv.getCheckedItemPosition());
            getSharedPreferences()
                    .edit()
                    .putString(Settings.PREF_ACCOUNT_NAME, (String) selectedItem)
                    .apply();
        }
    }

    /**
     * Listener for sign-out being initiated from from the picker.
     * Removed the account from shared preferences.
     */
    class AccountSignedOutListener implements DialogInterface.OnClickListener {
        @Override
        public void onClick(DialogInterface dialog, int which) {
            getSharedPreferences()
                    .edit()
                    .remove(Settings.PREF_ACCOUNT_NAME)
                    .apply();
        }
    }
}
+55 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2014 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.inputmethod.latin.settings;

import android.app.Activity;
import android.app.Fragment;
import android.app.FragmentManager;
import android.content.Intent;
import android.os.Bundle;

/**
 * Test activity to use when testing preference fragments. <br/>
 * Usage: <br/>
 * Create an ActivityInstrumentationTestCase2 for this activity
 * and call setIntent() with an intent that specifies the fragment to load in the activity.
 * The fragment can then be obtained from this activity and used for testing/verification.
 */
public final class TestFragmentActivity extends Activity {
    /**
     * The fragment name that should be loaded when starting this activity.
     * This must be specified when starting this activity, as this activity is only
     * meant to test fragments from instrumentation tests.
     */
    public static final String EXTRA_SHOW_FRAGMENT = "show_fragment";

    public Fragment mFragment;

    @Override
    protected void onCreate(final Bundle savedState) {
        super.onCreate(savedState);
        final Intent intent = getIntent();
        final String fragmentName = intent.getStringExtra(EXTRA_SHOW_FRAGMENT);
        if (fragmentName == null) {
            throw new IllegalArgumentException("No fragment name specified for testing");
        }

        mFragment = Fragment.instantiate(this, fragmentName);
        FragmentManager fragmentManager = getFragmentManager();
        fragmentManager.beginTransaction().add(mFragment, fragmentName).commit();
    }
}
Loading