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.applications;
18 
19 import static android.provider.DeviceConfig.NAMESPACE_APP_HIBERNATION;
20 
21 import static com.android.settings.Utils.PROPERTY_APP_HIBERNATION_ENABLED;
22 
23 import android.content.Context;
24 import android.content.Intent;
25 import android.icu.text.MessageFormat;
26 import android.permission.PermissionControllerManager;
27 import android.provider.DeviceConfig;
28 
29 import androidx.lifecycle.Lifecycle;
30 import androidx.lifecycle.LifecycleObserver;
31 import androidx.lifecycle.OnLifecycleEvent;
32 import androidx.preference.Preference;
33 import androidx.preference.PreferenceScreen;
34 
35 import com.android.settings.R;
36 import com.android.settings.core.BasePreferenceController;
37 
38 import com.google.common.annotations.VisibleForTesting;
39 
40 import java.util.HashMap;
41 import java.util.Locale;
42 import java.util.Map;
43 import java.util.concurrent.Executor;
44 
45 /**
46  * A preference controller handling the logic for updating summary of hibernated apps.
47  */
48 public final class HibernatedAppsPreferenceController extends BasePreferenceController
49         implements LifecycleObserver {
50     private static final String TAG = "HibernatedAppsPrefController";
51     private PreferenceScreen mScreen;
52     private int mUnusedCount = 0;
53     private boolean mLoadingUnusedApps;
54     private boolean mLoadedUnusedCount;
55     private final Executor mMainExecutor;
56 
HibernatedAppsPreferenceController(Context context, String preferenceKey)57     public HibernatedAppsPreferenceController(Context context, String preferenceKey) {
58         this(context, preferenceKey, context.getMainExecutor());
59     }
60 
61     @VisibleForTesting
HibernatedAppsPreferenceController(Context context, String preferenceKey, Executor mainExecutor)62     HibernatedAppsPreferenceController(Context context, String preferenceKey,
63             Executor mainExecutor) {
64         super(context, preferenceKey);
65         mMainExecutor = mainExecutor;
66     }
67 
68     @Override
getAvailabilityStatus()69     public int getAvailabilityStatus() {
70         return isHibernationEnabled() ? AVAILABLE : CONDITIONALLY_UNAVAILABLE;
71     }
72 
73     @Override
getSummary()74     public CharSequence getSummary() {
75         MessageFormat msgFormat = new MessageFormat(
76                 mContext.getResources().getString(R.string.unused_apps_summary),
77                 Locale.getDefault());
78         Map<String, Object> arguments = new HashMap<>();
79         arguments.put("count", mUnusedCount);
80         return mLoadedUnusedCount
81                 ? msgFormat.format(arguments)
82                 : mContext.getResources().getString(R.string.summary_placeholder);
83     }
84 
85     @Override
displayPreference(PreferenceScreen screen)86     public void displayPreference(PreferenceScreen screen) {
87         super.displayPreference(screen);
88         mScreen = screen;
89 
90         Preference pref = screen.findPreference(getPreferenceKey());
91         if (pref != null) {
92             pref.setIntent(new Intent(Intent.ACTION_MANAGE_UNUSED_APPS)
93                     .setPackage(mContext.getPackageManager().getPermissionControllerPackageName()));
94         }
95     }
96 
97     /**
98      * On lifecycle resume event.
99      */
100     @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
onResume()101     public void onResume() {
102         updatePreference();
103     }
104 
updatePreference()105     private void updatePreference() {
106         if (mScreen == null) {
107             return;
108         }
109         if (!mLoadingUnusedApps) {
110             final PermissionControllerManager permController =
111                     mContext.getSystemService(PermissionControllerManager.class);
112             permController.getUnusedAppCount(mMainExecutor, unusedCount -> {
113                 mUnusedCount = unusedCount;
114                 mLoadingUnusedApps = false;
115                 mLoadedUnusedCount = true;
116                 Preference pref = mScreen.findPreference(mPreferenceKey);
117                 refreshSummary(pref);
118             });
119             mLoadingUnusedApps = true;
120         }
121     }
122 
isHibernationEnabled()123     private static boolean isHibernationEnabled() {
124         return DeviceConfig.getBoolean(
125                 NAMESPACE_APP_HIBERNATION, PROPERTY_APP_HIBERNATION_ENABLED, true);
126     }
127 }
128