blob: c9990e574eed0d7d79298a59a3a81bea04df9d66 [file] [log] [blame]
Tony Mantler70676c12017-12-15 10:09:37 -08001/*
2 * Copyright (C) 2017 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
17package com.android.settingslib.fuelgauge;
18
Lei Yuf5a13f82018-06-28 14:06:29 -070019import android.app.admin.DevicePolicyManager;
Fan Zhang091a0572018-05-29 10:55:51 -070020import android.content.ComponentName;
21import android.content.Context;
Lei Yuae768652018-04-05 13:44:51 -070022import android.content.pm.PackageManager;
Tony Mantler70676c12017-12-15 10:09:37 -080023import android.os.IDeviceIdleController;
24import android.os.RemoteException;
25import android.os.ServiceManager;
26import android.support.annotation.VisibleForTesting;
Fan Zhang091a0572018-05-29 10:55:51 -070027import android.telecom.DefaultDialerManager;
28import android.text.TextUtils;
Tony Mantler70676c12017-12-15 10:09:37 -080029import android.util.ArraySet;
30import android.util.Log;
31
Fan Zhang091a0572018-05-29 10:55:51 -070032import com.android.internal.telephony.SmsApplication;
Lei Yuae768652018-04-05 13:44:51 -070033import com.android.internal.util.ArrayUtils;
34
Tony Mantler70676c12017-12-15 10:09:37 -080035/**
36 * Handles getting/changing the whitelist for the exceptions to battery saving features.
37 */
38public class PowerWhitelistBackend {
39
40 private static final String TAG = "PowerWhitelistBackend";
41
42 private static final String DEVICE_IDLE_SERVICE = "deviceidle";
43
44 private static PowerWhitelistBackend sInstance;
45
Fan Zhang091a0572018-05-29 10:55:51 -070046 private final Context mAppContext;
Tony Mantler70676c12017-12-15 10:09:37 -080047 private final IDeviceIdleController mDeviceIdleService;
48 private final ArraySet<String> mWhitelistedApps = new ArraySet<>();
49 private final ArraySet<String> mSysWhitelistedApps = new ArraySet<>();
Lei Yue93e77b2018-03-12 13:34:36 -070050 private final ArraySet<String> mSysWhitelistedAppsExceptIdle = new ArraySet<>();
Tony Mantler70676c12017-12-15 10:09:37 -080051
Fan Zhang091a0572018-05-29 10:55:51 -070052 public PowerWhitelistBackend(Context context) {
53 this(context, IDeviceIdleController.Stub.asInterface(
54 ServiceManager.getService(DEVICE_IDLE_SERVICE)));
Tony Mantler70676c12017-12-15 10:09:37 -080055 }
56
57 @VisibleForTesting
Fan Zhang091a0572018-05-29 10:55:51 -070058 PowerWhitelistBackend(Context context, IDeviceIdleController deviceIdleService) {
59 mAppContext = context.getApplicationContext();
Tony Mantler70676c12017-12-15 10:09:37 -080060 mDeviceIdleService = deviceIdleService;
61 refreshList();
62 }
63
64 public int getWhitelistSize() {
65 return mWhitelistedApps.size();
66 }
67
68 public boolean isSysWhitelisted(String pkg) {
69 return mSysWhitelistedApps.contains(pkg);
70 }
71
72 public boolean isWhitelisted(String pkg) {
Fan Zhang091a0572018-05-29 10:55:51 -070073 if (mWhitelistedApps.contains(pkg)) {
74 return true;
75 }
76
77 // Additionally, check if pkg is default dialer/sms. They are considered essential apps and
78 // should be automatically whitelisted (otherwise user may be able to set restriction on
79 // them, leading to bad device behavior.)
80 if (!mAppContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
81 return false;
82 }
83 final ComponentName defaultSms = SmsApplication.getDefaultSmsApplication(mAppContext,
84 true /* updateIfNeeded */);
85 if (defaultSms != null && TextUtils.equals(pkg, defaultSms.getPackageName())) {
86 return true;
87 }
88
89 final String defaultDialer = DefaultDialerManager.getDefaultDialerApplication(mAppContext);
90 if (TextUtils.equals(pkg, defaultDialer)) {
91 return true;
92 }
Lei Yuf5a13f82018-06-28 14:06:29 -070093
94 final DevicePolicyManager devicePolicyManager = mAppContext.getSystemService(
95 DevicePolicyManager.class);
96 if (devicePolicyManager.packageHasActiveAdmins(pkg)) {
97 return true;
98 }
99
Fan Zhang091a0572018-05-29 10:55:51 -0700100 return false;
Tony Mantler70676c12017-12-15 10:09:37 -0800101 }
102
Lei Yu3aec6d12018-05-08 18:09:51 -0700103 public boolean isWhitelisted(String[] pkgs) {
104 if (ArrayUtils.isEmpty(pkgs)) {
105 return false;
106 }
107 for (String pkg : pkgs) {
108 if (isWhitelisted(pkg)) {
109 return true;
110 }
111 }
112
113 return false;
114 }
115
Lei Yue93e77b2018-03-12 13:34:36 -0700116 public boolean isSysWhitelistedExceptIdle(String pkg) {
117 return mSysWhitelistedAppsExceptIdle.contains(pkg);
118 }
119
Lei Yuae768652018-04-05 13:44:51 -0700120 public boolean isSysWhitelistedExceptIdle(String[] pkgs) {
121 if (ArrayUtils.isEmpty(pkgs)) {
122 return false;
123 }
124 for (String pkg : pkgs) {
125 if (isSysWhitelistedExceptIdle(pkg)) {
126 return true;
127 }
128 }
129
130 return false;
131 }
132
Tony Mantler70676c12017-12-15 10:09:37 -0800133 public void addApp(String pkg) {
134 try {
135 mDeviceIdleService.addPowerSaveWhitelistApp(pkg);
136 mWhitelistedApps.add(pkg);
137 } catch (RemoteException e) {
138 Log.w(TAG, "Unable to reach IDeviceIdleController", e);
139 }
140 }
141
142 public void removeApp(String pkg) {
143 try {
144 mDeviceIdleService.removePowerSaveWhitelistApp(pkg);
145 mWhitelistedApps.remove(pkg);
146 } catch (RemoteException e) {
147 Log.w(TAG, "Unable to reach IDeviceIdleController", e);
148 }
149 }
150
151 @VisibleForTesting
152 public void refreshList() {
153 mSysWhitelistedApps.clear();
Lei Yue93e77b2018-03-12 13:34:36 -0700154 mSysWhitelistedAppsExceptIdle.clear();
Tony Mantler70676c12017-12-15 10:09:37 -0800155 mWhitelistedApps.clear();
Fan Zhang091a0572018-05-29 10:55:51 -0700156 if (mDeviceIdleService == null) {
157 return;
158 }
Tony Mantler70676c12017-12-15 10:09:37 -0800159 try {
Fan Zhang091a0572018-05-29 10:55:51 -0700160 final String[] whitelistedApps = mDeviceIdleService.getFullPowerWhitelist();
Tony Mantler70676c12017-12-15 10:09:37 -0800161 for (String app : whitelistedApps) {
162 mWhitelistedApps.add(app);
163 }
Fan Zhang091a0572018-05-29 10:55:51 -0700164 final String[] sysWhitelistedApps = mDeviceIdleService.getSystemPowerWhitelist();
Tony Mantler70676c12017-12-15 10:09:37 -0800165 for (String app : sysWhitelistedApps) {
166 mSysWhitelistedApps.add(app);
167 }
Fan Zhang091a0572018-05-29 10:55:51 -0700168 final String[] sysWhitelistedAppsExceptIdle =
Lei Yue93e77b2018-03-12 13:34:36 -0700169 mDeviceIdleService.getSystemPowerWhitelistExceptIdle();
170 for (String app : sysWhitelistedAppsExceptIdle) {
171 mSysWhitelistedAppsExceptIdle.add(app);
172 }
Tony Mantler70676c12017-12-15 10:09:37 -0800173 } catch (RemoteException e) {
174 Log.w(TAG, "Unable to reach IDeviceIdleController", e);
175 }
176 }
177
Fan Zhang091a0572018-05-29 10:55:51 -0700178 public static PowerWhitelistBackend getInstance(Context context) {
Tony Mantler70676c12017-12-15 10:09:37 -0800179 if (sInstance == null) {
Fan Zhang091a0572018-05-29 10:55:51 -0700180 sInstance = new PowerWhitelistBackend(context);
Tony Mantler70676c12017-12-15 10:09:37 -0800181 }
182 return sInstance;
183 }
184
185}