• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2017 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
5  * except in compliance with the License. You may obtain a copy of the License at
6  *
7  *      http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software distributed under the
10  * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
11  * KIND, either express or implied. See the License for the specific language governing
12  * permissions and limitations under the License.
13  */
14 
15 package com.android.settings.fuelgauge;
16 
17 import android.app.AppOpsManager;
18 import android.app.admin.DevicePolicyManager;
19 import android.content.Context;
20 import android.content.pm.ApplicationInfo;
21 import android.content.pm.PackageManager;
22 import android.os.Build;
23 import android.os.UserManager;
24 import android.support.annotation.VisibleForTesting;
25 import android.support.v14.preference.SwitchPreference;
26 import android.support.v7.preference.Preference;
27 import android.util.Log;
28 
29 import com.android.settings.R;
30 import com.android.settings.Utils;
31 import com.android.settings.core.PreferenceControllerMixin;
32 import com.android.settings.enterprise.DevicePolicyManagerWrapper;
33 import com.android.settings.enterprise.DevicePolicyManagerWrapperImpl;
34 import com.android.settingslib.core.AbstractPreferenceController;
35 
36 /**
37  * Controller to control whether an app can run in the background
38  */
39 public class BackgroundActivityPreferenceController extends AbstractPreferenceController
40         implements PreferenceControllerMixin, Preference.OnPreferenceChangeListener {
41 
42     private static final String TAG = "BgActivityPrefContr";
43     private static final String KEY_BACKGROUND_ACTIVITY = "background_activity";
44 
45     private final PackageManager mPackageManager;
46     private final AppOpsManager mAppOpsManager;
47     private final UserManager mUserManager;
48     private final String[] mPackages;
49     private final int mUid;
50     @VisibleForTesting
51     DevicePolicyManagerWrapper mDpm;
52 
53     private String mTargetPackage;
54 
BackgroundActivityPreferenceController(Context context, int uid)55     public BackgroundActivityPreferenceController(Context context, int uid) {
56         super(context);
57         mPackageManager = context.getPackageManager();
58         mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
59         mDpm = new DevicePolicyManagerWrapperImpl(
60                 (DevicePolicyManager) context.getSystemService(Context.DEVICE_POLICY_SERVICE));
61         mAppOpsManager = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
62         mUid = uid;
63         mPackages = mPackageManager.getPackagesForUid(mUid);
64     }
65 
66     @Override
updateState(Preference preference)67     public void updateState(Preference preference) {
68         final int mode = mAppOpsManager
69                 .checkOpNoThrow(AppOpsManager.OP_RUN_IN_BACKGROUND, mUid, mTargetPackage);
70         // Set checked or not before we may set it disabled
71         if (mode != AppOpsManager.MODE_ERRORED) {
72             final boolean checked = mode != AppOpsManager.MODE_IGNORED;
73             ((SwitchPreference) preference).setChecked(checked);
74         }
75         if (mode == AppOpsManager.MODE_ERRORED
76                 || Utils.isProfileOrDeviceOwner(mUserManager, mDpm, mTargetPackage)) {
77             preference.setEnabled(false);
78         }
79 
80         updateSummary(preference);
81     }
82 
83     @Override
isAvailable()84     public boolean isAvailable() {
85         if (mPackages == null) {
86             return false;
87         }
88         for (final String packageName : mPackages) {
89             if (isLegacyApp(packageName)) {
90                 mTargetPackage = packageName;
91                 return true;
92             }
93         }
94 
95         return false;
96     }
97 
98     @Override
getPreferenceKey()99     public String getPreferenceKey() {
100         return KEY_BACKGROUND_ACTIVITY;
101     }
102 
103     @Override
onPreferenceChange(Preference preference, Object newValue)104     public boolean onPreferenceChange(Preference preference, Object newValue) {
105         boolean switchOn = (Boolean) newValue;
106         mAppOpsManager.setMode(AppOpsManager.OP_RUN_IN_BACKGROUND, mUid, mTargetPackage,
107                 switchOn ? AppOpsManager.MODE_ALLOWED : AppOpsManager.MODE_IGNORED);
108 
109         updateSummary(preference);
110         return true;
111     }
112 
113     @VisibleForTesting
getTargetPackage()114     String getTargetPackage() {
115         return mTargetPackage;
116     }
117 
118     @VisibleForTesting
isLegacyApp(final String packageName)119     boolean isLegacyApp(final String packageName) {
120         try {
121             ApplicationInfo info = mPackageManager.getApplicationInfo(packageName,
122                     PackageManager.GET_META_DATA);
123 
124             return info.targetSdkVersion < Build.VERSION_CODES.O;
125         } catch (PackageManager.NameNotFoundException e) {
126             Log.e(TAG, "Cannot find package: " + packageName, e);
127         }
128 
129         return false;
130     }
131 
132     @VisibleForTesting
updateSummary(Preference preference)133     void updateSummary(Preference preference) {
134         final int mode = mAppOpsManager
135                 .checkOpNoThrow(AppOpsManager.OP_RUN_IN_BACKGROUND, mUid, mTargetPackage);
136 
137         if (mode == AppOpsManager.MODE_ERRORED) {
138             preference.setSummary(R.string.background_activity_summary_disabled);
139         } else {
140             final boolean checked = mode != AppOpsManager.MODE_IGNORED;
141             preference.setSummary(checked ? R.string.background_activity_summary_on
142                     : R.string.background_activity_summary_off);
143         }
144     }
145 }
146