1ddba96670048a07b98e5c1e0d9f3d9bd4ebe9b38jackqdyulei/*
2ddba96670048a07b98e5c1e0d9f3d9bd4ebe9b38jackqdyulei * Copyright (C) 2017 The Android Open Source Project
3ddba96670048a07b98e5c1e0d9f3d9bd4ebe9b38jackqdyulei *
4ddba96670048a07b98e5c1e0d9f3d9bd4ebe9b38jackqdyulei * Licensed under the Apache License, Version 2.0 (the "License");
5ddba96670048a07b98e5c1e0d9f3d9bd4ebe9b38jackqdyulei * you may not use this file except in compliance with the License.
6ddba96670048a07b98e5c1e0d9f3d9bd4ebe9b38jackqdyulei * You may obtain a copy of the License at
7ddba96670048a07b98e5c1e0d9f3d9bd4ebe9b38jackqdyulei *
8ddba96670048a07b98e5c1e0d9f3d9bd4ebe9b38jackqdyulei *      http://www.apache.org/licenses/LICENSE-2.0
9ddba96670048a07b98e5c1e0d9f3d9bd4ebe9b38jackqdyulei *
10ddba96670048a07b98e5c1e0d9f3d9bd4ebe9b38jackqdyulei * Unless required by applicable law or agreed to in writing, software
11ddba96670048a07b98e5c1e0d9f3d9bd4ebe9b38jackqdyulei * distributed under the License is distributed on an "AS IS" BASIS,
12ddba96670048a07b98e5c1e0d9f3d9bd4ebe9b38jackqdyulei * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13ddba96670048a07b98e5c1e0d9f3d9bd4ebe9b38jackqdyulei * See the License for the specific language governing permissions and
14ddba96670048a07b98e5c1e0d9f3d9bd4ebe9b38jackqdyulei * limitations under the License.
15ddba96670048a07b98e5c1e0d9f3d9bd4ebe9b38jackqdyulei */
16ddba96670048a07b98e5c1e0d9f3d9bd4ebe9b38jackqdyulei
17ddba96670048a07b98e5c1e0d9f3d9bd4ebe9b38jackqdyuleipackage com.android.settings.fuelgauge;
18ddba96670048a07b98e5c1e0d9f3d9bd4ebe9b38jackqdyulei
19ddba96670048a07b98e5c1e0d9f3d9bd4ebe9b38jackqdyuleiimport android.app.Activity;
2031b8de1e215f6f0dcd694024c617f9f185e510aejackqdyuleiimport android.app.ActivityManager;
2131b8de1e215f6f0dcd694024c617f9f185e510aejackqdyuleiimport android.app.Fragment;
2231b8de1e215f6f0dcd694024c617f9f185e510aejackqdyuleiimport android.content.BroadcastReceiver;
2331b8de1e215f6f0dcd694024c617f9f185e510aejackqdyuleiimport android.content.ComponentName;
2431b8de1e215f6f0dcd694024c617f9f185e510aejackqdyuleiimport android.content.Context;
2531b8de1e215f6f0dcd694024c617f9f185e510aejackqdyuleiimport android.content.Intent;
2631b8de1e215f6f0dcd694024c617f9f185e510aejackqdyuleiimport android.content.IntentFilter;
2731b8de1e215f6f0dcd694024c617f9f185e510aejackqdyuleiimport android.content.pm.ApplicationInfo;
2831b8de1e215f6f0dcd694024c617f9f185e510aejackqdyuleiimport android.content.pm.PackageInfo;
2931b8de1e215f6f0dcd694024c617f9f185e510aejackqdyuleiimport android.content.pm.PackageManager;
3031b8de1e215f6f0dcd694024c617f9f185e510aejackqdyuleiimport android.content.pm.ResolveInfo;
3131b8de1e215f6f0dcd694024c617f9f185e510aejackqdyuleiimport android.content.pm.UserInfo;
3231b8de1e215f6f0dcd694024c617f9f185e510aejackqdyuleiimport android.content.res.Resources;
3331b8de1e215f6f0dcd694024c617f9f185e510aejackqdyuleiimport android.net.Uri;
3431b8de1e215f6f0dcd694024c617f9f185e510aejackqdyuleiimport android.os.AsyncTask;
3531b8de1e215f6f0dcd694024c617f9f185e510aejackqdyuleiimport android.os.Bundle;
3631b8de1e215f6f0dcd694024c617f9f185e510aejackqdyuleiimport android.os.RemoteException;
3731b8de1e215f6f0dcd694024c617f9f185e510aejackqdyuleiimport android.os.ServiceManager;
38ddba96670048a07b98e5c1e0d9f3d9bd4ebe9b38jackqdyuleiimport android.os.UserHandle;
3931b8de1e215f6f0dcd694024c617f9f185e510aejackqdyuleiimport android.os.UserManager;
40ddba96670048a07b98e5c1e0d9f3d9bd4ebe9b38jackqdyuleiimport android.support.v7.preference.PreferenceScreen;
4131b8de1e215f6f0dcd694024c617f9f185e510aejackqdyuleiimport android.util.Log;
42ddba96670048a07b98e5c1e0d9f3d9bd4ebe9b38jackqdyuleiimport android.view.View;
4331b8de1e215f6f0dcd694024c617f9f185e510aejackqdyuleiimport android.webkit.IWebViewUpdateService;
44ddba96670048a07b98e5c1e0d9f3d9bd4ebe9b38jackqdyuleiimport android.widget.Button;
45ddba96670048a07b98e5c1e0d9f3d9bd4ebe9b38jackqdyulei
4631b8de1e215f6f0dcd694024c617f9f185e510aejackqdyuleiimport com.android.internal.annotations.VisibleForTesting;
4731b8de1e215f6f0dcd694024c617f9f185e510aejackqdyuleiimport com.android.internal.logging.nano.MetricsProto;
4831b8de1e215f6f0dcd694024c617f9f185e510aejackqdyuleiimport com.android.settings.DeviceAdminAdd;
49ddba96670048a07b98e5c1e0d9f3d9bd4ebe9b38jackqdyuleiimport com.android.settings.R;
5031b8de1e215f6f0dcd694024c617f9f185e510aejackqdyuleiimport com.android.settings.SettingsActivity;
5131b8de1e215f6f0dcd694024c617f9f185e510aejackqdyuleiimport com.android.settings.Utils;
52ddba96670048a07b98e5c1e0d9f3d9bd4ebe9b38jackqdyuleiimport com.android.settings.applications.LayoutPreference;
531d583e125faf3ae4c9cd82636d8f3ecf1cdec3aaTony Mantlerimport com.android.settings.core.PreferenceControllerMixin;
5431b8de1e215f6f0dcd694024c617f9f185e510aejackqdyuleiimport com.android.settings.core.instrumentation.MetricsFeatureProvider;
5531b8de1e215f6f0dcd694024c617f9f185e510aejackqdyuleiimport com.android.settings.enterprise.DevicePolicyManagerWrapper;
5631b8de1e215f6f0dcd694024c617f9f185e510aejackqdyuleiimport com.android.settings.overlay.FeatureFactory;
5731b8de1e215f6f0dcd694024c617f9f185e510aejackqdyuleiimport com.android.settingslib.RestrictedLockUtils;
580d7854aa43c7d8debc8daf1390625803fb56e9baJesse Evansimport com.android.settingslib.applications.AppUtils;
59ddba96670048a07b98e5c1e0d9f3d9bd4ebe9b38jackqdyuleiimport com.android.settingslib.applications.ApplicationsState;
601d583e125faf3ae4c9cd82636d8f3ecf1cdec3aaTony Mantlerimport com.android.settingslib.core.AbstractPreferenceController;
61777ed2535a7fd6f618a0d12f381af99252283574Juan Langimport com.android.settingslib.core.lifecycle.Lifecycle;
62777ed2535a7fd6f618a0d12f381af99252283574Juan Langimport com.android.settingslib.core.lifecycle.LifecycleObserver;
63777ed2535a7fd6f618a0d12f381af99252283574Juan Langimport com.android.settingslib.core.lifecycle.events.OnDestroy;
64777ed2535a7fd6f618a0d12f381af99252283574Juan Langimport com.android.settingslib.core.lifecycle.events.OnPause;
65777ed2535a7fd6f618a0d12f381af99252283574Juan Langimport com.android.settingslib.core.lifecycle.events.OnResume;
66ddba96670048a07b98e5c1e0d9f3d9bd4ebe9b38jackqdyulei
6731b8de1e215f6f0dcd694024c617f9f185e510aejackqdyuleiimport java.util.ArrayList;
6831b8de1e215f6f0dcd694024c617f9f185e510aejackqdyuleiimport java.util.HashSet;
6931b8de1e215f6f0dcd694024c617f9f185e510aejackqdyuleiimport java.util.List;
7031b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei
71ddba96670048a07b98e5c1e0d9f3d9bd4ebe9b38jackqdyulei/**
7231b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei * Controller to control the uninstall button and forcestop button. All fragments that use
7331b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei * this controller should implement {@link ButtonActionDialogFragment.AppButtonsDialogListener} and
7431b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei * handle {@link Fragment#onActivityResult(int, int, Intent)}
7531b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei *
7631b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei * An easy way to handle them is to delegate them to {@link #handleDialogClick(int)} and
7731b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei * {@link #handleActivityResult(int, int, Intent)} in this controller.
78ddba96670048a07b98e5c1e0d9f3d9bd4ebe9b38jackqdyulei */
7931b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei//TODO(b/35810915): Make InstalledAppDetails use this controller
801d583e125faf3ae4c9cd82636d8f3ecf1cdec3aaTony Mantlerpublic class AppButtonsPreferenceController extends AbstractPreferenceController implements
811d583e125faf3ae4c9cd82636d8f3ecf1cdec3aaTony Mantler        PreferenceControllerMixin, LifecycleObserver, OnResume, OnPause, OnDestroy,
821d583e125faf3ae4c9cd82636d8f3ecf1cdec3aaTony Mantler        View.OnClickListener, ApplicationsState.Callbacks {
8331b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei    public static final String APP_CHG = "chg";
8431b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei
8531b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei    private static final String TAG = "AppButtonsPrefCtl";
86ddba96670048a07b98e5c1e0d9f3d9bd4ebe9b38jackqdyulei    private static final String KEY_ACTION_BUTTONS = "action_buttons";
8731b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei    private static final boolean LOCAL_LOGV = false;
8831b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei
8931b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei    @VisibleForTesting
9031b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei    final HashSet<String> mHomePackages = new HashSet<>();
9131b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei    @VisibleForTesting
9231b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei    ApplicationsState mState;
9331b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei    @VisibleForTesting
9431b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei    ApplicationsState.AppEntry mAppEntry;
9531b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei    @VisibleForTesting
9631b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei    PackageInfo mPackageInfo;
9731b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei    @VisibleForTesting
9831b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei    Button mForceStopButton;
9931b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei    @VisibleForTesting
10031b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei    Button mUninstallButton;
10131b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei    @VisibleForTesting
1020b83954f1c86a5269b4b863e6ad0958dba03fed9jackqdyulei    String mPackageName;
1030b83954f1c86a5269b4b863e6ad0958dba03fed9jackqdyulei    @VisibleForTesting
10431b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei    boolean mDisableAfterUninstall = false;
10531b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei
10631b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei    private final int mRequestUninstall;
10731b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei    private final int mRequestRemoveDeviceAdmin;
10831b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei
10931b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei    private ApplicationsState.Session mSession;
11031b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei    private DevicePolicyManagerWrapper mDpm;
11131b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei    private UserManager mUserManager;
11231b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei    private PackageManager mPm;
11331b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei    private SettingsActivity mActivity;
11431b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei    private Fragment mFragment;
11531b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei    private RestrictedLockUtils.EnforcedAdmin mAppsControlDisallowedAdmin;
11631b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei    private MetricsFeatureProvider mMetricsFeatureProvider;
117ddba96670048a07b98e5c1e0d9f3d9bd4ebe9b38jackqdyulei
118ddba96670048a07b98e5c1e0d9f3d9bd4ebe9b38jackqdyulei    private LayoutPreference mButtonsPref;
11931b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei    private int mUserId;
12031b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei    private boolean mUpdatedSysApp = false;
12131b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei    private boolean mListeningToPackageRemove = false;
12231b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei    private boolean mFinishing = false;
12331b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei    private boolean mAppsControlDisallowedBySystem;
124ddba96670048a07b98e5c1e0d9f3d9bd4ebe9b38jackqdyulei
12531b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei    public AppButtonsPreferenceController(SettingsActivity activity, Fragment fragment,
12631b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei            Lifecycle lifecycle, String packageName, ApplicationsState state,
12731b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei            DevicePolicyManagerWrapper dpm, UserManager userManager,
12831b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei            PackageManager packageManager, int requestUninstall, int requestRemoveDeviceAdmin) {
129ddba96670048a07b98e5c1e0d9f3d9bd4ebe9b38jackqdyulei        super(activity);
130ddba96670048a07b98e5c1e0d9f3d9bd4ebe9b38jackqdyulei
13131b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        if (!(fragment instanceof ButtonActionDialogFragment.AppButtonsDialogListener)) {
13231b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei            throw new IllegalArgumentException(
13331b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei                    "Fragment should implement AppButtonsDialogListener");
13431b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        }
13531b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei
13631b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        mMetricsFeatureProvider = FeatureFactory.getFactory(activity).getMetricsFeatureProvider();
13731b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei
13831b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        mState = state;
13931b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        mDpm = dpm;
14031b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        mUserManager = userManager;
14131b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        mPm = packageManager;
14231b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        mPackageName = packageName;
14331b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        mActivity = activity;
14431b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        mFragment = fragment;
14531b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        mUserId = UserHandle.myUserId();
14631b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        mRequestUninstall = requestUninstall;
14731b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        mRequestRemoveDeviceAdmin = requestRemoveDeviceAdmin;
14831b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei
149ddba96670048a07b98e5c1e0d9f3d9bd4ebe9b38jackqdyulei        if (packageName != null) {
15031b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei            mAppEntry = mState.getEntry(packageName, mUserId);
1510b83954f1c86a5269b4b863e6ad0958dba03fed9jackqdyulei            mSession = mState.newSession(this);
1520b83954f1c86a5269b4b863e6ad0958dba03fed9jackqdyulei            lifecycle.addObserver(this);
15331b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        } else {
15431b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei            mFinishing = true;
155ddba96670048a07b98e5c1e0d9f3d9bd4ebe9b38jackqdyulei        }
156ddba96670048a07b98e5c1e0d9f3d9bd4ebe9b38jackqdyulei    }
157ddba96670048a07b98e5c1e0d9f3d9bd4ebe9b38jackqdyulei
158ddba96670048a07b98e5c1e0d9f3d9bd4ebe9b38jackqdyulei    @Override
159ddba96670048a07b98e5c1e0d9f3d9bd4ebe9b38jackqdyulei    public boolean isAvailable() {
1600d7854aa43c7d8debc8daf1390625803fb56e9baJesse Evans        // TODO(b/37313605): Re-enable once this controller supports instant apps
1610d7854aa43c7d8debc8daf1390625803fb56e9baJesse Evans        return mAppEntry != null && !AppUtils.isInstant(mAppEntry.info);
162ddba96670048a07b98e5c1e0d9f3d9bd4ebe9b38jackqdyulei    }
163ddba96670048a07b98e5c1e0d9f3d9bd4ebe9b38jackqdyulei
164ddba96670048a07b98e5c1e0d9f3d9bd4ebe9b38jackqdyulei    @Override
165ddba96670048a07b98e5c1e0d9f3d9bd4ebe9b38jackqdyulei    public void displayPreference(PreferenceScreen screen) {
166ddba96670048a07b98e5c1e0d9f3d9bd4ebe9b38jackqdyulei        super.displayPreference(screen);
167ddba96670048a07b98e5c1e0d9f3d9bd4ebe9b38jackqdyulei        if (isAvailable()) {
168ddba96670048a07b98e5c1e0d9f3d9bd4ebe9b38jackqdyulei            mButtonsPref = (LayoutPreference) screen.findPreference(KEY_ACTION_BUTTONS);
169ddba96670048a07b98e5c1e0d9f3d9bd4ebe9b38jackqdyulei
170ddba96670048a07b98e5c1e0d9f3d9bd4ebe9b38jackqdyulei            mUninstallButton = (Button) mButtonsPref.findViewById(R.id.left_button);
171ddba96670048a07b98e5c1e0d9f3d9bd4ebe9b38jackqdyulei            mUninstallButton.setText(R.string.uninstall_text);
172ddba96670048a07b98e5c1e0d9f3d9bd4ebe9b38jackqdyulei
173ddba96670048a07b98e5c1e0d9f3d9bd4ebe9b38jackqdyulei            mForceStopButton = (Button) mButtonsPref.findViewById(R.id.right_button);
174ddba96670048a07b98e5c1e0d9f3d9bd4ebe9b38jackqdyulei            mForceStopButton.setText(R.string.force_stop);
17531b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei            mForceStopButton.setEnabled(false);
176ddba96670048a07b98e5c1e0d9f3d9bd4ebe9b38jackqdyulei        }
177ddba96670048a07b98e5c1e0d9f3d9bd4ebe9b38jackqdyulei    }
178ddba96670048a07b98e5c1e0d9f3d9bd4ebe9b38jackqdyulei
179ddba96670048a07b98e5c1e0d9f3d9bd4ebe9b38jackqdyulei    @Override
180ddba96670048a07b98e5c1e0d9f3d9bd4ebe9b38jackqdyulei    public String getPreferenceKey() {
181ddba96670048a07b98e5c1e0d9f3d9bd4ebe9b38jackqdyulei        return KEY_ACTION_BUTTONS;
182ddba96670048a07b98e5c1e0d9f3d9bd4ebe9b38jackqdyulei    }
183ddba96670048a07b98e5c1e0d9f3d9bd4ebe9b38jackqdyulei
184ddba96670048a07b98e5c1e0d9f3d9bd4ebe9b38jackqdyulei    @Override
185ddba96670048a07b98e5c1e0d9f3d9bd4ebe9b38jackqdyulei    public void onResume() {
18631b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        mSession.resume();
18731b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        if (isAvailable() && !mFinishing) {
18831b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei            mAppsControlDisallowedBySystem = RestrictedLockUtils.hasBaseUserRestriction(mActivity,
18931b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei                    UserManager.DISALLOW_APPS_CONTROL, mUserId);
19031b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei            mAppsControlDisallowedAdmin = RestrictedLockUtils.checkIfRestrictionEnforced(mActivity,
19131b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei                    UserManager.DISALLOW_APPS_CONTROL, mUserId);
19231b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei
19331b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei            if (!refreshUi()) {
19431b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei                setIntentAndFinish(true);
19531b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei            }
19631b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        }
19731b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei    }
19831b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei
19931b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei    @Override
20031b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei    public void onPause() {
20131b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        mSession.pause();
20231b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei    }
20331b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei
20431b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei    @Override
20531b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei    public void onDestroy() {
20631b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        stopListeningToPackageRemove();
20731b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        mSession.release();
20831b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei    }
20931b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei
21031b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei    @Override
21131b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei    public void onClick(View v) {
21231b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        final String packageName = mAppEntry.info.packageName;
21331b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        final int id = v.getId();
21431b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        if (id == R.id.left_button) {
21531b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei            // Uninstall
21631b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei            if (mDpm.packageHasActiveAdmins(mPackageInfo.packageName)) {
21731b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei                stopListeningToPackageRemove();
21831b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei                Intent uninstallDaIntent = new Intent(mActivity, DeviceAdminAdd.class);
21931b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei                uninstallDaIntent.putExtra(DeviceAdminAdd.EXTRA_DEVICE_ADMIN_PACKAGE_NAME,
22031b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei                        packageName);
22131b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei                mMetricsFeatureProvider.action(mActivity,
22231b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei                        MetricsProto.MetricsEvent.ACTION_SETTINGS_UNINSTALL_DEVICE_ADMIN);
22331b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei                mFragment.startActivityForResult(uninstallDaIntent, mRequestRemoveDeviceAdmin);
22431b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei                return;
22531b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei            }
22631b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei            RestrictedLockUtils.EnforcedAdmin admin =
22731b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei                    RestrictedLockUtils.checkIfUninstallBlocked(mActivity,
22831b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei                            packageName, mUserId);
22931b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei            boolean uninstallBlockedBySystem = mAppsControlDisallowedBySystem ||
23031b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei                    RestrictedLockUtils.hasBaseUserRestriction(mActivity, packageName, mUserId);
23131b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei            if (admin != null && !uninstallBlockedBySystem) {
23231b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei                RestrictedLockUtils.sendShowAdminSupportDetailsIntent(mActivity, admin);
23331b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei            } else if ((mAppEntry.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
23431b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei                if (mAppEntry.info.enabled && !isDisabledUntilUsed()) {
23531b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei                    // If the system app has an update and this is the only user on the device,
23631b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei                    // then offer to downgrade the app, otherwise only offer to disable the
23731b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei                    // app for this user.
23831b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei                    if (mUpdatedSysApp && isSingleUser()) {
23931b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei                        showDialogInner(ButtonActionDialogFragment.DialogType.SPECIAL_DISABLE);
24031b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei                    } else {
24131b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei                        showDialogInner(ButtonActionDialogFragment.DialogType.DISABLE);
24231b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei                    }
24331b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei                } else {
24431b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei                    mMetricsFeatureProvider.action(
24531b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei                            mActivity,
24631b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei                            mAppEntry.info.enabled
24731b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei                                    ? MetricsProto.MetricsEvent.ACTION_SETTINGS_DISABLE_APP
24831b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei                                    : MetricsProto.MetricsEvent.ACTION_SETTINGS_ENABLE_APP);
24931b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei                    AsyncTask.execute(new DisableChangerRunnable(mPm, mAppEntry.info.packageName,
25031b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei                            PackageManager.COMPONENT_ENABLED_STATE_DEFAULT));
25131b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei                }
25231b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei            } else if ((mAppEntry.info.flags & ApplicationInfo.FLAG_INSTALLED) == 0) {
25331b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei                uninstallPkg(packageName, true, false);
25431b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei            } else {
25531b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei                uninstallPkg(packageName, false, false);
25631b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei            }
25731b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        } else if (id == R.id.right_button) {
25831b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei            // force stop
25931b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei            if (mAppsControlDisallowedAdmin != null && !mAppsControlDisallowedBySystem) {
26031b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei                RestrictedLockUtils.sendShowAdminSupportDetailsIntent(
26131b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei                        mActivity, mAppsControlDisallowedAdmin);
26231b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei            } else {
26331b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei                showDialogInner(ButtonActionDialogFragment.DialogType.FORCE_STOP);
26431b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei            }
26531b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        }
26631b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei    }
26731b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei
26831b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei    public void handleActivityResult(int requestCode, int resultCode, Intent data) {
26931b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        if (requestCode == mRequestUninstall) {
27031b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei            if (mDisableAfterUninstall) {
27131b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei                mDisableAfterUninstall = false;
27231b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei                AsyncTask.execute(new DisableChangerRunnable(mPm, mAppEntry.info.packageName,
27331b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei                        PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER));
27431b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei            }
27531b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei            refreshAndFinishIfPossible();
27631b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        } else if (requestCode == mRequestRemoveDeviceAdmin) {
27731b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei            refreshAndFinishIfPossible();
27831b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        }
27931b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei    }
28031b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei
28131b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei    public void handleDialogClick(int id) {
28231b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        switch (id) {
28331b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei            case ButtonActionDialogFragment.DialogType.DISABLE:
28431b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei                mMetricsFeatureProvider.action(mActivity,
28531b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei                        MetricsProto.MetricsEvent.ACTION_SETTINGS_DISABLE_APP);
28631b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei                AsyncTask.execute(new DisableChangerRunnable(mPm, mAppEntry.info.packageName,
28731b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei                        PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER));
28831b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei                break;
28931b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei            case ButtonActionDialogFragment.DialogType.SPECIAL_DISABLE:
29031b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei                mMetricsFeatureProvider.action(mActivity,
29131b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei                        MetricsProto.MetricsEvent.ACTION_SETTINGS_DISABLE_APP);
29231b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei                uninstallPkg(mAppEntry.info.packageName, false, true);
29331b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei                break;
29431b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei            case ButtonActionDialogFragment.DialogType.FORCE_STOP:
29531b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei                forceStopPackage(mAppEntry.info.packageName);
29631b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei                break;
29731b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        }
29831b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei    }
29931b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei
30031b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei    @Override
30131b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei    public void onRunningStateChanged(boolean running) {
30231b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei
30331b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei    }
30431b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei
30531b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei    @Override
30631b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei    public void onPackageListChanged() {
30731b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        refreshUi();
30831b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei    }
30931b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei
31031b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei    @Override
31131b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei    public void onRebuildComplete(ArrayList<ApplicationsState.AppEntry> apps) {
31231b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei
31331b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei    }
31431b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei
31531b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei    @Override
31631b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei    public void onPackageIconChanged() {
31731b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei
31831b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei    }
31931b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei
32031b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei    @Override
32131b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei    public void onPackageSizeChanged(String packageName) {
32231b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei
323ddba96670048a07b98e5c1e0d9f3d9bd4ebe9b38jackqdyulei    }
32431b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei
32531b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei    @Override
32631b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei    public void onAllSizesComputed() {
32731b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei
32831b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei    }
32931b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei
33031b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei    @Override
33131b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei    public void onLauncherInfoChanged() {
33231b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei
33331b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei    }
33431b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei
33531b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei    @Override
33631b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei    public void onLoadEntriesCompleted() {
33731b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei
33831b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei    }
33931b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei
34031b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei    @VisibleForTesting
34131b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei    void retrieveAppEntry() {
34231b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        mAppEntry = mState.getEntry(mPackageName, mUserId);
34331b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        if (mAppEntry != null) {
34431b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei            try {
34531b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei                mPackageInfo = mPm.getPackageInfo(mAppEntry.info.packageName,
34631b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei                        PackageManager.MATCH_DISABLED_COMPONENTS |
34731b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei                                PackageManager.MATCH_ANY_USER |
34831b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei                                PackageManager.GET_SIGNATURES |
34931b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei                                PackageManager.GET_PERMISSIONS);
35031b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei
35131b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei                mPackageName = mAppEntry.info.packageName;
35231b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei            } catch (PackageManager.NameNotFoundException e) {
35331b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei                Log.e(TAG, "Exception when retrieving package:" + mAppEntry.info.packageName, e);
35431b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei                mPackageInfo = null;
35531b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei            }
35631b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        } else {
35731b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei            mPackageInfo = null;
35831b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        }
35931b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei    }
36031b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei
36131b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei    @VisibleForTesting
36231b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei    void updateUninstallButton() {
36331b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        final boolean isBundled = (mAppEntry.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
36431b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        boolean enabled = true;
36531b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        if (isBundled) {
36631b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei            enabled = handleDisableable(mUninstallButton);
36731b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        } else {
36831b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei            if ((mPackageInfo.applicationInfo.flags & ApplicationInfo.FLAG_INSTALLED) == 0
36931b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei                    && mUserManager.getUsers().size() >= 2) {
37031b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei                // When we have multiple users, there is a separate menu
37131b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei                // to uninstall for all users.
37231b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei                enabled = false;
37331b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei            }
37431b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        }
37531b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        // If this is a device admin, it can't be uninstalled or disabled.
37631b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        // We do this here so the text of the button is still set correctly.
37731b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        if (isBundled && mDpm.packageHasActiveAdmins(mPackageInfo.packageName)) {
37831b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei            enabled = false;
37931b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        }
38031b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei
38131b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        // We don't allow uninstalling DO/PO on *any* users, because if it's a system app,
38231b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        // "uninstall" is actually "downgrade to the system version + disable", and "downgrade"
38331b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        // will clear data on all users.
38400015fbf500a3b9d7af75deac2764540c96179c2jackqdyulei        if (Utils.isProfileOrDeviceOwner(mUserManager, mDpm, mPackageInfo.packageName)) {
38531b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei            enabled = false;
38631b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        }
38731b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei
38831b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        // Don't allow uninstalling the device provisioning package.
38931b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        if (Utils.isDeviceProvisioningPackage(mContext.getResources(),
39031b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei                mAppEntry.info.packageName)) {
39131b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei            enabled = false;
39231b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        }
39331b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei
39431b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        // If the uninstall intent is already queued, disable the uninstall button
39531b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        if (mDpm.isUninstallInQueue(mPackageName)) {
39631b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei            enabled = false;
39731b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        }
39831b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei
39931b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        // Home apps need special handling.  Bundled ones we don't risk downgrading
40031b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        // because that can interfere with home-key resolution.  Furthermore, we
40131b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        // can't allow uninstallation of the only home app, and we don't want to
40231b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        // allow uninstallation of an explicitly preferred one -- the user can go
40331b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        // to Home settings and pick a different one, after which we'll permit
40431b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        // uninstallation of the now-not-default one.
40531b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        if (enabled && mHomePackages.contains(mPackageInfo.packageName)) {
40631b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei            if (isBundled) {
40731b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei                enabled = false;
40831b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei            } else {
40931b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei                ArrayList<ResolveInfo> homeActivities = new ArrayList<ResolveInfo>();
41031b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei                ComponentName currentDefaultHome = mPm.getHomeActivities(homeActivities);
41131b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei                if (currentDefaultHome == null) {
41231b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei                    // No preferred default, so permit uninstall only when
41331b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei                    // there is more than one candidate
41431b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei                    enabled = (mHomePackages.size() > 1);
41531b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei                } else {
41631b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei                    // There is an explicit default home app -- forbid uninstall of
41731b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei                    // that one, but permit it for installed-but-inactive ones.
41831b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei                    enabled = !mPackageInfo.packageName.equals(currentDefaultHome.getPackageName());
41931b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei                }
42031b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei            }
42131b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        }
42231b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei
42331b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        if (mAppsControlDisallowedBySystem) {
42431b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei            enabled = false;
42531b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        }
42631b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei
42731b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        if (isFallbackPackage(mAppEntry.info.packageName)) {
42831b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei            enabled = false;
42931b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        }
43031b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei
43131b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        mUninstallButton.setEnabled(enabled);
43231b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        if (enabled) {
43331b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei            // Register listener
43431b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei            mUninstallButton.setOnClickListener(this);
43531b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        }
43631b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei    }
43731b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei
43831b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei    /**
43931b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei     * Finish this fragment and return data if possible
44031b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei     */
44131b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei    private void setIntentAndFinish(boolean appChanged) {
44231b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        if (LOCAL_LOGV) {
44331b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei            Log.i(TAG, "appChanged=" + appChanged);
44431b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        }
44531b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        Intent intent = new Intent();
44631b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        intent.putExtra(APP_CHG, appChanged);
44731b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        mActivity.finishPreferencePanel(mFragment, Activity.RESULT_OK, intent);
44831b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        mFinishing = true;
44931b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei    }
45031b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei
45131b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei    private void refreshAndFinishIfPossible() {
45231b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        if (!refreshUi()) {
45331b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei            setIntentAndFinish(true);
45431b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        } else {
45531b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei            startListeningToPackageRemove();
45631b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        }
45731b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei    }
45831b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei
45931b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei    @VisibleForTesting
46031b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei    boolean isFallbackPackage(String packageName) {
46131b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        try {
46231b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei            IWebViewUpdateService webviewUpdateService =
46331b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei                    IWebViewUpdateService.Stub.asInterface(
46431b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei                            ServiceManager.getService("webviewupdate"));
46531b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei            if (webviewUpdateService.isFallbackPackage(packageName)) {
46631b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei                return true;
46731b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei            }
46831b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        } catch (RemoteException e) {
46931b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei            throw new RuntimeException(e);
47031b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        }
47131b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei
47231b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        return false;
47331b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei    }
47431b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei
47531b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei    @VisibleForTesting
47631b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei    void updateForceStopButton() {
47731b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        if (mDpm.packageHasActiveAdmins(mPackageInfo.packageName)) {
47831b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei            // User can't force stop device admin.
47931b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei            Log.w(TAG, "User can't force stop device admin");
48031b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei            updateForceStopButtonInner(false);
48131b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        } else if ((mAppEntry.info.flags & ApplicationInfo.FLAG_STOPPED) == 0) {
48231b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei            // If the app isn't explicitly stopped, then always show the
48331b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei            // force stop button.
48431b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei            Log.w(TAG, "App is not explicitly stopped");
48531b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei            updateForceStopButtonInner(true);
48631b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        } else {
48731b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei            Intent intent = new Intent(Intent.ACTION_QUERY_PACKAGE_RESTART,
48831b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei                    Uri.fromParts("package", mAppEntry.info.packageName, null));
48931b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei            intent.putExtra(Intent.EXTRA_PACKAGES, new String[]{mAppEntry.info.packageName});
49031b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei            intent.putExtra(Intent.EXTRA_UID, mAppEntry.info.uid);
49131b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei            intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(mAppEntry.info.uid));
49231b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei            Log.d(TAG, "Sending broadcast to query restart status for "
49331b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei                    + mAppEntry.info.packageName);
49431b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei            mActivity.sendOrderedBroadcastAsUser(intent, UserHandle.CURRENT, null,
49531b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei                    mCheckKillProcessesReceiver, null, Activity.RESULT_CANCELED, null, null);
49631b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        }
49731b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei    }
49831b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei
49931b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei    @VisibleForTesting
50031b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei    void updateForceStopButtonInner(boolean enabled) {
50131b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        if (mAppsControlDisallowedBySystem) {
50231b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei            mForceStopButton.setEnabled(false);
50331b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        } else {
50431b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei            mForceStopButton.setEnabled(enabled);
50531b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei            mForceStopButton.setOnClickListener(this);
50631b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        }
50731b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei    }
50831b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei
50931b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei    @VisibleForTesting
51031b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei    void uninstallPkg(String packageName, boolean allUsers, boolean andDisable) {
51131b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        stopListeningToPackageRemove();
51231b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        // Create new intent to launch Uninstaller activity
51331b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        Uri packageUri = Uri.parse("package:" + packageName);
51431b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        Intent uninstallIntent = new Intent(Intent.ACTION_UNINSTALL_PACKAGE, packageUri);
51531b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        uninstallIntent.putExtra(Intent.EXTRA_UNINSTALL_ALL_USERS, allUsers);
51631b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei
51731b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        mMetricsFeatureProvider.action(
51831b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei                mActivity, MetricsProto.MetricsEvent.ACTION_SETTINGS_UNINSTALL_APP);
51931b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        mFragment.startActivityForResult(uninstallIntent, mRequestUninstall);
52031b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        mDisableAfterUninstall = andDisable;
52131b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei    }
52231b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei
52331b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei    @VisibleForTesting
52431b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei    void forceStopPackage(String pkgName) {
52531b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        FeatureFactory.getFactory(mContext).getMetricsFeatureProvider().action(mContext,
52631b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei                MetricsProto.MetricsEvent.ACTION_APP_FORCE_STOP, pkgName);
52731b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        ActivityManager am = (ActivityManager) mActivity.getSystemService(
52831b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei                Context.ACTIVITY_SERVICE);
52931b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        Log.d(TAG, "Stopping package " + pkgName);
53031b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        am.forceStopPackage(pkgName);
53131b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        int userId = UserHandle.getUserId(mAppEntry.info.uid);
53231b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        mState.invalidatePackage(pkgName, userId);
53331b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        ApplicationsState.AppEntry newEnt = mState.getEntry(pkgName, userId);
53431b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        if (newEnt != null) {
53531b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei            mAppEntry = newEnt;
53631b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        }
53731b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        updateForceStopButton();
53831b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei    }
53931b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei
54031b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei    @VisibleForTesting
54131b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei    boolean handleDisableable(Button button) {
54231b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        boolean disableable = false;
54331b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        // Try to prevent the user from bricking their phone
54431b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        // by not allowing disabling of apps signed with the
54531b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        // system cert and any launcher app in the system.
54631b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        if (mHomePackages.contains(mAppEntry.info.packageName)
54731b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei                || isSystemPackage(mActivity.getResources(), mPm, mPackageInfo)) {
54831b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei            // Disable button for core system applications.
54931b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei            button.setText(R.string.disable_text);
55031b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        } else if (mAppEntry.info.enabled && !isDisabledUntilUsed()) {
55131b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei            button.setText(R.string.disable_text);
55231b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei            disableable = true;
55331b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        } else {
55431b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei            button.setText(R.string.enable_text);
55531b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei            disableable = true;
55631b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        }
55731b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei
55831b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        return disableable;
55931b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei    }
56031b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei
56131b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei    @VisibleForTesting
56231b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei    boolean isSystemPackage(Resources resources, PackageManager pm, PackageInfo packageInfo) {
56331b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        return Utils.isSystemPackage(resources, pm, packageInfo);
56431b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei    }
56531b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei
56631b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei    private boolean isDisabledUntilUsed() {
56731b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        return mAppEntry.info.enabledSetting
56831b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei                == PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED;
56931b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei    }
57031b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei
57131b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei    private void showDialogInner(@ButtonActionDialogFragment.DialogType int id) {
57231b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        ButtonActionDialogFragment newFragment = ButtonActionDialogFragment.newInstance(id);
57331b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        newFragment.setTargetFragment(mFragment, 0);
57431b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        newFragment.show(mActivity.getFragmentManager(), "dialog " + id);
57531b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei    }
57631b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei
57731b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei    /** Returns whether there is only one user on this device, not including the system-only user */
57831b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei    private boolean isSingleUser() {
57931b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        final int userCount = mUserManager.getUserCount();
58031b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        return userCount == 1
58131b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei                || (mUserManager.isSplitSystemUser() && userCount == 2);
58231b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei    }
58331b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei
58431b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei    private final BroadcastReceiver mCheckKillProcessesReceiver = new BroadcastReceiver() {
58531b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        @Override
58631b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        public void onReceive(Context context, Intent intent) {
58731b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei            final boolean enabled = getResultCode() != Activity.RESULT_CANCELED;
58831b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei            Log.d(TAG, "Got broadcast response: Restart status for "
58931b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei                    + mAppEntry.info.packageName + " " + enabled);
59031b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei            updateForceStopButtonInner(enabled);
59131b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        }
59231b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei    };
59331b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei
59431b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei    private boolean signaturesMatch(String pkg1, String pkg2) {
59531b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        if (pkg1 != null && pkg2 != null) {
59631b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei            try {
59731b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei                final int match = mPm.checkSignatures(pkg1, pkg2);
59831b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei                if (match >= PackageManager.SIGNATURE_MATCH) {
59931b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei                    return true;
60031b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei                }
60131b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei            } catch (Exception e) {
60231b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei                // e.g. named alternate package not found during lookup;
60331b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei                // this is an expected case sometimes
60431b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei            }
60531b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        }
60631b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        return false;
60731b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei    }
60831b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei
6090b83954f1c86a5269b4b863e6ad0958dba03fed9jackqdyulei    @VisibleForTesting
6100b83954f1c86a5269b4b863e6ad0958dba03fed9jackqdyulei    boolean refreshUi() {
6110b83954f1c86a5269b4b863e6ad0958dba03fed9jackqdyulei        if (mPackageName == null) {
6120b83954f1c86a5269b4b863e6ad0958dba03fed9jackqdyulei            return false;
6130b83954f1c86a5269b4b863e6ad0958dba03fed9jackqdyulei        }
61431b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        retrieveAppEntry();
61531b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        if (mAppEntry == null || mPackageInfo == null) {
61631b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei            return false;
61731b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        }
61831b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        // Get list of "home" apps and trace through any meta-data references
61931b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        List<ResolveInfo> homeActivities = new ArrayList<>();
62031b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        mPm.getHomeActivities(homeActivities);
62131b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        mHomePackages.clear();
62231b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        for (int i = 0, size = homeActivities.size(); i < size; i++) {
62331b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei            ResolveInfo ri = homeActivities.get(i);
62431b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei            final String activityPkg = ri.activityInfo.packageName;
62531b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei            mHomePackages.add(activityPkg);
62631b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei
62731b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei            // Also make sure to include anything proxying for the home app
62831b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei            final Bundle metadata = ri.activityInfo.metaData;
62931b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei            if (metadata != null) {
63031b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei                final String metaPkg = metadata.getString(ActivityManager.META_HOME_ALTERNATE);
63131b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei                if (signaturesMatch(metaPkg, activityPkg)) {
63231b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei                    mHomePackages.add(metaPkg);
63331b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei                }
63431b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei            }
63531b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        }
63631b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei
63731b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        updateUninstallButton();
63831b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        updateForceStopButton();
63931b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei
64031b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        return true;
64131b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei    }
64231b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei
64331b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei    private void startListeningToPackageRemove() {
64431b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        if (mListeningToPackageRemove) {
64531b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei            return;
64631b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        }
64731b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        mListeningToPackageRemove = true;
64831b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        final IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_REMOVED);
64931b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        filter.addDataScheme("package");
65031b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        mActivity.registerReceiver(mPackageRemovedReceiver, filter);
65131b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei    }
65231b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei
65331b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei    private void stopListeningToPackageRemove() {
65431b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        if (!mListeningToPackageRemove) {
65531b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei            return;
65631b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        }
65731b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        mListeningToPackageRemove = false;
65831b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        mActivity.unregisterReceiver(mPackageRemovedReceiver);
65931b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei    }
66031b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei
66131b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei
66231b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei    /**
66331b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei     * Changes the status of disable/enable for a package
66431b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei     */
66531b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei    private class DisableChangerRunnable implements Runnable {
66631b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        final PackageManager mPm;
66731b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        final String mPackageName;
66831b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        final int mState;
66931b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei
67031b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        public DisableChangerRunnable(PackageManager pm, String packageName, int state) {
67131b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei            mPm = pm;
67231b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei            mPackageName = packageName;
67331b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei            mState = state;
67431b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        }
67531b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei
67631b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        @Override
67731b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        public void run() {
67831b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei            mPm.setApplicationEnabledSetting(mPackageName, mState, 0);
67931b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        }
68031b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei    }
68131b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei
68231b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei    /**
68331b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei     * Receiver to listen to the remove action for packages
68431b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei     */
68531b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei    private final BroadcastReceiver mPackageRemovedReceiver = new BroadcastReceiver() {
68631b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        @Override
68731b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        public void onReceive(Context context, Intent intent) {
68831b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei            String packageName = intent.getData().getSchemeSpecificPart();
68931b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei            if (!mFinishing && mAppEntry.info.packageName.equals(packageName)) {
69031b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei                mActivity.finishAndRemoveTask();
69131b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei            }
69231b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei        }
69331b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei    };
69431b8de1e215f6f0dcd694024c617f9f185e510aejackqdyulei
695ddba96670048a07b98e5c1e0d9f3d9bd4ebe9b38jackqdyulei}
696