blob: 7234788b2e043a25a4136335a1ce9295386114d5 [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
Fan Zhang091a0572018-05-29 10:55:51 -070019import android.content.ComponentName;
20import android.content.Context;
Lei Yuae768652018-04-05 13:44:51 -070021import android.content.pm.PackageManager;
Tony Mantler70676c12017-12-15 10:09:37 -080022import android.os.IDeviceIdleController;
23import android.os.RemoteException;
24import android.os.ServiceManager;
25import android.support.annotation.VisibleForTesting;
Fan Zhang091a0572018-05-29 10:55:51 -070026import android.telecom.DefaultDialerManager;
27import android.text.TextUtils;
Tony Mantler70676c12017-12-15 10:09:37 -080028import android.util.ArraySet;
29import android.util.Log;
30
Fan Zhang091a0572018-05-29 10:55:51 -070031import com.android.internal.telephony.SmsApplication;
Lei Yuae768652018-04-05 13:44:51 -070032import com.android.internal.util.ArrayUtils;
33
Tony Mantler70676c12017-12-15 10:09:37 -080034/**
35 * Handles getting/changing the whitelist for the exceptions to battery saving features.
36 */
37public class PowerWhitelistBackend {
38
39 private static final String TAG = "PowerWhitelistBackend";
40
41 private static final String DEVICE_IDLE_SERVICE = "deviceidle";
42
43 private static PowerWhitelistBackend sInstance;
44
Fan Zhang091a0572018-05-29 10:55:51 -070045 private final Context mAppContext;
Tony Mantler70676c12017-12-15 10:09:37 -080046 private final IDeviceIdleController mDeviceIdleService;
47 private final ArraySet<String> mWhitelistedApps = new ArraySet<>();
48 private final ArraySet<String> mSysWhitelistedApps = new ArraySet<>();
Lei Yue93e77b2018-03-12 13:34:36 -070049 private final ArraySet<String> mSysWhitelistedAppsExceptIdle = new ArraySet<>();
Tony Mantler70676c12017-12-15 10:09:37 -080050
Fan Zhang091a0572018-05-29 10:55:51 -070051 public PowerWhitelistBackend(Context context) {
52 this(context, IDeviceIdleController.Stub.asInterface(
53 ServiceManager.getService(DEVICE_IDLE_SERVICE)));
Tony Mantler70676c12017-12-15 10:09:37 -080054 }
55
56 @VisibleForTesting
Fan Zhang091a0572018-05-29 10:55:51 -070057 PowerWhitelistBackend(Context context, IDeviceIdleController deviceIdleService) {
58 mAppContext = context.getApplicationContext();
Tony Mantler70676c12017-12-15 10:09:37 -080059 mDeviceIdleService = deviceIdleService;
60 refreshList();
61 }
62
63 public int getWhitelistSize() {
64 return mWhitelistedApps.size();
65 }
66
67 public boolean isSysWhitelisted(String pkg) {
68 return mSysWhitelistedApps.contains(pkg);
69 }
70
71 public boolean isWhitelisted(String pkg) {
Fan Zhang091a0572018-05-29 10:55:51 -070072 if (mWhitelistedApps.contains(pkg)) {
73 return true;
74 }
75
76 // Additionally, check if pkg is default dialer/sms. They are considered essential apps and
77 // should be automatically whitelisted (otherwise user may be able to set restriction on
78 // them, leading to bad device behavior.)
79 if (!mAppContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
80 return false;
81 }
82 final ComponentName defaultSms = SmsApplication.getDefaultSmsApplication(mAppContext,
83 true /* updateIfNeeded */);
84 if (defaultSms != null && TextUtils.equals(pkg, defaultSms.getPackageName())) {
85 return true;
86 }
87
88 final String defaultDialer = DefaultDialerManager.getDefaultDialerApplication(mAppContext);
89 if (TextUtils.equals(pkg, defaultDialer)) {
90 return true;
91 }
92 return false;
Tony Mantler70676c12017-12-15 10:09:37 -080093 }
94
Lei Yu3aec6d12018-05-08 18:09:51 -070095 public boolean isWhitelisted(String[] pkgs) {
96 if (ArrayUtils.isEmpty(pkgs)) {
97 return false;
98 }
99 for (String pkg : pkgs) {
100 if (isWhitelisted(pkg)) {
101 return true;
102 }
103 }
104
105 return false;
106 }
107
Lei Yue93e77b2018-03-12 13:34:36 -0700108 public boolean isSysWhitelistedExceptIdle(String pkg) {
109 return mSysWhitelistedAppsExceptIdle.contains(pkg);
110 }
111
Lei Yuae768652018-04-05 13:44:51 -0700112 public boolean isSysWhitelistedExceptIdle(String[] pkgs) {
113 if (ArrayUtils.isEmpty(pkgs)) {
114 return false;
115 }
116 for (String pkg : pkgs) {
117 if (isSysWhitelistedExceptIdle(pkg)) {
118 return true;
119 }
120 }
121
122 return false;
123 }
124
Tony Mantler70676c12017-12-15 10:09:37 -0800125 public void addApp(String pkg) {
126 try {
127 mDeviceIdleService.addPowerSaveWhitelistApp(pkg);
128 mWhitelistedApps.add(pkg);
129 } catch (RemoteException e) {
130 Log.w(TAG, "Unable to reach IDeviceIdleController", e);
131 }
132 }
133
134 public void removeApp(String pkg) {
135 try {
136 mDeviceIdleService.removePowerSaveWhitelistApp(pkg);
137 mWhitelistedApps.remove(pkg);
138 } catch (RemoteException e) {
139 Log.w(TAG, "Unable to reach IDeviceIdleController", e);
140 }
141 }
142
143 @VisibleForTesting
144 public void refreshList() {
145 mSysWhitelistedApps.clear();
Lei Yue93e77b2018-03-12 13:34:36 -0700146 mSysWhitelistedAppsExceptIdle.clear();
Tony Mantler70676c12017-12-15 10:09:37 -0800147 mWhitelistedApps.clear();
Fan Zhang091a0572018-05-29 10:55:51 -0700148 if (mDeviceIdleService == null) {
149 return;
150 }
Tony Mantler70676c12017-12-15 10:09:37 -0800151 try {
Fan Zhang091a0572018-05-29 10:55:51 -0700152 final String[] whitelistedApps = mDeviceIdleService.getFullPowerWhitelist();
Tony Mantler70676c12017-12-15 10:09:37 -0800153 for (String app : whitelistedApps) {
154 mWhitelistedApps.add(app);
155 }
Fan Zhang091a0572018-05-29 10:55:51 -0700156 final String[] sysWhitelistedApps = mDeviceIdleService.getSystemPowerWhitelist();
Tony Mantler70676c12017-12-15 10:09:37 -0800157 for (String app : sysWhitelistedApps) {
158 mSysWhitelistedApps.add(app);
159 }
Fan Zhang091a0572018-05-29 10:55:51 -0700160 final String[] sysWhitelistedAppsExceptIdle =
Lei Yue93e77b2018-03-12 13:34:36 -0700161 mDeviceIdleService.getSystemPowerWhitelistExceptIdle();
162 for (String app : sysWhitelistedAppsExceptIdle) {
163 mSysWhitelistedAppsExceptIdle.add(app);
164 }
Tony Mantler70676c12017-12-15 10:09:37 -0800165 } catch (RemoteException e) {
166 Log.w(TAG, "Unable to reach IDeviceIdleController", e);
167 }
168 }
169
Fan Zhang091a0572018-05-29 10:55:51 -0700170 public static PowerWhitelistBackend getInstance(Context context) {
Tony Mantler70676c12017-12-15 10:09:37 -0800171 if (sInstance == null) {
Fan Zhang091a0572018-05-29 10:55:51 -0700172 sInstance = new PowerWhitelistBackend(context);
Tony Mantler70676c12017-12-15 10:09:37 -0800173 }
174 return sInstance;
175 }
176
177}