diff --git a/src/com/android/settings/applications/appinfo/AppActionButtonPreferenceController.java b/src/com/android/settings/applications/appinfo/AppActionButtonPreferenceController.java deleted file mode 100644 index 79c22248a69..00000000000 --- a/src/com/android/settings/applications/appinfo/AppActionButtonPreferenceController.java +++ /dev/null @@ -1,321 +0,0 @@ -/* - * 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.applications.appinfo; - -import android.app.Activity; -import android.app.ActivityManager; -import android.app.admin.DevicePolicyManager; -import android.content.BroadcastReceiver; -import android.content.ComponentName; -import android.content.Context; -import android.content.Intent; -import android.content.pm.ApplicationInfo; -import android.content.pm.PackageInfo; -import android.content.pm.PackageManager; -import android.content.pm.ResolveInfo; -import android.net.Uri; -import android.os.Bundle; -import android.os.RemoteException; -import android.os.ServiceManager; -import android.os.UserHandle; -import android.os.UserManager; -import androidx.annotation.VisibleForTesting; -import androidx.preference.PreferenceScreen; -import android.util.Log; -import android.webkit.IWebViewUpdateService; - -import com.android.settings.R; -import com.android.settings.Utils; -import com.android.settings.applications.ApplicationFeatureProvider; -import com.android.settings.core.BasePreferenceController; -import com.android.settings.overlay.FeatureFactory; -import com.android.settings.widget.ActionButtonPreference; -import com.android.settingslib.RestrictedLockUtils; -import com.android.settingslib.applications.AppUtils; -import com.android.settingslib.applications.ApplicationsState.AppEntry; - -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; - -public class AppActionButtonPreferenceController extends BasePreferenceController - implements AppInfoDashboardFragment.Callback { - - private static final String TAG = "AppActionButtonControl"; - private static final String KEY_ACTION_BUTTONS = "action_buttons"; - - @VisibleForTesting - ActionButtonPreference mActionButtons; - private final AppInfoDashboardFragment mParent; - private final String mPackageName; - private final HashSet mHomePackages = new HashSet<>(); - private final ApplicationFeatureProvider mApplicationFeatureProvider; - - private int mUserId; - private DevicePolicyManager mDpm; - private UserManager mUserManager; - private PackageManager mPm; - - private final BroadcastReceiver mCheckKillProcessesReceiver = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - final boolean enabled = getResultCode() != Activity.RESULT_CANCELED; - Log.d(TAG, "Got broadcast response: Restart status for " - + mParent.getAppEntry().info.packageName + " " + enabled); - updateForceStopButton(enabled); - } - }; - - public AppActionButtonPreferenceController(Context context, AppInfoDashboardFragment parent, - String packageName) { - super(context, KEY_ACTION_BUTTONS); - mParent = parent; - mPackageName = packageName; - mUserId = UserHandle.myUserId(); - mApplicationFeatureProvider = FeatureFactory.getFactory(context) - .getApplicationFeatureProvider(context); - } - - @Override - public int getAvailabilityStatus() { - return AppUtils.isInstant(mParent.getPackageInfo().applicationInfo) - ? DISABLED_FOR_USER : AVAILABLE; - } - - @Override - public void displayPreference(PreferenceScreen screen) { - super.displayPreference(screen); - mActionButtons = ((ActionButtonPreference) screen.findPreference(KEY_ACTION_BUTTONS)) - .setButton2Text(R.string.force_stop) - .setButton2Positive(false) - .setButton2Enabled(false); - } - - @Override - public void refreshUi() { - if (mPm == null) { - mPm = mContext.getPackageManager(); - } - if (mDpm == null) { - mDpm = (DevicePolicyManager) mContext.getSystemService(Context.DEVICE_POLICY_SERVICE); - } - if (mUserManager == null) { - mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE); - } - final AppEntry appEntry = mParent.getAppEntry(); - final PackageInfo packageInfo = mParent.getPackageInfo(); - - // Get list of "home" apps and trace through any meta-data references - final List homeActivities = new ArrayList(); - mPm.getHomeActivities(homeActivities); - mHomePackages.clear(); - for (int i = 0; i < homeActivities.size(); i++) { - final ResolveInfo ri = homeActivities.get(i); - final String activityPkg = ri.activityInfo.packageName; - mHomePackages.add(activityPkg); - - // Also make sure to include anything proxying for the home app - final Bundle metadata = ri.activityInfo.metaData; - if (metadata != null) { - final String metaPkg = metadata.getString(ActivityManager.META_HOME_ALTERNATE); - if (signaturesMatch(metaPkg, activityPkg)) { - mHomePackages.add(metaPkg); - } - } - } - - checkForceStop(appEntry, packageInfo); - initUninstallButtons(appEntry, packageInfo); - } - - @VisibleForTesting - void initUninstallButtons(AppEntry appEntry, PackageInfo packageInfo) { - final boolean isBundled = (appEntry.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; - boolean enabled; - if (isBundled) { - enabled = handleDisableable(appEntry, packageInfo); - } else { - enabled = initUninstallButtonForUserApp(); - } - // If this is a device admin, it can't be uninstalled or disabled. - // We do this here so the text of the button is still set correctly. - if (isBundled && mDpm.packageHasActiveAdmins(packageInfo.packageName)) { - enabled = false; - } - - // We don't allow uninstalling DO/PO on *any* users, because if it's a system app, - // "uninstall" is actually "downgrade to the system version + disable", and "downgrade" - // will clear data on all users. - if (Utils.isProfileOrDeviceOwner(mUserManager, mDpm, packageInfo.packageName)) { - enabled = false; - } - - // Don't allow uninstalling the device provisioning package. - if (Utils.isDeviceProvisioningPackage(mContext.getResources(), appEntry.info.packageName)) { - enabled = false; - } - - // If the uninstall intent is already queued, disable the uninstall button - if (mDpm.isUninstallInQueue(mPackageName)) { - enabled = false; - } - - // Home apps need special handling. Bundled ones we don't risk downgrading - // because that can interfere with home-key resolution. Furthermore, we - // can't allow uninstallation of the only home app, and we don't want to - // allow uninstallation of an explicitly preferred one -- the user can go - // to Home settings and pick a different one, after which we'll permit - // uninstallation of the now-not-default one. - if (enabled && mHomePackages.contains(packageInfo.packageName)) { - if (isBundled) { - enabled = false; - } else { - ArrayList homeActivities = new ArrayList(); - ComponentName currentDefaultHome = mPm.getHomeActivities(homeActivities); - if (currentDefaultHome == null) { - // No preferred default, so permit uninstall only when - // there is more than one candidate - enabled = (mHomePackages.size() > 1); - } else { - // There is an explicit default home app -- forbid uninstall of - // that one, but permit it for installed-but-inactive ones. - enabled = !packageInfo.packageName.equals(currentDefaultHome.getPackageName()); - } - } - } - - if (RestrictedLockUtils.hasBaseUserRestriction( - mContext, UserManager.DISALLOW_APPS_CONTROL, mUserId)) { - enabled = false; - } - - try { - final IWebViewUpdateService webviewUpdateService = - IWebViewUpdateService.Stub.asInterface( - ServiceManager.getService("webviewupdate")); - if (webviewUpdateService.isFallbackPackage(appEntry.info.packageName)) { - enabled = false; - } - } catch (RemoteException e) { - throw new RuntimeException(e); - } - - mActionButtons.setButton1Enabled(enabled); - if (enabled) { - // Register listener - mActionButtons.setButton1OnClickListener(v -> mParent.handleUninstallButtonClick()); - } - } - - @VisibleForTesting - boolean initUninstallButtonForUserApp() { - boolean enabled = true; - final PackageInfo packageInfo = mParent.getPackageInfo(); - if ((packageInfo.applicationInfo.flags & ApplicationInfo.FLAG_INSTALLED) == 0 - && mUserManager.getUsers().size() >= 2) { - // When we have multiple users, there is a separate menu - // to uninstall for all users. - enabled = false; - } else if (AppUtils.isInstant(packageInfo.applicationInfo)) { - enabled = false; - mActionButtons.setButton1Visible(false); - } - mActionButtons.setButton1Text(R.string.uninstall_text).setButton1Positive(false); - return enabled; - } - - @VisibleForTesting - boolean handleDisableable(AppEntry appEntry, PackageInfo packageInfo) { - boolean disableable = false; - // Try to prevent the user from bricking their phone - // by not allowing disabling of apps signed with the - // system cert and any launcher app in the system. - if (mHomePackages.contains(appEntry.info.packageName) - || Utils.isSystemPackage(mContext.getResources(), mPm, packageInfo)) { - // Disable button for core system applications. - mActionButtons - .setButton1Text(R.string.disable_text) - .setButton1Positive(false); - } else if (appEntry.info.enabled && appEntry.info.enabledSetting - != PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED) { - mActionButtons - .setButton1Text(R.string.disable_text) - .setButton1Positive(false); - disableable = !mApplicationFeatureProvider.getKeepEnabledPackages() - .contains(appEntry.info.packageName); - } else { - mActionButtons - .setButton1Text(R.string.enable_text) - .setButton1Positive(true); - disableable = true; - } - - return disableable; - } - - private void updateForceStopButton(boolean enabled) { - final boolean disallowedBySystem = RestrictedLockUtils.hasBaseUserRestriction( - mContext, UserManager.DISALLOW_APPS_CONTROL, mUserId); - mActionButtons - .setButton2Enabled(disallowedBySystem ? false : enabled) - .setButton2OnClickListener( - disallowedBySystem ? null : v -> mParent.handleForceStopButtonClick()); - } - - void checkForceStop(AppEntry appEntry, PackageInfo packageInfo) { - if (mDpm.packageHasActiveAdmins(packageInfo.packageName)) { - // User can't force stop device admin. - Log.w(TAG, "User can't force stop device admin"); - updateForceStopButton(false); - } else if (mPm.isPackageStateProtected(packageInfo.packageName, - UserHandle.getUserId(appEntry.info.uid))) { - Log.w(TAG, "User can't force stop protected packages"); - updateForceStopButton(false); - } else if (AppUtils.isInstant(packageInfo.applicationInfo)) { - updateForceStopButton(false); - mActionButtons.setButton2Visible(false); - } else if ((appEntry.info.flags & ApplicationInfo.FLAG_STOPPED) == 0) { - // If the app isn't explicitly stopped, then always show the - // force stop button. - Log.w(TAG, "App is not explicitly stopped"); - updateForceStopButton(true); - } else { - final Intent intent = new Intent(Intent.ACTION_QUERY_PACKAGE_RESTART, - Uri.fromParts("package", appEntry.info.packageName, null)); - intent.putExtra(Intent.EXTRA_PACKAGES, new String[] {appEntry.info.packageName}); - intent.putExtra(Intent.EXTRA_UID, appEntry.info.uid); - intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(appEntry.info.uid)); - Log.d(TAG, "Sending broadcast to query restart status for " - + appEntry.info.packageName); - mContext.sendOrderedBroadcastAsUser(intent, UserHandle.CURRENT, null, - mCheckKillProcessesReceiver, null, Activity.RESULT_CANCELED, null, null); - } - } - - private boolean signaturesMatch(String pkg1, String pkg2) { - if (pkg1 != null && pkg2 != null) { - try { - return mPm.checkSignatures(pkg1, pkg2) >= PackageManager.SIGNATURE_MATCH; - } catch (Exception e) { - // e.g. named alternate package not found during lookup; - // this is an expected case sometimes - } - } - return false; - } - -} diff --git a/src/com/android/settings/fuelgauge/AppButtonsPreferenceController.java b/src/com/android/settings/applications/appinfo/AppButtonsPreferenceController.java similarity index 97% rename from src/com/android/settings/fuelgauge/AppButtonsPreferenceController.java rename to src/com/android/settings/applications/appinfo/AppButtonsPreferenceController.java index a2ba9a96181..dfbe064b832 100644 --- a/src/com/android/settings/fuelgauge/AppButtonsPreferenceController.java +++ b/src/com/android/settings/applications/appinfo/AppButtonsPreferenceController.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.settings.fuelgauge; +package com.android.settings.applications.appinfo; import android.app.Activity; import android.app.ActivityManager; @@ -49,13 +49,13 @@ import com.android.settings.R; import com.android.settings.SettingsActivity; import com.android.settings.Utils; import com.android.settings.applications.ApplicationFeatureProvider; +import com.android.settings.core.BasePreferenceController; import com.android.settings.core.PreferenceControllerMixin; import com.android.settings.overlay.FeatureFactory; import com.android.settings.widget.ActionButtonPreference; import com.android.settingslib.RestrictedLockUtils; import com.android.settingslib.applications.AppUtils; import com.android.settingslib.applications.ApplicationsState; -import com.android.settingslib.core.AbstractPreferenceController; import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; import com.android.settingslib.core.lifecycle.Lifecycle; import com.android.settingslib.core.lifecycle.LifecycleObserver; @@ -74,8 +74,7 @@ import java.util.List; * An easy way to handle them is to delegate them to {@link #handleDialogClick(int)} and * {@link #handleActivityResult(int, int, Intent)} in this controller. */ -//TODO(80312809): Merge this class into {@link AppActionButtonPreferenceController} -public class AppButtonsPreferenceController extends AbstractPreferenceController implements +public class AppButtonsPreferenceController extends BasePreferenceController implements PreferenceControllerMixin, LifecycleObserver, OnResume, OnDestroy, ApplicationsState.Callbacks { public static final String APP_CHG = "chg"; @@ -120,9 +119,8 @@ public class AppButtonsPreferenceController extends AbstractPreferenceController public AppButtonsPreferenceController(SettingsActivity activity, Fragment fragment, Lifecycle lifecycle, String packageName, ApplicationsState state, - DevicePolicyManager dpm, UserManager userManager, - PackageManager packageManager, int requestUninstall, int requestRemoveDeviceAdmin) { - super(activity); + int requestUninstall, int requestRemoveDeviceAdmin) { + super(activity, KEY_ACTION_BUTTONS); if (!(fragment instanceof ButtonActionDialogFragment.AppButtonsDialogListener)) { throw new IllegalArgumentException( @@ -133,9 +131,9 @@ public class AppButtonsPreferenceController extends AbstractPreferenceController mMetricsFeatureProvider = factory.getMetricsFeatureProvider(); mApplicationFeatureProvider = factory.getApplicationFeatureProvider(activity); mState = state; - mDpm = dpm; - mUserManager = userManager; - mPm = packageManager; + mDpm = (DevicePolicyManager) activity.getSystemService(Context.DEVICE_POLICY_SERVICE); + mUserManager = (UserManager) activity.getSystemService(Context.USER_SERVICE); + mPm = activity.getPackageManager(); mPackageName = packageName; mActivity = activity; mFragment = fragment; @@ -153,9 +151,10 @@ public class AppButtonsPreferenceController extends AbstractPreferenceController } @Override - public boolean isAvailable() { + public int getAvailabilityStatus() { // TODO(b/37313605): Re-enable once this controller supports instant apps - return mAppEntry != null && !AppUtils.isInstant(mAppEntry.info); + return mAppEntry != null && !AppUtils.isInstant(mAppEntry.info) + ? AVAILABLE : DISABLED_FOR_USER ; } @Override diff --git a/src/com/android/settings/applications/appinfo/AppInfoDashboardFragment.java b/src/com/android/settings/applications/appinfo/AppInfoDashboardFragment.java index 1f8a3a07585..7107ff754aa 100755 --- a/src/com/android/settings/applications/appinfo/AppInfoDashboardFragment.java +++ b/src/com/android/settings/applications/appinfo/AppInfoDashboardFragment.java @@ -19,14 +19,12 @@ package com.android.settings.applications.appinfo; import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin; import android.app.Activity; -import android.app.ActivityManager; import android.app.AlertDialog; import android.app.Dialog; import android.app.DialogFragment; import android.app.admin.DevicePolicyManager; import android.content.BroadcastReceiver; import android.content.Context; -import android.content.DialogInterface; import android.content.Intent; import android.content.IntentFilter; import android.content.pm.ApplicationInfo; @@ -35,7 +33,6 @@ import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; import android.content.pm.UserInfo; import android.net.Uri; -import android.os.AsyncTask; import android.os.Bundle; import android.os.UserHandle; import android.os.UserManager; @@ -47,7 +44,6 @@ import android.view.MenuInflater; import android.view.MenuItem; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; -import com.android.settings.DeviceAdminAdd; import com.android.settings.R; import com.android.settings.SettingsActivity; import com.android.settings.SettingsPreferenceFragment; @@ -62,7 +58,6 @@ import com.android.settingslib.applications.ApplicationsState.AppEntry; import com.android.settingslib.core.AbstractPreferenceController; import com.android.settingslib.core.lifecycle.Lifecycle; -import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -77,7 +72,8 @@ import java.util.List; * uninstall the application. */ public class AppInfoDashboardFragment extends DashboardFragment - implements ApplicationsState.Callbacks { + implements ApplicationsState.Callbacks, + ButtonActionDialogFragment.AppButtonsDialogListener { private static final String TAG = "AppInfoDashboard"; @@ -101,10 +97,7 @@ public class AppInfoDashboardFragment extends DashboardFragment // Dialog identifiers used in showDialog private static final int DLG_BASE = 0; - private static final int DLG_FORCE_STOP = DLG_BASE + 1; - private static final int DLG_DISABLE = DLG_BASE + 2; - private static final int DLG_SPECIAL_DISABLE = DLG_BASE + 3; - static final int DLG_CLEAR_INSTANT_APP = DLG_BASE + 4; + static final int DLG_CLEAR_INSTANT_APP = DLG_BASE + 1; public static final String ARG_PACKAGE_NAME = "package"; public static final String ARG_PACKAGE_UID = "uid"; @@ -132,12 +125,11 @@ public class AppInfoDashboardFragment extends DashboardFragment private boolean mInitialized; private boolean mShowUninstalled; private boolean mUpdatedSysApp = false; - private boolean mDisableAfterUninstall; private List mCallbacks = new ArrayList<>(); private InstantAppButtonsPreferenceController mInstantAppButtonPreferenceController; - private AppActionButtonPreferenceController mAppActionButtonPreferenceController; + private AppButtonsPreferenceController mAppButtonsPreferenceController; /** * Callback to invoke when app info has been changed. @@ -146,11 +138,6 @@ public class AppInfoDashboardFragment extends DashboardFragment void refreshUi(); } - private boolean isDisabledUntilUsed() { - return mAppEntry.info.enabledSetting - == PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED; - } - @Override public void onAttach(Context context) { super.onAttach(context); @@ -262,9 +249,6 @@ public class AppInfoDashboardFragment extends DashboardFragment // when app state changes. controllers.add( new AppHeaderViewPreferenceController(context, this, packageName, lifecycle)); - mAppActionButtonPreferenceController = - new AppActionButtonPreferenceController(context, this, packageName); - controllers.add(mAppActionButtonPreferenceController); for (AbstractPreferenceController controller : controllers) { mCallbacks.add((Callback) controller); @@ -275,6 +259,10 @@ public class AppInfoDashboardFragment extends DashboardFragment mInstantAppButtonPreferenceController = new InstantAppButtonsPreferenceController(context, this, packageName, lifecycle); controllers.add(mInstantAppButtonPreferenceController); + mAppButtonsPreferenceController = new AppButtonsPreferenceController( + (SettingsActivity) getActivity(), this, lifecycle, packageName, mState, + REQUEST_UNINSTALL, REQUEST_REMOVE_DEVICE_ADMIN); + controllers.add(mAppButtonsPreferenceController); controllers.add(new AppBatteryPreferenceController(context, this, packageName, lifecycle)); controllers.add(new AppMemoryPreferenceController(context, this, lifecycle)); controllers.add(new DefaultHomeShortcutPreferenceController(context, packageName)); @@ -374,30 +362,19 @@ public class AppInfoDashboardFragment extends DashboardFragment @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); - switch (requestCode) { - case REQUEST_UNINSTALL: - // Refresh option menu - getActivity().invalidateOptionsMenu(); + if (requestCode == REQUEST_UNINSTALL) { + // Refresh option menu + getActivity().invalidateOptionsMenu(); + } + if (mAppButtonsPreferenceController != null) { + mAppButtonsPreferenceController.handleActivityResult(requestCode, resultCode, data); + } + } - if (mDisableAfterUninstall) { - mDisableAfterUninstall = false; - new DisableChanger(this, mAppEntry.info, - PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER) - .execute((Object) null); - } - if (!refreshUi()) { - onPackageRemoved(); - } else { - startListeningToPackageRemove(); - } - break; - case REQUEST_REMOVE_DEVICE_ADMIN: - if (!refreshUi()) { - setIntentAndFinish(true, true); - } else { - startListeningToPackageRemove(); - } - break; + @Override + public void handleDialogClick(int id) { + if (mAppButtonsPreferenceController != null) { + mAppButtonsPreferenceController.handleDialogClick(id); } } @@ -442,6 +419,7 @@ public class AppInfoDashboardFragment extends DashboardFragment for (Callback callback : mCallbacks) { callback.refreshUi(); } + mAppButtonsPreferenceController.refreshUi(); if (!mInitialized) { // First time init: are we displaying an uninstalled app? @@ -471,53 +449,6 @@ public class AppInfoDashboardFragment extends DashboardFragment @VisibleForTesting AlertDialog createDialog(int id, int errorCode) { - switch (id) { - case DLG_DISABLE: - return new AlertDialog.Builder(getActivity()) - .setMessage(getActivity().getText(R.string.app_disable_dlg_text)) - .setPositiveButton(R.string.app_disable_dlg_positive, - new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int which) { - // Disable the app - mMetricsFeatureProvider.action(getContext(), - MetricsEvent.ACTION_SETTINGS_DISABLE_APP); - new DisableChanger(AppInfoDashboardFragment.this, - mAppEntry.info, - PackageManager - .COMPONENT_ENABLED_STATE_DISABLED_USER) - .execute((Object) null); - } - }) - .setNegativeButton(R.string.dlg_cancel, null) - .create(); - case DLG_SPECIAL_DISABLE: - return new AlertDialog.Builder(getActivity()) - .setMessage(getActivity().getText(R.string.app_disable_dlg_text)) - .setPositiveButton(R.string.app_disable_dlg_positive, - new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int which) { - // Disable the app and ask for uninstall - mMetricsFeatureProvider.action(getContext(), - MetricsEvent.ACTION_SETTINGS_DISABLE_APP); - uninstallPkg(mAppEntry.info.packageName, - false, true); - } - }) - .setNegativeButton(R.string.dlg_cancel, null) - .create(); - case DLG_FORCE_STOP: - return new AlertDialog.Builder(getActivity()) - .setTitle(getActivity().getText(R.string.force_stop_dlg_title)) - .setMessage(getActivity().getText(R.string.force_stop_dlg_text)) - .setPositiveButton(R.string.dlg_ok, new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int which) { - // Force stop - forceStopPackage(mAppEntry.info.packageName); - } - }) - .setNegativeButton(R.string.dlg_cancel, null) - .create(); - } return mInstantAppButtonPreferenceController.createDialog(id); } @@ -530,22 +461,6 @@ public class AppInfoDashboardFragment extends DashboardFragment mMetricsFeatureProvider.action( getContext(), MetricsEvent.ACTION_SETTINGS_UNINSTALL_APP); startActivityForResult(uninstallIntent, REQUEST_UNINSTALL); - mDisableAfterUninstall = andDisable; - } - - private void forceStopPackage(String pkgName) { - mMetricsFeatureProvider.action(getContext(), MetricsEvent.ACTION_APP_FORCE_STOP, pkgName); - final ActivityManager am = (ActivityManager) getActivity().getSystemService( - Context.ACTIVITY_SERVICE); - Log.d(TAG, "Stopping package " + pkgName); - am.forceStopPackage(pkgName); - final int userId = UserHandle.getUserId(mAppEntry.info.uid); - mState.invalidatePackage(pkgName, userId); - final AppEntry newEnt = mState.getEntry(pkgName, userId); - if (newEnt != null) { - mAppEntry = newEnt; - } - mAppActionButtonPreferenceController.checkForceStop(mAppEntry, mPackageInfo); } public static void startAppInfoFragment(Class fragment, int title, Bundle args, @@ -565,74 +480,6 @@ public class AppInfoDashboardFragment extends DashboardFragment .launch(); } - void handleUninstallButtonClick() { - if (mAppEntry == null) { - setIntentAndFinish(true, true); - return; - } - final String packageName = mAppEntry.info.packageName; - if (mDpm.packageHasActiveAdmins(mPackageInfo.packageName)) { - stopListeningToPackageRemove(); - final Activity activity = getActivity(); - final Intent uninstallDAIntent = new Intent(activity, DeviceAdminAdd.class); - uninstallDAIntent.putExtra(DeviceAdminAdd.EXTRA_DEVICE_ADMIN_PACKAGE_NAME, - mPackageName); - mMetricsFeatureProvider.action( - activity, MetricsEvent.ACTION_SETTINGS_UNINSTALL_DEVICE_ADMIN); - activity.startActivityForResult(uninstallDAIntent, REQUEST_REMOVE_DEVICE_ADMIN); - return; - } - final EnforcedAdmin admin = RestrictedLockUtils.checkIfUninstallBlocked(getActivity(), - packageName, mUserId); - final boolean uninstallBlockedBySystem = mAppsControlDisallowedBySystem || - RestrictedLockUtils.hasBaseUserRestriction(getActivity(), packageName, mUserId); - if (admin != null && !uninstallBlockedBySystem) { - RestrictedLockUtils.sendShowAdminSupportDetailsIntent(getActivity(), admin); - } else if ((mAppEntry.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { - if (mAppEntry.info.enabled && !isDisabledUntilUsed()) { - // If the system app has an update and this is the only user on the device, - // then offer to downgrade the app, otherwise only offer to disable the - // app for this user. - if (mUpdatedSysApp && isSingleUser()) { - showDialogInner(DLG_SPECIAL_DISABLE, 0); - } else { - showDialogInner(DLG_DISABLE, 0); - } - } else { - mMetricsFeatureProvider.action( - getActivity(), - MetricsEvent.ACTION_SETTINGS_ENABLE_APP); - new DisableChanger(this, mAppEntry.info, - PackageManager.COMPONENT_ENABLED_STATE_ENABLED) - .execute((Object) null); - } - } else if ((mAppEntry.info.flags & ApplicationInfo.FLAG_INSTALLED) == 0) { - uninstallPkg(packageName, true, false); - } else { - uninstallPkg(packageName, false, false); - } - } - - void handleForceStopButtonClick() { - if (mAppEntry == null) { - setIntentAndFinish(true, true); - return; - } - if (mAppsControlDisallowedAdmin != null && !mAppsControlDisallowedBySystem) { - RestrictedLockUtils.sendShowAdminSupportDetailsIntent( - getActivity(), mAppsControlDisallowedAdmin); - } else { - showDialogInner(DLG_FORCE_STOP, 0); - //forceStopPackage(mAppInfo.packageName); - } - } - - /** Returns whether there is only one user on this device, not including the system-only user */ - private boolean isSingleUser() { - final int userCount = mUserManager.getUserCount(); - return userCount == 1 || (mUserManager.isSplitSystemUser() && userCount == 2); - } - private void onPackageRemoved() { getActivity().finishActivity(SUB_INFO_FRAGMENT); getActivity().finishAndRemoveTask(); @@ -659,26 +506,6 @@ public class AppInfoDashboardFragment extends DashboardFragment return count; } - private static class DisableChanger extends AsyncTask { - final PackageManager mPm; - final WeakReference mActivity; - final ApplicationInfo mInfo; - final int mState; - - DisableChanger(AppInfoDashboardFragment activity, ApplicationInfo info, int state) { - mPm = activity.mPm; - mActivity = new WeakReference(activity); - mInfo = info; - mState = state; - } - - @Override - protected Object doInBackground(Object... params) { - mPm.setApplicationEnabledSetting(mInfo.packageName, mState, 0); - return null; - } - } - private String getPackageName() { if (mPackageName != null) { return mPackageName; diff --git a/src/com/android/settings/fuelgauge/ButtonActionDialogFragment.java b/src/com/android/settings/applications/appinfo/ButtonActionDialogFragment.java similarity index 96% rename from src/com/android/settings/fuelgauge/ButtonActionDialogFragment.java rename to src/com/android/settings/applications/appinfo/ButtonActionDialogFragment.java index f4784a97824..a3f1bab78c5 100644 --- a/src/com/android/settings/fuelgauge/ButtonActionDialogFragment.java +++ b/src/com/android/settings/applications/appinfo/ButtonActionDialogFragment.java @@ -1,6 +1,5 @@ -package com.android.settings.fuelgauge; +package com.android.settings.applications.appinfo; -import android.app.Activity; import android.app.AlertDialog; import android.app.Dialog; import android.content.Context; @@ -26,7 +25,7 @@ public class ButtonActionDialogFragment extends InstrumentedDialogFragment imple /** * Interface to handle the dialog click */ - interface AppButtonsDialogListener { + public interface AppButtonsDialogListener { void handleDialogClick(int type); } diff --git a/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetail.java b/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetail.java index c25463a1f86..af1de4856f0 100644 --- a/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetail.java +++ b/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetail.java @@ -20,7 +20,6 @@ import android.annotation.UserIdInt; import android.app.Activity; import android.app.ActivityManager; import android.app.LoaderManager; -import android.app.admin.DevicePolicyManager; import android.content.Context; import android.content.Intent; import android.content.Loader; @@ -28,7 +27,6 @@ import android.content.pm.PackageManager; import android.os.BatteryStats; import android.os.Bundle; import android.os.UserHandle; -import android.os.UserManager; import androidx.annotation.VisibleForTesting; import androidx.preference.Preference; import android.text.TextUtils; @@ -43,6 +41,8 @@ import com.android.settings.R; import com.android.settings.SettingsActivity; import com.android.settings.Utils; import com.android.settings.applications.LayoutPreference; +import com.android.settings.applications.appinfo.AppButtonsPreferenceController; +import com.android.settings.applications.appinfo.ButtonActionDialogFragment; import com.android.settings.core.InstrumentedPreferenceFragment; import com.android.settings.core.SubSettingLauncher; import com.android.settings.dashboard.DashboardFragment; @@ -112,9 +112,6 @@ public class AdvancedPowerUsageDetail extends DashboardFragment implements private AppButtonsPreferenceController mAppButtonsPreferenceController; private BackgroundActivityPreferenceController mBackgroundActivityPreferenceController; - private DevicePolicyManager mDpm; - private UserManager mUserManager; - private PackageManager mPackageManager; private List mAnomalies; private String mPackageName; @@ -203,9 +200,6 @@ public class AdvancedPowerUsageDetail extends DashboardFragment implements super.onAttach(activity); mState = ApplicationsState.getInstance(getActivity().getApplication()); - mDpm = (DevicePolicyManager) activity.getSystemService(Context.DEVICE_POLICY_SERVICE); - mUserManager = (UserManager) activity.getSystemService(Context.USER_SERVICE); - mPackageManager = activity.getPackageManager(); mBatteryUtils = BatteryUtils.getInstance(getContext()); } @@ -332,8 +326,8 @@ public class AdvancedPowerUsageDetail extends DashboardFragment implements controllers.add(new BatteryOptimizationPreferenceController( (SettingsActivity) getActivity(), this, packageName)); mAppButtonsPreferenceController = new AppButtonsPreferenceController( - (SettingsActivity) getActivity(), this, getLifecycle(), packageName, mState, mDpm, - mUserManager, mPackageManager, REQUEST_UNINSTALL, REQUEST_REMOVE_DEVICE_ADMIN); + (SettingsActivity) getActivity(), this, getLifecycle(), packageName, mState, + REQUEST_UNINSTALL, REQUEST_REMOVE_DEVICE_ADMIN); controllers.add(mAppButtonsPreferenceController); return controllers; diff --git a/tests/robotests/assets/grandfather_invalid_base_preference_controller_constructor b/tests/robotests/assets/grandfather_invalid_base_preference_controller_constructor index c2b3da98a1f..a2be681ce5c 100644 --- a/tests/robotests/assets/grandfather_invalid_base_preference_controller_constructor +++ b/tests/robotests/assets/grandfather_invalid_base_preference_controller_constructor @@ -1,4 +1,4 @@ -com.android.settings.applications.appinfo.AppActionButtonPreferenceController +com.android.settings.applications.appinfo.AppButtonsPreferenceController com.android.settings.applications.appinfo.AppBatteryPreferenceController com.android.settings.applications.appinfo.AppHeaderViewPreferenceController com.android.settings.applications.appinfo.AppMemoryPreferenceController diff --git a/tests/robotests/src/com/android/settings/applications/appinfo/AppActionButtonPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/applications/appinfo/AppActionButtonPreferenceControllerTest.java deleted file mode 100644 index cf423f7a635..00000000000 --- a/tests/robotests/src/com/android/settings/applications/appinfo/AppActionButtonPreferenceControllerTest.java +++ /dev/null @@ -1,360 +0,0 @@ -/* - * 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.applications.appinfo; - -import static com.google.common.truth.Truth.assertThat; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyInt; -import static org.mockito.ArgumentMatchers.argThat; -import static org.mockito.ArgumentMatchers.nullable; -import static org.mockito.Mockito.doNothing; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import android.app.admin.DevicePolicyManager; -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import android.content.pm.ApplicationInfo; -import android.content.pm.PackageInfo; -import android.content.pm.PackageManager; -import android.content.pm.UserInfo; -import android.content.res.Resources; -import android.os.Bundle; -import android.os.Handler; -import android.os.UserHandle; -import android.os.UserManager; -import androidx.preference.PreferenceScreen; - -import com.android.settings.R; -import com.android.settings.testutils.FakeFeatureFactory; -import com.android.settings.testutils.SettingsRobolectricTestRunner; -import com.android.settings.widget.ActionButtonPreference; -import com.android.settings.widget.ActionButtonPreferenceTest; -import com.android.settingslib.Utils; -import com.android.settingslib.applications.AppUtils; -import com.android.settingslib.applications.ApplicationsState; -import com.android.settingslib.applications.instantapps.InstantAppDataProvider; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -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 org.robolectric.util.ReflectionHelpers; - -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; - -@RunWith(SettingsRobolectricTestRunner.class) -public class AppActionButtonPreferenceControllerTest { - - @Mock - private UserManager mUserManager; - @Mock - private DevicePolicyManager mDevicePolicyManager; - @Mock - private AppInfoDashboardFragment mFragment; - @Mock - private ApplicationInfo mAppInfo; - @Mock - private PackageManager mPackageManager; - - private Context mContext; - private AppActionButtonPreferenceController mController; - private FakeFeatureFactory mFeatureFactory; - - @Before - public void setUp() { - MockitoAnnotations.initMocks(this); - mFeatureFactory = FakeFeatureFactory.setupForTest(); - mContext = spy(RuntimeEnvironment.application); - mController = spy(new AppActionButtonPreferenceController(mContext, mFragment, "Package1")); - mController.mActionButtons = ActionButtonPreferenceTest.createMock(); - ReflectionHelpers.setField(mController, "mUserManager", mUserManager); - ReflectionHelpers.setField(mController, "mDpm", mDevicePolicyManager); - ReflectionHelpers.setField(mController, "mApplicationFeatureProvider", - mFeatureFactory.applicationFeatureProvider); - ReflectionHelpers.setField(mController, "mPm", mPackageManager); - when(mContext.getSystemService(Context.USER_SERVICE)).thenReturn(mUserManager); - when(mContext.getPackageManager()).thenReturn(mPackageManager); - final PackageInfo packageInfo = mock(PackageInfo.class); - packageInfo.applicationInfo = mAppInfo; - when(mFragment.getPackageInfo()).thenReturn(packageInfo); - } - - @Test - public void getAvailabilityStatus_notInstantApp_shouldReturnAvailable() { - ReflectionHelpers.setStaticField(AppUtils.class, "sInstantAppDataProvider", - (InstantAppDataProvider) (i -> false)); - - assertThat(mController.getAvailabilityStatus()).isEqualTo(mController.AVAILABLE); - } - - @Test - public void getAvailabilityStatus_isInstantApp_shouldReturnDisabled() { - ReflectionHelpers.setStaticField(AppUtils.class, "sInstantAppDataProvider", - (InstantAppDataProvider) (i -> true)); - - assertThat(mController.getAvailabilityStatus()).isEqualTo(mController.DISABLED_FOR_USER); - } - - @Test - public void displayPreference_shouldInitializeForceStopButton() { - final PreferenceScreen screen = mock(PreferenceScreen.class); - final ActionButtonPreference preference = spy(new ActionButtonPreference(mContext)); - when(screen.findPreference(mController.getPreferenceKey())).thenReturn(preference); - - mController.displayPreference(screen); - - verify(preference).setButton2Positive(false); - verify(preference).setButton2Text(R.string.force_stop); - verify(preference).setButton2Enabled(false); - } - - @Test - public void refreshUi_shouldRefreshButton() { - final PackageInfo packageInfo = mock(PackageInfo.class); - final ApplicationsState.AppEntry appEntry = mock(ApplicationsState.AppEntry.class); - final ApplicationInfo info = new ApplicationInfo(); - appEntry.info = info; - doNothing().when(mController).checkForceStop(appEntry, packageInfo); - doNothing().when(mController).initUninstallButtons(appEntry, packageInfo); - when(mFragment.getAppEntry()).thenReturn(appEntry); - when(mFragment.getPackageInfo()).thenReturn(packageInfo); - - mController.refreshUi(); - - verify(mController).checkForceStop(appEntry, packageInfo); - verify(mController).initUninstallButtons(appEntry, packageInfo); - } - - @Test - public void initUninstallButtonForUserApp_shouldSetNegativeButton() { - final ApplicationInfo info = new ApplicationInfo(); - info.flags = ApplicationInfo.FLAG_INSTALLED; - info.enabled = true; - final PackageInfo packageInfo = mock(PackageInfo.class); - packageInfo.applicationInfo = info; - when(mFragment.getPackageInfo()).thenReturn(packageInfo); - - assertThat(mController.initUninstallButtonForUserApp()).isTrue(); - verify(mController.mActionButtons).setButton1Positive(false); - } - - // Tests that we don't show the uninstall button for instant apps" - @Test - public void initUninstallButtonForUserApp_instantApps_noUninstallButton() { - // Make this app appear to be instant. - ReflectionHelpers.setStaticField(AppUtils.class, "sInstantAppDataProvider", - (InstantAppDataProvider) (i -> true)); - final ApplicationInfo info = new ApplicationInfo(); - info.flags = ApplicationInfo.FLAG_INSTALLED; - info.enabled = true; - final ApplicationsState.AppEntry appEntry = mock(ApplicationsState.AppEntry.class); - appEntry.info = info; - final PackageInfo packageInfo = mock(PackageInfo.class); - packageInfo.applicationInfo = info; - when(mFragment.getPackageInfo()).thenReturn(packageInfo); - - assertThat(mController.initUninstallButtonForUserApp()).isFalse(); - verify(mController.mActionButtons).setButton1Visible(false); - } - - @Test - public void initUninstallButtonForUserApp_notInstalledForCurrentUser_shouldDisableButton() { - final ApplicationInfo info = new ApplicationInfo(); - info.enabled = true; - final PackageInfo packageInfo = mock(PackageInfo.class); - packageInfo.applicationInfo = info; - when(mFragment.getPackageInfo()).thenReturn(packageInfo); - final int userID1 = 1; - final int userID2 = 2; - final List userInfos = new ArrayList<>(); - userInfos.add(new UserInfo(userID1, "User1", UserInfo.FLAG_PRIMARY)); - userInfos.add(new UserInfo(userID2, "User2", UserInfo.FLAG_GUEST)); - when(mUserManager.getUsers(true)).thenReturn(userInfos); - - assertThat(mController.initUninstallButtonForUserApp()).isFalse(); - } - - // Tests that we don't show the force stop button for instant apps (they aren't allowed to run - // when they aren't in the foreground). - @Test - public void checkForceStop_instantApps_shouldNotShowForceStop() { - // Make this app appear to be instant. - ReflectionHelpers.setStaticField(AppUtils.class, "sInstantAppDataProvider", - (InstantAppDataProvider) (i -> true)); - final PackageInfo packageInfo = mock(PackageInfo.class); - final ApplicationsState.AppEntry appEntry = mock(ApplicationsState.AppEntry.class); - final ApplicationInfo info = new ApplicationInfo(); - appEntry.info = info; - - mController.checkForceStop(appEntry, packageInfo); - - verify(mController.mActionButtons).setButton2Visible(false); - } - - @Test - public void checkForceStop_isStateProtected_shouldDisableForceStop() { - ReflectionHelpers.setStaticField(AppUtils.class, "sInstantAppDataProvider", - (InstantAppDataProvider) (i -> false)); - final String packageName = "Package1"; - final PackageInfo packageInfo = new PackageInfo(); - packageInfo.packageName = packageName; - final ApplicationInfo appInfo = new ApplicationInfo(); - appInfo.uid = 42; - appInfo.sourceDir = "source"; - final ApplicationsState.AppEntry appEntry = new ApplicationsState.AppEntry( - mContext, appInfo, 0); - when(mPackageManager.isPackageStateProtected(packageName, 0)).thenReturn(true); - - mController.checkForceStop(appEntry, packageInfo); - - verify(mController.mActionButtons).setButton2Enabled(false); - } - - @Test - public void checkForceStop_hasActiveAdmin_shouldDisableForceStop() { - ReflectionHelpers.setStaticField(AppUtils.class, "sInstantAppDataProvider", - (InstantAppDataProvider) (i -> false)); - final String packageName = "Package1"; - final PackageInfo packageInfo = new PackageInfo(); - packageInfo.packageName = packageName; - final ApplicationsState.AppEntry appEntry = mock(ApplicationsState.AppEntry.class); - when(mDevicePolicyManager.packageHasActiveAdmins(packageName)).thenReturn(true); - - mController.checkForceStop(appEntry, packageInfo); - - verify(mController.mActionButtons).setButton2Enabled(false); - } - - @Test - public void checkForceStop_appRunning_shouldEnableForceStop() { - ReflectionHelpers.setStaticField(AppUtils.class, "sInstantAppDataProvider", - (InstantAppDataProvider) (i -> false)); - final PackageInfo packageInfo = mock(PackageInfo.class); - final ApplicationsState.AppEntry appEntry = mock(ApplicationsState.AppEntry.class); - final ApplicationInfo info = new ApplicationInfo(); - appEntry.info = info; - - mController.checkForceStop(appEntry, packageInfo); - - verify(mController.mActionButtons).setButton2Enabled(true); - } - - @Test - public void checkForceStop_appStopped_shouldQueryPackageRestart() { - ReflectionHelpers.setStaticField(AppUtils.class, "sInstantAppDataProvider", - (InstantAppDataProvider) (i -> false)); - final PackageInfo packageInfo = mock(PackageInfo.class); - final ApplicationsState.AppEntry appEntry = mock(ApplicationsState.AppEntry.class); - final ApplicationInfo info = new ApplicationInfo(); - appEntry.info = info; - info.flags = ApplicationInfo.FLAG_STOPPED; - info.packageName = "com.android.setting"; - - mController.checkForceStop(appEntry, packageInfo); - - verify(mContext).sendOrderedBroadcastAsUser(argThat(intent -> intent != null - && intent.getAction().equals(Intent.ACTION_QUERY_PACKAGE_RESTART)), - any(UserHandle.class), nullable(String.class), any(BroadcastReceiver.class), - nullable(Handler.class), anyInt(), nullable(String.class), nullable(Bundle.class)); - } - - @Test - public void handleDisableable_appIsHomeApp_buttonShouldNotWork() { - final ApplicationInfo info = new ApplicationInfo(); - info.packageName = "pkg"; - info.enabled = true; - final ApplicationsState.AppEntry appEntry = mock(ApplicationsState.AppEntry.class); - appEntry.info = info; - final HashSet homePackages = new HashSet<>(); - homePackages.add(info.packageName); - ReflectionHelpers.setField(mController, "mHomePackages", homePackages); - - assertThat(mController.handleDisableable(appEntry, mock(PackageInfo.class))).isFalse(); - verify(mController.mActionButtons).setButton1Text(R.string.disable_text); - } - - @Test - @Config(shadows = ShadowUtils.class) - public void handleDisableable_appIsEnabled_buttonShouldWork() { - final ApplicationInfo info = new ApplicationInfo(); - info.packageName = "pkg"; - info.enabled = true; - info.enabledSetting = PackageManager.COMPONENT_ENABLED_STATE_ENABLED; - final ApplicationsState.AppEntry appEntry = mock(ApplicationsState.AppEntry.class); - appEntry.info = info; - when(mFeatureFactory.applicationFeatureProvider.getKeepEnabledPackages()) - .thenReturn(new HashSet<>()); - - assertThat(mController.handleDisableable(appEntry, mock(PackageInfo.class))).isTrue(); - verify(mController.mActionButtons).setButton1Text(R.string.disable_text); - } - - @Test - @Config(shadows = ShadowUtils.class) - public void handleDisableable_appIsDisabled_buttonShouldShowEnable() { - final ApplicationInfo info = new ApplicationInfo(); - info.packageName = "pkg"; - info.enabled = false; - info.enabledSetting = PackageManager.COMPONENT_ENABLED_STATE_ENABLED; - final ApplicationsState.AppEntry appEntry = mock(ApplicationsState.AppEntry.class); - appEntry.info = info; - when(mFeatureFactory.applicationFeatureProvider.getKeepEnabledPackages()) - .thenReturn(new HashSet<>()); - - assertThat(mController.handleDisableable(appEntry, mock(PackageInfo.class))).isTrue(); - verify(mController.mActionButtons).setButton1Text(R.string.enable_text); - verify(mController.mActionButtons).setButton1Positive(true); - } - - @Test - @Config(shadows = ShadowUtils.class) - public void handleDisableable_appIsEnabledAndInKeepEnabledWhitelist_buttonShouldNotWork() { - final ApplicationInfo info = new ApplicationInfo(); - info.packageName = "pkg"; - info.enabled = true; - info.enabledSetting = PackageManager.COMPONENT_ENABLED_STATE_ENABLED; - final ApplicationsState.AppEntry appEntry = mock(ApplicationsState.AppEntry.class); - appEntry.info = info; - final HashSet packages = new HashSet<>(); - packages.add(info.packageName); - when(mFeatureFactory.applicationFeatureProvider.getKeepEnabledPackages()) - .thenReturn(packages); - - assertThat(mController.handleDisableable(appEntry, mock(PackageInfo.class))).isFalse(); - verify(mController.mActionButtons).setButton1Text(R.string.disable_text); - } - - @Implements(Utils.class) - public static class ShadowUtils { - @Implementation - public static boolean isSystemPackage(Resources resources, PackageManager pm, - PackageInfo pkg) { - return false; - } - } -} diff --git a/tests/robotests/src/com/android/settings/fuelgauge/AppButtonsPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/applications/appinfo/AppButtonsPreferenceControllerTest.java similarity index 93% rename from tests/robotests/src/com/android/settings/fuelgauge/AppButtonsPreferenceControllerTest.java rename to tests/robotests/src/com/android/settings/applications/appinfo/AppButtonsPreferenceControllerTest.java index 551cb3e0bb0..24579ef961f 100644 --- a/tests/robotests/src/com/android/settings/fuelgauge/AppButtonsPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/applications/appinfo/AppButtonsPreferenceControllerTest.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.settings.fuelgauge; +package com.android.settings.applications.appinfo; import static com.google.common.truth.Truth.assertThat; import static org.mockito.Matchers.any; @@ -44,6 +44,8 @@ import android.os.UserManager; import com.android.settings.R; import com.android.settings.SettingsActivity; +import com.android.settings.applications.appinfo.AppButtonsPreferenceController; +import com.android.settings.applications.appinfo.ButtonActionDialogFragment; import com.android.settings.testutils.FakeFeatureFactory; import com.android.settings.widget.ActionButtonPreference; import com.android.settings.widget.ActionButtonPreferenceTest; @@ -107,6 +109,7 @@ public class AppButtonsPreferenceControllerTest { MockitoAnnotations.initMocks(this); FakeFeatureFactory.setupForTest(); + doReturn(mDpm).when(mSettingsActivity).getSystemService(Context.DEVICE_POLICY_SERVICE); doReturn(mUserManager).when(mSettingsActivity).getSystemService(Context.USER_SERVICE); doReturn(mPackageManger).when(mSettingsActivity).getPackageManager(); doReturn(mAm).when(mSettingsActivity).getSystemService(Context.ACTIVITY_SERVICE); @@ -115,8 +118,7 @@ public class AppButtonsPreferenceControllerTest { when(mSettingsActivity.getResources().getString(anyInt())).thenReturn(RESOURCE_STRING); mController = spy(new AppButtonsPreferenceController(mSettingsActivity, mFragment, - mLifecycle, PACKAGE_NAME, mState, mDpm, mUserManager, mPackageManger, - REQUEST_UNINSTALL, REQUEST_REMOVE_DEVICE_ADMIN)); + mLifecycle, PACKAGE_NAME, mState, REQUEST_UNINSTALL, REQUEST_REMOVE_DEVICE_ADMIN)); doReturn(false).when(mController).isFallbackPackage(anyString()); mAppEntry.info = mAppInfo; @@ -334,6 +336,15 @@ public class AppButtonsPreferenceControllerTest { assertThat(controllable).isTrue(); } + @Test + public void handleActivityResult_packageUninstalled_shouldFinishPrefernecePanel() { + doReturn(false).when(mController).refreshUi(); + + mController.handleActivityResult(REQUEST_UNINSTALL, 0, mock(Intent.class)); + + verify(mSettingsActivity).finishPreferencePanel(anyInt(), any(Intent.class)); + } + @Test public void refreshUi_packageNull_shouldNotCrash() { mController.mPackageName = null; @@ -344,7 +355,7 @@ public class AppButtonsPreferenceControllerTest { @Test public void onPackageListChanged_available_shouldRefreshUi() { - doReturn(true).when(mController).isAvailable(); + doReturn(mController.AVAILABLE).when(mController).getAvailabilityStatus(); doReturn(true).when(mController).refreshUi(); mController.onPackageListChanged(); @@ -354,7 +365,7 @@ public class AppButtonsPreferenceControllerTest { @Test public void onPackageListChanged_notAvailable_shouldNotRefreshUiAndNoCrash() { - doReturn(false).when(mController).isAvailable(); + doReturn(mController.DISABLED_FOR_USER).when(mController).getAvailabilityStatus(); mController.onPackageListChanged(); diff --git a/tests/robotests/src/com/android/settings/applications/appinfo/AppInfoDashboardFragmentTest.java b/tests/robotests/src/com/android/settings/applications/appinfo/AppInfoDashboardFragmentTest.java index 3128f30f656..8314cb70f5d 100644 --- a/tests/robotests/src/com/android/settings/applications/appinfo/AppInfoDashboardFragmentTest.java +++ b/tests/robotests/src/com/android/settings/applications/appinfo/AppInfoDashboardFragmentTest.java @@ -232,15 +232,6 @@ public final class AppInfoDashboardFragmentTest { verify(mActivity).invalidateOptionsMenu(); } - @Test - public void onActivityResult_packageUninstalled_shouldFinishAndRemoveTask() { - doReturn(false).when(mFragment).refreshUi(); - - mFragment.onActivityResult(mFragment.REQUEST_UNINSTALL, 0, mock(Intent.class)); - - verify(mActivity).finishAndRemoveTask(); - } - @Test public void getPreferenceControllers_noPackageInfo_shouldReturnNull() { doNothing().when(mFragment).retrieveAppEntry(); diff --git a/tests/robotests/src/com/android/settings/fuelgauge/ButtonActionDialogFragmentTest.java b/tests/robotests/src/com/android/settings/applications/appinfo/ButtonActionDialogFragmentTest.java similarity index 97% rename from tests/robotests/src/com/android/settings/fuelgauge/ButtonActionDialogFragmentTest.java rename to tests/robotests/src/com/android/settings/applications/appinfo/ButtonActionDialogFragmentTest.java index 83d8f7a81f6..ae6ba1d8146 100644 --- a/tests/robotests/src/com/android/settings/fuelgauge/ButtonActionDialogFragmentTest.java +++ b/tests/robotests/src/com/android/settings/applications/appinfo/ButtonActionDialogFragmentTest.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.android.settings.fuelgauge; +package com.android.settings.applications.appinfo; import static com.google.common.truth.Truth.assertThat; import static org.mockito.Matchers.anyInt; @@ -128,7 +128,7 @@ public class ButtonActionDialogFragmentTest { /** * Test fragment that used as the target fragment, it must implement the - * {@link com.android.settings.fuelgauge.ButtonActionDialogFragment.AppButtonsDialogListener} + * {@link ButtonActionDialogFragment.AppButtonsDialogListener} */ public static class TestFragment extends Fragment implements ButtonActionDialogFragment.AppButtonsDialogListener { diff --git a/tests/robotests/src/com/android/settings/core/BasePreferenceControllerSignatureInspector.java b/tests/robotests/src/com/android/settings/core/BasePreferenceControllerSignatureInspector.java index a9b4f5dc550..ce438b06bb0 100644 --- a/tests/robotests/src/com/android/settings/core/BasePreferenceControllerSignatureInspector.java +++ b/tests/robotests/src/com/android/settings/core/BasePreferenceControllerSignatureInspector.java @@ -67,7 +67,7 @@ public class BasePreferenceControllerSignatureInspector extends CodeInspector { } assertWithMessage("All BasePreferenceController (and subclasses) constructor must either" - + "only take Context, or (Context, String). No other types are allowed") + + " only take Context, or (Context, String). No other types are allowed") .that(badClasses.toString()) .isEmpty();