Merge "Password settings: Fix work profile" into sc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
e6cff5497d
@@ -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
|
||||
|
@@ -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(
|
||||
new Intent(Intent.ACTION_MAIN)
|
||||
.setClassName(serviceInfo.packageName, service.getPasswordsActivity()));
|
||||
pref.setOnPreferenceClickListener(p -> {
|
||||
final Intent intent =
|
||||
new Intent(Intent.ACTION_MAIN)
|
||||
.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();
|
||||
}
|
||||
}
|
||||
|
@@ -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() {
|
||||
|
Reference in New Issue
Block a user