1 /*
2  * Copyright (C) 2015 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.android.settings.applications;
17 
18 import android.app.ActivityManager;
19 import android.app.AlertDialog;
20 import android.app.AppOpsManager;
21 import android.app.INotificationManager;
22 import android.content.Context;
23 import android.content.DialogInterface;
24 import android.content.pm.ApplicationInfo;
25 import android.content.pm.IPackageManager;
26 import android.content.pm.PackageManager;
27 import android.net.NetworkPolicyManager;
28 import android.os.AsyncTask;
29 import android.os.Bundle;
30 import android.os.RemoteException;
31 import android.os.ServiceManager;
32 import android.os.UserHandle;
33 import android.webkit.IWebViewUpdateService;
34 
35 import com.android.settings.R;
36 
37 import java.util.List;
38 
39 import static android.net.NetworkPolicyManager.POLICY_NONE;
40 import static android.net.NetworkPolicyManager.POLICY_REJECT_METERED_BACKGROUND;
41 
42 public class ResetAppsHelper implements DialogInterface.OnClickListener,
43         DialogInterface.OnDismissListener {
44 
45     private static final String EXTRA_RESET_DIALOG = "resetDialog";
46 
47     private final PackageManager mPm;
48     private final IPackageManager mIPm;
49     private final INotificationManager mNm;
50     private final IWebViewUpdateService mWvus;
51     private final NetworkPolicyManager mNpm;
52     private final AppOpsManager mAom;
53     private final Context mContext;
54 
55     private AlertDialog mResetDialog;
56 
ResetAppsHelper(Context context)57     public ResetAppsHelper(Context context) {
58         mContext = context;
59         mPm = context.getPackageManager();
60         mIPm = IPackageManager.Stub.asInterface(ServiceManager.getService("package"));
61         mNm = INotificationManager.Stub.asInterface(
62                 ServiceManager.getService(Context.NOTIFICATION_SERVICE));
63         mWvus = IWebViewUpdateService.Stub.asInterface(ServiceManager.getService("webviewupdate"));
64         mNpm = NetworkPolicyManager.from(context);
65         mAom = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
66     }
67 
onRestoreInstanceState(Bundle savedInstanceState)68     public void onRestoreInstanceState(Bundle savedInstanceState) {
69         if (savedInstanceState != null && savedInstanceState.getBoolean(EXTRA_RESET_DIALOG)) {
70             buildResetDialog();
71         }
72     }
73 
onSaveInstanceState(Bundle outState)74     public void onSaveInstanceState(Bundle outState) {
75         if (mResetDialog != null) {
76             outState.putBoolean(EXTRA_RESET_DIALOG, true);
77         }
78     }
79 
stop()80     public void stop() {
81         if (mResetDialog != null) {
82             mResetDialog.dismiss();
83             mResetDialog = null;
84         }
85     }
86 
buildResetDialog()87     void buildResetDialog() {
88         if (mResetDialog == null) {
89             mResetDialog = new AlertDialog.Builder(mContext)
90                     .setTitle(R.string.reset_app_preferences_title)
91                     .setMessage(R.string.reset_app_preferences_desc)
92                     .setPositiveButton(R.string.reset_app_preferences_button, this)
93                     .setNegativeButton(R.string.cancel, null)
94                     .setOnDismissListener(this)
95                     .show();
96         }
97     }
98 
99     @Override
onDismiss(DialogInterface dialog)100     public void onDismiss(DialogInterface dialog) {
101         if (mResetDialog == dialog) {
102             mResetDialog = null;
103         }
104     }
105 
106     @Override
onClick(DialogInterface dialog, int which)107     public void onClick(DialogInterface dialog, int which) {
108         if (mResetDialog != dialog) {
109             return;
110         }
111         AsyncTask.execute(new Runnable() {
112             @Override
113             public void run() {
114                 List<ApplicationInfo> apps = mPm.getInstalledApplications(
115                         PackageManager.GET_DISABLED_COMPONENTS);
116                 for (int i = 0; i < apps.size(); i++) {
117                     ApplicationInfo app = apps.get(i);
118                     try {
119                         mNm.setNotificationsEnabledForPackage(app.packageName, app.uid, true);
120                     } catch (android.os.RemoteException ex) {
121                     }
122                     if (!app.enabled) {
123                         if (mPm.getApplicationEnabledSetting(app.packageName)
124                                 == PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER
125                                 && !isNonEnableableFallback(app.packageName)) {
126                             mPm.setApplicationEnabledSetting(app.packageName,
127                                     PackageManager.COMPONENT_ENABLED_STATE_DEFAULT,
128                                     PackageManager.DONT_KILL_APP);
129                         }
130                     }
131                 }
132                 try {
133                     mIPm.resetApplicationPreferences(UserHandle.myUserId());
134                 } catch (RemoteException e) {
135                 }
136                 mAom.resetAllModes();
137                 final int[] restrictedUids = mNpm.getUidsWithPolicy(
138                         POLICY_REJECT_METERED_BACKGROUND);
139                 final int currentUserId = ActivityManager.getCurrentUser();
140                 for (int uid : restrictedUids) {
141                     // Only reset for current user
142                     if (UserHandle.getUserId(uid) == currentUserId) {
143                         mNpm.setUidPolicy(uid, POLICY_NONE);
144                     }
145                 }
146             }
147         });
148     }
149 
isNonEnableableFallback(String packageName)150     private boolean isNonEnableableFallback(String packageName) {
151         try {
152             return mWvus.isFallbackPackage(packageName);
153         } catch (RemoteException e) {
154             throw new RuntimeException(e);
155         }
156     }
157 }
158