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 import android.util.IconDrawableFactory;
24 
25 import androidx.preference.Preference;
26 import androidx.preference.PreferenceGroup;
27 import androidx.preference.PreferenceScreen;
28 
29 import com.android.settings.R;
30 import com.android.settings.applications.AppInfoBase;
31 import com.android.settings.applications.intentpicker.AppLaunchSettings;
32 import com.android.settings.core.BasePreferenceController;
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, R.string.auto_launch_label,
74                     entry.info.packageName, entry.info.uid, mFragment,
75                     INSTALLED_APP_DETAILS, mMetricsCategory);
76             return true;
77         }
78         return false;
79     }
80 
setFragment(ManageDomainUrls fragment)81     public void setFragment(ManageDomainUrls fragment) {
82         mFragment = fragment;
83         mMetricsCategory = fragment.getMetricsCategory();
84         mSession = mApplicationsState.newSession(this, mFragment.getSettingsLifecycle());
85     }
86 
87     @Override
onRunningStateChanged(boolean running)88     public void onRunningStateChanged(boolean running) {
89     }
90 
91     @Override
onPackageListChanged()92     public void onPackageListChanged() {
93     }
94 
95     @Override
onRebuildComplete(ArrayList<AppEntry> apps)96     public void onRebuildComplete(ArrayList<AppEntry> apps) {
97         if (mContext == null) {
98             return;
99         }
100         rebuildAppList(mDomainAppList, apps);
101     }
102 
103     @Override
onPackageIconChanged()104     public void onPackageIconChanged() {
105     }
106 
107     @Override
onPackageSizeChanged(String packageName)108     public void onPackageSizeChanged(String packageName) {
109     }
110 
111     @Override
onAllSizesComputed()112     public void onAllSizesComputed() {
113     }
114 
115     @Override
onLauncherInfoChanged()116     public void onLauncherInfoChanged() {
117     }
118 
119     @Override
onLoadEntriesCompleted()120     public void onLoadEntriesCompleted() {
121         rebuild();
122     }
123 
cacheAllPrefs(PreferenceGroup group)124     private void cacheAllPrefs(PreferenceGroup group) {
125         mPreferenceCache = new ArrayMap();
126         final int count = group.getPreferenceCount();
127         for (int i = 0; i < count; i++) {
128             Preference p = group.getPreference(i);
129             if (TextUtils.isEmpty(p.getKey())) {
130                 continue;
131             }
132             mPreferenceCache.put(p.getKey(), p);
133         }
134     }
135 
getCachedPreference(String key)136     private Preference getCachedPreference(String key) {
137         return mPreferenceCache != null ? mPreferenceCache.remove(key) : null;
138     }
139 
removeCachedPrefs(PreferenceGroup group)140     private void removeCachedPrefs(PreferenceGroup group) {
141         for (Preference p : mPreferenceCache.values()) {
142             group.removePreference(p);
143         }
144         mPreferenceCache = null;
145     }
146 
rebuild()147     private void rebuild() {
148         final ArrayList<AppEntry> apps = mSession.rebuild(
149                 ApplicationsState.FILTER_WITH_DOMAIN_URLS, ApplicationsState.ALPHA_COMPARATOR);
150         if (apps != null) {
151             onRebuildComplete(apps);
152         }
153     }
154 
rebuildAppList(PreferenceGroup group, ArrayList<AppEntry> apps)155     private void rebuildAppList(PreferenceGroup group, ArrayList<AppEntry> apps) {
156         cacheAllPrefs(group);
157         final int size = apps.size();
158         final Context context = group.getContext();
159         final IconDrawableFactory iconDrawableFactory = IconDrawableFactory.newInstance(context);
160         for (int i = 0; i < size; i++) {
161             final AppEntry entry = apps.get(i);
162             final String key = entry.info.packageName + "|" + entry.info.uid;
163             DomainAppPreference preference = (DomainAppPreference) getCachedPreference(key);
164             if (preference == null) {
165                 preference = new DomainAppPreference(context, iconDrawableFactory, entry);
166                 preference.setKey(key);
167                 group.addPreference(preference);
168             } else {
169                 preference.reuse();
170             }
171             preference.setOrder(i);
172         }
173         removeCachedPrefs(group);
174     }
175 }
176