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