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

Commit e6cff549 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Password settings: Fix work profile" into sc-dev

parents 235006fc d4ce558f
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@
        android:persistent="false"
        android:title="@string/autofill_passwords"
        settings:controller="com.android.settings.applications.autofill.PasswordsPreferenceController"
        settings:forWork="true"
        settings:keywords="@string/autofill_keywords" />

    <com.android.settings.widget.WorkOnlyCategory
+31 −18
Original line number Diff line number Diff line
@@ -55,6 +55,7 @@ import com.android.settings.core.BasePreferenceController;
import com.android.settingslib.widget.AppPreference;

import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;

@@ -76,28 +77,30 @@ public class PasswordsPreferenceController extends BasePreferenceController
    private LifecycleOwner mLifecycleOwner;

    public PasswordsPreferenceController(Context context, String preferenceKey) {
        this(context, preferenceKey,
                AutofillServiceInfo.getAvailableServices(context, UserHandle.myUserId()));
    }

    @VisibleForTesting
    public PasswordsPreferenceController(
            Context context, String preferenceKey, List<AutofillServiceInfo> availableServices) {
        super(context, preferenceKey);
        mPm = context.getPackageManager();
        mIconFactory = IconDrawableFactory.newInstance(mContext);
        mServices = new ArrayList<>();
    }

    @OnLifecycleEvent(ON_CREATE)
    void onCreate(LifecycleOwner lifecycleOwner) {
        init(lifecycleOwner, AutofillServiceInfo.getAvailableServices(mContext, getUser()));
    }

    @VisibleForTesting
    void init(LifecycleOwner lifecycleOwner, List<AutofillServiceInfo> availableServices) {
        mLifecycleOwner = lifecycleOwner;

        for (int i = availableServices.size() - 1; i >= 0; i--) {
            final String passwordsActivity = availableServices.get(i).getPasswordsActivity();
            if (TextUtils.isEmpty(passwordsActivity)) {
                availableServices.remove(i);
            }
        }
        mServices = availableServices;
    }

    @OnLifecycleEvent(ON_CREATE)
    void onCreate(LifecycleOwner lifecycleOwner) {
        mLifecycleOwner = lifecycleOwner;
        // TODO: Reverse the loop above and add to mServices directly.
        mServices.clear();
        mServices.addAll(availableServices);
    }

    @Override
@@ -109,8 +112,7 @@ public class PasswordsPreferenceController extends BasePreferenceController
    public void displayPreference(PreferenceScreen screen) {
        super.displayPreference(screen);
        final PreferenceGroup group = screen.findPreference(getPreferenceKey());
        // TODO(b/169455298): Show work profile passwords too.
        addPasswordPreferences(screen.getContext(), UserHandle.myUserId(), group);
        addPasswordPreferences(screen.getContext(), getUser(), group);
    }

    private void addPasswordPreferences(
@@ -126,9 +128,15 @@ public class PasswordsPreferenceController extends BasePreferenceController
                            serviceInfo.applicationInfo,
                            user);
            pref.setIcon(Utils.getSafeIcon(icon));
            pref.setIntent(
            pref.setOnPreferenceClickListener(p -> {
                final Intent intent =
                        new Intent(Intent.ACTION_MAIN)
                            .setClassName(serviceInfo.packageName, service.getPasswordsActivity()));
                                .setClassName(
                                        serviceInfo.packageName,
                                        service.getPasswordsActivity());
                prefContext.startActivityAsUser(intent, UserHandle.of(user));
                return true;
            });
            // Set an empty summary to avoid a UI flicker when the value loads.
            pref.setSummary(R.string.summary_placeholder);

@@ -213,4 +221,9 @@ public class PasswordsPreferenceController extends BasePreferenceController
            }
        }
    }

    private int getUser() {
        UserHandle workUser = getWorkProfileUser();
        return workUser != null ? workUser.getIdentifier() : UserHandle.myUserId();
    }
}
+31 −7
Original line number Diff line number Diff line
@@ -21,11 +21,19 @@ import static com.android.settings.core.BasePreferenceController.CONDITIONALLY_U

import static com.google.common.truth.Truth.assertThat;

import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;

import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.os.Looper;
import android.os.UserHandle;
import android.service.autofill.AutofillServiceInfo;

import androidx.lifecycle.Lifecycle;
@@ -40,9 +48,9 @@ import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.google.android.collect.Lists;

import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;

import java.util.Collections;
import java.util.List;
@@ -56,7 +64,7 @@ public class PasswordsPreferenceControllerTest {

    @Before
    public void setUp() {
        mContext = ApplicationProvider.getApplicationContext();
        mContext = spy(ApplicationProvider.getApplicationContext());
        if (Looper.myLooper() == null) {
            Looper.prepare(); // needed to create the preference screen
        }
@@ -66,6 +74,15 @@ public class PasswordsPreferenceControllerTest {
        mScreen.addPreference(mPasswordsPreferenceCategory);
    }

    @Test
    // Tests that getAvailabilityStatus() does not throw an exception if it's called before the
    // Controller is initialized (this can happen during indexing).
    public void getAvailabilityStatus_withoutInit_returnsUnavailable() {
        PasswordsPreferenceController controller =
                new PasswordsPreferenceController(mContext, mPasswordsPreferenceCategory.getKey());
        assertThat(controller.getAvailabilityStatus()).isEqualTo(CONDITIONALLY_UNAVAILABLE);
    }

    @Test
    public void getAvailabilityStatus_noServices_returnsUnavailable() {
        PasswordsPreferenceController controller =
@@ -105,21 +122,26 @@ public class PasswordsPreferenceControllerTest {
        assertThat(mPasswordsPreferenceCategory.getPreferenceCount()).isEqualTo(0);
    }

    @Ignore("TODO: Fix the test to handle the service binding.")
    @Test
    @UiThreadTest
    public void displayPreference_withPasswords_addsPreference() {
        AutofillServiceInfo service = createServiceWithPasswords();
        service.getServiceInfo().packageName = "";
        service.getServiceInfo().name = "";
        PasswordsPreferenceController controller =
                createControllerWithServices(Lists.newArrayList(service));
        controller.onCreate(() -> mock(Lifecycle.class));
        doReturn(false).when(mContext).bindServiceAsUser(any(), any(), anyInt(), any());

        controller.displayPreference(mScreen);

        assertThat(mPasswordsPreferenceCategory.getPreferenceCount()).isEqualTo(1);
        Preference pref = mPasswordsPreferenceCategory.getPreference(0);
        assertThat(pref.getIcon()).isNotNull();
        assertThat(pref.getIntent().getComponent())
        pref.performClick();
        ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
        UserHandle user = mContext.getUser();
        verify(mContext).startActivityAsUser(intentCaptor.capture(), eq(user));
        assertThat(intentCaptor.getValue().getComponent())
                .isEqualTo(
                        new ComponentName(
                                service.getServiceInfo().packageName,
@@ -128,8 +150,10 @@ public class PasswordsPreferenceControllerTest {

    private PasswordsPreferenceController createControllerWithServices(
            List<AutofillServiceInfo> availableServices) {
        return new PasswordsPreferenceController(
                mContext, mPasswordsPreferenceCategory.getKey(), availableServices);
        PasswordsPreferenceController controller =
                new PasswordsPreferenceController(mContext, mPasswordsPreferenceCategory.getKey());
        controller.init(() -> mock(Lifecycle.class), availableServices);
        return controller;
    }

    private AutofillServiceInfo createServiceWithPasswords() {