Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6bfcba78 authored by Antony Sargent's avatar Antony Sargent Committed by Android (Google) Code Review
Browse files

Merge "Move force stop button back out of options menu"

parents 1ee0aa96 b513ca93
Loading
Loading
Loading
Loading
+54 −1
Original line number Diff line number Diff line
@@ -16,14 +16,18 @@

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;
@@ -31,6 +35,7 @@ import android.os.UserHandle;
import android.os.UserManager;
import android.support.annotation.VisibleForTesting;
import android.support.v7.preference.PreferenceScreen;
import android.util.Log;
import android.webkit.IWebViewUpdateService;

import com.android.settings.R;
@@ -66,6 +71,16 @@ public class AppActionButtonPreferenceController extends BasePreferenceControlle
    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);
@@ -86,7 +101,9 @@ public class AppActionButtonPreferenceController extends BasePreferenceControlle
    public void displayPreference(PreferenceScreen screen) {
        super.displayPreference(screen);
        mActionButtons = ((ActionButtonPreference) screen.findPreference(KEY_ACTION_BUTTONS))
                .setButton2Visible(false);
                .setButton2Text(R.string.force_stop)
                .setButton2Positive(false)
                .setButton2Enabled(false);
    }

    @Override
@@ -123,6 +140,7 @@ public class AppActionButtonPreferenceController extends BasePreferenceControlle
            }
        }

        checkForceStop(appEntry, packageInfo);
        initUninstallButtons(appEntry, packageInfo);
    }

@@ -251,6 +269,41 @@ public class AppActionButtonPreferenceController extends BasePreferenceControlle
        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 (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 {
+49 −16
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ 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;
@@ -44,16 +45,20 @@ import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;

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;
import com.android.settings.Utils;
import com.android.settings.applications.LayoutPreference;
import com.android.settings.applications.manageapplications.ManageApplications;
import com.android.settings.core.SubSettingLauncher;
import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
import com.android.settings.dashboard.DashboardFragment;
import com.android.settings.widget.EntityHeaderController;
import com.android.settings.widget.PreferenceCategoryController;
import com.android.settings.wrapper.DevicePolicyManagerWrapper;
import com.android.settingslib.RestrictedLockUtils;
@@ -85,8 +90,7 @@ public class AppInfoDashboardFragment extends DashboardFragment
    // Menu identifiers
    @VisibleForTesting static final int UNINSTALL_ALL_USERS_MENU = 1;
    @VisibleForTesting static final int UNINSTALL_UPDATES = 2;
    static final int FORCE_STOP_MENU = 3;
    static final int INSTALL_INSTANT_APP_MENU = 4;
    static final int INSTALL_INSTANT_APP_MENU = 3;

    // Result code identifiers
    @VisibleForTesting
@@ -101,7 +105,7 @@ public class AppInfoDashboardFragment extends DashboardFragment

    // Dialog identifiers used in showDialog
    private static final int DLG_BASE = 0;
    static final int DLG_FORCE_STOP = DLG_BASE + 1;
    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;
@@ -140,7 +144,6 @@ public class AppInfoDashboardFragment extends DashboardFragment

    private InstantAppButtonsPreferenceController mInstantAppButtonPreferenceController;
    private AppActionButtonPreferenceController mAppActionButtonPreferenceController;
    private ForceStopOptionsMenuController mForceStopOptionsMenuController;

    /**
     * Callback to invoke when app info has been changed.
@@ -171,9 +174,6 @@ public class AppInfoDashboardFragment extends DashboardFragment

        startListeningToPackageRemove();

        mForceStopOptionsMenuController =
            new ForceStopOptionsMenuController(activity, this /* parent */, mDpm,
                mMetricsFeatureProvider, getLifecycle());
        setHasOptionsMenu(true);
    }

@@ -285,10 +285,6 @@ public class AppInfoDashboardFragment extends DashboardFragment
        return mPackageInfo;
    }

    ApplicationsState getAppState() {
        return mState;
    }

    @Override
    public void onPackageSizeChanged(String packageName) {
        if (!TextUtils.equals(packageName, mPackageName)) {
@@ -488,10 +484,18 @@ public class AppInfoDashboardFragment extends DashboardFragment
                        })
                        .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);
                            }
        final AlertDialog dialog = mForceStopOptionsMenuController.createDialog(id);
        if (dialog != null) {
            return dialog;
                        })
                        .setNegativeButton(R.string.dlg_cancel, null)
                        .create();
        }
        return mInstantAppButtonPreferenceController.createDialog(id);
    }
@@ -508,6 +512,21 @@ public class AppInfoDashboardFragment extends DashboardFragment
        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,
            SettingsPreferenceFragment caller, AppEntry appEntry) {
        // start new fragment to display extended information
@@ -573,6 +592,20 @@ public class AppInfoDashboardFragment extends DashboardFragment
        }
    }

    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();
@@ -671,7 +704,7 @@ public class AppInfoDashboardFragment extends DashboardFragment
        }
    }

    void setIntentAndFinish(boolean finish, boolean appChanged) {
    private void setIntentAndFinish(boolean finish, boolean appChanged) {
        if (localLOGV) Log.i(TAG, "appChanged="+appChanged);
        final Intent intent = new Intent();
        intent.putExtra(ManageApplications.APP_CHG, appChanged);
+0 −198
Original line number Diff line number Diff line
/*
 * Copyright (C) 2018 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.android.settings.applications.appinfo.AppInfoDashboardFragment.FORCE_STOP_MENU;
import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;

import android.app.Activity;
import android.app.ActivityManager;
import android.app.AlertDialog;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.net.Uri;
import android.os.UserHandle;
import android.os.UserManager;
import android.support.annotation.VisibleForTesting;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;

import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.settings.R;
import com.android.settings.wrapper.DevicePolicyManagerWrapper;
import com.android.settingslib.RestrictedLockUtils;
import com.android.settingslib.applications.AppUtils;
import com.android.settingslib.applications.ApplicationsState;
import com.android.settingslib.applications.ApplicationsState.AppEntry;
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
import com.android.settingslib.core.lifecycle.Lifecycle;
import com.android.settingslib.core.lifecycle.LifecycleObserver;
import com.android.settingslib.core.lifecycle.events.OnCreateOptionsMenu;
import com.android.settingslib.core.lifecycle.events.OnOptionsItemSelected;
import com.android.settingslib.core.lifecycle.events.OnPrepareOptionsMenu;

public class ForceStopOptionsMenuController implements LifecycleObserver, OnCreateOptionsMenu,
        OnPrepareOptionsMenu, OnOptionsItemSelected {

    private static final String TAG = "ForceStopMenuController";

    private final Context mContext;
    private final AppInfoDashboardFragment mParent;
    private final DevicePolicyManagerWrapper mDpm;
    private final MetricsFeatureProvider mMetricsFeatureProvider;

    private int mUserId;
    private MenuItem mForceStopMenu;

    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);
            enableForceStopMenu(enabled);
        }
    };

    public ForceStopOptionsMenuController(Context context, AppInfoDashboardFragment parent,
            DevicePolicyManagerWrapper devicePolicyManager,
            MetricsFeatureProvider metricsFeatureProvider, Lifecycle lifecycle) {
        mContext = context;
        mParent = parent;
        mDpm = devicePolicyManager;
        mMetricsFeatureProvider = metricsFeatureProvider;
        mUserId = UserHandle.myUserId();
        if (lifecycle != null) {
            lifecycle.addObserver(this);
        }
    }

    @Override
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
        menu.add(0, FORCE_STOP_MENU, 2, R.string.force_stop)
            .setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem menuItem) {
        if (menuItem.getItemId() == FORCE_STOP_MENU) {
            handleForceStopMenuClick();
            return true;
        }
        return false;
    }

    @Override
    public void onPrepareOptionsMenu(Menu menu) {
        mForceStopMenu = menu.findItem(FORCE_STOP_MENU);
        updateForceStopMenu(mParent.getAppEntry(), mParent.getPackageInfo());
    }

    @VisibleForTesting
    void updateForceStopMenu(AppEntry appEntry, PackageInfo packageInfo) {
        boolean enabled = false;
        if (mDpm.packageHasActiveAdmins(packageInfo.packageName)) {
            // User can't force stop device admin.
            Log.w(TAG, "User can't force stop device admin");
        } else if (AppUtils.isInstant(packageInfo.applicationInfo)) {
            // No force stop for instant app
            if (mForceStopMenu != null) {
                mForceStopMenu.setVisible(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");
            enabled = 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);
        }
        enableForceStopMenu(enabled);
    }

    private void enableForceStopMenu(boolean enabled) {
        if (mForceStopMenu != null) {
            final boolean disallowedBySystem = RestrictedLockUtils.hasBaseUserRestriction(
                mContext, UserManager.DISALLOW_APPS_CONTROL, mUserId);
            mForceStopMenu.setEnabled(disallowedBySystem ? false : enabled);
        }
    }

    @VisibleForTesting
    void handleForceStopMenuClick() {
        if (mParent.getAppEntry() == null) {
            mParent.setIntentAndFinish(true, true);
            return;
        }
        final EnforcedAdmin admin = RestrictedLockUtils.checkIfRestrictionEnforced(
            mContext, UserManager.DISALLOW_APPS_CONTROL, mUserId);
        final boolean disallowedBySystem = RestrictedLockUtils.hasBaseUserRestriction(
            mContext, UserManager.DISALLOW_APPS_CONTROL, mUserId);
        if (admin != null && !disallowedBySystem) {
            RestrictedLockUtils.sendShowAdminSupportDetailsIntent(mContext, admin);
        } else {
            mParent.showDialogInner(mParent.DLG_FORCE_STOP, 0);
        }
    }

    private void forceStopPackage(String pkgName) {
        mMetricsFeatureProvider.action(mContext, MetricsEvent.ACTION_APP_FORCE_STOP, pkgName);
        final ActivityManager am = (ActivityManager) mContext.getSystemService(
            Context.ACTIVITY_SERVICE);
        Log.d(TAG, "Stopping package " + pkgName);
        am.forceStopPackage(pkgName);
        final int userId = UserHandle.getUserId(mParent.getAppEntry().info.uid);
        final ApplicationsState appState = mParent.getAppState();
        appState.invalidatePackage(pkgName, userId);
        final AppEntry newEnt = appState.getEntry(pkgName, userId);
        if (newEnt != null) {
            mParent.setAppEntry(newEnt);
        }
    }

    public AlertDialog createDialog(int id) {
        if (id != mParent.DLG_FORCE_STOP) {
            return null;
        }
        return new AlertDialog.Builder(mContext)
            .setTitle(mContext.getText(R.string.force_stop_dlg_title))
            .setMessage(mContext.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(mParent.getAppEntry().info.packageName);
                }
            })
            .setNegativeButton(R.string.dlg_cancel, null)
            .create();
    }

}
+80 −2
Original line number Diff line number Diff line
@@ -18,18 +18,27 @@ 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.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 android.support.v7.preference.PreferenceScreen;

@@ -111,14 +120,16 @@ public class AppActionButtonPreferenceControllerTest {
    }

    @Test
    public void displayPreference_shouldSetButton2Invisible() {
    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).setButton2Visible(false);
        verify(preference).setButton2Positive(false);
        verify(preference).setButton2Text(R.string.force_stop);
        verify(preference).setButton2Enabled(false);
    }

    @Test
@@ -127,12 +138,14 @@ public class AppActionButtonPreferenceControllerTest {
        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);
    }

@@ -185,6 +198,71 @@ public class AppActionButtonPreferenceControllerTest {
        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_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();
+1 −5

File changed.

Preview size limit exceeded, changes collapsed.

Loading