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:
@@ -20,9 +20,11 @@ import android.content.Context;
|
|||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.UserManager;
|
import android.os.UserManager;
|
||||||
|
import android.permission.PermissionControllerManager;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
|
|
||||||
import androidx.preference.Preference;
|
import androidx.preference.Preference;
|
||||||
|
import androidx.preference.PreferenceScreen;
|
||||||
|
|
||||||
import com.android.internal.util.CollectionUtils;
|
import com.android.internal.util.CollectionUtils;
|
||||||
import com.android.settings.R;
|
import com.android.settings.R;
|
||||||
@@ -43,6 +45,10 @@ public abstract class DefaultAppShortcutPreferenceControllerBase extends BasePre
|
|||||||
|
|
||||||
private final RoleManager mRoleManager;
|
private final RoleManager mRoleManager;
|
||||||
|
|
||||||
|
private boolean mAppQualified;
|
||||||
|
|
||||||
|
private PreferenceScreen mPreferenceScreen;
|
||||||
|
|
||||||
public DefaultAppShortcutPreferenceControllerBase(Context context, String preferenceKey,
|
public DefaultAppShortcutPreferenceControllerBase(Context context, String preferenceKey,
|
||||||
String roleName, String packageName) {
|
String roleName, String packageName) {
|
||||||
super(context, preferenceKey);
|
super(context, preferenceKey);
|
||||||
@@ -51,6 +57,17 @@ public abstract class DefaultAppShortcutPreferenceControllerBase extends BasePre
|
|||||||
mPackageName = packageName;
|
mPackageName = packageName;
|
||||||
|
|
||||||
mRoleManager = context.getSystemService(RoleManager.class);
|
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.
|
// 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);
|
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
|
@Override
|
||||||
public int getAvailabilityStatus() {
|
public int getAvailabilityStatus() {
|
||||||
if (mContext.getSystemService(UserManager.class).isManagedProfile()) {
|
if (mContext.getSystemService(UserManager.class).isManagedProfile()) {
|
||||||
@@ -104,7 +138,7 @@ public abstract class DefaultAppShortcutPreferenceControllerBase extends BasePre
|
|||||||
protected boolean hasAppCapability() {
|
protected boolean hasAppCapability() {
|
||||||
// TODO: STOPSHIP(b/110557011): Remove this check once we have all default apps migrated.
|
// TODO: STOPSHIP(b/110557011): Remove this check once we have all default apps migrated.
|
||||||
if (mRoleName != null) {
|
if (mRoleName != null) {
|
||||||
return mRoleManager.isRoleAvailable(mRoleName);
|
return mAppQualified;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@@ -18,6 +18,7 @@ package com.android.settings.applications.appinfo;
|
|||||||
|
|
||||||
import static com.google.common.truth.Truth.assertThat;
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
|
|
||||||
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
import static org.mockito.ArgumentMatchers.eq;
|
import static org.mockito.ArgumentMatchers.eq;
|
||||||
import static org.mockito.Mockito.verify;
|
import static org.mockito.Mockito.verify;
|
||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
@@ -28,6 +29,7 @@ import android.app.role.RoleManager;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.os.UserManager;
|
import android.os.UserManager;
|
||||||
|
import android.permission.PermissionControllerManager;
|
||||||
|
|
||||||
import androidx.preference.Preference;
|
import androidx.preference.Preference;
|
||||||
|
|
||||||
@@ -38,6 +40,7 @@ import com.android.settings.applications.DefaultAppSettings;
|
|||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
|
import org.mockito.ArgumentCaptor;
|
||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
import org.mockito.MockitoAnnotations;
|
import org.mockito.MockitoAnnotations;
|
||||||
import org.robolectric.Robolectric;
|
import org.robolectric.Robolectric;
|
||||||
@@ -48,6 +51,8 @@ import org.robolectric.shadows.ShadowApplication;
|
|||||||
import org.robolectric.shadows.ShadowUserManager;
|
import org.robolectric.shadows.ShadowUserManager;
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.concurrent.Executor;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
@RunWith(RobolectricTestRunner.class)
|
@RunWith(RobolectricTestRunner.class)
|
||||||
@Config(shadows = ShadowUserManager.class)
|
@Config(shadows = ShadowUserManager.class)
|
||||||
@@ -60,6 +65,8 @@ public class DefaultAppShortcutPreferenceControllerBaseTest {
|
|||||||
@Mock
|
@Mock
|
||||||
private RoleManager mRoleManager;
|
private RoleManager mRoleManager;
|
||||||
@Mock
|
@Mock
|
||||||
|
private PermissionControllerManager mPermissionControllerManager;
|
||||||
|
@Mock
|
||||||
private Preference mPreference;
|
private Preference mPreference;
|
||||||
|
|
||||||
private Activity mActivity;
|
private Activity mActivity;
|
||||||
@@ -71,7 +78,10 @@ public class DefaultAppShortcutPreferenceControllerBaseTest {
|
|||||||
@Before
|
@Before
|
||||||
public void setUp() {
|
public void setUp() {
|
||||||
MockitoAnnotations.initMocks(this);
|
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);
|
mActivity = Robolectric.setupActivity(Activity.class);
|
||||||
mShadowUserManager = shadowOf(mActivity.getSystemService(UserManager.class));
|
mShadowUserManager = shadowOf(mActivity.getSystemService(UserManager.class));
|
||||||
mController = new TestRolePreferenceController(mActivity);
|
mController = new TestRolePreferenceController(mActivity);
|
||||||
@@ -79,6 +89,12 @@ public class DefaultAppShortcutPreferenceControllerBaseTest {
|
|||||||
mLegacyController = new TestLegacyPreferenceController(mActivity);
|
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
|
@Test
|
||||||
public void getAvailabilityStatus_isManagedProfile_shouldReturnDisabled() {
|
public void getAvailabilityStatus_isManagedProfile_shouldReturnDisabled() {
|
||||||
mShadowUserManager.setManagedProfile(true);
|
mShadowUserManager.setManagedProfile(true);
|
||||||
@@ -88,23 +104,38 @@ public class DefaultAppShortcutPreferenceControllerBaseTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void getAvailabilityStatus_roleIsAvailable_shouldReturnAvailable() {
|
public void
|
||||||
mShadowUserManager.setManagedProfile(false);
|
getAvailabilityStatus_noCallbackForIsApplicationNotQualifiedForRole_shouldReturnUnsupported() {
|
||||||
when(mRoleManager.isRoleAvailable(eq(TEST_ROLE_NAME))).thenReturn(true);
|
|
||||||
|
|
||||||
assertThat(mController.getAvailabilityStatus()).isEqualTo(
|
assertThat(mController.getAvailabilityStatus()).isEqualTo(
|
||||||
DefaultAppShortcutPreferenceControllerBase.AVAILABLE);
|
DefaultAppShortcutPreferenceControllerBase.UNSUPPORTED_ON_DEVICE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void getAvailabilityStatus_roleNotAvailable_shouldReturnDisabled() {
|
public void getAvailabilityStatus_applicationIsNotQualifiedForRole_shouldReturnUnsupported() {
|
||||||
mShadowUserManager.setManagedProfile(false);
|
final ArgumentCaptor<Consumer<Boolean>> callbackCaptor = ArgumentCaptor.forClass(
|
||||||
when(mRoleManager.isRoleAvailable(eq(TEST_ROLE_NAME))).thenReturn(false);
|
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(
|
assertThat(mController.getAvailabilityStatus()).isEqualTo(
|
||||||
DefaultAppShortcutPreferenceControllerBase.UNSUPPORTED_ON_DEVICE);
|
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
|
@Test
|
||||||
public void updateState_isRoleHolder_shouldSetSummaryToYes() {
|
public void updateState_isRoleHolder_shouldSetSummaryToYes() {
|
||||||
when(mRoleManager.getRoleHolders(eq(TEST_ROLE_NAME))).thenReturn(Collections.singletonList(
|
when(mRoleManager.getRoleHolders(eq(TEST_ROLE_NAME))).thenReturn(Collections.singletonList(
|
||||||
|
@@ -18,11 +18,17 @@ package com.android.settings.applications.appinfo;
|
|||||||
|
|
||||||
import static com.google.common.truth.Truth.assertThat;
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.permission.PermissionControllerManager;
|
||||||
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.MockitoAnnotations;
|
||||||
import org.robolectric.RobolectricTestRunner;
|
import org.robolectric.RobolectricTestRunner;
|
||||||
import org.robolectric.RuntimeEnvironment;
|
import org.robolectric.RuntimeEnvironment;
|
||||||
|
import org.robolectric.shadows.ShadowApplication;
|
||||||
|
|
||||||
@RunWith(RobolectricTestRunner.class)
|
@RunWith(RobolectricTestRunner.class)
|
||||||
public class DefaultSmsShortcutPreferenceControllerTest {
|
public class DefaultSmsShortcutPreferenceControllerTest {
|
||||||
@@ -30,10 +36,16 @@ public class DefaultSmsShortcutPreferenceControllerTest {
|
|||||||
private static final String TEST_PACKAGE_NAME = "TestPackage";
|
private static final String TEST_PACKAGE_NAME = "TestPackage";
|
||||||
private static final String PREFERENCE_KEY = "default_sms_app";
|
private static final String PREFERENCE_KEY = "default_sms_app";
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private PermissionControllerManager mPermissionControllerManager;
|
||||||
|
|
||||||
private DefaultSmsShortcutPreferenceController mController;
|
private DefaultSmsShortcutPreferenceController mController;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() {
|
public void setUp() {
|
||||||
|
MockitoAnnotations.initMocks(this);
|
||||||
|
ShadowApplication.getInstance().setSystemService(Context.PERMISSION_CONTROLLER_SERVICE,
|
||||||
|
mPermissionControllerManager);
|
||||||
mController = new DefaultSmsShortcutPreferenceController(RuntimeEnvironment.application,
|
mController = new DefaultSmsShortcutPreferenceController(RuntimeEnvironment.application,
|
||||||
TEST_PACKAGE_NAME);
|
TEST_PACKAGE_NAME);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user