Merge "Use role for App info default SMS shortcut."

This commit is contained in:
TreeHugger Robot
2019-01-15 00:47:40 +00:00
committed by Android (Google) Code Review
4 changed files with 160 additions and 119 deletions

View File

@@ -14,7 +14,9 @@
package com.android.settings.applications.appinfo; package com.android.settings.applications.appinfo;
import android.app.role.RoleManager;
import android.content.Context; import android.content.Context;
import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
import android.os.UserManager; import android.os.UserManager;
import android.text.TextUtils; import android.text.TextUtils;
@@ -22,6 +24,7 @@ import android.text.TextUtils;
import androidx.preference.Preference; import androidx.preference.Preference;
import com.android.internal.logging.nano.MetricsProto; import com.android.internal.logging.nano.MetricsProto;
import com.android.internal.util.CollectionUtils;
import com.android.settings.R; import com.android.settings.R;
import com.android.settings.SettingsActivity; import com.android.settings.SettingsActivity;
import com.android.settings.applications.DefaultAppSettings; import com.android.settings.applications.DefaultAppSettings;
@@ -34,17 +37,31 @@ import com.android.settings.core.SubSettingLauncher;
*/ */
public abstract class DefaultAppShortcutPreferenceControllerBase extends BasePreferenceController { public abstract class DefaultAppShortcutPreferenceControllerBase extends BasePreferenceController {
private final String mRoleName;
protected final String mPackageName; protected final String mPackageName;
private final RoleManager mRoleManager;
public DefaultAppShortcutPreferenceControllerBase(Context context, String preferenceKey,
String roleName, String packageName) {
super(context, preferenceKey);
mRoleName = roleName;
mPackageName = packageName;
mRoleManager = context.getSystemService(RoleManager.class);
}
// TODO: STOPSHIP(b/110557011): Remove this once we have all default apps migrated.
public DefaultAppShortcutPreferenceControllerBase(Context context, String preferenceKey, public DefaultAppShortcutPreferenceControllerBase(Context context, String preferenceKey,
String packageName) { String packageName) {
super(context, preferenceKey); this(context, preferenceKey, null /* roleName */, packageName);
mPackageName = packageName;
} }
@Override @Override
public int getAvailabilityStatus() { public int getAvailabilityStatus() {
if (UserManager.get(mContext).isManagedProfile()) { if (mContext.getSystemService(UserManager.class).isManagedProfile()) {
return DISABLED_FOR_USER; return DISABLED_FOR_USER;
} }
return hasAppCapability() ? AVAILABLE : UNSUPPORTED_ON_DEVICE; return hasAppCapability() ? AVAILABLE : UNSUPPORTED_ON_DEVICE;
@@ -52,13 +69,21 @@ public abstract class DefaultAppShortcutPreferenceControllerBase extends BasePre
@Override @Override
public CharSequence getSummary() { public CharSequence getSummary() {
int summaryResId = isDefaultApp() ? R.string.yes : R.string.no; final int summaryResId = isDefaultApp() ? R.string.yes : R.string.no;
return mContext.getText(summaryResId); return mContext.getText(summaryResId);
} }
@Override @Override
public boolean handlePreferenceTreeClick(Preference preference) { public boolean handlePreferenceTreeClick(Preference preference) {
if (TextUtils.equals(mPreferenceKey, preference.getKey())) { if (!TextUtils.equals(mPreferenceKey, preference.getKey())) {
return false;
}
// TODO: STOPSHIP(b/110557011): Remove this check once we have all default apps migrated.
if (mRoleName != null) {
final Intent intent = new Intent(Intent.ACTION_MANAGE_DEFAULT_APP)
.putExtra(Intent.EXTRA_ROLE_NAME, mRoleName);
mContext.startActivity(intent);
} else {
final Bundle bundle = new Bundle(); final Bundle bundle = new Bundle();
bundle.putString(SettingsActivity.EXTRA_FRAGMENT_ARG_KEY, mPreferenceKey); bundle.putString(SettingsActivity.EXTRA_FRAGMENT_ARG_KEY, mPreferenceKey);
new SubSettingLauncher(mContext) new SubSettingLauncher(mContext)
@@ -67,9 +92,8 @@ public abstract class DefaultAppShortcutPreferenceControllerBase extends BasePre
.setTitleRes(R.string.configure_apps) .setTitleRes(R.string.configure_apps)
.setSourceMetricsCategory(MetricsProto.MetricsEvent.VIEW_UNKNOWN) .setSourceMetricsCategory(MetricsProto.MetricsEvent.VIEW_UNKNOWN)
.launch(); .launch();
return true;
} }
return false; return true;
} }
/** /**
@@ -77,13 +101,26 @@ public abstract class DefaultAppShortcutPreferenceControllerBase extends BasePre
* *
* @return true if the app has the default app capability * @return true if the app has the default app capability
*/ */
protected abstract boolean hasAppCapability(); 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 false;
}
/** /**
* Check whether the app is the default app * Check whether the app is the default app
* *
* @return true if the app is the default app * @return true if the app is the default app
*/ */
protected abstract boolean isDefaultApp(); protected boolean isDefaultApp() {
// TODO: STOPSHIP(b/110557011): Remove this check once we have all default apps migrated.
if (mRoleName != null) {
final String packageName = CollectionUtils.firstOrNull(mRoleManager.getRoleHolders(
mRoleName));
return TextUtils.equals(mPackageName, packageName);
}
return false;
}
} }

View File

@@ -14,27 +14,15 @@
package com.android.settings.applications.appinfo; package com.android.settings.applications.appinfo;
import android.app.role.RoleManager;
import android.content.Context; import android.content.Context;
import com.android.settings.applications.defaultapps.DefaultSmsPreferenceController;
public class DefaultSmsShortcutPreferenceController public class DefaultSmsShortcutPreferenceController
extends DefaultAppShortcutPreferenceControllerBase { extends DefaultAppShortcutPreferenceControllerBase {
private static final String KEY = "default_sms_app"; private static final String KEY = "default_sms_app";
public DefaultSmsShortcutPreferenceController(Context context, String packageName) { public DefaultSmsShortcutPreferenceController(Context context, String packageName) {
super(context, KEY, packageName); super(context, KEY, RoleManager.ROLE_SMS, packageName);
} }
@Override
protected boolean hasAppCapability() {
return DefaultSmsPreferenceController.hasSmsPreference(mPackageName, mContext);
}
@Override
protected boolean isDefaultApp() {
return DefaultSmsPreferenceController.isSmsDefault(mPackageName, mContext);
}
} }

View File

@@ -18,11 +18,13 @@ 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.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;
import static org.robolectric.Shadows.shadowOf; import static org.robolectric.Shadows.shadowOf;
import android.app.Activity; import android.app.Activity;
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;
@@ -42,108 +44,173 @@ import org.robolectric.Robolectric;
import org.robolectric.RobolectricTestRunner; import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config; import org.robolectric.annotation.Config;
import org.robolectric.shadows.ShadowActivity; import org.robolectric.shadows.ShadowActivity;
import org.robolectric.shadows.ShadowApplication;
import org.robolectric.shadows.ShadowUserManager; import org.robolectric.shadows.ShadowUserManager;
import java.util.Collections;
@RunWith(RobolectricTestRunner.class) @RunWith(RobolectricTestRunner.class)
@Config(shadows = ShadowUserManager.class) @Config(shadows = ShadowUserManager.class)
public class DefaultAppShortcutPreferenceControllerBaseTest { public class DefaultAppShortcutPreferenceControllerBaseTest {
private ShadowUserManager mShadowUserManager; private static final String TEST_PREFERENCE_KEY = "TestKey";
private static final String TEST_ROLE_NAME = "TestRole";
private static final String TEST_PACKAGE_NAME = "TestPackage";
@Mock @Mock
private AppInfoDashboardFragment mFragment; private RoleManager mRoleManager;
@Mock @Mock
private Preference mPreference; private Preference mPreference;
private Activity mActivity; private Activity mActivity;
private TestPreferenceController mController; private ShadowUserManager mShadowUserManager;
private TestRolePreferenceController mController;
private TestLegacyPreferenceController mLegacyController;
@Before @Before
public void setUp() { public void setUp() {
MockitoAnnotations.initMocks(this); MockitoAnnotations.initMocks(this);
ShadowApplication.getInstance().setSystemService(Context.ROLE_SERVICE, mRoleManager);
mActivity = Robolectric.setupActivity(Activity.class); mActivity = Robolectric.setupActivity(Activity.class);
mShadowUserManager = shadowOf(mActivity.getSystemService(UserManager.class)); mShadowUserManager = shadowOf(mActivity.getSystemService(UserManager.class));
mController = new TestPreferenceController(mActivity, mFragment); mController = new TestRolePreferenceController(mActivity);
final String key = mController.getPreferenceKey(); when(mPreference.getKey()).thenReturn(mController.getPreferenceKey());
when(mPreference.getKey()).thenReturn(key); mLegacyController = new TestLegacyPreferenceController(mActivity);
} }
@Test @Test
public void getAvailabilityStatus_managedProfile_shouldReturnDisabled() { public void getAvailabilityStatus_isManagedProfile_shouldReturnDisabled() {
mShadowUserManager.setManagedProfile(true); mShadowUserManager.setManagedProfile(true);
assertThat(mController.getAvailabilityStatus()) assertThat(mController.getAvailabilityStatus()).isEqualTo(
.isEqualTo(DefaultAppShortcutPreferenceControllerBase.DISABLED_FOR_USER); DefaultAppShortcutPreferenceControllerBase.DISABLED_FOR_USER);
} }
@Test @Test
public void getAvailabilityStatus_hasAppCapability_shouldReturnAvailable() { public void getAvailabilityStatus_roleIsAvailable_shouldReturnAvailable() {
mController.capable = true;
mShadowUserManager.setManagedProfile(false); mShadowUserManager.setManagedProfile(false);
when(mRoleManager.isRoleAvailable(eq(TEST_ROLE_NAME))).thenReturn(true);
assertThat(mController.getAvailabilityStatus()) assertThat(mController.getAvailabilityStatus()).isEqualTo(
.isEqualTo(DefaultAppShortcutPreferenceControllerBase.AVAILABLE); DefaultAppShortcutPreferenceControllerBase.AVAILABLE);
} }
@Test @Test
public void getAvailabilityStatus_noAppCapability_shouldReturnDisabled() { public void getAvailabilityStatus_roleNotAvailable_shouldReturnDisabled() {
mController.capable = false;
mShadowUserManager.setManagedProfile(false); mShadowUserManager.setManagedProfile(false);
when(mRoleManager.isRoleAvailable(eq(TEST_ROLE_NAME))).thenReturn(false);
assertThat(mController.getAvailabilityStatus()).isEqualTo( assertThat(mController.getAvailabilityStatus()).isEqualTo(
DefaultAppShortcutPreferenceControllerBase.UNSUPPORTED_ON_DEVICE); DefaultAppShortcutPreferenceControllerBase.UNSUPPORTED_ON_DEVICE);
} }
@Test @Test
public void updateState_isDefaultApp_shouldSetSummaryToYes() { public void updateState_isRoleHolder_shouldSetSummaryToYes() {
mController.isDefault = true; when(mRoleManager.getRoleHolders(eq(TEST_ROLE_NAME))).thenReturn(Collections.singletonList(
TEST_PACKAGE_NAME));
final CharSequence yesText = mActivity.getText(R.string.yes);
mController.updateState(mPreference); mController.updateState(mPreference);
String yesString = mActivity.getString(R.string.yes); verify(mPreference).setSummary(yesText);
verify(mPreference).setSummary(yesString); }
@Test
public void updateState_notRoleHoler_shouldSetSummaryToNo() {
when(mRoleManager.getRoleHolders(eq(TEST_ROLE_NAME))).thenReturn(Collections.emptyList());
final CharSequence noText = mActivity.getText(R.string.no);
mController.updateState(mPreference);
verify(mPreference).setSummary(noText);
}
@Test
public void handlePreferenceTreeClick_shouldStartManageDefaultAppIntent() {
final ShadowActivity shadowActivity = shadowOf(mActivity);
mController.handlePreferenceTreeClick(mPreference);
final Intent intent = shadowActivity.getNextStartedActivity();
assertThat(intent).isNotNull();
assertThat(intent.getAction()).isEqualTo(Intent.ACTION_MANAGE_DEFAULT_APP);
assertThat(intent.getStringExtra(Intent.EXTRA_ROLE_NAME)).isEqualTo(TEST_ROLE_NAME);
}
private class TestRolePreferenceController extends DefaultAppShortcutPreferenceControllerBase {
private TestRolePreferenceController(Context context) {
super(context, TEST_PREFERENCE_KEY, TEST_ROLE_NAME, TEST_PACKAGE_NAME);
}
}
// TODO: STOPSHIP(b/110557011): Remove following tests once we have all default apps migrated.
@Test
public void getAvailabilityStatus_hasAppCapability_shouldReturnAvailable() {
mShadowUserManager.setManagedProfile(false);
mLegacyController.mHasAppCapability = true;
assertThat(mLegacyController.getAvailabilityStatus()).isEqualTo(
DefaultAppShortcutPreferenceControllerBase.AVAILABLE);
}
@Test
public void getAvailabilityStatus_noAppCapability_shouldReturnDisabled() {
mShadowUserManager.setManagedProfile(false);
mLegacyController.mHasAppCapability = false;
assertThat(mLegacyController.getAvailabilityStatus()).isEqualTo(
DefaultAppShortcutPreferenceControllerBase.UNSUPPORTED_ON_DEVICE);
}
@Test
public void updateState_isDefaultApp_shouldSetSummaryToYes() {
mLegacyController.mIsDefaultApp = true;
final CharSequence yesText = mActivity.getText(R.string.yes);
mLegacyController.updateState(mPreference);
verify(mPreference).setSummary(yesText);
} }
@Test @Test
public void updateState_notDefaultApp_shouldSetSummaryToNo() { public void updateState_notDefaultApp_shouldSetSummaryToNo() {
mController.isDefault = false; mLegacyController.mIsDefaultApp = false;
final CharSequence noText = mActivity.getText(R.string.no);
mController.updateState(mPreference); mLegacyController.updateState(mPreference);
verify(mPreference).setSummary(noText);
String noString = mActivity.getString(R.string.no);
verify(mPreference).setSummary(noString);
} }
@Test @Test
public void handlePreferenceTreeClick_shouldStartDefaultAppSettings() { public void handlePreferenceTreeClick_shouldStartDefaultAppSettings() {
final ShadowActivity shadowActivity = shadowOf(mActivity); final ShadowActivity shadowActivity = shadowOf(mActivity);
mController.handlePreferenceTreeClick(mPreference); mLegacyController.handlePreferenceTreeClick(mPreference);
final Intent intent = shadowActivity.getNextStartedActivity();
final Intent nextIntent = shadowActivity.getNextStartedActivity(); assertThat(intent).isNotNull();
assertThat(nextIntent).isNotNull(); assertThat(intent.getStringExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT)).isEqualTo(
assertThat(nextIntent.getStringExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT)).isEqualTo(
DefaultAppSettings.class.getName()); DefaultAppSettings.class.getName());
assertThat( assertThat(intent.getBundleExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT_ARGUMENTS).getString(
nextIntent.getBundleExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT_ARGUMENTS).getString( SettingsActivity.EXTRA_FRAGMENT_ARG_KEY)).isEqualTo(TEST_PREFERENCE_KEY);
SettingsActivity.EXTRA_FRAGMENT_ARG_KEY)).isEqualTo("TestKey");
} }
private class TestPreferenceController extends DefaultAppShortcutPreferenceControllerBase { private class TestLegacyPreferenceController
extends DefaultAppShortcutPreferenceControllerBase {
private boolean isDefault; private boolean mIsDefaultApp;
private boolean capable; private boolean mHasAppCapability;
private TestPreferenceController(Context context, AppInfoDashboardFragment parent) { private TestLegacyPreferenceController(Context context) {
super(context, "TestKey", "TestPackage"); super(context, TEST_PREFERENCE_KEY, TEST_PACKAGE_NAME);
} }
@Override @Override
protected boolean hasAppCapability() { protected boolean hasAppCapability() {
return capable; return mHasAppCapability;
} }
@Override @Override
protected boolean isDefaultApp() { protected boolean isDefaultApp() {
return isDefault; return mIsDefaultApp;
} }
} }
} }

View File

@@ -18,79 +18,28 @@ 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.Mockito.spy;
import static org.mockito.Mockito.when;
import android.content.Context;
import android.content.pm.PackageManager;
import com.android.settings.applications.defaultapps.DefaultSmsPreferenceController;
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.annotation.Config;
import org.robolectric.annotation.Implementation;
import org.robolectric.annotation.Implements;
@RunWith(RobolectricTestRunner.class) @RunWith(RobolectricTestRunner.class)
public class DefaultSmsShortcutPreferenceControllerTest { public class DefaultSmsShortcutPreferenceControllerTest {
@Mock private static final String TEST_PACKAGE_NAME = "TestPackage";
private PackageManager mPackageManager; private static final String PREFERENCE_KEY = "default_sms_app";
private Context mContext;
private DefaultSmsShortcutPreferenceController mController; private DefaultSmsShortcutPreferenceController mController;
@Before @Before
public void setUp() { public void setUp() {
MockitoAnnotations.initMocks(this); mController = new DefaultSmsShortcutPreferenceController(RuntimeEnvironment.application,
mContext = spy(RuntimeEnvironment.application); TEST_PACKAGE_NAME);
when(mContext.getPackageManager()).thenReturn(mPackageManager);
mController = new DefaultSmsShortcutPreferenceController(mContext, "Package1");
} }
@Test @Test
public void getPreferenceKey_shouldReturnDefaultSms() { public void getPreferenceKey_shouldReturnDefaultSms() {
assertThat(mController.getPreferenceKey()).isEqualTo("default_sms_app"); assertThat(mController.getPreferenceKey()).isEqualTo(PREFERENCE_KEY);
}
@Test
@Config(shadows = ShadowDefaultSmsPreferenceController.class)
public void hasAppCapability_hasSmsCapability_shouldReturnTrue() {
assertThat(mController.hasAppCapability()).isTrue();
}
@Test
public void hasAppCapability_noSmsCapability_shouldReturnFalse() {
assertThat(mController.hasAppCapability()).isFalse();
}
@Test
@Config(shadows = ShadowDefaultSmsPreferenceController.class)
public void isDefaultApp_isDefaultSms_shouldReturnTrue() {
assertThat(mController.isDefaultApp()).isTrue();
}
@Test
public void isDefaultApp_notDefaultSms_shouldReturnFalse() {
assertThat(mController.isDefaultApp()).isFalse();
}
@Implements(DefaultSmsPreferenceController.class)
public static class ShadowDefaultSmsPreferenceController {
@Implementation
protected static boolean hasSmsPreference(String pkg, Context context) {
return true;
}
@Implementation
protected static boolean isSmsDefault(String pkg, Context context) {
return true;
}
} }
} }