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

Commit bff393ce authored by Dan Zivkovic's avatar Dan Zivkovic
Browse files

Fix NPE in AccountSettingsFragment.

Bug 19773815.

Change-Id: Ib5eb27cdf385c81d1a3822836f424fa29c0bbaa8
parent 52dafe8c
Loading
Loading
Loading
Loading
+30 −13
Original line number Diff line number Diff line
@@ -119,24 +119,34 @@ public final class AccountsSettingsFragment extends SubScreenFragment {
            removeSyncPreferences();
        } else {
            disableSyncPreferences();
            final AsyncTask<Void, Void, Void> checkManagedProfileTask =
                    new AsyncTask<Void, Void, Void>() {
            new ManagedProfileCheckerTask(this).execute();
        }
    }

    private static class ManagedProfileCheckerTask extends AsyncTask<Void, Void, Void> {
        private final AccountsSettingsFragment mFragment;

        private ManagedProfileCheckerTask(final AccountsSettingsFragment fragment) {
            mFragment = fragment;
        }

        @Override
        protected Void doInBackground(Void... params) {
                            if (ManagedProfileUtils.hasManagedWorkProfile(getActivity())) {
                                removeSyncPreferences();
            if (ManagedProfileUtils.getInstance().hasManagedWorkProfile(mFragment.getActivity())) {
                mFragment.removeSyncPreferences();
            } else {
                                enableSyncPreferences();
                mFragment.enableSyncPreferences();
            }
            return null;
        }
                    };
            checkManagedProfileTask.execute();
        }
    }

    private void enableSyncPreferences() {
        mAccountSwitcher = findPreference(PREF_ACCCOUNT_SWITCHER);
        if (mAccountSwitcher == null) {
            // Preference has been removed because the device has a managed profile.
            return;
        }
        mAccountSwitcher.setEnabled(true);

        mEnableSyncPreference = (TwoStatePreference) findPreference(PREF_ENABLE_SYNC_NOW);
@@ -154,6 +164,10 @@ public final class AccountsSettingsFragment extends SubScreenFragment {

    private void disableSyncPreferences() {
        mAccountSwitcher = findPreference(PREF_ACCCOUNT_SWITCHER);
        if (mAccountSwitcher == null) {
            // Preference has been removed because the device has a managed profile.
            return;
        }
        mAccountSwitcher.setEnabled(false);

        mEnableSyncPreference = (TwoStatePreference) findPreference(PREF_ENABLE_SYNC_NOW);
@@ -211,6 +225,9 @@ public final class AccountsSettingsFragment extends SubScreenFragment {

        if (accountsForLogin.length > 0) {
            enableSyncPreferences();
            if (mAccountSwitcher == null) {
                return;
            }
            mAccountSwitcher.setOnPreferenceClickListener(new OnPreferenceClickListener() {
                @Override
                public boolean onPreferenceClick(final Preference preference) {
+15 −1
Original line number Diff line number Diff line
@@ -23,6 +23,8 @@ import android.os.UserHandle;
import android.os.UserManager;
import android.util.Log;

import com.android.inputmethod.annotations.UsedForTesting;

import java.util.List;

/**
@@ -32,16 +34,28 @@ public class ManagedProfileUtils {
    private static final boolean DEBUG = false;
    private static final String TAG = ManagedProfileUtils.class.getSimpleName();

    private static ManagedProfileUtils INSTANCE = new ManagedProfileUtils();
    private static ManagedProfileUtils sTestInstance;

    private ManagedProfileUtils() {
        // This utility class is not publicly instantiable.
    }

    @UsedForTesting
    public static void setTestInstance(final ManagedProfileUtils testInstance) {
        sTestInstance = testInstance;
    }

    public static ManagedProfileUtils getInstance() {
        return sTestInstance == null ? INSTANCE : sTestInstance;
    }

    /**
     * Note that {@link UserManager#getUserProfiles} has been introduced
     * in API level 21 (Build.VERSION_CODES.LOLLIPOP).
     */
    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    public static boolean hasManagedWorkProfile(final Context context) {
    public boolean hasManagedWorkProfile(final Context context) {
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
            return false;
        }
+62 −39
Original line number Diff line number Diff line
@@ -16,7 +16,12 @@

package com.android.inputmethod.latin.settings;

import static org.mockito.Matchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.test.ActivityInstrumentationTestCase2;
@@ -24,6 +29,11 @@ import android.test.suitebuilder.annotation.MediumTest;
import android.view.View;
import android.widget.ListView;

import com.android.inputmethod.latin.utils.ManagedProfileUtils;

import org.mockito.Mock;
import org.mockito.MockitoAnnotations;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

@@ -33,6 +43,8 @@ public class AccountsSettingsFragmentTests
    private static final String FRAG_NAME = AccountsSettingsFragment.class.getName();
    private static final long TEST_TIMEOUT_MILLIS = 5000;

    @Mock private ManagedProfileUtils mManagedProfileUtils;

    public AccountsSettingsFragmentTests() {
        super(TestFragmentActivity.class);
    }
@@ -40,11 +52,22 @@ public class AccountsSettingsFragmentTests
    @Override
    protected void setUp() throws Exception {
        super.setUp();

        // Initialize the mocks.
        MockitoAnnotations.initMocks(this);
        ManagedProfileUtils.setTestInstance(mManagedProfileUtils);

        Intent intent = new Intent();
        intent.putExtra(TestFragmentActivity.EXTRA_SHOW_FRAGMENT, FRAG_NAME);
        setActivityIntent(intent);
    }

    @Override
    public void tearDown() throws Exception {
        ManagedProfileUtils.setTestInstance(null);
        super.tearDown();
    }

    public void testEmptyAccounts() {
        final AccountsSettingsFragment fragment =
                (AccountsSettingsFragment) getActivity().mFragment;
@@ -61,36 +84,26 @@ public class AccountsSettingsFragmentTests
        DialogHolder() {}
    }

    public void testMultipleAccounts_noCurrentAccount() {
    public void testMultipleAccounts_noSettingsForManagedProfile() {
        when(mManagedProfileUtils.hasManagedWorkProfile(any(Context.class))).thenReturn(true);

        final AccountsSettingsFragment fragment =
                (AccountsSettingsFragment) getActivity().mFragment;
        final DialogHolder dialogHolder = new DialogHolder();
        final CountDownLatch latch = new CountDownLatch(1);
        final AlertDialog dialog = initDialog(fragment, null).mDialog;
        final ListView lv = dialog.getListView();

        getActivity().runOnUiThread(new Runnable() {
            @Override
            public void run() {
                final AlertDialog dialog = fragment.createAccountPicker(
                        new String[] {
                                "1@example.com",
                                "2@example.com",
                                "3@example.com",
                                "4@example.com"},
                        null, null /* positiveButtonListner */);
                dialog.show();
                dialogHolder.mDialog = dialog;
                latch.countDown();
        // Nothing to check/uncheck.
        assertNull(fragment.findPreference(AccountsSettingsFragment.PREF_ACCCOUNT_SWITCHER));
    }
        });

        try {
            latch.await(TEST_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS);
        } catch (InterruptedException ex) {
            fail();
        }
        getInstrumentation().waitForIdleSync();
        final AlertDialog dialog = dialogHolder.mDialog;
    public void testMultipleAccounts_noCurrentAccount() {
        when(mManagedProfileUtils.hasManagedWorkProfile(any(Context.class))).thenReturn(false);

        final AccountsSettingsFragment fragment =
                (AccountsSettingsFragment) getActivity().mFragment;
        final AlertDialog dialog = initDialog(fragment, null).mDialog;
        final ListView lv = dialog.getListView();

        // The 1st account should be checked by default.
        assertEquals("checked-item", 0, lv.getCheckedItemPosition());
        // There should be 4 accounts in the list.
@@ -105,10 +118,32 @@ public class AccountsSettingsFragmentTests
    }

    public void testMultipleAccounts_currentAccount() {
        when(mManagedProfileUtils.hasManagedWorkProfile(any(Context.class))).thenReturn(false);

        final AccountsSettingsFragment fragment =
                (AccountsSettingsFragment) getActivity().mFragment;
        final AlertDialog dialog = initDialog(fragment, "3@example.com").mDialog;
        final ListView lv = dialog.getListView();

        // The 3rd account should be checked by default.
        assertEquals("checked-item", 2, lv.getCheckedItemPosition());
        // There should be 4 accounts in the list.
        assertEquals("count", 4, lv.getCount());
        // The sign-out button should be shown
        assertEquals(View.VISIBLE,
                dialog.getButton(DialogInterface.BUTTON_NEUTRAL).getVisibility());
        assertEquals(View.VISIBLE,
                dialog.getButton(DialogInterface.BUTTON_NEGATIVE).getVisibility());
        assertEquals(View.VISIBLE,
                dialog.getButton(DialogInterface.BUTTON_POSITIVE).getVisibility());
    }

    private DialogHolder initDialog(
            final AccountsSettingsFragment fragment,
            final String selectedAccount) {
        final DialogHolder dialogHolder = new DialogHolder();
        final CountDownLatch latch = new CountDownLatch(1);

        getActivity().runOnUiThread(new Runnable() {
            @Override
            public void run() {
@@ -118,7 +153,7 @@ public class AccountsSettingsFragmentTests
                                "2@example.com",
                                "3@example.com",
                                "4@example.com"},
                        "3@example.com", null /* positiveButtonListner */);
                        selectedAccount, null /* positiveButtonListner */);
                dialog.show();
                dialogHolder.mDialog = dialog;
                latch.countDown();
@@ -131,18 +166,6 @@ public class AccountsSettingsFragmentTests
            fail();
        }
        getInstrumentation().waitForIdleSync();
        final AlertDialog dialog = dialogHolder.mDialog;
        final ListView lv = dialog.getListView();
        // The 3rd account should be checked by default.
        assertEquals("checked-item", 2, lv.getCheckedItemPosition());
        // There should be 4 accounts in the list.
        assertEquals("count", 4, lv.getCount());
        // The sign-out button should be shown
        assertEquals(View.VISIBLE,
                dialog.getButton(DialogInterface.BUTTON_NEUTRAL).getVisibility());
        assertEquals(View.VISIBLE,
                dialog.getButton(DialogInterface.BUTTON_NEGATIVE).getVisibility());
        assertEquals(View.VISIBLE,
                dialog.getButton(DialogInterface.BUTTON_POSITIVE).getVisibility());
        return dialogHolder;
    }
}