16ef272300416b89c1ab4710614eea3d80d8d0f33Jason Monk/*
26ef272300416b89c1ab4710614eea3d80d8d0f33Jason Monk * Copyright (C) 2015 The Android Open Source Project
36ef272300416b89c1ab4710614eea3d80d8d0f33Jason Monk *
46ef272300416b89c1ab4710614eea3d80d8d0f33Jason Monk * Licensed under the Apache License, Version 2.0 (the "License");
56ef272300416b89c1ab4710614eea3d80d8d0f33Jason Monk * you may not use this file except in compliance with the License.
66ef272300416b89c1ab4710614eea3d80d8d0f33Jason Monk * You may obtain a copy of the License at
76ef272300416b89c1ab4710614eea3d80d8d0f33Jason Monk *
86ef272300416b89c1ab4710614eea3d80d8d0f33Jason Monk *      http://www.apache.org/licenses/LICENSE-2.0
96ef272300416b89c1ab4710614eea3d80d8d0f33Jason Monk *
106ef272300416b89c1ab4710614eea3d80d8d0f33Jason Monk * Unless required by applicable law or agreed to in writing, software
116ef272300416b89c1ab4710614eea3d80d8d0f33Jason Monk * distributed under the License is distributed on an "AS IS" BASIS,
126ef272300416b89c1ab4710614eea3d80d8d0f33Jason Monk * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
136ef272300416b89c1ab4710614eea3d80d8d0f33Jason Monk * See the License for the specific language governing permissions and
146ef272300416b89c1ab4710614eea3d80d8d0f33Jason Monk * limitations under the License.
156ef272300416b89c1ab4710614eea3d80d8d0f33Jason Monk */
166ef272300416b89c1ab4710614eea3d80d8d0f33Jason Monkpackage com.android.settings.applications;
176ef272300416b89c1ab4710614eea3d80d8d0f33Jason Monk
1851059c5c9101300c7cd410bfe6582de25145079eFan Zhangimport static android.net.NetworkPolicyManager.POLICY_NONE;
1951059c5c9101300c7cd410bfe6582de25145079eFan Zhangimport static android.net.NetworkPolicyManager.POLICY_REJECT_METERED_BACKGROUND;
2051059c5c9101300c7cd410bfe6582de25145079eFan Zhang
216ef272300416b89c1ab4710614eea3d80d8d0f33Jason Monkimport android.app.ActivityManager;
226ef272300416b89c1ab4710614eea3d80d8d0f33Jason Monkimport android.app.AlertDialog;
236ef272300416b89c1ab4710614eea3d80d8d0f33Jason Monkimport android.app.AppOpsManager;
246ef272300416b89c1ab4710614eea3d80d8d0f33Jason Monkimport android.app.INotificationManager;
256ef272300416b89c1ab4710614eea3d80d8d0f33Jason Monkimport android.content.Context;
266ef272300416b89c1ab4710614eea3d80d8d0f33Jason Monkimport android.content.DialogInterface;
276ef272300416b89c1ab4710614eea3d80d8d0f33Jason Monkimport android.content.pm.ApplicationInfo;
286ef272300416b89c1ab4710614eea3d80d8d0f33Jason Monkimport android.content.pm.IPackageManager;
296ef272300416b89c1ab4710614eea3d80d8d0f33Jason Monkimport android.content.pm.PackageManager;
306ef272300416b89c1ab4710614eea3d80d8d0f33Jason Monkimport android.net.NetworkPolicyManager;
316ef272300416b89c1ab4710614eea3d80d8d0f33Jason Monkimport android.os.AsyncTask;
326ef272300416b89c1ab4710614eea3d80d8d0f33Jason Monkimport android.os.Bundle;
336ef272300416b89c1ab4710614eea3d80d8d0f33Jason Monkimport android.os.RemoteException;
346ef272300416b89c1ab4710614eea3d80d8d0f33Jason Monkimport android.os.ServiceManager;
356ef272300416b89c1ab4710614eea3d80d8d0f33Jason Monkimport android.os.UserHandle;
36a4e32a24c4f70c6c54a459cbeaf70a6eac63f52cGustav Senntonimport android.webkit.IWebViewUpdateService;
376ef272300416b89c1ab4710614eea3d80d8d0f33Jason Monk
386ef272300416b89c1ab4710614eea3d80d8d0f33Jason Monkimport com.android.settings.R;
396ef272300416b89c1ab4710614eea3d80d8d0f33Jason Monk
406ef272300416b89c1ab4710614eea3d80d8d0f33Jason Monkimport java.util.List;
416ef272300416b89c1ab4710614eea3d80d8d0f33Jason Monk
426ef272300416b89c1ab4710614eea3d80d8d0f33Jason Monkpublic class ResetAppsHelper implements DialogInterface.OnClickListener,
436ef272300416b89c1ab4710614eea3d80d8d0f33Jason Monk        DialogInterface.OnDismissListener {
446ef272300416b89c1ab4710614eea3d80d8d0f33Jason Monk
456ef272300416b89c1ab4710614eea3d80d8d0f33Jason Monk    private static final String EXTRA_RESET_DIALOG = "resetDialog";
466ef272300416b89c1ab4710614eea3d80d8d0f33Jason Monk
476ef272300416b89c1ab4710614eea3d80d8d0f33Jason Monk    private final PackageManager mPm;
486ef272300416b89c1ab4710614eea3d80d8d0f33Jason Monk    private final IPackageManager mIPm;
496ef272300416b89c1ab4710614eea3d80d8d0f33Jason Monk    private final INotificationManager mNm;
50a4e32a24c4f70c6c54a459cbeaf70a6eac63f52cGustav Sennton    private final IWebViewUpdateService mWvus;
516ef272300416b89c1ab4710614eea3d80d8d0f33Jason Monk    private final NetworkPolicyManager mNpm;
526ef272300416b89c1ab4710614eea3d80d8d0f33Jason Monk    private final AppOpsManager mAom;
536ef272300416b89c1ab4710614eea3d80d8d0f33Jason Monk    private final Context mContext;
546ef272300416b89c1ab4710614eea3d80d8d0f33Jason Monk
556ef272300416b89c1ab4710614eea3d80d8d0f33Jason Monk    private AlertDialog mResetDialog;
566ef272300416b89c1ab4710614eea3d80d8d0f33Jason Monk
576ef272300416b89c1ab4710614eea3d80d8d0f33Jason Monk    public ResetAppsHelper(Context context) {
586ef272300416b89c1ab4710614eea3d80d8d0f33Jason Monk        mContext = context;
596ef272300416b89c1ab4710614eea3d80d8d0f33Jason Monk        mPm = context.getPackageManager();
606ef272300416b89c1ab4710614eea3d80d8d0f33Jason Monk        mIPm = IPackageManager.Stub.asInterface(ServiceManager.getService("package"));
616ef272300416b89c1ab4710614eea3d80d8d0f33Jason Monk        mNm = INotificationManager.Stub.asInterface(
626ef272300416b89c1ab4710614eea3d80d8d0f33Jason Monk                ServiceManager.getService(Context.NOTIFICATION_SERVICE));
63a4e32a24c4f70c6c54a459cbeaf70a6eac63f52cGustav Sennton        mWvus = IWebViewUpdateService.Stub.asInterface(ServiceManager.getService("webviewupdate"));
646ef272300416b89c1ab4710614eea3d80d8d0f33Jason Monk        mNpm = NetworkPolicyManager.from(context);
656ef272300416b89c1ab4710614eea3d80d8d0f33Jason Monk        mAom = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
666ef272300416b89c1ab4710614eea3d80d8d0f33Jason Monk    }
676ef272300416b89c1ab4710614eea3d80d8d0f33Jason Monk
686ef272300416b89c1ab4710614eea3d80d8d0f33Jason Monk    public void onRestoreInstanceState(Bundle savedInstanceState) {
696ef272300416b89c1ab4710614eea3d80d8d0f33Jason Monk        if (savedInstanceState != null && savedInstanceState.getBoolean(EXTRA_RESET_DIALOG)) {
706ef272300416b89c1ab4710614eea3d80d8d0f33Jason Monk            buildResetDialog();
716ef272300416b89c1ab4710614eea3d80d8d0f33Jason Monk        }
726ef272300416b89c1ab4710614eea3d80d8d0f33Jason Monk    }
736ef272300416b89c1ab4710614eea3d80d8d0f33Jason Monk
746ef272300416b89c1ab4710614eea3d80d8d0f33Jason Monk    public void onSaveInstanceState(Bundle outState) {
756ef272300416b89c1ab4710614eea3d80d8d0f33Jason Monk        if (mResetDialog != null) {
766ef272300416b89c1ab4710614eea3d80d8d0f33Jason Monk            outState.putBoolean(EXTRA_RESET_DIALOG, true);
776ef272300416b89c1ab4710614eea3d80d8d0f33Jason Monk        }
786ef272300416b89c1ab4710614eea3d80d8d0f33Jason Monk    }
796ef272300416b89c1ab4710614eea3d80d8d0f33Jason Monk
806ef272300416b89c1ab4710614eea3d80d8d0f33Jason Monk    public void stop() {
816ef272300416b89c1ab4710614eea3d80d8d0f33Jason Monk        if (mResetDialog != null) {
826ef272300416b89c1ab4710614eea3d80d8d0f33Jason Monk            mResetDialog.dismiss();
836ef272300416b89c1ab4710614eea3d80d8d0f33Jason Monk            mResetDialog = null;
846ef272300416b89c1ab4710614eea3d80d8d0f33Jason Monk        }
856ef272300416b89c1ab4710614eea3d80d8d0f33Jason Monk    }
866ef272300416b89c1ab4710614eea3d80d8d0f33Jason Monk
876ef272300416b89c1ab4710614eea3d80d8d0f33Jason Monk    void buildResetDialog() {
886ef272300416b89c1ab4710614eea3d80d8d0f33Jason Monk        if (mResetDialog == null) {
896ef272300416b89c1ab4710614eea3d80d8d0f33Jason Monk            mResetDialog = new AlertDialog.Builder(mContext)
906ef272300416b89c1ab4710614eea3d80d8d0f33Jason Monk                    .setTitle(R.string.reset_app_preferences_title)
916ef272300416b89c1ab4710614eea3d80d8d0f33Jason Monk                    .setMessage(R.string.reset_app_preferences_desc)
926ef272300416b89c1ab4710614eea3d80d8d0f33Jason Monk                    .setPositiveButton(R.string.reset_app_preferences_button, this)
936ef272300416b89c1ab4710614eea3d80d8d0f33Jason Monk                    .setNegativeButton(R.string.cancel, null)
946ef272300416b89c1ab4710614eea3d80d8d0f33Jason Monk                    .setOnDismissListener(this)
956ef272300416b89c1ab4710614eea3d80d8d0f33Jason Monk                    .show();
966ef272300416b89c1ab4710614eea3d80d8d0f33Jason Monk        }
976ef272300416b89c1ab4710614eea3d80d8d0f33Jason Monk    }
986ef272300416b89c1ab4710614eea3d80d8d0f33Jason Monk
996ef272300416b89c1ab4710614eea3d80d8d0f33Jason Monk    @Override
1006ef272300416b89c1ab4710614eea3d80d8d0f33Jason Monk    public void onDismiss(DialogInterface dialog) {
1016ef272300416b89c1ab4710614eea3d80d8d0f33Jason Monk        if (mResetDialog == dialog) {
1026ef272300416b89c1ab4710614eea3d80d8d0f33Jason Monk            mResetDialog = null;
1036ef272300416b89c1ab4710614eea3d80d8d0f33Jason Monk        }
1046ef272300416b89c1ab4710614eea3d80d8d0f33Jason Monk    }
1056ef272300416b89c1ab4710614eea3d80d8d0f33Jason Monk
1066ef272300416b89c1ab4710614eea3d80d8d0f33Jason Monk    @Override
1076ef272300416b89c1ab4710614eea3d80d8d0f33Jason Monk    public void onClick(DialogInterface dialog, int which) {
1086ef272300416b89c1ab4710614eea3d80d8d0f33Jason Monk        if (mResetDialog != dialog) {
1096ef272300416b89c1ab4710614eea3d80d8d0f33Jason Monk            return;
1106ef272300416b89c1ab4710614eea3d80d8d0f33Jason Monk        }
1116ef272300416b89c1ab4710614eea3d80d8d0f33Jason Monk        AsyncTask.execute(new Runnable() {
1126ef272300416b89c1ab4710614eea3d80d8d0f33Jason Monk            @Override
1136ef272300416b89c1ab4710614eea3d80d8d0f33Jason Monk            public void run() {
1146ef272300416b89c1ab4710614eea3d80d8d0f33Jason Monk                List<ApplicationInfo> apps = mPm.getInstalledApplications(
1156ef272300416b89c1ab4710614eea3d80d8d0f33Jason Monk                        PackageManager.GET_DISABLED_COMPONENTS);
1166ef272300416b89c1ab4710614eea3d80d8d0f33Jason Monk                for (int i = 0; i < apps.size(); i++) {
1176ef272300416b89c1ab4710614eea3d80d8d0f33Jason Monk                    ApplicationInfo app = apps.get(i);
1186ef272300416b89c1ab4710614eea3d80d8d0f33Jason Monk                    try {
1196ef272300416b89c1ab4710614eea3d80d8d0f33Jason Monk                        mNm.setNotificationsEnabledForPackage(app.packageName, app.uid, true);
1206ef272300416b89c1ab4710614eea3d80d8d0f33Jason Monk                    } catch (android.os.RemoteException ex) {
1216ef272300416b89c1ab4710614eea3d80d8d0f33Jason Monk                    }
1226ef272300416b89c1ab4710614eea3d80d8d0f33Jason Monk                    if (!app.enabled) {
1236ef272300416b89c1ab4710614eea3d80d8d0f33Jason Monk                        if (mPm.getApplicationEnabledSetting(app.packageName)
124a4e32a24c4f70c6c54a459cbeaf70a6eac63f52cGustav Sennton                                == PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER
125a4e32a24c4f70c6c54a459cbeaf70a6eac63f52cGustav Sennton                                && !isNonEnableableFallback(app.packageName)) {
1266ef272300416b89c1ab4710614eea3d80d8d0f33Jason Monk                            mPm.setApplicationEnabledSetting(app.packageName,
1276ef272300416b89c1ab4710614eea3d80d8d0f33Jason Monk                                    PackageManager.COMPONENT_ENABLED_STATE_DEFAULT,
1286ef272300416b89c1ab4710614eea3d80d8d0f33Jason Monk                                    PackageManager.DONT_KILL_APP);
1296ef272300416b89c1ab4710614eea3d80d8d0f33Jason Monk                        }
1306ef272300416b89c1ab4710614eea3d80d8d0f33Jason Monk                    }
1316ef272300416b89c1ab4710614eea3d80d8d0f33Jason Monk                }
1326ef272300416b89c1ab4710614eea3d80d8d0f33Jason Monk                try {
133841bb3d336b8c485ee71c5d065583c666a08fc86Svet Ganov                    mIPm.resetApplicationPreferences(UserHandle.myUserId());
1346ef272300416b89c1ab4710614eea3d80d8d0f33Jason Monk                } catch (RemoteException e) {
1356ef272300416b89c1ab4710614eea3d80d8d0f33Jason Monk                }
1366ef272300416b89c1ab4710614eea3d80d8d0f33Jason Monk                mAom.resetAllModes();
1376ef272300416b89c1ab4710614eea3d80d8d0f33Jason Monk                final int[] restrictedUids = mNpm.getUidsWithPolicy(
1386ef272300416b89c1ab4710614eea3d80d8d0f33Jason Monk                        POLICY_REJECT_METERED_BACKGROUND);
1396ef272300416b89c1ab4710614eea3d80d8d0f33Jason Monk                final int currentUserId = ActivityManager.getCurrentUser();
1406ef272300416b89c1ab4710614eea3d80d8d0f33Jason Monk                for (int uid : restrictedUids) {
1416ef272300416b89c1ab4710614eea3d80d8d0f33Jason Monk                    // Only reset for current user
1426ef272300416b89c1ab4710614eea3d80d8d0f33Jason Monk                    if (UserHandle.getUserId(uid) == currentUserId) {
1436ef272300416b89c1ab4710614eea3d80d8d0f33Jason Monk                        mNpm.setUidPolicy(uid, POLICY_NONE);
1446ef272300416b89c1ab4710614eea3d80d8d0f33Jason Monk                    }
1456ef272300416b89c1ab4710614eea3d80d8d0f33Jason Monk                }
1466ef272300416b89c1ab4710614eea3d80d8d0f33Jason Monk            }
1476ef272300416b89c1ab4710614eea3d80d8d0f33Jason Monk        });
1486ef272300416b89c1ab4710614eea3d80d8d0f33Jason Monk    }
149a4e32a24c4f70c6c54a459cbeaf70a6eac63f52cGustav Sennton
150a4e32a24c4f70c6c54a459cbeaf70a6eac63f52cGustav Sennton    private boolean isNonEnableableFallback(String packageName) {
151a4e32a24c4f70c6c54a459cbeaf70a6eac63f52cGustav Sennton        try {
152a4e32a24c4f70c6c54a459cbeaf70a6eac63f52cGustav Sennton            return mWvus.isFallbackPackage(packageName);
153a4e32a24c4f70c6c54a459cbeaf70a6eac63f52cGustav Sennton        } catch (RemoteException e) {
154a4e32a24c4f70c6c54a459cbeaf70a6eac63f52cGustav Sennton            throw new RuntimeException(e);
155a4e32a24c4f70c6c54a459cbeaf70a6eac63f52cGustav Sennton        }
156a4e32a24c4f70c6c54a459cbeaf70a6eac63f52cGustav Sennton    }
1576ef272300416b89c1ab4710614eea3d80d8d0f33Jason Monk}
158