From bf3e2243efe73651ca762b1a455ae7a60059d5dd Mon Sep 17 00:00:00 2001 From: Julia Reynolds Date: Mon, 12 Feb 2018 16:47:59 -0500 Subject: [PATCH] Allow extras to be passed to app info subscreens And pass though some extras through to notification settings. This enables us to highlight appropriate preferences on the subscreens while still funneling users through the app info screen. Test: make RunSettingsRoboTests Bug: 72764587 Change-Id: I0197b595fe4bf3504588d9dd2985dd20de73c640 --- .../appinfo/AppInfoDashboardFragment.java | 6 ++- .../AppInfoPreferenceControllerBase.java | 11 ++++- .../AppNotificationPreferenceController.java | 18 +++++++++ .../datausage/UnrestrictedDataAccess.java | 1 + .../appinfo/AppInfoDashboardFragmentTest.java | 40 ++++++++++++++++++- .../AppInfoPreferenceControllerBaseTest.java | 16 +++++++- ...pNotificationPreferenceControllerTest.java | 22 ++++++++++ 7 files changed, 108 insertions(+), 6 deletions(-) diff --git a/src/com/android/settings/applications/appinfo/AppInfoDashboardFragment.java b/src/com/android/settings/applications/appinfo/AppInfoDashboardFragment.java index 5e12503ddaf..a5f06a557f2 100755 --- a/src/com/android/settings/applications/appinfo/AppInfoDashboardFragment.java +++ b/src/com/android/settings/applications/appinfo/AppInfoDashboardFragment.java @@ -505,10 +505,12 @@ public class AppInfoDashboardFragment extends DashboardFragment mDisableAfterUninstall = andDisable; } - public static void startAppInfoFragment(Class fragment, int title, + public static void startAppInfoFragment(Class fragment, int title, Bundle args, SettingsPreferenceFragment caller, AppEntry appEntry) { // start new fragment to display extended information - final Bundle args = new Bundle(); + if (args == null) { + args = new Bundle(); + } args.putString(ARG_PACKAGE_NAME, appEntry.info.packageName); args.putInt(ARG_PACKAGE_UID, appEntry.info.uid); diff --git a/src/com/android/settings/applications/appinfo/AppInfoPreferenceControllerBase.java b/src/com/android/settings/applications/appinfo/AppInfoPreferenceControllerBase.java index 105a01e38f4..fd545a7bef5 100644 --- a/src/com/android/settings/applications/appinfo/AppInfoPreferenceControllerBase.java +++ b/src/com/android/settings/applications/appinfo/AppInfoPreferenceControllerBase.java @@ -17,6 +17,7 @@ package com.android.settings.applications.appinfo; import android.content.Context; +import android.os.Bundle; import android.support.v7.preference.Preference; import android.support.v7.preference.PreferenceScreen; import android.text.TextUtils; @@ -58,7 +59,7 @@ public abstract class AppInfoPreferenceControllerBase extends BasePreferenceCont public boolean handlePreferenceTreeClick(Preference preference) { if (TextUtils.equals(preference.getKey(), mPreferenceKey) && mDetailFragmenClass != null) { AppInfoDashboardFragment.startAppInfoFragment( - mDetailFragmenClass, -1, mParent, mParent.getAppEntry()); + mDetailFragmenClass, -1, getArguments(), mParent, mParent.getAppEntry()); return true; } return false; @@ -77,4 +78,12 @@ public abstract class AppInfoPreferenceControllerBase extends BasePreferenceCont return null; } + /** + * Gets any extras that should be passed to the fragment class when the preference is clicked. + * @return a bundle of extras to include in the launch intent + */ + protected Bundle getArguments() { + return null; + } + } diff --git a/src/com/android/settings/applications/appinfo/AppNotificationPreferenceController.java b/src/com/android/settings/applications/appinfo/AppNotificationPreferenceController.java index 1f1950418b3..5a970f6f390 100644 --- a/src/com/android/settings/applications/appinfo/AppNotificationPreferenceController.java +++ b/src/com/android/settings/applications/appinfo/AppNotificationPreferenceController.java @@ -16,7 +16,10 @@ package com.android.settings.applications.appinfo; +import static com.android.settings.SettingsActivity.EXTRA_FRAGMENT_ARG_KEY; + import android.content.Context; +import android.os.Bundle; import android.support.v7.preference.Preference; import com.android.settings.SettingsPreferenceFragment; @@ -27,12 +30,17 @@ import com.android.settingslib.applications.ApplicationsState; public class AppNotificationPreferenceController extends AppInfoPreferenceControllerBase { private static final String KEY_NOTIFICATION = "notification_settings"; + private String mChannelId = null; // Used for updating notification preference. private final NotificationBackend mBackend = new NotificationBackend(); public AppNotificationPreferenceController(Context context, AppInfoDashboardFragment parent) { super(context, parent, KEY_NOTIFICATION); + if (parent != null && parent.getActivity() != null + && parent.getActivity().getIntent() != null) { + mChannelId = parent.getActivity().getIntent().getStringExtra(EXTRA_FRAGMENT_ARG_KEY); + } } @Override @@ -45,6 +53,16 @@ public class AppNotificationPreferenceController extends AppInfoPreferenceContro return AppNotificationSettings.class; } + @Override + protected Bundle getArguments() { + Bundle bundle = null; + if (mChannelId != null) { + bundle = new Bundle(); + bundle.putString(EXTRA_FRAGMENT_ARG_KEY, mChannelId); + } + return bundle; + } + private CharSequence getNotificationSummary(ApplicationsState.AppEntry appEntry, Context context, NotificationBackend backend) { NotificationBackend.AppRow appRow = diff --git a/src/com/android/settings/datausage/UnrestrictedDataAccess.java b/src/com/android/settings/datausage/UnrestrictedDataAccess.java index 2e204063bdb..83ff755f21a 100644 --- a/src/com/android/settings/datausage/UnrestrictedDataAccess.java +++ b/src/com/android/settings/datausage/UnrestrictedDataAccess.java @@ -285,6 +285,7 @@ public class UnrestrictedDataAccess extends SettingsPreferenceFragment // app is blacklisted, launch App Data Usage screen AppInfoDashboardFragment.startAppInfoFragment(AppDataUsage.class, R.string.app_data_usage, + null /* arguments */, UnrestrictedDataAccess.this, mEntry); } else { diff --git a/tests/robotests/src/com/android/settings/applications/appinfo/AppInfoDashboardFragmentTest.java b/tests/robotests/src/com/android/settings/applications/appinfo/AppInfoDashboardFragmentTest.java index d721e17459f..226ea384419 100644 --- a/tests/robotests/src/com/android/settings/applications/appinfo/AppInfoDashboardFragmentTest.java +++ b/tests/robotests/src/com/android/settings/applications/appinfo/AppInfoDashboardFragmentTest.java @@ -16,6 +16,7 @@ package com.android.settings.applications.appinfo; +import static com.android.settings.applications.appinfo.AppInfoDashboardFragment.ARG_PACKAGE_NAME; import static com.android.settings.applications.appinfo.AppInfoDashboardFragment .UNINSTALL_ALL_USERS_MENU; import static com.android.settings.applications.appinfo.AppInfoDashboardFragment.UNINSTALL_UPDATES; @@ -23,6 +24,8 @@ import static com.android.settings.applications.appinfo.AppInfoDashboardFragment 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.anyString; import static org.mockito.ArgumentMatchers.nullable; import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.doReturn; @@ -33,18 +36,19 @@ import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; -import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.pm.ApplicationInfo; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.pm.UserInfo; +import android.os.Bundle; import android.os.UserManager; import android.view.Menu; import android.view.MenuItem; import com.android.settings.SettingsActivity; +import com.android.settings.SettingsPreferenceFragment; import com.android.settings.TestConfig; import com.android.settings.testutils.SettingsRobolectricTestRunner; import com.android.settings.wrapper.DevicePolicyManagerWrapper; @@ -57,6 +61,7 @@ import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Answers; +import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.robolectric.RuntimeEnvironment; @@ -315,4 +320,37 @@ public final class AppInfoDashboardFragmentTest { verify(context).unregisterReceiver(mFragment.mPackageRemovedReceiver); } + @Test + public void startAppInfoFragment_noCrashOnNullArgs() { + final SettingsPreferenceFragment caller = mock(SettingsPreferenceFragment.class); + final SettingsActivity sa = mock (SettingsActivity.class); + when(caller.getActivity()).thenReturn(sa); + final AppEntry appEntry = mock(AppEntry.class); + appEntry.info = mock(ApplicationInfo.class); + + AppInfoDashboardFragment.startAppInfoFragment(AppInfoDashboardFragment.class, 0, null, + caller, appEntry); + } + + @Test + public void startAppInfoFragment_includesNewAndOldArgs() { + final SettingsPreferenceFragment caller = mock(SettingsPreferenceFragment.class); + final SettingsActivity sa = mock (SettingsActivity.class); + when(caller.getActivity()).thenReturn(sa); + final AppEntry appEntry = mock(AppEntry.class); + appEntry.info = mock(ApplicationInfo.class); + + final Bundle bundle = new Bundle(); + bundle.putString("test", "test"); + + AppInfoDashboardFragment.startAppInfoFragment(AppInfoDashboardFragment.class, 0, bundle, + caller, appEntry); + + final ArgumentCaptor captor = ArgumentCaptor.forClass(Bundle.class); + verify(sa).startPreferencePanel(any(), anyString(), captor.capture(), anyInt(), any(), + any(), anyInt()); + + assertThat(captor.getValue().containsKey("test")); + assertThat(captor.getValue().containsKey(ARG_PACKAGE_NAME)); + } } diff --git a/tests/robotests/src/com/android/settings/applications/appinfo/AppInfoPreferenceControllerBaseTest.java b/tests/robotests/src/com/android/settings/applications/appinfo/AppInfoPreferenceControllerBaseTest.java index 51b6ddf06d6..0c80ef42193 100644 --- a/tests/robotests/src/com/android/settings/applications/appinfo/AppInfoPreferenceControllerBaseTest.java +++ b/tests/robotests/src/com/android/settings/applications/appinfo/AppInfoPreferenceControllerBaseTest.java @@ -26,6 +26,7 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.content.pm.ApplicationInfo; +import android.os.Bundle; import android.support.v7.preference.Preference; import android.support.v7.preference.PreferenceScreen; @@ -39,6 +40,7 @@ import com.android.settingslib.applications.ApplicationsState; 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.RuntimeEnvironment; @@ -90,9 +92,12 @@ public class AppInfoPreferenceControllerBaseTest { mController.handlePreferenceTreeClick(mPreference); + ArgumentCaptor captor = ArgumentCaptor.forClass(Bundle.class); verify(mActivity).startPreferencePanel(any(), - eq(mController.getDetailFragmentClass().getName()), any(), anyInt(), any(), any(), - anyInt()); + eq(mController.getDetailFragmentClass().getName()), captor.capture(), anyInt(), + any(), any(), anyInt()); + + assertThat(captor.getValue().containsKey("test")); } private class TestPreferenceController extends AppInfoPreferenceControllerBase { @@ -113,6 +118,13 @@ public class AppInfoPreferenceControllerBaseTest { return AppNotificationSettings.class; } + @Override + protected Bundle getArguments() { + Bundle bundle = new Bundle(); + bundle.putString("test", "test"); + return bundle; + } + } } diff --git a/tests/robotests/src/com/android/settings/applications/appinfo/AppNotificationPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/applications/appinfo/AppNotificationPreferenceControllerTest.java index 0b747a8f662..8dc47f81088 100644 --- a/tests/robotests/src/com/android/settings/applications/appinfo/AppNotificationPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/applications/appinfo/AppNotificationPreferenceControllerTest.java @@ -16,6 +16,8 @@ package com.android.settings.applications.appinfo; +import static com.android.settings.SettingsActivity.EXTRA_FRAGMENT_ARG_KEY; + import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.any; @@ -24,7 +26,9 @@ import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import android.app.Activity; import android.content.Context; +import android.content.Intent; import android.content.pm.ApplicationInfo; import android.support.v7.preference.Preference; import android.support.v7.preference.PreferenceScreen; @@ -87,4 +91,22 @@ public class AppNotificationPreferenceControllerTest { verify(mPreference).setSummary(any()); } + @Test + public void getArguments_nullIfChannelIsNull() { + assertThat(mController.getArguments()).isNull(); + } + + @Test + public void getArguments_containsChannelId() { + Activity activity = mock(Activity.class); + Intent intent = new Intent(); + intent.putExtra(EXTRA_FRAGMENT_ARG_KEY, "test"); + when(mFragment.getActivity()).thenReturn(activity); + when(activity.getIntent()).thenReturn(intent); + AppNotificationPreferenceController controller = + new AppNotificationPreferenceController(mContext, mFragment); + + assertThat(controller.getArguments().containsKey(EXTRA_FRAGMENT_ARG_KEY)).isTrue(); + assertThat(controller.getArguments().getString(EXTRA_FRAGMENT_ARG_KEY)).isEqualTo("test"); + } }