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 2db23e40ac8..ce81b49db31 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/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"> - + - + 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..36e0965e101 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; @@ -53,11 +52,6 @@ public class ApplicationFeatureProviderImpl implements ApplicationFeatureProvide mUm = UserManager.get(mContext); } - @Override - public AppHeaderController newAppHeaderController(Fragment fragment, View appHeader) { - return new AppHeaderController(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 3b82b4cf1f8..3021f7560c2 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; @@ -96,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; @@ -411,14 +407,12 @@ 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.app_snippet)) + EntityHeaderController.newInstance(activity, 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,15 +578,13 @@ 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); 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) @@ -1245,32 +1237,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..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.AppHeaderController.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 3d2db9650b4..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.AppHeaderController; 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,13 +325,12 @@ 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 - ? 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..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.AppHeaderController; 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; @@ -180,14 +179,13 @@ 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) - .getApplicationFeatureProvider(context) - .newAppHeaderController(this, appSnippet) - .setButtonActions(AppHeaderController.ActionType.ACTION_NONE, - AppHeaderController.ActionType.ACTION_NONE); + EntityHeaderController controller = EntityHeaderController + .newInstance(context, this, appSnippet) + .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..92ad3f1e814 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,22 +37,24 @@ 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.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; 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"; @@ -128,19 +126,18 @@ 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) .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..85a56baa609 100644 --- a/src/com/android/settings/notification/ChannelNotificationSettings.java +++ b/src/com/android/settings/notification/ChannelNotificationSettings.java @@ -16,18 +16,12 @@ 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; 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,19 +32,21 @@ 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.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"; @@ -110,20 +106,19 @@ 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) .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/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/AppHeaderController.java b/src/com/android/settings/widget/EntityHeaderController.java similarity index 65% rename from src/com/android/settings/applications/AppHeaderController.java rename to src/com/android/settings/widget/EntityHeaderController.java index c638d351f0e..d7ba35ae48e 100644 --- a/src/com/android/settings/applications/AppHeaderController.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,13 +41,16 @@ 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; 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 +71,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,90 +81,101 @@ 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) { + /** + * 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() .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; } /** - * Done mutating appheader, rebinds everything and return a new {@link LayoutPreference}. + * Done mutating entity header, rebinds everything and return a new {@link LayoutPreference}. */ public LayoutPreference done(Activity activity, Context uiContext) { final LayoutPreference pref = new LayoutPreference(uiContext, done(activity)); @@ -172,41 +186,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. + * Only binds entity 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 +238,7 @@ public class AppHeaderController { } /** - * Done mutating appheader, rebinds everything. + * Done mutating entity header, rebinds everything. */ @VisibleForTesting View done(Activity activity) { @@ -245,9 +259,16 @@ public class AppHeaderController { 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 AppHeaderController { 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 AppHeaderController { 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; } @@ -289,7 +320,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/tests/robotests/src/com/android/settings/accounts/AccountDetailDashboardFragmentTest.java b/tests/robotests/src/com/android/settings/accounts/AccountDetailDashboardFragmentTest.java index 90728e82c1b..a215d13033c 100644 --- a/tests/robotests/src/com/android/settings/accounts/AccountDetailDashboardFragmentTest.java +++ b/tests/robotests/src/com/android/settings/accounts/AccountDetailDashboardFragmentTest.java @@ -17,7 +17,6 @@ package com.android.settings.accounts; import android.accounts.Account; import android.accounts.AccountManager; -import android.accounts.AuthenticatorDescription; import android.content.Context; import android.os.Bundle; import android.os.UserHandle; @@ -26,8 +25,6 @@ import android.support.v7.preference.PreferenceScreen; import com.android.settings.SettingsRobolectricTestRunner; import com.android.settings.TestConfig; -import com.android.settings.testutils.shadow.ShadowAccountManager; -import com.android.settings.testutils.shadow.ShadowContentResolver; import com.android.settingslib.drawer.CategoryKey; import com.android.settingslib.drawer.Tile; @@ -41,11 +38,7 @@ import org.robolectric.shadows.ShadowApplication; import static com.google.common.truth.Truth.assertThat; import static org.mockito.Answers.RETURNS_DEEP_STUBS; -import static org.mockito.Matchers.anyInt; -import static org.mockito.Mockito.doReturn; 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) @@ -54,7 +47,6 @@ public class AccountDetailDashboardFragmentTest { private static final String METADATA_CATEGORY = "com.android.settings.category"; private static final String METADATA_ACCOUNT_TYPE = "com.android.settings.ia.account"; private static final String METADATA_USER_HANDLE = "user_handle"; - private static final String PREF_ACCOUNT_HEADER = "account_header"; @Mock(answer = RETURNS_DEEP_STUBS) private AccountManager mAccountManager; @@ -118,20 +110,4 @@ public class AccountDetailDashboardFragmentTest { assertThat(mFragment.displayTile(tile)).isFalse(); } - - @Test - @Config(shadows = {ShadowAccountManager.class, ShadowContentResolver.class}) - public void updateAccountHeader_shouldShowAccountName() throws Exception { - when(mAccountManager.getAuthenticatorTypesAsUser(anyInt())).thenReturn( - new AuthenticatorDescription[0]); - when(mAccountManager.getAccountsAsUser(anyInt())).thenReturn(new Account[0]); - when(mFragment.getContext()).thenReturn(mContext); - doReturn(mScreen).when(mFragment).getPreferenceScreen(); - doReturn(mPreference).when(mFragment).findPreference(PREF_ACCOUNT_HEADER); - - mFragment.updateUi(); - - verify(mPreference).setTitle("name1@abc.com"); - } - } diff --git a/tests/robotests/src/com/android/settings/accounts/AccountHeaderPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/accounts/AccountHeaderPreferenceControllerTest.java new file mode 100644 index 00000000000..0668379c93c --- /dev/null +++ b/tests/robotests/src/com/android/settings/accounts/AccountHeaderPreferenceControllerTest.java @@ -0,0 +1,114 @@ +/* + * 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.accounts; + +import android.accounts.Account; +import android.app.Activity; +import android.app.Fragment; +import android.content.Context; +import android.os.Bundle; +import android.os.UserHandle; +import android.support.v7.preference.PreferenceScreen; +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 com.android.settingslib.accounts.AuthenticatorHelper; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Answers; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.robolectric.RuntimeEnvironment; +import org.robolectric.annotation.Config; +import org.robolectric.annotation.Implementation; +import org.robolectric.annotation.Implements; + +import static com.google.common.truth.Truth.assertThat; +import static org.mockito.Matchers.anyString; +import static org.mockito.Mockito.when; + + +@RunWith(SettingsRobolectricTestRunner.class) +@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION) +public class AccountHeaderPreferenceControllerTest { + + @Mock(answer = Answers.RETURNS_DEEP_STUBS) + private Context mContext; + @Mock + private Activity mActivity; + @Mock + private Fragment mFragment; + @Mock + private PreferenceScreen mScreen; + + private LayoutPreference mHeaderPreference; + + private AccountHeaderPreferenceController mController; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + FakeFeatureFactory.setupForTest(mContext); + mHeaderPreference = new LayoutPreference( + RuntimeEnvironment.application, R.layout.settings_entity_header); + } + + @Test + public void isAvailable_noArgs_shouldReturnNull() { + mController = new AccountHeaderPreferenceController(RuntimeEnvironment.application, + mActivity, mFragment, null /* args */); + + assertThat(mController.isAvailable()).isFalse(); + } + + @Test + @Config(shadows = ShadowAuthenticatorHelper.class) + public void displayPreference_shouldDisplayAccountInEntityHeader() { + final Account account = new Account("name1@abc.com", "com.abc"); + Bundle args = new Bundle(); + args.putParcelable(AccountDetailDashboardFragment.KEY_ACCOUNT, account); + args.putParcelable(AccountDetailDashboardFragment.KEY_USER_HANDLE, UserHandle.CURRENT); + mController = new AccountHeaderPreferenceController(RuntimeEnvironment.application, + mActivity, mFragment, args); + + assertThat(mController.isAvailable()).isTrue(); + + when(mScreen.findPreference(anyString())).thenReturn(mHeaderPreference); + + mController.displayPreference(mScreen); + + final CharSequence label = + ((TextView) mHeaderPreference.findViewById(R.id.entity_header_title)).getText(); + + assertThat(label).isEqualTo(account.name); + + } + + @Implements(AuthenticatorHelper.class) + public static class ShadowAuthenticatorHelper { + @Implementation + public void onAccountsUpdated(Account[] accounts) { + + } + } +} diff --git a/tests/robotests/src/com/android/settings/applications/AppInfoWithHeaderTest.java b/tests/robotests/src/com/android/settings/applications/AppInfoWithHeaderTest.java index 68c153cb6e4..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 AppHeaderController appHeaderController = new AppHeaderController( - ShadowApplication.getInstance().getApplicationContext(), - mAppInfoWithHeader, - null); - when(mFactory.applicationFeatureProvider.newAppHeaderController(mAppInfoWithHeader, null)) - .thenReturn(appHeaderController); 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 2e49ed2a8b6..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.AppHeaderController; -import com.android.settings.applications.AppHeaderController.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 AppHeaderController mHeaderController; - private FakeFeatureFactory mFeatureFactory; + private EntityHeaderController mHeaderController; + 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 69bd767c501..7b2d8cc63ac 100644 --- a/tests/robotests/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetailTest.java +++ b/tests/robotests/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetailTest.java @@ -16,41 +16,28 @@ 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; 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.AppHeaderController; 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,8 +51,21 @@ 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) +@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"; @@ -85,7 +85,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 +121,17 @@ public class AdvancedPowerUsageDetailTest { doReturn(APP_LABEL).when(mBundle).getString(anyString()); doReturn(mBundle).when(mFragment).getArguments(); - doReturn(mAppHeaderController).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( + ShadowEntityHeaderController.setUseMock(mEntityHeaderController); + 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(); @@ -166,13 +165,18 @@ public class AdvancedPowerUsageDetailTest { captor.capture(), anyInt(), any(), any()); } + @After + public void reset() { + ShadowEntityHeaderController.reset(); + } + @Test public void testInitHeader_NoAppEntry_BuildByBundle() { 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 +191,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 +208,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 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/AppHeaderControllerTest.java b/tests/robotests/src/com/android/settings/widget/EntityHeaderControllerTest.java similarity index 65% rename from tests/robotests/src/com/android/settings/applications/AppHeaderControllerTest.java rename to tests/robotests/src/com/android/settings/widget/EntityHeaderControllerTest.java index 2cdafe8fcf6..e6c742a72a2 100644 --- a/tests/robotests/src/com/android/settings/applications/AppHeaderControllerTest.java +++ b/tests/robotests/src/com/android/settings/widget/EntityHeaderControllerTest.java @@ -14,17 +14,9 @@ * limitations under the License. */ -package com.android.settings.applications; +package com.android.settings.widget; -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; @@ -43,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; @@ -53,9 +47,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; @@ -64,16 +66,19 @@ public class AppHeaderControllerTest { @Mock private Fragment mFragment; + private FakeFeatureFactory mFeatureFactory; private Context mShadowContext; private LayoutInflater mLayoutInflater; private PackageInfo mInfo; - private AppHeaderController mController; - + 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 AppHeaderControllerTest { @Test public void testBuildView_constructedWithoutView_shouldCreateNewView() { - mController = new AppHeaderController(mShadowContext, mFragment, null); + mController = EntityHeaderController.newInstance(mShadowContext, mFragment, null); View view = mController.done(mActivity); assertThat(view).isNotNull(); @@ -90,7 +95,7 @@ public class AppHeaderControllerTest { @Test public void testBuildView_withContext_shouldBuildPreference() { - mController = new AppHeaderController(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 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 = EntityHeaderController.newInstance(mShadowContext, mFragment, inputView); View view = mController.done(mActivity); assertThat(view).isSameAs(inputView); @@ -108,11 +113,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 = EntityHeaderController.newInstance(mShadowContext, mFragment, header); mController.setLabel(testString); mController.setSummary(testString); mController.setIcon(mShadowContext.getDrawable(R.drawable.ic_add)); @@ -133,18 +139,18 @@ public class AppHeaderControllerTest { when(mContext.getPackageManager().resolveActivity(any(Intent.class), anyInt())) .thenReturn(info); - mController = new AppHeaderController(mContext, mFragment, appLinks); + mController = EntityHeaderController.newInstance(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 +164,15 @@ public class AppHeaderControllerTest { when(mContext.getPackageManager().resolveActivity(any(Intent.class), anyInt())) .thenReturn(null); - mController = new AppHeaderController(mContext, mFragment, appLinks); + mController = EntityHeaderController.newInstance(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 +181,16 @@ public class AppHeaderControllerTest { final View appLinks = mLayoutInflater .inflate(R.layout.settings_entity_header, null /* root */); - mController = new AppHeaderController(mContext, mFragment, appLinks); + mController = EntityHeaderController.newInstance(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 +200,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 = EntityHeaderController.newInstance(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 +221,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 = EntityHeaderController.newInstance(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 +238,16 @@ public class AppHeaderControllerTest { final View appLinks = mLayoutInflater .inflate(R.layout.settings_entity_header, null /* root */); - mController = new AppHeaderController(mContext, mFragment, appLinks); + mController = EntityHeaderController.newInstance(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 +255,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 = EntityHeaderController.newInstance(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 = EntityHeaderController.newInstance(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 = EntityHeaderController.newInstance(mShadowContext, mFragment, null); mController.styleActionBar(null); when(mActivity.getActionBar()).thenReturn(null); @@ -286,7 +296,7 @@ public class AppHeaderControllerTest { public void styleActionBar_setElevationAndBackground() { final ActionBar actionBar = mActivity.getActionBar(); - mController = new AppHeaderController(mShadowContext, mFragment, null); + mController = EntityHeaderController.newInstance(mShadowContext, mFragment, null); mController.styleActionBar(mActivity); verify(actionBar).setElevation(0); @@ -297,7 +307,7 @@ public class AppHeaderControllerTest { @Test public void initAppHeaderController_appHeaderNull_useFragmentContext() { - mController = new AppHeaderController(mContext, mFragment, null); + mController = EntityHeaderController.newInstance(mContext, mFragment, null); // Fragment.getContext() is invoked to inflate the view verify(mFragment).getContext();