• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
17 package com.android.settings.fuelgauge;
18 
19 import static android.app.usage.UsageStatsManager.STANDBY_BUCKET_ACTIVE;
20 import static android.app.usage.UsageStatsManager.STANDBY_BUCKET_EXEMPTED;
21 import static android.app.usage.UsageStatsManager.STANDBY_BUCKET_FREQUENT;
22 import static android.app.usage.UsageStatsManager.STANDBY_BUCKET_NEVER;
23 import static android.app.usage.UsageStatsManager.STANDBY_BUCKET_RARE;
24 import static android.app.usage.UsageStatsManager.STANDBY_BUCKET_RESTRICTED;
25 import static android.app.usage.UsageStatsManager.STANDBY_BUCKET_WORKING_SET;
26 
27 import android.app.settings.SettingsEnums;
28 import android.app.usage.UsageStatsManager;
29 import android.content.Context;
30 import android.content.Intent;
31 import android.content.pm.PackageManager;
32 import android.content.pm.ResolveInfo;
33 import android.content.res.Resources;
34 import android.os.Bundle;
35 import android.text.TextUtils;
36 
37 import androidx.preference.ListPreference;
38 import androidx.preference.Preference;
39 import androidx.preference.PreferenceGroup;
40 
41 import com.android.settings.R;
42 import com.android.settings.SettingsPreferenceFragment;
43 
44 import java.util.Arrays;
45 import java.util.List;
46 
47 public class InactiveApps extends SettingsPreferenceFragment
48         implements Preference.OnPreferenceChangeListener {
49 
50     private static final CharSequence[] FULL_SETTABLE_BUCKETS_NAMES =
51             {"ACTIVE", "WORKING_SET", "FREQUENT", "RARE", "RESTRICTED"};
52 
53     private static final CharSequence[] FULL_SETTABLE_BUCKETS_VALUES = {
54             Integer.toString(STANDBY_BUCKET_ACTIVE),
55             Integer.toString(STANDBY_BUCKET_WORKING_SET),
56             Integer.toString(STANDBY_BUCKET_FREQUENT),
57             Integer.toString(STANDBY_BUCKET_RARE),
58             Integer.toString(STANDBY_BUCKET_RESTRICTED)
59     };
60 
61     private UsageStatsManager mUsageStats;
62 
63     @Override
getMetricsCategory()64     public int getMetricsCategory() {
65         return SettingsEnums.FUELGAUGE_INACTIVE_APPS;
66     }
67 
68     @Override
onCreate(Bundle icicle)69     public void onCreate(Bundle icicle) {
70         super.onCreate(icicle);
71 
72         mUsageStats = getActivity().getSystemService(UsageStatsManager.class);
73         addPreferencesFromResource(R.xml.placeholder_preference_screen);
74         getActivity().setTitle(R.string.inactive_apps_title);
75     }
76 
77     @Override
onResume()78     public void onResume() {
79         super.onResume();
80         init();
81     }
82 
init()83     private void init() {
84         PreferenceGroup screen = getPreferenceScreen();
85         screen.removeAll();
86         screen.setOrderingAsAdded(false);
87         final Context context = getActivity();
88         final PackageManager pm = context.getPackageManager();
89         final String settingsPackage = context.getPackageName();
90         final CharSequence[] bucketNames = FULL_SETTABLE_BUCKETS_NAMES;
91         final CharSequence[] bucketValues = FULL_SETTABLE_BUCKETS_VALUES;
92 
93         Intent launcherIntent = new Intent(Intent.ACTION_MAIN);
94         launcherIntent.addCategory(Intent.CATEGORY_LAUNCHER);
95         List<ResolveInfo> apps = pm.queryIntentActivities(launcherIntent, 0);
96         for (ResolveInfo app : apps) {
97             String packageName = app.activityInfo.applicationInfo.packageName;
98             ListPreference p = new ListPreference(getPrefContext());
99             p.setTitle(app.loadLabel(pm));
100             p.setIcon(app.loadIcon(pm));
101             p.setKey(packageName);
102             p.setEntries(getAllowableBuckets(packageName, bucketNames));
103             p.setEntryValues(getAllowableBuckets(packageName, bucketValues));
104             updateSummary(p);
105             // Don't allow Settings to change its own standby bucket.
106             if (TextUtils.equals(packageName, settingsPackage)) {
107                 p.setEnabled(false);
108             }
109             p.setOnPreferenceChangeListener(this);
110 
111             screen.addPreference(p);
112         }
113     }
114 
getAllowableBuckets(String packageName, CharSequence[] possibleBuckets)115     private CharSequence[] getAllowableBuckets(String packageName, CharSequence[] possibleBuckets) {
116         final int minBucket = mUsageStats.getAppMinStandbyBucket(packageName);
117         if (minBucket > STANDBY_BUCKET_RESTRICTED) {
118             return possibleBuckets;
119         }
120         if (minBucket < STANDBY_BUCKET_ACTIVE) {
121             return new CharSequence[]{};
122         }
123         // Use FULL_SETTABLE_BUCKETS_VALUES since we're searching using the int value. The index
124         // should apply no matter which array we're going to copy from.
125         final int idx =
126                 Arrays.binarySearch(FULL_SETTABLE_BUCKETS_VALUES, Integer.toString(minBucket));
127         if (idx < 0) {
128             // Include everything
129             return possibleBuckets;
130         }
131         return Arrays.copyOfRange(possibleBuckets, 0, idx + 1);
132     }
133 
bucketToName(int bucket)134     static String bucketToName(int bucket) {
135         switch (bucket) {
136             case STANDBY_BUCKET_EXEMPTED: return "EXEMPTED";
137             case STANDBY_BUCKET_ACTIVE: return "ACTIVE";
138             case STANDBY_BUCKET_WORKING_SET: return "WORKING_SET";
139             case STANDBY_BUCKET_FREQUENT: return "FREQUENT";
140             case STANDBY_BUCKET_RARE: return "RARE";
141             case STANDBY_BUCKET_RESTRICTED: return "RESTRICTED";
142             case STANDBY_BUCKET_NEVER: return "NEVER";
143         }
144         return "";
145     }
146 
updateSummary(ListPreference p)147     private void updateSummary(ListPreference p) {
148         final Resources res = getActivity().getResources();
149         final int appBucket = mUsageStats.getAppStandbyBucket(p.getKey());
150         final String bucketName = bucketToName(appBucket);
151         p.setSummary(res.getString(R.string.standby_bucket_summary, bucketName));
152         // Buckets outside of the range of the dynamic ones are only used for special
153         // purposes and can either not be changed out of, or might have undesirable
154         // side-effects in combination with other assumptions.
155         final boolean changeable = appBucket >= STANDBY_BUCKET_ACTIVE
156                 && appBucket <= STANDBY_BUCKET_RESTRICTED;
157         if (changeable) {
158             p.setValue(Integer.toString(appBucket));
159         }
160         p.setEnabled(changeable);
161     }
162 
163     @Override
onPreferenceChange(Preference preference, Object newValue)164     public boolean onPreferenceChange(Preference preference, Object newValue) {
165         mUsageStats.setAppStandbyBucket(preference.getKey(), Integer.parseInt((String) newValue));
166         updateSummary((ListPreference) preference);
167         return false;
168     }
169 }
170