• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 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 
17 package com.android.settings.fuelgauge;
18 
19 import android.app.AppOpsManager;
20 import android.content.Context;
21 import android.util.Log;
22 
23 import androidx.annotation.VisibleForTesting;
24 
25 import com.android.settingslib.fuelgauge.PowerAllowlistBackend;
26 
27 /** A utility class for application usage operation. */
28 public class BatteryOptimizeUtils {
29     private static final String TAG = "BatteryOptimizeUtils";
30     private static final String UNKNOWN_PACKAGE = "unknown";
31 
32     @VisibleForTesting AppOpsManager mAppOpsManager;
33     @VisibleForTesting BatteryUtils mBatteryUtils;
34     @VisibleForTesting PowerAllowlistBackend mPowerAllowListBackend;
35     private final String mPackageName;
36     private final int mUid;
37 
38     private int mMode;
39     private boolean mAllowListed;
40 
41     /**
42      * Usage type of application.
43      */
44     public enum AppUsageState {
45         UNKNOWN,
46         RESTRICTED,
47         UNRESTRICTED,
48         OPTIMIZED,
49     }
50 
BatteryOptimizeUtils(Context context, int uid, String packageName)51     public BatteryOptimizeUtils(Context context, int uid, String packageName) {
52         mUid = uid;
53         mPackageName = packageName;
54         mAppOpsManager = context.getSystemService(AppOpsManager.class);
55         mBatteryUtils = BatteryUtils.getInstance(context);
56         mPowerAllowListBackend = PowerAllowlistBackend.getInstance(context);
57         mMode = mAppOpsManager
58                 .checkOpNoThrow(AppOpsManager.OP_RUN_ANY_IN_BACKGROUND, mUid, mPackageName);
59         mAllowListed = mPowerAllowListBackend.isAllowlisted(mPackageName);
60     }
61 
getAppUsageState()62     public AppUsageState getAppUsageState() {
63         refreshState();
64         if (!mAllowListed && mMode == AppOpsManager.MODE_IGNORED) {
65             return AppUsageState.RESTRICTED;
66         } else if (mAllowListed && mMode == AppOpsManager.MODE_ALLOWED) {
67             return AppUsageState.UNRESTRICTED;
68         } else if (!mAllowListed && mMode == AppOpsManager.MODE_ALLOWED) {
69             return AppUsageState.OPTIMIZED;
70         } else {
71             Log.d(TAG, "get unknown app usage state.");
72             return AppUsageState.UNKNOWN;
73         }
74     }
75 
setAppUsageState(AppUsageState state)76     public void setAppUsageState(AppUsageState state) {
77         switch (state) {
78             case RESTRICTED:
79                 mBatteryUtils.setForceAppStandby(mUid, mPackageName, AppOpsManager.MODE_IGNORED);
80                 mPowerAllowListBackend.removeApp(mPackageName);
81                 break;
82             case UNRESTRICTED:
83                 mBatteryUtils.setForceAppStandby(mUid, mPackageName, AppOpsManager.MODE_ALLOWED);
84                 mPowerAllowListBackend.addApp(mPackageName);
85                 break;
86             case OPTIMIZED:
87                 mBatteryUtils.setForceAppStandby(mUid, mPackageName, AppOpsManager.MODE_ALLOWED);
88                 mPowerAllowListBackend.removeApp(mPackageName);
89                 break;
90             default:
91                 Log.d(TAG, "set unknown app usage state.");
92         }
93     }
94 
95     /**
96      * Return {@code true} if package name is valid (can get an uid).
97      */
isValidPackageName()98     public boolean isValidPackageName() {
99         return mBatteryUtils.getPackageUid(mPackageName) != BatteryUtils.UID_NULL;
100     }
101 
102     /**
103      * Return {@code true} if this package is system or default active app.
104      */
isSystemOrDefaultApp()105     public boolean isSystemOrDefaultApp() {
106         mPowerAllowListBackend.refreshList();
107 
108         return mPowerAllowListBackend.isSysAllowlisted(mPackageName)
109                 || mPowerAllowListBackend.isDefaultActiveApp(mPackageName);
110     }
111 
getPackageName()112     String getPackageName() {
113         return mPackageName == null ? UNKNOWN_PACKAGE : mPackageName;
114     }
115 
refreshState()116     private void refreshState() {
117         mPowerAllowListBackend.refreshList();
118         mAllowListed = mPowerAllowListBackend.isAllowlisted(mPackageName);
119         mMode = mAppOpsManager
120                 .checkOpNoThrow(AppOpsManager.OP_RUN_ANY_IN_BACKGROUND, mUid, mPackageName);
121         Log.d(TAG, String.format("refresh %s state, allowlisted = %s, mode = %d",
122                 mPackageName,
123                 mAllowListed,
124                 mMode));
125     }
126 }
127