Expand SettingsLib ProviderTile to support non-switch type of Preferences

- Added new metadata allowing to set PendingIntent onto a Tile, which will be executed on click;
- Update the rendering logic to render with SwitchPreference only when Tile.hasSwitch() == true.

Test: robotest, manual
Bug: 281517110
Change-Id: I1253029be1e172792679f80be24bd58e368b9e73
This commit is contained in:
Peter Zhang
2023-05-07 23:55:50 +02:00
parent 860002b42c
commit ddb65e569b
6 changed files with 226 additions and 14 deletions

View File

@@ -43,6 +43,7 @@ import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoInteractions;
import static org.mockito.Mockito.when;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ActivityInfo;
@@ -57,6 +58,7 @@ import android.os.UserHandle;
import android.os.UserManager;
import android.util.Pair;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
import androidx.preference.Preference;
import androidx.preference.SwitchPreference;
@@ -199,6 +201,27 @@ public class DashboardFeatureProviderImplTest {
assertThat(observers.get(0).getUri().toString()).isEqualTo(SWITCH_URI);
}
@Test
public void bindPreference_providerTileWithPendingIntent_shouldBindIntent() {
final Preference preference = new SwitchPreference(RuntimeEnvironment.application);
Bundle metaData = new Bundle();
metaData.putInt(META_DATA_PREFERENCE_TITLE, R.string.settings_label);
metaData.putInt(META_DATA_PREFERENCE_SUMMARY, R.string.about_settings_summary);
metaData.putInt(META_DATA_KEY_ORDER, 10);
metaData.putString(META_DATA_PREFERENCE_KEYHINT, KEY);
final Tile tile = new ProviderTile(mProviderInfo, CategoryKey.CATEGORY_HOMEPAGE, metaData);
PendingIntent pendingIntent =
PendingIntent.getActivity(RuntimeEnvironment.application, 0, new Intent("test"), 0);
tile.pendingIntentMap.put(UserHandle.CURRENT, pendingIntent);
mImpl.bindPreferenceToTileAndGetObservers(mActivity, mFragment, mForceRoundedIcon,
preference, tile, "123", Preference.DEFAULT_ORDER);
assertThat(preference.getFragment()).isNull();
assertThat(preference.getOnPreferenceClickListener()).isNotNull();
assertThat(preference.getOrder()).isEqualTo(tile.getOrder());
}
@Test
public void bindPreference_noFragmentMetadata_shouldBindIntent() {
final Preference preference = new Preference(RuntimeEnvironment.application);
@@ -630,6 +653,55 @@ public class DashboardFeatureProviderImplTest {
assertThat(launchIntent).isNull();
}
@Test
public void clickPreference_providerTileWithPendingIntent_singleUser_executesPendingIntent() {
final Preference preference = new SwitchPreference(RuntimeEnvironment.application);
Bundle metaData = new Bundle();
metaData.putInt(META_DATA_PREFERENCE_TITLE, R.string.settings_label);
metaData.putInt(META_DATA_PREFERENCE_SUMMARY, R.string.about_settings_summary);
metaData.putInt(META_DATA_KEY_ORDER, 10);
metaData.putString(META_DATA_PREFERENCE_KEYHINT, KEY);
final Tile tile = new ProviderTile(mProviderInfo, CategoryKey.CATEGORY_HOMEPAGE, metaData);
PendingIntent pendingIntent =
PendingIntent.getActivity(RuntimeEnvironment.application, 0, new Intent("test"), 0);
tile.pendingIntentMap.put(UserHandle.CURRENT, pendingIntent);
mImpl.bindPreferenceToTileAndGetObservers(mActivity, mFragment, mForceRoundedIcon,
preference, tile, "123", Preference.DEFAULT_ORDER);
preference.performClick();
Intent nextStartedActivity =
Shadows.shadowOf(RuntimeEnvironment.application).peekNextStartedActivity();
assertThat(nextStartedActivity).isNotNull();
assertThat(nextStartedActivity.getAction()).isEqualTo("test");
}
@Test
public void clickPreference_providerTileWithPendingIntent_multiUser_showsProfileDialog() {
final Preference preference = new SwitchPreference(RuntimeEnvironment.application);
Bundle metaData = new Bundle();
metaData.putInt(META_DATA_PREFERENCE_TITLE, R.string.settings_label);
metaData.putInt(META_DATA_PREFERENCE_SUMMARY, R.string.about_settings_summary);
metaData.putInt(META_DATA_KEY_ORDER, 10);
metaData.putString(META_DATA_PREFERENCE_KEYHINT, KEY);
final Tile tile = new ProviderTile(mProviderInfo, CategoryKey.CATEGORY_HOMEPAGE, metaData);
PendingIntent pendingIntent =
PendingIntent.getActivity(RuntimeEnvironment.application, 0, new Intent("test"), 0);
tile.pendingIntentMap.put(UserHandle.CURRENT, pendingIntent);
tile.pendingIntentMap.put(new UserHandle(10), pendingIntent);
mImpl.bindPreferenceToTileAndGetObservers(mActivity, mFragment, mForceRoundedIcon,
preference, tile, "123", Preference.DEFAULT_ORDER);
preference.performClick();
Fragment dialogFragment =
mActivity.getSupportFragmentManager().findFragmentByTag("select_profile");
assertThat(dialogFragment).isNotNull();
Intent nextStartedActivity =
Shadows.shadowOf(RuntimeEnvironment.application).peekNextStartedActivity();
assertThat(nextStartedActivity).isNull();
}
@Test
public void openTileIntent_profileSelectionDialog_shouldShow() {
ShadowUserManager.getShadow().addUser(10, "Someone", 0);

View File

@@ -30,6 +30,7 @@ import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.app.PendingIntent;
import android.app.settings.SettingsEnums;
import android.content.ContentResolver;
import android.content.Context;
@@ -38,6 +39,7 @@ import android.content.pm.ActivityInfo;
import android.content.pm.ProviderInfo;
import android.net.Uri;
import android.os.Bundle;
import android.os.UserHandle;
import android.preference.PreferenceManager.OnActivityResultListener;
import androidx.preference.Preference;
@@ -358,6 +360,36 @@ public class DashboardFragmentTest {
assertThat(pref).isInstanceOf(PrimarySwitchPreference.class);
}
@Test
public void createPreference_isProviderTileWithPendingIntent_returnPreference() {
final ProviderInfo providerInfo = new ProviderInfo();
providerInfo.packageName = "pkg";
providerInfo.name = "provider";
providerInfo.authority = "authority";
final Bundle metaData = new Bundle();
metaData.putString(META_DATA_PREFERENCE_KEYHINT, "injected_tile_key2");
ProviderTile providerTile = new ProviderTile(providerInfo, mDashboardCategory.key,
metaData);
providerTile.pendingIntentMap.put(
UserHandle.CURRENT, PendingIntent.getActivity(mContext, 0, new Intent(), 0));
final Preference pref = mTestFragment.createPreference(providerTile);
assertThat(pref).isInstanceOf(Preference.class);
assertThat(pref).isNotInstanceOf(PrimarySwitchPreference.class);
assertThat(pref).isNotInstanceOf(SwitchPreference.class);
}
@Test
public void createPreference_isProviderTileWithPendingIntentAndSwitch_returnPrimarySwitch() {
mProviderTile.pendingIntentMap.put(
UserHandle.CURRENT, PendingIntent.getActivity(mContext, 0, new Intent(), 0));
final Preference pref = mTestFragment.createPreference(mProviderTile);
assertThat(pref).isInstanceOf(PrimarySwitchPreference.class);
}
@Test
public void onActivityResult_test() {
final int requestCode = 10;

View File

@@ -24,7 +24,9 @@ import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.app.Dialog;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.UserInfo;
import android.os.UserHandle;
@@ -118,6 +120,28 @@ public class ProfileSelectDialogTest {
verify(mUserManager, times(1)).getUserInfo(CLONE_USER.getIdentifier());
}
@Test
public void updatePendingIntentsIfNeeded_removesUsersWithNoPendingIntentsAndCloneProfile() {
final UserInfo userInfo = new UserInfo(CLONE_USER.getIdentifier(), "clone_user", null,
UserInfo.FLAG_PROFILE, UserManager.USER_TYPE_PROFILE_CLONE);
when(mUserManager.getUserInfo(CLONE_USER.getIdentifier())).thenReturn(userInfo);
final Tile tile = new ActivityTile(mActivityInfo, CategoryKey.CATEGORY_HOMEPAGE);
tile.userHandle.add(CLONE_USER);
tile.userHandle.add(NORMAL_USER);
tile.userHandle.add(new UserHandle(10));
PendingIntent pendingIntent = PendingIntent.getActivity(mContext, 0, new Intent(), 0);
tile.pendingIntentMap.put(CLONE_USER, pendingIntent);
tile.pendingIntentMap.put(NORMAL_USER, pendingIntent);
ProfileSelectDialog.updatePendingIntentsIfNeeded(mContext, tile);
assertThat(tile.userHandle).hasSize(1);
assertThat(tile.userHandle).containsExactly(NORMAL_USER);
assertThat(tile.pendingIntentMap).hasSize(1);
assertThat(tile.pendingIntentMap).containsKey(NORMAL_USER);
verify(mUserManager, times(1)).getUserInfo(CLONE_USER.getIdentifier());
}
@Test
public void createDialog_showsCorrectTitle() {
mContext.setTheme(R.style.Theme_AppCompat);