Show Default app shortcut preference only when app is qualified.

This change uses the new isApplicationQualifiedForRole() API on
PermissionControllerManager to correctly report availability of
default app shortcut preference.

Bug: 110557011
Bug: 123238935
Test: atest DefaultAppShortcutPreferenceControllerBaseTest DefaultSmsShortcutPreferenceControllerTest
Change-Id: Ib86ab0fd84334a149f7c6c3556297745f2990f47
This commit is contained in:
Hai Zhang
2019-01-23 16:51:40 -08:00
parent d3c02d87f9
commit 3850908671
3 changed files with 87 additions and 10 deletions

View File

@@ -20,9 +20,11 @@ import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.UserManager;
import android.permission.PermissionControllerManager;
import android.text.TextUtils;
import androidx.preference.Preference;
import androidx.preference.PreferenceScreen;
import com.android.internal.util.CollectionUtils;
import com.android.settings.R;
@@ -43,6 +45,10 @@ public abstract class DefaultAppShortcutPreferenceControllerBase extends BasePre
private final RoleManager mRoleManager;
private boolean mAppQualified;
private PreferenceScreen mPreferenceScreen;
public DefaultAppShortcutPreferenceControllerBase(Context context, String preferenceKey,
String roleName, String packageName) {
super(context, preferenceKey);
@@ -51,6 +57,17 @@ public abstract class DefaultAppShortcutPreferenceControllerBase extends BasePre
mPackageName = packageName;
mRoleManager = context.getSystemService(RoleManager.class);
// TODO: STOPSHIP(b/110557011): Remove this check once we have all default apps migrated.
if (mRoleName != null) {
final PermissionControllerManager permissionControllerManager =
mContext.getSystemService(PermissionControllerManager.class);
permissionControllerManager.isApplicationQualifiedForRole(mRoleName, mPackageName,
mContext.getMainExecutor(), qualified -> {
mAppQualified = qualified;
refreshAvailability();
});
}
}
// TODO: STOPSHIP(b/110557011): Remove this once we have all default apps migrated.
@@ -59,6 +76,23 @@ public abstract class DefaultAppShortcutPreferenceControllerBase extends BasePre
this(context, preferenceKey, null /* roleName */, packageName);
}
@Override
public void displayPreference(PreferenceScreen screen) {
super.displayPreference(screen);
mPreferenceScreen = screen;
}
private void refreshAvailability() {
if (mPreferenceScreen != null) {
final Preference preference = mPreferenceScreen.findPreference(getPreferenceKey());
if (preference != null) {
preference.setVisible(isAvailable());
updateState(preference);
}
}
}
@Override
public int getAvailabilityStatus() {
if (mContext.getSystemService(UserManager.class).isManagedProfile()) {
@@ -104,7 +138,7 @@ public abstract class DefaultAppShortcutPreferenceControllerBase extends BasePre
protected boolean hasAppCapability() {
// TODO: STOPSHIP(b/110557011): Remove this check once we have all default apps migrated.
if (mRoleName != null) {
return mRoleManager.isRoleAvailable(mRoleName);
return mAppQualified;
}
return false;
}

View File

@@ -18,6 +18,7 @@ package com.android.settings.applications.appinfo;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -28,6 +29,7 @@ import android.app.role.RoleManager;
import android.content.Context;
import android.content.Intent;
import android.os.UserManager;
import android.permission.PermissionControllerManager;
import androidx.preference.Preference;
@@ -38,6 +40,7 @@ import com.android.settings.applications.DefaultAppSettings;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.Robolectric;
@@ -48,6 +51,8 @@ import org.robolectric.shadows.ShadowApplication;
import org.robolectric.shadows.ShadowUserManager;
import java.util.Collections;
import java.util.concurrent.Executor;
import java.util.function.Consumer;
@RunWith(RobolectricTestRunner.class)
@Config(shadows = ShadowUserManager.class)
@@ -60,6 +65,8 @@ public class DefaultAppShortcutPreferenceControllerBaseTest {
@Mock
private RoleManager mRoleManager;
@Mock
private PermissionControllerManager mPermissionControllerManager;
@Mock
private Preference mPreference;
private Activity mActivity;
@@ -71,7 +78,10 @@ public class DefaultAppShortcutPreferenceControllerBaseTest {
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
ShadowApplication.getInstance().setSystemService(Context.ROLE_SERVICE, mRoleManager);
ShadowApplication shadowApplication = ShadowApplication.getInstance();
shadowApplication.setSystemService(Context.ROLE_SERVICE, mRoleManager);
shadowApplication.setSystemService(Context.PERMISSION_CONTROLLER_SERVICE,
mPermissionControllerManager);
mActivity = Robolectric.setupActivity(Activity.class);
mShadowUserManager = shadowOf(mActivity.getSystemService(UserManager.class));
mController = new TestRolePreferenceController(mActivity);
@@ -79,6 +89,12 @@ public class DefaultAppShortcutPreferenceControllerBaseTest {
mLegacyController = new TestLegacyPreferenceController(mActivity);
}
@Test
public void constructor_callsIsApplicationQualifiedForRole() {
verify(mPermissionControllerManager).isApplicationQualifiedForRole(eq(TEST_ROLE_NAME), eq(
TEST_PACKAGE_NAME), any(Executor.class), any(Consumer.class));
}
@Test
public void getAvailabilityStatus_isManagedProfile_shouldReturnDisabled() {
mShadowUserManager.setManagedProfile(true);
@@ -88,23 +104,38 @@ public class DefaultAppShortcutPreferenceControllerBaseTest {
}
@Test
public void getAvailabilityStatus_roleIsAvailable_shouldReturnAvailable() {
mShadowUserManager.setManagedProfile(false);
when(mRoleManager.isRoleAvailable(eq(TEST_ROLE_NAME))).thenReturn(true);
public void
getAvailabilityStatus_noCallbackForIsApplicationNotQualifiedForRole_shouldReturnUnsupported() {
assertThat(mController.getAvailabilityStatus()).isEqualTo(
DefaultAppShortcutPreferenceControllerBase.AVAILABLE);
DefaultAppShortcutPreferenceControllerBase.UNSUPPORTED_ON_DEVICE);
}
@Test
public void getAvailabilityStatus_roleNotAvailable_shouldReturnDisabled() {
mShadowUserManager.setManagedProfile(false);
when(mRoleManager.isRoleAvailable(eq(TEST_ROLE_NAME))).thenReturn(false);
public void getAvailabilityStatus_applicationIsNotQualifiedForRole_shouldReturnUnsupported() {
final ArgumentCaptor<Consumer<Boolean>> callbackCaptor = ArgumentCaptor.forClass(
Consumer.class);
verify(mPermissionControllerManager).isApplicationQualifiedForRole(eq(TEST_ROLE_NAME), eq(
TEST_PACKAGE_NAME), any(Executor.class), callbackCaptor.capture());
final Consumer<Boolean> callback = callbackCaptor.getValue();
callback.accept(false);
assertThat(mController.getAvailabilityStatus()).isEqualTo(
DefaultAppShortcutPreferenceControllerBase.UNSUPPORTED_ON_DEVICE);
}
@Test
public void getAvailabilityStatus_applicationIsQualifiedForRole_shouldReturnAvailable() {
final ArgumentCaptor<Consumer<Boolean>> callbackCaptor = ArgumentCaptor.forClass(
Consumer.class);
verify(mPermissionControllerManager).isApplicationQualifiedForRole(eq(TEST_ROLE_NAME), eq(
TEST_PACKAGE_NAME), any(Executor.class), callbackCaptor.capture());
final Consumer<Boolean> callback = callbackCaptor.getValue();
callback.accept(true);
assertThat(mController.getAvailabilityStatus()).isEqualTo(
DefaultAppShortcutPreferenceControllerBase.AVAILABLE);
}
@Test
public void updateState_isRoleHolder_shouldSetSummaryToYes() {
when(mRoleManager.getRoleHolders(eq(TEST_ROLE_NAME))).thenReturn(Collections.singletonList(

View File

@@ -18,11 +18,17 @@ package com.android.settings.applications.appinfo;
import static com.google.common.truth.Truth.assertThat;
import android.content.Context;
import android.permission.PermissionControllerManager;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.shadows.ShadowApplication;
@RunWith(RobolectricTestRunner.class)
public class DefaultSmsShortcutPreferenceControllerTest {
@@ -30,10 +36,16 @@ public class DefaultSmsShortcutPreferenceControllerTest {
private static final String TEST_PACKAGE_NAME = "TestPackage";
private static final String PREFERENCE_KEY = "default_sms_app";
@Mock
private PermissionControllerManager mPermissionControllerManager;
private DefaultSmsShortcutPreferenceController mController;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
ShadowApplication.getInstance().setSystemService(Context.PERMISSION_CONTROLLER_SERVICE,
mPermissionControllerManager);
mController = new DefaultSmsShortcutPreferenceController(RuntimeEnvironment.application,
TEST_PACKAGE_NAME);
}