1 /*
2  * Copyright (C) 2018 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.managedomainurls;
18 
19 import android.app.Application;
20 import android.content.Context;
21 import android.text.TextUtils;
22 import android.util.ArrayMap;
23 
24 import androidx.preference.Preference;
25 import androidx.preference.PreferenceGroup;
26 import androidx.preference.PreferenceScreen;
27 
28 import com.android.settings.R;
29 import com.android.settings.applications.AppInfoBase;
30 import com.android.settings.applications.intentpicker.AppLaunchSettings;
31 import com.android.settings.core.BasePreferenceController;
32 import com.android.settingslib.applications.AppUtils;
33 import com.android.settingslib.applications.ApplicationsState;
34 import com.android.settingslib.applications.ApplicationsState.AppEntry;
35 
36 import java.util.ArrayList;
37 import java.util.Map;
38 
39 public class DomainAppPreferenceController extends BasePreferenceController implements
40         ApplicationsState.Callbacks {
41 
42     // constant value that can be used to check return code from sub activity.
43     private static final int INSTALLED_APP_DETAILS = 1;
44 
45     private int mMetricsCategory;
46     private ApplicationsState mApplicationsState;
47     private ApplicationsState.Session mSession;
48     private ManageDomainUrls mFragment;
49     private PreferenceGroup mDomainAppList;
50     private Map<String, Preference> mPreferenceCache;
51 
DomainAppPreferenceController(Context context, String key)52     public DomainAppPreferenceController(Context context, String key) {
53         super(context, key);
54         mApplicationsState = ApplicationsState.getInstance(
55                 (Application) mContext.getApplicationContext());
56     }
57 
58     @Override
getAvailabilityStatus()59     public int getAvailabilityStatus() {
60         return AVAILABLE;
61     }
62 
63     @Override
displayPreference(PreferenceScreen screen)64     public void displayPreference(PreferenceScreen screen) {
65         super.displayPreference(screen);
66         mDomainAppList = screen.findPreference(getPreferenceKey());
67     }
68 
69     @Override
handlePreferenceTreeClick(Preference preference)70     public boolean handlePreferenceTreeClick(Preference preference) {
71         if (preference instanceof DomainAppPreference) {
72             ApplicationsState.AppEntry entry = ((DomainAppPreference) preference).getEntry();
73             AppInfoBase.startAppInfoFragment(AppLaunchSettings.class,
74                     mContext.getString(R.string.auto_launch_label),
75                     entry.info.packageName, entry.info.uid, mFragment,
76                     INSTALLED_APP_DETAILS, mMetricsCategory);
77             return true;
78         }
79         return false;
80     }
81 
setFragment(ManageDomainUrls fragment)82     public void setFragment(ManageDomainUrls fragment) {
83         mFragment = fragment;
84         mMetricsCategory = fragment.getMetricsCategory();
85         mSession = mApplicationsState.newSession(this, mFragment.getSettingsLifecycle());
86     }
87 
88     @Override
onRunningStateChanged(boolean running)89     public void onRunningStateChanged(boolean running) {
90     }
91 
92     @Override
onPackageListChanged()93     public void onPackageListChanged() {
94     }
95 
96     @Override
onRebuildComplete(ArrayList<AppEntry> apps)97     public void onRebuildComplete(ArrayList<AppEntry> apps) {
98         if (mContext == null) {
99             return;
100         }
101         // Preload top visible icons of app list.
102         AppUtils.preloadTopIcons(mContext, apps,
103                 mContext.getResources().getInteger(R.integer.config_num_visible_app_icons));
104 
105         rebuildAppList(mDomainAppList, apps);
106     }
107 
108     @Override
onPackageIconChanged()109     public void onPackageIconChanged() {
110     }
111 
112     @Override
onPackageSizeChanged(String packageName)113     public void onPackageSizeChanged(String packageName) {
114     }
115 
116     @Override
onAllSizesComputed()117     public void onAllSizesComputed() {
118     }
119 
120     @Override
onLauncherInfoChanged()121     public void onLauncherInfoChanged() {
122     }
123 
124     @Override
onLoadEntriesCompleted()125     public void onLoadEntriesCompleted() {
126         rebuild();
127     }
128 
cacheAllPrefs(PreferenceGroup group)129     private void cacheAllPrefs(PreferenceGroup group) {
130         mPreferenceCache = new ArrayMap();
131         final int count = group.getPreferenceCount();
132         for (int i = 0; i < count; i++) {
133             Preference p = group.getPreference(i);
134             if (TextUtils.isEmpty(p.getKey())) {
135                 continue;
136             }
137             mPreferenceCache.put(p.getKey(), p);
138         }
139     }
140 
getCachedPreference(String key)141     private Preference getCachedPreference(String key) {
142         return mPreferenceCache != null ? mPreferenceCache.remove(key) : null;
143     }
144 
removeCachedPrefs(PreferenceGroup group)145     private void removeCachedPrefs(PreferenceGroup group) {
146         for (Preference p : mPreferenceCache.values()) {
147             group.removePreference(p);
148         }
149         mPreferenceCache = null;
150     }
151 
rebuild()152     private void rebuild() {
153         final ArrayList<AppEntry> apps = mSession.rebuild(
154                 ApplicationsState.FILTER_WITH_DOMAIN_URLS, ApplicationsState.ALPHA_COMPARATOR);
155         if (apps != null) {
156             onRebuildComplete(apps);
157         }
158     }
159 
rebuildAppList(PreferenceGroup group, ArrayList<AppEntry> apps)160     private void rebuildAppList(PreferenceGroup group, ArrayList<AppEntry> apps) {
161         cacheAllPrefs(group);
162         final int size = apps.size();
163         final Context context = group.getContext();
164         for (int i = 0; i < size; i++) {
165             final AppEntry entry = apps.get(i);
166             final String key = entry.info.packageName + "|" + entry.info.uid;
167             DomainAppPreference preference = (DomainAppPreference) getCachedPreference(key);
168             if (preference == null) {
169                 preference = new DomainAppPreference(context, entry);
170                 preference.setKey(key);
171                 group.addPreference(preference);
172             } else {
173                 preference.reuse();
174             }
175             preference.setOrder(i);
176         }
177         removeCachedPrefs(group);
178     }
179 }
180