From f5bd885a1d0cd5e61aeb3d4a03261dea6548789a Mon Sep 17 00:00:00 2001 From: Fan Zhang Date: Wed, 17 May 2017 17:22:09 -0700 Subject: [PATCH 1/3] Clean up settings_entity_header layout. update layout view IDs, and controller variable names to be more generic. Fix: 36734470 Bug: 37669238 Test: make RunSettingsRoboTests Change-Id: Ib80827ae3eae6d01a600068b4a8a44b239c32511 --- res/layout/settings_entity_header.xml | 166 +++++++++--------- res/xml/development_prefs.xml | 4 +- .../applications/AppInfoWithHeader.java | 4 +- .../settings/applications/AppOpsDetails.java | 29 ++- .../ApplicationFeatureProvider.java | 32 ++-- .../ApplicationFeatureProviderImpl.java | 5 +- ...oller.java => EntityHeaderController.java} | 74 ++++---- .../applications/InstalledAppDetails.java | 41 +---- .../applications/ProcessStatsDetail.java | 2 +- .../settings/datausage/AppDataUsage.java | 8 +- .../fuelgauge/AdvancedPowerUsageDetail.java | 10 +- .../notification/AppNotificationSettings.java | 15 +- .../ChannelNotificationSettings.java | 9 +- .../applications/AppInfoWithHeaderTest.java | 4 +- ...t.java => EntityHeaderControllerTest.java} | 121 +++++++------ .../settings/datausage/AppDataUsageTest.java | 6 +- .../AdvancedPowerUsageDetailTest.java | 67 ++++--- 17 files changed, 292 insertions(+), 305 deletions(-) rename src/com/android/settings/applications/{AppHeaderController.java => EntityHeaderController.java} (79%) rename tests/robotests/src/com/android/settings/applications/{AppHeaderControllerTest.java => EntityHeaderControllerTest.java} (68%) diff --git a/res/layout/settings_entity_header.xml b/res/layout/settings_entity_header.xml index 2db23e40ac8..72b688b2f0f 100644 --- a/res/layout/settings_entity_header.xml +++ b/res/layout/settings_entity_header.xml @@ -15,102 +15,96 @@ limitations under the License. --> - + + android:paddingStart="?android:attr/listPreferredItemPaddingStart" + android:paddingEnd="0dp" + android:paddingTop="24dp" + android:paddingBottom="24dp"> - - + + + + + + + + + + - + android:layout_toEndOf="@id/entity_header_icon" + android:layout_toStartOf="@id/entity_header_links" + android:paddingStart="24dp" + android:paddingEnd="24dp" + android:orientation="vertical"> - - - - - - - - - + android:singleLine="false" + android:ellipsize="marquee" + android:gravity="start" + android:textDirection="locale" + android:paddingTop="8dp" /> - + - + - + - - - - - \ No newline at end of file + diff --git a/res/xml/development_prefs.xml b/res/xml/development_prefs.xml index 1eea8dda464..273b80d2d82 100644 --- a/res/xml/development_prefs.xml +++ b/res/xml/development_prefs.xml @@ -412,12 +412,12 @@ android:entries="@array/app_process_limit_entries" android:entryValues="@array/app_process_limit_values" /> - + findPersistentPreferredActivities(@UserIdInt int userId, Intent[] intents); diff --git a/src/com/android/settings/applications/ApplicationFeatureProviderImpl.java b/src/com/android/settings/applications/ApplicationFeatureProviderImpl.java index a74479239ce..cdbbeb6cf65 100644 --- a/src/com/android/settings/applications/ApplicationFeatureProviderImpl.java +++ b/src/com/android/settings/applications/ApplicationFeatureProviderImpl.java @@ -24,7 +24,6 @@ import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.content.pm.UserInfo; import android.os.RemoteException; -import android.os.UserHandle; import android.os.UserManager; import android.util.ArraySet; import android.view.View; @@ -54,8 +53,8 @@ public class ApplicationFeatureProviderImpl implements ApplicationFeatureProvide } @Override - public AppHeaderController newAppHeaderController(Fragment fragment, View appHeader) { - return new AppHeaderController(mContext, fragment, appHeader); + public EntityHeaderController newAppHeaderController(Fragment fragment, View appHeader) { + return new EntityHeaderController(mContext, fragment, appHeader); } @Override diff --git a/src/com/android/settings/applications/AppHeaderController.java b/src/com/android/settings/applications/EntityHeaderController.java similarity index 79% rename from src/com/android/settings/applications/AppHeaderController.java rename to src/com/android/settings/applications/EntityHeaderController.java index c638d351f0e..98658b13ef4 100644 --- a/src/com/android/settings/applications/AppHeaderController.java +++ b/src/com/android/settings/applications/EntityHeaderController.java @@ -47,7 +47,7 @@ import com.android.settingslib.applications.ApplicationsState; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; -public class AppHeaderController { +public class EntityHeaderController { @IntDef({ActionType.ACTION_NONE, ActionType.ACTION_APP_INFO, @@ -68,7 +68,7 @@ public class AppHeaderController { private final Context mContext; private final Fragment mFragment; private final int mMetricsCategory; - private final View mAppHeader; + private final View mHeader; private Drawable mIcon; private CharSequence mLabel; @@ -78,84 +78,84 @@ public class AppHeaderController { @UserIdInt private int mUid = UserHandle.USER_NULL; @ActionType - private int mLeftAction; + private int mAction1; @ActionType - private int mRightAction; + private int mAction2; private boolean mIsInstantApp; - public AppHeaderController(Context context, Fragment fragment, View appHeader) { + public EntityHeaderController(Context context, Fragment fragment, View header) { mContext = context; mFragment = fragment; mMetricsCategory = FeatureFactory.getFactory(context).getMetricsFeatureProvider() .getMetricsCategory(fragment); - if (appHeader != null) { - mAppHeader = appHeader; + if (header != null) { + mHeader = header; } else { - mAppHeader = LayoutInflater.from(fragment.getContext()) + mHeader = LayoutInflater.from(fragment.getContext()) .inflate(R.layout.settings_entity_header, null /* root */); } } - public AppHeaderController setIcon(Drawable icon) { + public EntityHeaderController setIcon(Drawable icon) { if (icon != null) { mIcon = icon.getConstantState().newDrawable(mContext.getResources()); } return this; } - public AppHeaderController setIcon(ApplicationsState.AppEntry appEntry) { + public EntityHeaderController setIcon(ApplicationsState.AppEntry appEntry) { if (appEntry.icon != null) { mIcon = appEntry.icon.getConstantState().newDrawable(mContext.getResources()); } return this; } - public AppHeaderController setLabel(CharSequence label) { + public EntityHeaderController setLabel(CharSequence label) { mLabel = label; return this; } - public AppHeaderController setLabel(ApplicationsState.AppEntry appEntry) { + public EntityHeaderController setLabel(ApplicationsState.AppEntry appEntry) { mLabel = appEntry.label; return this; } - public AppHeaderController setSummary(CharSequence summary) { + public EntityHeaderController setSummary(CharSequence summary) { mSummary = summary; return this; } - public AppHeaderController setSummary(PackageInfo packageInfo) { + public EntityHeaderController setSummary(PackageInfo packageInfo) { if (packageInfo != null) { mSummary = packageInfo.versionName; } return this; } - public AppHeaderController setButtonActions(@ActionType int leftAction, - @ActionType int rightAction) { - mLeftAction = leftAction; - mRightAction = rightAction; + public EntityHeaderController setButtonActions(@ActionType int action1, + @ActionType int action2) { + mAction1 = action1; + mAction2 = action2; return this; } - public AppHeaderController setPackageName(String packageName) { + public EntityHeaderController setPackageName(String packageName) { mPackageName = packageName; return this; } - public AppHeaderController setUid(int uid) { + public EntityHeaderController setUid(int uid) { mUid = uid; return this; } - public AppHeaderController setAppNotifPrefIntent(Intent appNotifPrefIntent) { + public EntityHeaderController setAppNotifPrefIntent(Intent appNotifPrefIntent) { mAppNotifPrefIntent = appNotifPrefIntent; return this; } - public AppHeaderController setIsInstantApp(boolean isInstantApp) { + public EntityHeaderController setIsInstantApp(boolean isInstantApp) { this.mIsInstantApp = isInstantApp; return this; } @@ -172,41 +172,41 @@ public class AppHeaderController { } /** - * Done mutating appheader, rebinds everything (optionally skip rebinding buttons). + * Done mutating entity header, rebinds everything (optionally skip rebinding buttons). */ public View done(Activity activity, boolean rebindActions) { styleActionBar(activity); - ImageView iconView = mAppHeader.findViewById(R.id.app_detail_icon); + ImageView iconView = mHeader.findViewById(R.id.entity_header_icon); if (iconView != null) { iconView.setImageDrawable(mIcon); } - setText(R.id.app_detail_title, mLabel); - setText(R.id.app_detail_summary, mSummary); + setText(R.id.entity_header_title, mLabel); + setText(R.id.entity_header_summary, mSummary); if (mIsInstantApp) { setText(R.id.install_type, - mAppHeader.getResources().getString(R.string.install_type_instant)); + mHeader.getResources().getString(R.string.install_type_instant)); } if (rebindActions) { - bindAppHeaderButtons(); + bindHeaderButtons(); } - return mAppHeader; + return mHeader; } /** * Only binds app header with button actions. */ - public AppHeaderController bindAppHeaderButtons() { - ImageButton leftButton = mAppHeader.findViewById(R.id.left_button); - ImageButton rightButton = mAppHeader.findViewById(R.id.right_button); + public EntityHeaderController bindHeaderButtons() { + ImageButton button1 = mHeader.findViewById(android.R.id.button1); + ImageButton button2 = mHeader.findViewById(android.R.id.button2); - bindButton(leftButton, mLeftAction); - bindButton(rightButton, mRightAction); + bindButton(button1, mAction1); + bindButton(button2, mAction2); return this; } - public AppHeaderController styleActionBar(Activity activity) { + public EntityHeaderController styleActionBar(Activity activity) { if (activity == null) { Log.w(TAG, "No activity, cannot style actionbar."); return this; @@ -224,7 +224,7 @@ public class AppHeaderController { } /** - * Done mutating appheader, rebinds everything. + * Done mutating entity header, rebinds everything. */ @VisibleForTesting View done(Activity activity) { @@ -289,7 +289,7 @@ public class AppHeaderController { } private void setText(@IdRes int id, CharSequence text) { - TextView textView = mAppHeader.findViewById(id); + TextView textView = mHeader.findViewById(id); if (textView != null) { textView.setText(text); textView.setVisibility(TextUtils.isEmpty(text) ? View.GONE : View.VISIBLE); diff --git a/src/com/android/settings/applications/InstalledAppDetails.java b/src/com/android/settings/applications/InstalledAppDetails.java index 3b82b4cf1f8..1ff4a03073f 100755 --- a/src/com/android/settings/applications/InstalledAppDetails.java +++ b/src/com/android/settings/applications/InstalledAppDetails.java @@ -37,7 +37,6 @@ import android.content.pm.PackageManager.NameNotFoundException; import android.content.pm.ResolveInfo; import android.content.pm.UserInfo; import android.content.res.Resources; -import android.graphics.drawable.Drawable; import android.icu.text.ListFormatter; import android.net.INetworkStatsService; import android.net.INetworkStatsSession; @@ -60,16 +59,12 @@ import android.text.TextUtils; import android.text.format.DateUtils; import android.text.format.Formatter; import android.util.Log; -import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; import android.view.View; -import android.view.ViewGroup; import android.webkit.IWebViewUpdateService; import android.widget.Button; -import android.widget.ImageView; -import android.widget.TextView; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.internal.os.BatterySipper; @@ -413,12 +408,12 @@ public class InstalledAppDetails extends AppInfoBase mActionButtons = (LayoutPreference) findPreference(KEY_ACTION_BUTTONS); FeatureFactory.getFactory(activity) .getApplicationFeatureProvider(activity) - .newAppHeaderController(this, mHeader.findViewById(R.id.app_snippet)) + .newAppHeaderController(this, mHeader.findViewById(R.id.entity_header)) .setPackageName(mPackageName) - .setButtonActions(AppHeaderController.ActionType.ACTION_APP_PREFERENCE, - AppHeaderController.ActionType.ACTION_NONE) + .setButtonActions(EntityHeaderController.ActionType.ACTION_APP_PREFERENCE, + EntityHeaderController.ActionType.ACTION_NONE) .styleActionBar(activity) - .bindAppHeaderButtons(); + .bindHeaderButtons(); prepareUninstallAndStop(); mNotificationPreference = findPreference(KEY_NOTIFICATION); @@ -584,7 +579,7 @@ public class InstalledAppDetails extends AppInfoBase // Utility method to set application label and icon. private void setAppLabelAndIcon(PackageInfo pkgInfo) { - final View appSnippet = mHeader.findViewById(R.id.app_snippet); + final View appSnippet = mHeader.findViewById(R.id.entity_header); mState.ensureIcon(mAppEntry); final Activity activity = getActivity(); final boolean isInstantApp = AppUtils.isInstant(mPackageInfo.applicationInfo); @@ -1245,32 +1240,6 @@ public class InstalledAppDetails extends AppInfoBase } } - /** - * @deprecated app info pages should use {@link AppHeaderController} to show the app header. - */ - public static void setupAppSnippet(View appSnippet, CharSequence label, Drawable icon, - CharSequence versionName) { - LayoutInflater.from(appSnippet.getContext()).inflate(R.layout.widget_text_views, - (ViewGroup) appSnippet.findViewById(android.R.id.widget_frame)); - - ImageView iconView = (ImageView) appSnippet.findViewById(R.id.app_detail_icon); - iconView.setImageDrawable(icon); - // Set application name. - TextView labelView = (TextView) appSnippet.findViewById(R.id.app_detail_title); - labelView.setText(label); - // Version number of application - TextView appVersion = (TextView) appSnippet.findViewById(R.id.widget_text1); - - if (!TextUtils.isEmpty(versionName)) { - appVersion.setSelected(true); - appVersion.setVisibility(View.VISIBLE); - appVersion.setText(appSnippet.getContext().getString(R.string.version_text, - String.valueOf(versionName))); - } else { - appVersion.setVisibility(View.INVISIBLE); - } - } - public static NetworkTemplate getTemplate(Context context) { if (DataUsageList.hasReadyMobileRadio(context)) { return NetworkTemplate.buildTemplateMobileWildcard(); diff --git a/src/com/android/settings/applications/ProcessStatsDetail.java b/src/com/android/settings/applications/ProcessStatsDetail.java index 6c0928c1e6e..0313239b288 100644 --- a/src/com/android/settings/applications/ProcessStatsDetail.java +++ b/src/com/android/settings/applications/ProcessStatsDetail.java @@ -16,7 +16,7 @@ package com.android.settings.applications; -import static com.android.settings.applications.AppHeaderController.ActionType; +import static com.android.settings.applications.EntityHeaderController.ActionType; import android.app.Activity; import android.app.ActivityManager; diff --git a/src/com/android/settings/datausage/AppDataUsage.java b/src/com/android/settings/datausage/AppDataUsage.java index 3d2db9650b4..0aa08422cb8 100644 --- a/src/com/android/settings/datausage/AppDataUsage.java +++ b/src/com/android/settings/datausage/AppDataUsage.java @@ -41,7 +41,7 @@ import android.widget.AdapterView; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.settings.R; -import com.android.settings.applications.AppHeaderController; +import com.android.settings.applications.EntityHeaderController; import com.android.settings.applications.AppInfoBase; import com.android.settings.overlay.FeatureFactory; import com.android.settingslib.AppItem; @@ -330,9 +330,9 @@ public class AppDataUsage extends DataUsageBase implements Preference.OnPreferen .getApplicationFeatureProvider(activity) .newAppHeaderController(this, null /* appHeader */) .setButtonActions(showInfoButton - ? AppHeaderController.ActionType.ACTION_APP_INFO - : AppHeaderController.ActionType.ACTION_NONE, - AppHeaderController.ActionType.ACTION_NONE) + ? EntityHeaderController.ActionType.ACTION_APP_INFO + : EntityHeaderController.ActionType.ACTION_NONE, + EntityHeaderController.ActionType.ACTION_NONE) .setIcon(mIcon) .setLabel(mLabel) .setPackageName(pkg) diff --git a/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetail.java b/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetail.java index 37e685dc6a6..456a5112547 100644 --- a/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetail.java +++ b/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetail.java @@ -37,7 +37,7 @@ import com.android.internal.util.ArrayUtils; import com.android.settings.R; import com.android.settings.SettingsActivity; import com.android.settings.Utils; -import com.android.settings.applications.AppHeaderController; +import com.android.settings.applications.EntityHeaderController; import com.android.settings.applications.LayoutPreference; import com.android.settings.core.PreferenceController; import com.android.settings.dashboard.DashboardFragment; @@ -180,14 +180,14 @@ public class AdvancedPowerUsageDetail extends DashboardFragment implements @VisibleForTesting void initHeader() { - final View appSnippet = mHeaderPreference.findViewById(R.id.app_snippet); + final View appSnippet = mHeaderPreference.findViewById(R.id.entity_header); final Activity context = getActivity(); final Bundle bundle = getArguments(); - AppHeaderController controller = FeatureFactory.getFactory(context) + EntityHeaderController controller = FeatureFactory.getFactory(context) .getApplicationFeatureProvider(context) .newAppHeaderController(this, appSnippet) - .setButtonActions(AppHeaderController.ActionType.ACTION_NONE, - AppHeaderController.ActionType.ACTION_NONE); + .setButtonActions(EntityHeaderController.ActionType.ACTION_NONE, + EntityHeaderController.ActionType.ACTION_NONE); if (mAppEntry == null) { controller.setLabel(bundle.getString(EXTRA_LABEL)); diff --git a/src/com/android/settings/notification/AppNotificationSettings.java b/src/com/android/settings/notification/AppNotificationSettings.java index 03a71ca705b..3a4e1c91a17 100644 --- a/src/com/android/settings/notification/AppNotificationSettings.java +++ b/src/com/android/settings/notification/AppNotificationSettings.java @@ -16,10 +16,6 @@ package com.android.settings.notification; -import static android.app.NotificationManager.IMPORTANCE_LOW; -import static android.app.NotificationManager.IMPORTANCE_NONE; -import static android.app.NotificationManager.IMPORTANCE_UNSPECIFIED; - import android.app.Activity; import android.app.NotificationChannel; import android.app.NotificationChannelGroup; @@ -41,8 +37,8 @@ import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.settings.AppHeader; import com.android.settings.R; import com.android.settings.Utils; -import com.android.settings.applications.AppHeaderController; import com.android.settings.applications.AppInfoBase; +import com.android.settings.applications.EntityHeaderController; import com.android.settings.applications.LayoutPreference; import com.android.settings.notification.NotificationBackend.AppRow; import com.android.settings.overlay.FeatureFactory; @@ -51,12 +47,15 @@ import com.android.settings.widget.SwitchBar; import com.android.settingslib.RestrictedSwitchPreference; import com.android.settingslib.widget.FooterPreference; -import java.text.Collator; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; +import static android.app.NotificationManager.IMPORTANCE_LOW; +import static android.app.NotificationManager.IMPORTANCE_NONE; +import static android.app.NotificationManager.IMPORTANCE_UNSPECIFIED; + /** These settings are per app, so should not be returned in global search results. */ public class AppNotificationSettings extends NotificationSettingsBase { private static final String TAG = "AppNotificationSettings"; @@ -139,8 +138,8 @@ public class AppNotificationSettings extends NotificationSettingsBase { .setLabel(mAppRow.label) .setPackageName(mAppRow.pkg) .setUid(mAppRow.uid) - .setButtonActions(AppHeaderController.ActionType.ACTION_APP_INFO, - AppHeaderController.ActionType.ACTION_NOTIF_PREFERENCE) + .setButtonActions(EntityHeaderController.ActionType.ACTION_APP_INFO, + EntityHeaderController.ActionType.ACTION_NOTIF_PREFERENCE) .done(activity, getPrefContext()); pref.setKey(KEY_HEADER); getPreferenceScreen().addPreference(pref); diff --git a/src/com/android/settings/notification/ChannelNotificationSettings.java b/src/com/android/settings/notification/ChannelNotificationSettings.java index 0ce9ec3e7ef..6984c212601 100644 --- a/src/com/android/settings/notification/ChannelNotificationSettings.java +++ b/src/com/android/settings/notification/ChannelNotificationSettings.java @@ -24,10 +24,8 @@ import android.app.Activity; import android.app.NotificationChannel; import android.app.NotificationManager; import android.content.Intent; -import android.content.pm.UserInfo; import android.net.Uri; import android.os.Bundle; -import android.os.UserHandle; import android.provider.Settings; import android.support.v7.preference.Preference; import android.text.TextUtils; @@ -38,12 +36,11 @@ import android.view.View; import android.widget.Switch; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; -import com.android.internal.widget.LockPatternUtils; import com.android.settings.AppHeader; import com.android.settings.R; import com.android.settings.RingtonePreference; import com.android.settings.Utils; -import com.android.settings.applications.AppHeaderController; +import com.android.settings.applications.EntityHeaderController; import com.android.settings.applications.AppInfoBase; import com.android.settings.applications.LayoutPreference; import com.android.settings.overlay.FeatureFactory; @@ -122,8 +119,8 @@ public class ChannelNotificationSettings extends NotificationSettingsBase { .setSummary(mAppRow.label) .setPackageName(mAppRow.pkg) .setUid(mAppRow.uid) - .setButtonActions(AppHeaderController.ActionType.ACTION_APP_INFO, - AppHeaderController.ActionType.ACTION_NOTIF_PREFERENCE) + .setButtonActions(EntityHeaderController.ActionType.ACTION_APP_INFO, + EntityHeaderController.ActionType.ACTION_NOTIF_PREFERENCE) .done(activity, getPrefContext()); getPreferenceScreen().addPreference(pref); } diff --git a/tests/robotests/src/com/android/settings/applications/AppInfoWithHeaderTest.java b/tests/robotests/src/com/android/settings/applications/AppInfoWithHeaderTest.java index 68c153cb6e4..c8a782e9343 100644 --- a/tests/robotests/src/com/android/settings/applications/AppInfoWithHeaderTest.java +++ b/tests/robotests/src/com/android/settings/applications/AppInfoWithHeaderTest.java @@ -68,12 +68,12 @@ public class AppInfoWithHeaderTest { @Test public void testAppHeaderIsAdded() { - final AppHeaderController appHeaderController = new AppHeaderController( + final EntityHeaderController entityHeaderController = new EntityHeaderController( ShadowApplication.getInstance().getApplicationContext(), mAppInfoWithHeader, null); when(mFactory.applicationFeatureProvider.newAppHeaderController(mAppInfoWithHeader, null)) - .thenReturn(appHeaderController); + .thenReturn(entityHeaderController); mAppInfoWithHeader.onActivityCreated(null); verify(mAppInfoWithHeader.mScreen).addPreference(any(LayoutPreference.class)); diff --git a/tests/robotests/src/com/android/settings/applications/AppHeaderControllerTest.java b/tests/robotests/src/com/android/settings/applications/EntityHeaderControllerTest.java similarity index 68% rename from tests/robotests/src/com/android/settings/applications/AppHeaderControllerTest.java rename to tests/robotests/src/com/android/settings/applications/EntityHeaderControllerTest.java index 2cdafe8fcf6..e2e0fa0c027 100644 --- a/tests/robotests/src/com/android/settings/applications/AppHeaderControllerTest.java +++ b/tests/robotests/src/com/android/settings/applications/EntityHeaderControllerTest.java @@ -17,14 +17,6 @@ package com.android.settings.applications; -import static com.google.common.truth.Truth.assertThat; -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.anyInt; -import static org.mockito.Matchers.eq; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - import android.app.ActionBar; import android.app.Activity; import android.app.Fragment; @@ -53,9 +45,17 @@ import org.mockito.MockitoAnnotations; import org.robolectric.RuntimeEnvironment; import org.robolectric.annotation.Config; +import static com.google.common.truth.Truth.assertThat; +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.anyInt; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + @RunWith(SettingsRobolectricTestRunner.class) @Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION) -public class AppHeaderControllerTest { +public class EntityHeaderControllerTest { @Mock(answer = Answers.RETURNS_DEEP_STUBS) private Context mContext; @@ -67,7 +67,7 @@ public class AppHeaderControllerTest { private Context mShadowContext; private LayoutInflater mLayoutInflater; private PackageInfo mInfo; - private AppHeaderController mController; + private EntityHeaderController mController; @Before @@ -82,7 +82,7 @@ public class AppHeaderControllerTest { @Test public void testBuildView_constructedWithoutView_shouldCreateNewView() { - mController = new AppHeaderController(mShadowContext, mFragment, null); + mController = new EntityHeaderController(mShadowContext, mFragment, null); View view = mController.done(mActivity); assertThat(view).isNotNull(); @@ -90,7 +90,7 @@ public class AppHeaderControllerTest { @Test public void testBuildView_withContext_shouldBuildPreference() { - mController = new AppHeaderController(mShadowContext, mFragment, null); + mController = new EntityHeaderController(mShadowContext, mFragment, null); Preference preference = mController.done(mActivity, mShadowContext); assertThat(preference instanceof LayoutPreference).isTrue(); @@ -99,7 +99,7 @@ public class AppHeaderControllerTest { @Test public void testBuildView_constructedWithView_shouldReturnSameView() { View inputView = mLayoutInflater.inflate(R.layout.settings_entity_header, null /* root */); - mController = new AppHeaderController(mShadowContext, mFragment, inputView); + mController = new EntityHeaderController(mShadowContext, mFragment, inputView); View view = mController.done(mActivity); assertThat(view).isSameAs(inputView); @@ -108,11 +108,12 @@ public class AppHeaderControllerTest { @Test public void bindViews_shouldBindAllData() { final String testString = "test"; - final View appHeader = mLayoutInflater.inflate(R.layout.settings_entity_header, null /* root */); - final TextView label = appHeader.findViewById(R.id.app_detail_title); - final TextView version = appHeader.findViewById(R.id.app_detail_summary); + final View header = mLayoutInflater.inflate( + R.layout.settings_entity_header, null /* root */); + final TextView label = header.findViewById(R.id.entity_header_title); + final TextView version = header.findViewById(R.id.entity_header_summary); - mController = new AppHeaderController(mShadowContext, mFragment, appHeader); + mController = new EntityHeaderController(mShadowContext, mFragment, header); mController.setLabel(testString); mController.setSummary(testString); mController.setIcon(mShadowContext.getDrawable(R.drawable.ic_add)); @@ -133,18 +134,18 @@ public class AppHeaderControllerTest { when(mContext.getPackageManager().resolveActivity(any(Intent.class), anyInt())) .thenReturn(info); - mController = new AppHeaderController(mContext, mFragment, appLinks); + mController = new EntityHeaderController(mContext, mFragment, appLinks); mController.setButtonActions( - AppHeaderController.ActionType.ACTION_APP_PREFERENCE, - AppHeaderController.ActionType.ACTION_NONE); + EntityHeaderController.ActionType.ACTION_APP_PREFERENCE, + EntityHeaderController.ActionType.ACTION_NONE); mController.done(mActivity); - assertThat(appLinks.findViewById(R.id.left_button).getVisibility()) + assertThat(appLinks.findViewById(android.R.id.button1).getVisibility()) .isEqualTo(View.VISIBLE); - assertThat(appLinks.findViewById(R.id.right_button).getVisibility()) + assertThat(appLinks.findViewById(android.R.id.button2).getVisibility()) .isEqualTo(View.GONE); try { - appLinks.findViewById(R.id.left_button).performClick(); + appLinks.findViewById(android.R.id.button1).performClick(); } catch (Exception e) { // Ignore exception because the launching intent is fake. } @@ -158,15 +159,15 @@ public class AppHeaderControllerTest { when(mContext.getPackageManager().resolveActivity(any(Intent.class), anyInt())) .thenReturn(null); - mController = new AppHeaderController(mContext, mFragment, appLinks); + mController = new EntityHeaderController(mContext, mFragment, appLinks); mController.setButtonActions( - AppHeaderController.ActionType.ACTION_APP_PREFERENCE, - AppHeaderController.ActionType.ACTION_NONE); + EntityHeaderController.ActionType.ACTION_APP_PREFERENCE, + EntityHeaderController.ActionType.ACTION_NONE); mController.done(mActivity); - assertThat(appLinks.findViewById(R.id.left_button).getVisibility()) + assertThat(appLinks.findViewById(android.R.id.button1).getVisibility()) .isEqualTo(View.GONE); - assertThat(appLinks.findViewById(R.id.right_button).getVisibility()) + assertThat(appLinks.findViewById(android.R.id.button2).getVisibility()) .isEqualTo(View.GONE); } @@ -175,16 +176,16 @@ public class AppHeaderControllerTest { final View appLinks = mLayoutInflater .inflate(R.layout.settings_entity_header, null /* root */); - mController = new AppHeaderController(mContext, mFragment, appLinks); + mController = new EntityHeaderController(mContext, mFragment, appLinks); mController.setPackageName(null) .setButtonActions( - AppHeaderController.ActionType.ACTION_APP_INFO, - AppHeaderController.ActionType.ACTION_NONE); + EntityHeaderController.ActionType.ACTION_APP_INFO, + EntityHeaderController.ActionType.ACTION_NONE); mController.done(mActivity); - assertThat(appLinks.findViewById(R.id.left_button).getVisibility()) + assertThat(appLinks.findViewById(android.R.id.button1).getVisibility()) .isEqualTo(View.GONE); - assertThat(appLinks.findViewById(R.id.right_button).getVisibility()) + assertThat(appLinks.findViewById(android.R.id.button2).getVisibility()) .isEqualTo(View.GONE); } @@ -194,17 +195,17 @@ public class AppHeaderControllerTest { .inflate(R.layout.settings_entity_header, null /* root */); when(mFragment.getActivity()).thenReturn(mock(Activity.class)); - mController = new AppHeaderController(mContext, mFragment, appLinks); + mController = new EntityHeaderController(mContext, mFragment, appLinks); mController.setPackageName("123") .setUid(UserHandle.USER_SYSTEM) .setButtonActions( - AppHeaderController.ActionType.ACTION_APP_INFO, - AppHeaderController.ActionType.ACTION_NOTIF_PREFERENCE); + EntityHeaderController.ActionType.ACTION_APP_INFO, + EntityHeaderController.ActionType.ACTION_NOTIF_PREFERENCE); mController.done(mActivity); - assertThat(appLinks.findViewById(R.id.left_button).getVisibility()) + assertThat(appLinks.findViewById(android.R.id.button1).getVisibility()) .isEqualTo(View.VISIBLE); - assertThat(appLinks.findViewById(R.id.right_button).getVisibility()) + assertThat(appLinks.findViewById(android.R.id.button2).getVisibility()) .isEqualTo(View.GONE); } @@ -215,15 +216,15 @@ public class AppHeaderControllerTest { when(mFragment.getActivity()).thenReturn(mock(Activity.class)); when(mContext.getString(eq(R.string.application_info_label))).thenReturn("App Info"); - mController = new AppHeaderController(mContext, mFragment, appLinks); + mController = new EntityHeaderController(mContext, mFragment, appLinks); mController.setPackageName("123") .setUid(UserHandle.USER_SYSTEM) .setButtonActions( - AppHeaderController.ActionType.ACTION_APP_INFO, - AppHeaderController.ActionType.ACTION_NOTIF_PREFERENCE); + EntityHeaderController.ActionType.ACTION_APP_INFO, + EntityHeaderController.ActionType.ACTION_NOTIF_PREFERENCE); mController.done(mActivity); - assertThat(appLinks.findViewById(R.id.left_button).getContentDescription()) + assertThat(appLinks.findViewById(android.R.id.button1).getContentDescription()) .isEqualTo("App Info"); } @@ -232,16 +233,16 @@ public class AppHeaderControllerTest { final View appLinks = mLayoutInflater .inflate(R.layout.settings_entity_header, null /* root */); - mController = new AppHeaderController(mContext, mFragment, appLinks); + mController = new EntityHeaderController(mContext, mFragment, appLinks); mController.setAppNotifPrefIntent(new Intent()) .setButtonActions( - AppHeaderController.ActionType.ACTION_NOTIF_PREFERENCE, - AppHeaderController.ActionType.ACTION_NONE); + EntityHeaderController.ActionType.ACTION_NOTIF_PREFERENCE, + EntityHeaderController.ActionType.ACTION_NONE); mController.done(mActivity); - assertThat(appLinks.findViewById(R.id.left_button).getVisibility()) + assertThat(appLinks.findViewById(android.R.id.button1).getVisibility()) .isEqualTo(View.VISIBLE); - assertThat(appLinks.findViewById(R.id.right_button).getVisibility()) + assertThat(appLinks.findViewById(android.R.id.button2).getVisibility()) .isEqualTo(View.GONE); } @@ -249,31 +250,35 @@ public class AppHeaderControllerTest { // app is instant. @Test public void instantApps_normalAppsDontGetLabel() { - final View appHeader = mLayoutInflater.inflate(R.layout.settings_entity_header, null /* root */); - mController = new AppHeaderController(mContext, mFragment, appHeader); + final View header = mLayoutInflater.inflate( + R.layout.settings_entity_header, null /* root */); + mController = new EntityHeaderController(mContext, mFragment, header); mController.done(mActivity); - assertThat(appHeader.findViewById(R.id.install_type).getVisibility()) + + assertThat(header.findViewById(R.id.install_type).getVisibility()) .isEqualTo(View.GONE); } // Test that the "instant apps" label is present in the header when we have an instant app. @Test public void instantApps_expectedHeaderItem() { - final View appHeader = mLayoutInflater.inflate(R.layout.settings_entity_header, null /* root */); - mController = new AppHeaderController(mContext, mFragment, appHeader); + final View header = mLayoutInflater.inflate( + R.layout.settings_entity_header, null /* root */); + mController = new EntityHeaderController(mContext, mFragment, header); mController.setIsInstantApp(true); mController.done(mActivity); - TextView label = appHeader.findViewById(R.id.install_type); + TextView label = header.findViewById(R.id.install_type); + assertThat(label.getVisibility()).isEqualTo(View.VISIBLE); assertThat(label.getText()).isEqualTo( - appHeader.getResources().getString(R.string.install_type_instant)); - assertThat(appHeader.findViewById(R.id.app_detail_summary).getVisibility()) + header.getResources().getString(R.string.install_type_instant)); + assertThat(header.findViewById(R.id.entity_header_summary).getVisibility()) .isEqualTo(View.GONE); } @Test public void styleActionBar_invalidObjects_shouldNotCrash() { - mController = new AppHeaderController(mShadowContext, mFragment, null); + mController = new EntityHeaderController(mShadowContext, mFragment, null); mController.styleActionBar(null); when(mActivity.getActionBar()).thenReturn(null); @@ -286,7 +291,7 @@ public class AppHeaderControllerTest { public void styleActionBar_setElevationAndBackground() { final ActionBar actionBar = mActivity.getActionBar(); - mController = new AppHeaderController(mShadowContext, mFragment, null); + mController = new EntityHeaderController(mShadowContext, mFragment, null); mController.styleActionBar(mActivity); verify(actionBar).setElevation(0); @@ -297,7 +302,7 @@ public class AppHeaderControllerTest { @Test public void initAppHeaderController_appHeaderNull_useFragmentContext() { - mController = new AppHeaderController(mContext, mFragment, null); + mController = new EntityHeaderController(mContext, mFragment, null); // Fragment.getContext() is invoked to inflate the view verify(mFragment).getContext(); diff --git a/tests/robotests/src/com/android/settings/datausage/AppDataUsageTest.java b/tests/robotests/src/com/android/settings/datausage/AppDataUsageTest.java index 2e49ed2a8b6..6edbe351d5b 100644 --- a/tests/robotests/src/com/android/settings/datausage/AppDataUsageTest.java +++ b/tests/robotests/src/com/android/settings/datausage/AppDataUsageTest.java @@ -25,8 +25,8 @@ import android.view.View; import com.android.settings.SettingsRobolectricTestRunner; import com.android.settings.TestConfig; -import com.android.settings.applications.AppHeaderController; -import com.android.settings.applications.AppHeaderController.ActionType; +import com.android.settings.applications.EntityHeaderController; +import com.android.settings.applications.EntityHeaderController.ActionType; import com.android.settings.testutils.FakeFeatureFactory; import com.android.settingslib.AppItem; @@ -54,7 +54,7 @@ public class AppDataUsageTest { @Mock(answer = Answers.RETURNS_DEEP_STUBS) private Context mContext; @Mock(answer = Answers.RETURNS_DEEP_STUBS) - private AppHeaderController mHeaderController; + private EntityHeaderController mHeaderController; private FakeFeatureFactory mFeatureFactory; private AppDataUsage mFragment; diff --git a/tests/robotests/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetailTest.java b/tests/robotests/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetailTest.java index 69bd767c501..5762e76c0b1 100644 --- a/tests/robotests/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetailTest.java +++ b/tests/robotests/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetailTest.java @@ -16,19 +16,6 @@ package com.android.settings.fuelgauge; -import static com.google.common.truth.Truth.assertThat; - -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.anyInt; -import static org.mockito.Matchers.anyLong; -import static org.mockito.Matchers.anyString; -import static org.mockito.Matchers.eq; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.verify; - import android.app.Activity; import android.app.Fragment; import android.content.Context; @@ -44,7 +31,7 @@ import com.android.internal.os.BatteryStatsHelper; import com.android.settings.SettingsActivity; import com.android.settings.SettingsRobolectricTestRunner; import com.android.settings.TestConfig; -import com.android.settings.applications.AppHeaderController; +import com.android.settings.applications.EntityHeaderController; import com.android.settings.applications.LayoutPreference; import com.android.settings.testutils.FakeFeatureFactory; import com.android.settingslib.applications.AppUtils; @@ -64,6 +51,18 @@ import org.robolectric.RuntimeEnvironment; import org.robolectric.annotation.Config; import org.robolectric.util.ReflectionHelpers; +import static com.google.common.truth.Truth.assertThat; +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.anyInt; +import static org.mockito.Matchers.anyLong; +import static org.mockito.Matchers.anyString; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.doAnswer; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.verify; + @RunWith(SettingsRobolectricTestRunner.class) @Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION) public class AdvancedPowerUsageDetailTest { @@ -85,7 +84,7 @@ public class AdvancedPowerUsageDetailTest { @Mock(answer = Answers.RETURNS_DEEP_STUBS) private Activity mActivity; @Mock - private AppHeaderController mAppHeaderController; + private EntityHeaderController mEntityHeaderController; @Mock private LayoutPreference mHeaderPreference; @Mock @@ -121,18 +120,18 @@ public class AdvancedPowerUsageDetailTest { doReturn(APP_LABEL).when(mBundle).getString(anyString()); doReturn(mBundle).when(mFragment).getArguments(); - doReturn(mAppHeaderController).when(mFeatureFactory.applicationFeatureProvider) + doReturn(mEntityHeaderController).when(mFeatureFactory.applicationFeatureProvider) .newAppHeaderController(any(Fragment.class), any(View.class)); - doReturn(mAppHeaderController).when(mAppHeaderController).setButtonActions(anyInt(), - anyInt()); - doReturn(mAppHeaderController).when(mAppHeaderController).setIcon(any(Drawable.class)); - doReturn(mAppHeaderController).when(mAppHeaderController).setIcon(any( + doReturn(mEntityHeaderController).when(mEntityHeaderController) + .setButtonActions(anyInt(), anyInt()); + doReturn(mEntityHeaderController).when(mEntityHeaderController) + .setIcon(any(Drawable.class)); + doReturn(mEntityHeaderController).when(mEntityHeaderController).setIcon(any( ApplicationsState.AppEntry.class)); - doReturn(mAppHeaderController).when(mAppHeaderController).setLabel(anyString()); - doReturn(mAppHeaderController).when(mAppHeaderController).setLabel(any( - ApplicationsState.AppEntry.class)); - doReturn(mAppHeaderController).when(mAppHeaderController).setSummary(anyString()); - + doReturn(mEntityHeaderController).when(mEntityHeaderController).setLabel(anyString()); + doReturn(mEntityHeaderController).when(mEntityHeaderController) + .setLabel(any(ApplicationsState.AppEntry.class)); + doReturn(mEntityHeaderController).when(mEntityHeaderController).setSummary(anyString()); doReturn(UID).when(mBatterySipper).getUid(); doReturn(APP_LABEL).when(mBatteryEntry).getLabel(); @@ -171,8 +170,8 @@ public class AdvancedPowerUsageDetailTest { mFragment.mAppEntry = null; mFragment.initHeader(); - verify(mAppHeaderController).setIcon(any(Drawable.class)); - verify(mAppHeaderController).setLabel(APP_LABEL); + verify(mEntityHeaderController).setIcon(any(Drawable.class)); + verify(mEntityHeaderController).setLabel(APP_LABEL); } @Test @@ -187,9 +186,9 @@ public class AdvancedPowerUsageDetailTest { mFragment.mAppEntry = mAppEntry; mFragment.initHeader(); - verify(mAppHeaderController).setIcon(mAppEntry); - verify(mAppHeaderController).setLabel(mAppEntry); - verify(mAppHeaderController).setIsInstantApp(false); + verify(mEntityHeaderController).setIcon(mAppEntry); + verify(mEntityHeaderController).setLabel(mAppEntry); + verify(mEntityHeaderController).setIsInstantApp(false); } @Test @@ -204,10 +203,10 @@ public class AdvancedPowerUsageDetailTest { mFragment.mAppEntry = mAppEntry; mFragment.initHeader(); - verify(mAppHeaderController).setIcon(mAppEntry); - verify(mAppHeaderController).setLabel(mAppEntry); - verify(mAppHeaderController).setIsInstantApp(true); - verify(mAppHeaderController).setSummary((CharSequence) null); + verify(mEntityHeaderController).setIcon(mAppEntry); + verify(mEntityHeaderController).setLabel(mAppEntry); + verify(mEntityHeaderController).setIsInstantApp(true); + verify(mEntityHeaderController).setSummary((CharSequence) null); } @Test From d7414259d03f00b08d2ad4bc223ff1d417c4c4a8 Mon Sep 17 00:00:00 2001 From: Fan Zhang Date: Thu, 18 May 2017 11:28:21 -0700 Subject: [PATCH 2/3] Move entity header controller out of application package. Bug: 37669238 Test: rerun robotests Change-Id: I54eb30f28fa0a88a6f0b97b53f9f1408320b5ce0 --- .../applications/AppInfoWithHeader.java | 9 ++-- .../settings/applications/AppOpsDetails.java | 1 + .../ApplicationFeatureProvider.java | 5 -- .../ApplicationFeatureProviderImpl.java | 5 -- .../applications/InstalledAppDetails.java | 9 ++-- .../applications/ProcessStatsDetail.java | 11 ++--- .../settings/datausage/AppDataUsage.java | 8 ++- .../fuelgauge/AdvancedPowerUsageDetail.java | 8 ++- .../notification/AppNotificationSettings.java | 10 ++-- .../ChannelNotificationSettings.java | 18 +++---- .../settings/overlay/FeatureFactory.java | 2 +- .../EntityHeaderController.java | 45 ++++++++++++++--- .../applications/AppInfoWithHeaderTest.java | 22 ++++++--- .../settings/datausage/AppDataUsageTest.java | 21 +++++--- .../AdvancedPowerUsageDetailTest.java | 17 ++++--- .../LanguageAndInputSettingsTest.java | 19 ++++--- .../testutils/FakeFeatureFactory.java | 8 +-- .../shadow/ShadowEntityHeaderController.java | 49 +++++++++++++++++++ .../EntityHeaderControllerTest.java | 39 ++++++++------- 19 files changed, 192 insertions(+), 114 deletions(-) rename src/com/android/settings/{applications => widget}/EntityHeaderController.java (84%) create mode 100644 tests/robotests/src/com/android/settings/testutils/shadow/ShadowEntityHeaderController.java rename tests/robotests/src/com/android/settings/{applications => widget}/EntityHeaderControllerTest.java (86%) diff --git a/src/com/android/settings/applications/AppInfoWithHeader.java b/src/com/android/settings/applications/AppInfoWithHeader.java index 6129fef2519..bbcec3c0f8a 100644 --- a/src/com/android/settings/applications/AppInfoWithHeader.java +++ b/src/com/android/settings/applications/AppInfoWithHeader.java @@ -22,10 +22,10 @@ import android.support.v7.preference.Preference; import android.util.IconDrawableFactory; import android.util.Log; -import com.android.settings.overlay.FeatureFactory; +import com.android.settings.widget.EntityHeaderController; import com.android.settingslib.applications.AppUtils; -import static com.android.settings.applications.EntityHeaderController.ActionType; +import static com.android.settings.widget.EntityHeaderController.ActionType; public abstract class AppInfoWithHeader extends AppInfoBase { @@ -41,9 +41,8 @@ public abstract class AppInfoWithHeader extends AppInfoBase { mCreated = true; if (mPackageInfo == null) return; final Activity activity = getActivity(); - final Preference pref = FeatureFactory.getFactory(activity) - .getApplicationFeatureProvider(activity) - .newAppHeaderController(this, null /* appHeader */) + final Preference pref = EntityHeaderController + .newInstance(activity, this, null /* header */) .setIcon(IconDrawableFactory.newInstance(activity) .getBadgedIcon(mPackageInfo.applicationInfo)) .setLabel(mPackageInfo.applicationInfo.loadLabel(mPm)) diff --git a/src/com/android/settings/applications/AppOpsDetails.java b/src/com/android/settings/applications/AppOpsDetails.java index 9800ea0281e..b488af696e8 100644 --- a/src/com/android/settings/applications/AppOpsDetails.java +++ b/src/com/android/settings/applications/AppOpsDetails.java @@ -44,6 +44,7 @@ import com.android.settings.core.InstrumentedPreferenceFragment; import com.android.settings.R; import com.android.settings.SettingsActivity; import com.android.settings.Utils; +import com.android.settings.widget.EntityHeaderController; import java.util.List; diff --git a/src/com/android/settings/applications/ApplicationFeatureProvider.java b/src/com/android/settings/applications/ApplicationFeatureProvider.java index a6d26ebd01a..bff93b8e748 100644 --- a/src/com/android/settings/applications/ApplicationFeatureProvider.java +++ b/src/com/android/settings/applications/ApplicationFeatureProvider.java @@ -27,11 +27,6 @@ import java.util.List; public interface ApplicationFeatureProvider { - /** - * Returns a new {@link EntityHeaderController} instance to customize app header. - */ - EntityHeaderController newAppHeaderController(Fragment fragment, View appHeader); - /** * Returns a new {@link InstantAppButtonsController} instance for showing buttons * only relevant to instant apps. diff --git a/src/com/android/settings/applications/ApplicationFeatureProviderImpl.java b/src/com/android/settings/applications/ApplicationFeatureProviderImpl.java index cdbbeb6cf65..36e0965e101 100644 --- a/src/com/android/settings/applications/ApplicationFeatureProviderImpl.java +++ b/src/com/android/settings/applications/ApplicationFeatureProviderImpl.java @@ -52,11 +52,6 @@ public class ApplicationFeatureProviderImpl implements ApplicationFeatureProvide mUm = UserManager.get(mContext); } - @Override - public EntityHeaderController newAppHeaderController(Fragment fragment, View appHeader) { - return new EntityHeaderController(mContext, fragment, appHeader); - } - @Override public InstantAppButtonsController newInstantAppButtonsController(Fragment fragment, View view, InstantAppButtonsController.ShowDialogDelegate showDialogDelegate) { diff --git a/src/com/android/settings/applications/InstalledAppDetails.java b/src/com/android/settings/applications/InstalledAppDetails.java index 1ff4a03073f..3021f7560c2 100755 --- a/src/com/android/settings/applications/InstalledAppDetails.java +++ b/src/com/android/settings/applications/InstalledAppDetails.java @@ -91,6 +91,7 @@ import com.android.settings.notification.AppNotificationSettings; import com.android.settings.notification.NotificationBackend; import com.android.settings.notification.NotificationBackend.AppRow; import com.android.settings.overlay.FeatureFactory; +import com.android.settings.widget.EntityHeaderController; import com.android.settingslib.AppItem; import com.android.settingslib.RestrictedLockUtils; import com.android.settingslib.applications.AppUtils; @@ -406,9 +407,7 @@ public class InstalledAppDetails extends AppInfoBase final Activity activity = getActivity(); mHeader = (LayoutPreference) findPreference(KEY_HEADER); mActionButtons = (LayoutPreference) findPreference(KEY_ACTION_BUTTONS); - FeatureFactory.getFactory(activity) - .getApplicationFeatureProvider(activity) - .newAppHeaderController(this, mHeader.findViewById(R.id.entity_header)) + EntityHeaderController.newInstance(activity, this, mHeader.findViewById(R.id.entity_header)) .setPackageName(mPackageName) .setButtonActions(EntityHeaderController.ActionType.ACTION_APP_PREFERENCE, EntityHeaderController.ActionType.ACTION_NONE) @@ -585,9 +584,7 @@ public class InstalledAppDetails extends AppInfoBase final boolean isInstantApp = AppUtils.isInstant(mPackageInfo.applicationInfo); final CharSequence summary = isInstantApp ? null : getString(Utils.getInstallationStatus(mAppEntry.info)); - FeatureFactory.getFactory(activity) - .getApplicationFeatureProvider(activity) - .newAppHeaderController(this, appSnippet) + EntityHeaderController.newInstance(activity, this, appSnippet) .setLabel(mAppEntry) .setIcon(mAppEntry) .setSummary(summary) diff --git a/src/com/android/settings/applications/ProcessStatsDetail.java b/src/com/android/settings/applications/ProcessStatsDetail.java index 0313239b288..9f229afa1f4 100644 --- a/src/com/android/settings/applications/ProcessStatsDetail.java +++ b/src/com/android/settings/applications/ProcessStatsDetail.java @@ -16,8 +16,6 @@ package com.android.settings.applications; -import static com.android.settings.applications.EntityHeaderController.ActionType; - import android.app.Activity; import android.app.ActivityManager; import android.app.ActivityManager.RunningServiceInfo; @@ -53,7 +51,7 @@ import com.android.settings.R; import com.android.settings.SettingsPreferenceFragment; import com.android.settings.SummaryPreference; import com.android.settings.applications.ProcStatsEntry.Service; -import com.android.settings.overlay.FeatureFactory; +import com.android.settings.widget.EntityHeaderController; import java.util.ArrayList; import java.util.Collections; @@ -61,6 +59,8 @@ import java.util.Comparator; import java.util.HashMap; import java.util.List; +import static com.android.settings.widget.EntityHeaderController.ActionType; + public class ProcessStatsDetail extends SettingsPreferenceFragment { private static final String TAG = "ProcessStatsDetail"; @@ -126,9 +126,8 @@ public class ProcessStatsDetail extends SettingsPreferenceFragment { return; } final Activity activity = getActivity(); - final Preference pref = FeatureFactory.getFactory(activity) - .getApplicationFeatureProvider(activity) - .newAppHeaderController(this, null /* appHeader */) + final Preference pref = EntityHeaderController + .newInstance(activity, this, null /* appHeader */) .setIcon(mApp.mUiTargetApp != null ? IconDrawableFactory.newInstance(activity).getBadgedIcon(mApp.mUiTargetApp) : new ColorDrawable(0)) diff --git a/src/com/android/settings/datausage/AppDataUsage.java b/src/com/android/settings/datausage/AppDataUsage.java index 0aa08422cb8..a47e1357533 100644 --- a/src/com/android/settings/datausage/AppDataUsage.java +++ b/src/com/android/settings/datausage/AppDataUsage.java @@ -41,9 +41,8 @@ import android.widget.AdapterView; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.settings.R; -import com.android.settings.applications.EntityHeaderController; import com.android.settings.applications.AppInfoBase; -import com.android.settings.overlay.FeatureFactory; +import com.android.settings.widget.EntityHeaderController; import com.android.settingslib.AppItem; import com.android.settingslib.net.ChartData; import com.android.settingslib.net.ChartDataLoader; @@ -326,9 +325,8 @@ public class AppDataUsage extends DataUsageBase implements Preference.OnPreferen final boolean showInfoButton = mAppItem.key > 0; final Activity activity = getActivity(); - final Preference pref = FeatureFactory.getFactory(activity) - .getApplicationFeatureProvider(activity) - .newAppHeaderController(this, null /* appHeader */) + final Preference pref = EntityHeaderController + .newInstance(activity, this, null /* header */) .setButtonActions(showInfoButton ? EntityHeaderController.ActionType.ACTION_APP_INFO : EntityHeaderController.ActionType.ACTION_NONE, diff --git a/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetail.java b/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetail.java index 456a5112547..18223410831 100644 --- a/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetail.java +++ b/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetail.java @@ -37,13 +37,12 @@ import com.android.internal.util.ArrayUtils; import com.android.settings.R; import com.android.settings.SettingsActivity; import com.android.settings.Utils; -import com.android.settings.applications.EntityHeaderController; import com.android.settings.applications.LayoutPreference; import com.android.settings.core.PreferenceController; import com.android.settings.dashboard.DashboardFragment; import com.android.settings.enterprise.DevicePolicyManagerWrapper; import com.android.settings.enterprise.DevicePolicyManagerWrapperImpl; -import com.android.settings.overlay.FeatureFactory; +import com.android.settings.widget.EntityHeaderController; import com.android.settingslib.applications.AppUtils; import com.android.settingslib.applications.ApplicationsState; @@ -183,9 +182,8 @@ public class AdvancedPowerUsageDetail extends DashboardFragment implements final View appSnippet = mHeaderPreference.findViewById(R.id.entity_header); final Activity context = getActivity(); final Bundle bundle = getArguments(); - EntityHeaderController controller = FeatureFactory.getFactory(context) - .getApplicationFeatureProvider(context) - .newAppHeaderController(this, appSnippet) + EntityHeaderController controller = EntityHeaderController + .newInstance(context, this, appSnippet) .setButtonActions(EntityHeaderController.ActionType.ACTION_NONE, EntityHeaderController.ActionType.ACTION_NONE); diff --git a/src/com/android/settings/notification/AppNotificationSettings.java b/src/com/android/settings/notification/AppNotificationSettings.java index 3a4e1c91a17..92ad3f1e814 100644 --- a/src/com/android/settings/notification/AppNotificationSettings.java +++ b/src/com/android/settings/notification/AppNotificationSettings.java @@ -38,10 +38,9 @@ import com.android.settings.AppHeader; import com.android.settings.R; import com.android.settings.Utils; import com.android.settings.applications.AppInfoBase; -import com.android.settings.applications.EntityHeaderController; import com.android.settings.applications.LayoutPreference; import com.android.settings.notification.NotificationBackend.AppRow; -import com.android.settings.overlay.FeatureFactory; +import com.android.settings.widget.EntityHeaderController; import com.android.settings.widget.MasterSwitchPreference; import com.android.settings.widget.SwitchBar; import com.android.settingslib.RestrictedSwitchPreference; @@ -127,13 +126,12 @@ public class AppNotificationSettings extends NotificationSettingsBase { } private void addHeaderPref() { - ArrayMap rows = new ArrayMap(); + ArrayMap rows = new ArrayMap<>(); rows.put(mAppRow.pkg, mAppRow); collectConfigActivities(rows); final Activity activity = getActivity(); - final Preference pref = FeatureFactory.getFactory(activity) - .getApplicationFeatureProvider(activity) - .newAppHeaderController(this /* fragment */, null /* appHeader */) + final Preference pref = EntityHeaderController + .newInstance(activity, this /* fragment */, null /* header */) .setIcon(mAppRow.icon) .setLabel(mAppRow.label) .setPackageName(mAppRow.pkg) diff --git a/src/com/android/settings/notification/ChannelNotificationSettings.java b/src/com/android/settings/notification/ChannelNotificationSettings.java index 6984c212601..85a56baa609 100644 --- a/src/com/android/settings/notification/ChannelNotificationSettings.java +++ b/src/com/android/settings/notification/ChannelNotificationSettings.java @@ -16,10 +16,6 @@ package com.android.settings.notification; -import static android.app.NotificationManager.IMPORTANCE_LOW; -import static android.app.NotificationManager.IMPORTANCE_NONE; -import static android.app.NotificationManager.IMPORTANCE_UNSPECIFIED; - import android.app.Activity; import android.app.NotificationChannel; import android.app.NotificationManager; @@ -40,14 +36,17 @@ import com.android.settings.AppHeader; import com.android.settings.R; import com.android.settings.RingtonePreference; import com.android.settings.Utils; -import com.android.settings.applications.EntityHeaderController; import com.android.settings.applications.AppInfoBase; import com.android.settings.applications.LayoutPreference; -import com.android.settings.overlay.FeatureFactory; +import com.android.settings.widget.EntityHeaderController; import com.android.settings.widget.SwitchBar; import com.android.settingslib.RestrictedSwitchPreference; import com.android.settingslib.widget.FooterPreference; +import static android.app.NotificationManager.IMPORTANCE_LOW; +import static android.app.NotificationManager.IMPORTANCE_NONE; +import static android.app.NotificationManager.IMPORTANCE_UNSPECIFIED; + public class ChannelNotificationSettings extends NotificationSettingsBase { private static final String TAG = "ChannelSettings"; @@ -107,13 +106,12 @@ public class ChannelNotificationSettings extends NotificationSettingsBase { } private void addHeaderPref() { - ArrayMap rows = new ArrayMap(); + ArrayMap rows = new ArrayMap<>(); rows.put(mAppRow.pkg, mAppRow); collectConfigActivities(rows); final Activity activity = getActivity(); - final Preference pref = FeatureFactory.getFactory(activity) - .getApplicationFeatureProvider(activity) - .newAppHeaderController(this /* fragment */, null /* appHeader */) + final Preference pref = EntityHeaderController + .newInstance(activity, this /* fragment */, null /* header */) .setIcon(mAppRow.icon) .setLabel(mChannel.getName()) .setSummary(mAppRow.label) diff --git a/src/com/android/settings/overlay/FeatureFactory.java b/src/com/android/settings/overlay/FeatureFactory.java index 6f1d35051d6..60893b29790 100644 --- a/src/com/android/settings/overlay/FeatureFactory.java +++ b/src/com/android/settings/overlay/FeatureFactory.java @@ -30,8 +30,8 @@ import com.android.settings.enterprise.EnterprisePrivacyFeatureProvider; import com.android.settings.fuelgauge.PowerUsageFeatureProvider; import com.android.settings.gestures.AssistGestureFeatureProvider; import com.android.settings.localepicker.LocaleFeatureProvider; -import com.android.settings.security.SecurityFeatureProvider; import com.android.settings.search2.SearchFeatureProvider; +import com.android.settings.security.SecurityFeatureProvider; import com.android.settings.users.UserFeatureProvider; /** diff --git a/src/com/android/settings/applications/EntityHeaderController.java b/src/com/android/settings/widget/EntityHeaderController.java similarity index 84% rename from src/com/android/settings/applications/EntityHeaderController.java rename to src/com/android/settings/widget/EntityHeaderController.java index 98658b13ef4..d5231776f67 100644 --- a/src/com/android/settings/applications/EntityHeaderController.java +++ b/src/com/android/settings/widget/EntityHeaderController.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.settings.applications; +package com.android.settings.widget; import android.annotation.IdRes; import android.annotation.UserIdInt; @@ -41,6 +41,9 @@ import android.widget.TextView; import com.android.settings.AppHeader; import com.android.settings.R; import com.android.settings.Utils; +import com.android.settings.applications.AppInfoBase; +import com.android.settings.applications.InstalledAppDetails; +import com.android.settings.applications.LayoutPreference; import com.android.settings.overlay.FeatureFactory; import com.android.settingslib.applications.ApplicationsState; @@ -84,7 +87,18 @@ public class EntityHeaderController { private boolean mIsInstantApp; - public EntityHeaderController(Context context, Fragment fragment, View header) { + /** + * Creates a new instance of the controller. + * + * @param fragment The fragment that header will be placed in. + * @param header Optional: header view if it's already created. + */ + public static EntityHeaderController newInstance(Context context, Fragment fragment, + View header) { + return new EntityHeaderController(context.getApplicationContext(), fragment, header); + } + + private EntityHeaderController(Context context, Fragment fragment, View header) { mContext = context; mFragment = fragment; mMetricsCategory = FeatureFactory.getFactory(context).getMetricsFeatureProvider() @@ -245,9 +259,16 @@ public class EntityHeaderController { button.setContentDescription( mContext.getString(R.string.application_info_label)); button.setImageResource(com.android.settings.R.drawable.ic_info); - button.setOnClickListener(v -> AppInfoBase.startAppInfoFragment( - InstalledAppDetails.class, R.string.application_info_label, - mPackageName, mUid, mFragment, 0 /* request */, mMetricsCategory)); + button.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + AppInfoBase.startAppInfoFragment( + InstalledAppDetails.class, R.string.application_info_label, + mPackageName, mUid, mFragment, 0 /* request */, + mMetricsCategory); + + } + }); button.setVisibility(View.VISIBLE); } return; @@ -256,7 +277,12 @@ public class EntityHeaderController { if (mAppNotifPrefIntent == null) { button.setVisibility(View.GONE); } else { - button.setOnClickListener(v -> mFragment.startActivity(mAppNotifPrefIntent)); + button.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + mFragment.startActivity(mAppNotifPrefIntent); + } + }); button.setVisibility(View.VISIBLE); } return; @@ -268,7 +294,12 @@ public class EntityHeaderController { button.setVisibility(View.GONE); return; } - button.setOnClickListener(v -> mFragment.startActivity(intent)); + button.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + mFragment.startActivity(intent); + } + }); button.setVisibility(View.VISIBLE); return; } diff --git a/tests/robotests/src/com/android/settings/applications/AppInfoWithHeaderTest.java b/tests/robotests/src/com/android/settings/applications/AppInfoWithHeaderTest.java index c8a782e9343..5a526e724ee 100644 --- a/tests/robotests/src/com/android/settings/applications/AppInfoWithHeaderTest.java +++ b/tests/robotests/src/com/android/settings/applications/AppInfoWithHeaderTest.java @@ -28,9 +28,12 @@ import com.android.internal.logging.nano.MetricsProto; import com.android.settings.SettingsRobolectricTestRunner; import com.android.settings.TestConfig; import com.android.settings.testutils.FakeFeatureFactory; +import com.android.settings.testutils.shadow.ShadowEntityHeaderController; +import com.android.settings.widget.EntityHeaderController; import com.android.settingslib.applications.AppUtils; import com.android.settingslib.applications.instantapps.InstantAppDataProvider; +import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -47,10 +50,13 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @RunWith(SettingsRobolectricTestRunner.class) -@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION) +@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION, + shadows = ShadowEntityHeaderController.class) public class AppInfoWithHeaderTest { @Mock(answer = Answers.RETURNS_DEEP_STUBS) private Context mContext; + @Mock(answer = Answers.RETURNS_DEEP_STUBS) + private EntityHeaderController mHeaderController; private FakeFeatureFactory mFactory; private TestFragment mAppInfoWithHeader; @@ -64,16 +70,16 @@ public class AppInfoWithHeaderTest { when(mFactory.metricsFeatureProvider.getMetricsCategory(any(Object.class))) .thenReturn(MetricsProto.MetricsEvent.SETTINGS_APP_NOTIF_CATEGORY); mAppInfoWithHeader = new TestFragment(); + ShadowEntityHeaderController.setUseMock(mHeaderController); + } + + @After + public void tearDown() { + ShadowEntityHeaderController.reset(); } @Test public void testAppHeaderIsAdded() { - final EntityHeaderController entityHeaderController = new EntityHeaderController( - ShadowApplication.getInstance().getApplicationContext(), - mAppInfoWithHeader, - null); - when(mFactory.applicationFeatureProvider.newAppHeaderController(mAppInfoWithHeader, null)) - .thenReturn(entityHeaderController); mAppInfoWithHeader.onActivityCreated(null); verify(mAppInfoWithHeader.mScreen).addPreference(any(LayoutPreference.class)); @@ -93,7 +99,7 @@ public class AppInfoWithHeaderTest { mPackageInfo.applicationInfo = new ApplicationInfo(); mShadowContext = ShadowApplication.getInstance().getApplicationContext(); ReflectionHelpers.setStaticField(AppUtils.class, "sInstantAppDataProvider", - (InstantAppDataProvider) (info -> false)); + (InstantAppDataProvider) (info -> false)); when(mManager.getContext()).thenReturn(mShadowContext); } diff --git a/tests/robotests/src/com/android/settings/datausage/AppDataUsageTest.java b/tests/robotests/src/com/android/settings/datausage/AppDataUsageTest.java index 6edbe351d5b..2d0f0318188 100644 --- a/tests/robotests/src/com/android/settings/datausage/AppDataUsageTest.java +++ b/tests/robotests/src/com/android/settings/datausage/AppDataUsageTest.java @@ -25,11 +25,13 @@ import android.view.View; import com.android.settings.SettingsRobolectricTestRunner; import com.android.settings.TestConfig; -import com.android.settings.applications.EntityHeaderController; -import com.android.settings.applications.EntityHeaderController.ActionType; import com.android.settings.testutils.FakeFeatureFactory; +import com.android.settings.testutils.shadow.ShadowEntityHeaderController; +import com.android.settings.widget.EntityHeaderController; +import com.android.settings.widget.EntityHeaderController.ActionType; import com.android.settingslib.AppItem; +import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -45,28 +47,33 @@ import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; @RunWith(SettingsRobolectricTestRunner.class) -@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION) +@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION, + shadows = ShadowEntityHeaderController.class) public class AppDataUsageTest { @Mock(answer = Answers.RETURNS_DEEP_STUBS) private Context mContext; @Mock(answer = Answers.RETURNS_DEEP_STUBS) private EntityHeaderController mHeaderController; - private FakeFeatureFactory mFeatureFactory; + private AppDataUsage mFragment; @Before public void setUp() { MockitoAnnotations.initMocks(this); FakeFeatureFactory.setupForTest(mContext); - mFeatureFactory = (FakeFeatureFactory) FakeFeatureFactory.getFactory(mContext); + } + + @After + public void tearDown() { + ShadowEntityHeaderController.reset(); } @Test public void bindAppHeader_allWorkApps_shouldNotShowAppInfoLink() { + ShadowEntityHeaderController.setUseMock(mHeaderController); mFragment = spy(new AppDataUsage()); doReturn(mock(PreferenceManager.class, RETURNS_DEEP_STUBS)) @@ -74,8 +81,6 @@ public class AppDataUsageTest { .getPreferenceManager(); doReturn(mock(PreferenceScreen.class)).when(mFragment).getPreferenceScreen(); ReflectionHelpers.setField(mFragment, "mAppItem", mock(AppItem.class)); - when(mFeatureFactory.applicationFeatureProvider.newAppHeaderController(mFragment, null)) - .thenReturn(mHeaderController); mFragment.onViewCreated(new View(RuntimeEnvironment.application), new Bundle()); diff --git a/tests/robotests/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetailTest.java b/tests/robotests/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetailTest.java index 5762e76c0b1..7b2d8cc63ac 100644 --- a/tests/robotests/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetailTest.java +++ b/tests/robotests/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetailTest.java @@ -17,27 +17,27 @@ package com.android.settings.fuelgauge; import android.app.Activity; -import android.app.Fragment; import android.content.Context; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.graphics.drawable.Drawable; import android.os.BatteryStats; import android.os.Bundle; -import android.view.View; import com.android.internal.os.BatterySipper; import com.android.internal.os.BatteryStatsHelper; import com.android.settings.SettingsActivity; import com.android.settings.SettingsRobolectricTestRunner; import com.android.settings.TestConfig; -import com.android.settings.applications.EntityHeaderController; import com.android.settings.applications.LayoutPreference; import com.android.settings.testutils.FakeFeatureFactory; +import com.android.settings.testutils.shadow.ShadowEntityHeaderController; +import com.android.settings.widget.EntityHeaderController; import com.android.settingslib.applications.AppUtils; import com.android.settingslib.applications.ApplicationsState; import com.android.settingslib.applications.instantapps.InstantAppDataProvider; +import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -64,7 +64,8 @@ import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; @RunWith(SettingsRobolectricTestRunner.class) -@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION) +@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION, + shadows = ShadowEntityHeaderController.class) public class AdvancedPowerUsageDetailTest { private static final String APP_LABEL = "app label"; private static final String SUMMARY = "summary"; @@ -120,8 +121,7 @@ public class AdvancedPowerUsageDetailTest { doReturn(APP_LABEL).when(mBundle).getString(anyString()); doReturn(mBundle).when(mFragment).getArguments(); - doReturn(mEntityHeaderController).when(mFeatureFactory.applicationFeatureProvider) - .newAppHeaderController(any(Fragment.class), any(View.class)); + ShadowEntityHeaderController.setUseMock(mEntityHeaderController); doReturn(mEntityHeaderController).when(mEntityHeaderController) .setButtonActions(anyInt(), anyInt()); doReturn(mEntityHeaderController).when(mEntityHeaderController) @@ -165,6 +165,11 @@ public class AdvancedPowerUsageDetailTest { captor.capture(), anyInt(), any(), any()); } + @After + public void reset() { + ShadowEntityHeaderController.reset(); + } + @Test public void testInitHeader_NoAppEntry_BuildByBundle() { mFragment.mAppEntry = null; diff --git a/tests/robotests/src/com/android/settings/language/LanguageAndInputSettingsTest.java b/tests/robotests/src/com/android/settings/language/LanguageAndInputSettingsTest.java index aedb289d20b..195e0075ecd 100644 --- a/tests/robotests/src/com/android/settings/language/LanguageAndInputSettingsTest.java +++ b/tests/robotests/src/com/android/settings/language/LanguageAndInputSettingsTest.java @@ -16,15 +16,6 @@ package com.android.settings.language; -import static com.google.common.truth.Truth.assertThat; -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - import android.app.Activity; import android.app.admin.DevicePolicyManager; import android.content.ComponentName; @@ -44,7 +35,6 @@ import com.android.settings.SettingsRobolectricTestRunner; import com.android.settings.TestConfig; import com.android.settings.core.PreferenceController; import com.android.settings.dashboard.SummaryLoader; -import com.android.settings.fuelgauge.PowerUsageSummary; import com.android.settings.testutils.FakeFeatureFactory; import com.android.settings.testutils.XmlTestUtils; import com.android.settings.testutils.shadow.ShadowSecureSettings; @@ -63,6 +53,15 @@ import org.robolectric.annotation.Config; import java.util.ArrayList; import java.util.List; +import static com.google.common.truth.Truth.assertThat; +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + @RunWith(SettingsRobolectricTestRunner.class) @Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION) public class LanguageAndInputSettingsTest { diff --git a/tests/robotests/src/com/android/settings/testutils/FakeFeatureFactory.java b/tests/robotests/src/com/android/settings/testutils/FakeFeatureFactory.java index 65bb3898073..6085c1ea01c 100644 --- a/tests/robotests/src/com/android/settings/testutils/FakeFeatureFactory.java +++ b/tests/robotests/src/com/android/settings/testutils/FakeFeatureFactory.java @@ -28,14 +28,13 @@ import com.android.settings.gestures.AssistGestureFeatureProvider; import com.android.settings.localepicker.LocaleFeatureProvider; import com.android.settings.overlay.FeatureFactory; import com.android.settings.overlay.SupportFeatureProvider; -import com.android.settings.security.SecurityFeatureProvider; -import com.android.settings.search2.SearchFeatureProvider; import com.android.settings.overlay.SurveyFeatureProvider; +import com.android.settings.search2.SearchFeatureProvider; +import com.android.settings.security.SecurityFeatureProvider; import com.android.settings.users.UserFeatureProvider; import static org.mockito.Matchers.anyString; import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.mockingDetails; import static org.mockito.Mockito.when; /** @@ -64,7 +63,7 @@ public class FakeFeatureFactory extends FeatureFactory { * * @param context The context must be a deep mock. */ - public static void setupForTest(Context context) { + public static FakeFeatureFactory setupForTest(Context context) { sFactory = null; when(context.getString(com.android.settings.R.string.config_featureFactory)) .thenReturn(FakeFeatureFactory.class.getName()); @@ -74,6 +73,7 @@ public class FakeFeatureFactory extends FeatureFactory { } catch (ClassNotFoundException e) { // Ignore. } + return (FakeFeatureFactory) FakeFeatureFactory.getFactory(context); } /** diff --git a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowEntityHeaderController.java b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowEntityHeaderController.java new file mode 100644 index 00000000000..bccb2972d4e --- /dev/null +++ b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowEntityHeaderController.java @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settings.testutils.shadow; + +import android.app.Fragment; +import android.content.Context; +import android.view.View; + +import com.android.settings.widget.EntityHeaderController; + +import org.robolectric.annotation.Implementation; +import org.robolectric.annotation.Implements; +import org.robolectric.annotation.Resetter; + +@Implements(value = EntityHeaderController.class, callThroughByDefault = false) +public class ShadowEntityHeaderController { + + private static EntityHeaderController sMockController; + + public static void setUseMock(EntityHeaderController mockController) { + sMockController = mockController; + } + + @Resetter + public static void reset() { + sMockController = null; + } + + @Implementation + public static EntityHeaderController newInstance(Context context, Fragment fragment, + View header) { + return sMockController; + } + +} diff --git a/tests/robotests/src/com/android/settings/applications/EntityHeaderControllerTest.java b/tests/robotests/src/com/android/settings/widget/EntityHeaderControllerTest.java similarity index 86% rename from tests/robotests/src/com/android/settings/applications/EntityHeaderControllerTest.java rename to tests/robotests/src/com/android/settings/widget/EntityHeaderControllerTest.java index e2e0fa0c027..e6c742a72a2 100644 --- a/tests/robotests/src/com/android/settings/applications/EntityHeaderControllerTest.java +++ b/tests/robotests/src/com/android/settings/widget/EntityHeaderControllerTest.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.settings.applications; +package com.android.settings.widget; import android.app.ActionBar; @@ -35,6 +35,8 @@ import android.widget.TextView; import com.android.settings.R; import com.android.settings.SettingsRobolectricTestRunner; import com.android.settings.TestConfig; +import com.android.settings.applications.LayoutPreference; +import com.android.settings.testutils.FakeFeatureFactory; import org.junit.Before; import org.junit.Test; @@ -64,16 +66,19 @@ public class EntityHeaderControllerTest { @Mock private Fragment mFragment; + private FakeFeatureFactory mFeatureFactory; private Context mShadowContext; private LayoutInflater mLayoutInflater; private PackageInfo mInfo; private EntityHeaderController mController; - @Before public void setUp() { MockitoAnnotations.initMocks(this); + FakeFeatureFactory.setupForTest(mContext); + mFeatureFactory = (FakeFeatureFactory) FakeFeatureFactory.getFactory(mContext); mShadowContext = RuntimeEnvironment.application; + when(mContext.getApplicationContext()).thenReturn(mContext); when(mFragment.getContext()).thenReturn(mShadowContext); mLayoutInflater = LayoutInflater.from(mShadowContext); mInfo = new PackageInfo(); @@ -82,7 +87,7 @@ public class EntityHeaderControllerTest { @Test public void testBuildView_constructedWithoutView_shouldCreateNewView() { - mController = new EntityHeaderController(mShadowContext, mFragment, null); + mController = EntityHeaderController.newInstance(mShadowContext, mFragment, null); View view = mController.done(mActivity); assertThat(view).isNotNull(); @@ -90,7 +95,7 @@ public class EntityHeaderControllerTest { @Test public void testBuildView_withContext_shouldBuildPreference() { - mController = new EntityHeaderController(mShadowContext, mFragment, null); + mController = EntityHeaderController.newInstance(mShadowContext, mFragment, null); Preference preference = mController.done(mActivity, mShadowContext); assertThat(preference instanceof LayoutPreference).isTrue(); @@ -99,7 +104,7 @@ public class EntityHeaderControllerTest { @Test public void testBuildView_constructedWithView_shouldReturnSameView() { View inputView = mLayoutInflater.inflate(R.layout.settings_entity_header, null /* root */); - mController = new EntityHeaderController(mShadowContext, mFragment, inputView); + mController = EntityHeaderController.newInstance(mShadowContext, mFragment, inputView); View view = mController.done(mActivity); assertThat(view).isSameAs(inputView); @@ -113,7 +118,7 @@ public class EntityHeaderControllerTest { final TextView label = header.findViewById(R.id.entity_header_title); final TextView version = header.findViewById(R.id.entity_header_summary); - mController = new EntityHeaderController(mShadowContext, mFragment, header); + mController = EntityHeaderController.newInstance(mShadowContext, mFragment, header); mController.setLabel(testString); mController.setSummary(testString); mController.setIcon(mShadowContext.getDrawable(R.drawable.ic_add)); @@ -134,7 +139,7 @@ public class EntityHeaderControllerTest { when(mContext.getPackageManager().resolveActivity(any(Intent.class), anyInt())) .thenReturn(info); - mController = new EntityHeaderController(mContext, mFragment, appLinks); + mController = EntityHeaderController.newInstance(mContext, mFragment, appLinks); mController.setButtonActions( EntityHeaderController.ActionType.ACTION_APP_PREFERENCE, EntityHeaderController.ActionType.ACTION_NONE); @@ -159,7 +164,7 @@ public class EntityHeaderControllerTest { when(mContext.getPackageManager().resolveActivity(any(Intent.class), anyInt())) .thenReturn(null); - mController = new EntityHeaderController(mContext, mFragment, appLinks); + mController = EntityHeaderController.newInstance(mContext, mFragment, appLinks); mController.setButtonActions( EntityHeaderController.ActionType.ACTION_APP_PREFERENCE, EntityHeaderController.ActionType.ACTION_NONE); @@ -176,7 +181,7 @@ public class EntityHeaderControllerTest { final View appLinks = mLayoutInflater .inflate(R.layout.settings_entity_header, null /* root */); - mController = new EntityHeaderController(mContext, mFragment, appLinks); + mController = EntityHeaderController.newInstance(mContext, mFragment, appLinks); mController.setPackageName(null) .setButtonActions( EntityHeaderController.ActionType.ACTION_APP_INFO, @@ -195,7 +200,7 @@ public class EntityHeaderControllerTest { .inflate(R.layout.settings_entity_header, null /* root */); when(mFragment.getActivity()).thenReturn(mock(Activity.class)); - mController = new EntityHeaderController(mContext, mFragment, appLinks); + mController = EntityHeaderController.newInstance(mContext, mFragment, appLinks); mController.setPackageName("123") .setUid(UserHandle.USER_SYSTEM) .setButtonActions( @@ -216,7 +221,7 @@ public class EntityHeaderControllerTest { when(mFragment.getActivity()).thenReturn(mock(Activity.class)); when(mContext.getString(eq(R.string.application_info_label))).thenReturn("App Info"); - mController = new EntityHeaderController(mContext, mFragment, appLinks); + mController = EntityHeaderController.newInstance(mContext, mFragment, appLinks); mController.setPackageName("123") .setUid(UserHandle.USER_SYSTEM) .setButtonActions( @@ -233,7 +238,7 @@ public class EntityHeaderControllerTest { final View appLinks = mLayoutInflater .inflate(R.layout.settings_entity_header, null /* root */); - mController = new EntityHeaderController(mContext, mFragment, appLinks); + mController = EntityHeaderController.newInstance(mContext, mFragment, appLinks); mController.setAppNotifPrefIntent(new Intent()) .setButtonActions( EntityHeaderController.ActionType.ACTION_NOTIF_PREFERENCE, @@ -252,7 +257,7 @@ public class EntityHeaderControllerTest { public void instantApps_normalAppsDontGetLabel() { final View header = mLayoutInflater.inflate( R.layout.settings_entity_header, null /* root */); - mController = new EntityHeaderController(mContext, mFragment, header); + mController = EntityHeaderController.newInstance(mContext, mFragment, header); mController.done(mActivity); assertThat(header.findViewById(R.id.install_type).getVisibility()) @@ -264,7 +269,7 @@ public class EntityHeaderControllerTest { public void instantApps_expectedHeaderItem() { final View header = mLayoutInflater.inflate( R.layout.settings_entity_header, null /* root */); - mController = new EntityHeaderController(mContext, mFragment, header); + mController = EntityHeaderController.newInstance(mContext, mFragment, header); mController.setIsInstantApp(true); mController.done(mActivity); TextView label = header.findViewById(R.id.install_type); @@ -278,7 +283,7 @@ public class EntityHeaderControllerTest { @Test public void styleActionBar_invalidObjects_shouldNotCrash() { - mController = new EntityHeaderController(mShadowContext, mFragment, null); + mController = EntityHeaderController.newInstance(mShadowContext, mFragment, null); mController.styleActionBar(null); when(mActivity.getActionBar()).thenReturn(null); @@ -291,7 +296,7 @@ public class EntityHeaderControllerTest { public void styleActionBar_setElevationAndBackground() { final ActionBar actionBar = mActivity.getActionBar(); - mController = new EntityHeaderController(mShadowContext, mFragment, null); + mController = EntityHeaderController.newInstance(mShadowContext, mFragment, null); mController.styleActionBar(mActivity); verify(actionBar).setElevation(0); @@ -302,7 +307,7 @@ public class EntityHeaderControllerTest { @Test public void initAppHeaderController_appHeaderNull_useFragmentContext() { - mController = new EntityHeaderController(mContext, mFragment, null); + mController = EntityHeaderController.newInstance(mContext, mFragment, null); // Fragment.getContext() is invoked to inflate the view verify(mFragment).getContext(); From 98289a887b7ed9201c3a74794225ead571ced28f Mon Sep 17 00:00:00 2001 From: Fan Zhang Date: Thu, 18 May 2017 15:11:01 -0700 Subject: [PATCH 3/3] Use entity header on AccountDetailDashboardFragment Bug: 37669238 Test: make RunSettingsRoboTests Change-Id: Iaf92730e8c6b5c44cb8eca4525fc931487ce9630 --- res/layout/account_header.xml | 53 -------- res/layout/settings_entity_header.xml | 4 +- res/xml/account_type_settings.xml | 10 +- .../AccountDetailDashboardFragment.java | 16 +-- .../AccountHeaderPreferenceController.java | 87 +++++++++++++ .../widget/EntityHeaderController.java | 4 +- .../AccountDetailDashboardFragmentTest.java | 24 ---- ...AccountHeaderPreferenceControllerTest.java | 114 ++++++++++++++++++ 8 files changed, 216 insertions(+), 96 deletions(-) delete mode 100755 res/layout/account_header.xml create mode 100644 src/com/android/settings/accounts/AccountHeaderPreferenceController.java create mode 100644 tests/robotests/src/com/android/settings/accounts/AccountHeaderPreferenceControllerTest.java diff --git a/res/layout/account_header.xml b/res/layout/account_header.xml deleted file mode 100755 index 818d47c469e..00000000000 --- a/res/layout/account_header.xml +++ /dev/null @@ -1,53 +0,0 @@ - - - - - - - - - - - - diff --git a/res/layout/settings_entity_header.xml b/res/layout/settings_entity_header.xml index 72b688b2f0f..ce81b49db31 100644 --- a/res/layout/settings_entity_header.xml +++ b/res/layout/settings_entity_header.xml @@ -29,8 +29,8 @@ diff --git a/res/xml/account_type_settings.xml b/res/xml/account_type_settings.xml index ab997a577f1..0ba961f2153 100644 --- a/res/xml/account_type_settings.xml +++ b/res/xml/account_type_settings.xml @@ -19,11 +19,11 @@ android:title="@string/account_settings_title" settings:keywords="@string/keywords_accounts"> - +