1 /*
2  * Copyright (C) 2019 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.car.settings.applications.managedomainurls;
18 
19 import android.app.Application;
20 import android.car.drivingstate.CarUxRestrictions;
21 import android.car.userlib.CarUserManagerHelper;
22 import android.content.Context;
23 import android.content.pm.PackageManager;
24 import android.util.ArrayMap;
25 import android.util.IconDrawableFactory;
26 
27 import androidx.annotation.VisibleForTesting;
28 import androidx.lifecycle.Lifecycle;
29 import androidx.preference.Preference;
30 import androidx.preference.PreferenceGroup;
31 
32 import com.android.car.settings.common.FragmentController;
33 import com.android.car.settings.common.PreferenceController;
34 import com.android.car.ui.preference.CarUiPreference;
35 import com.android.settingslib.applications.ApplicationsState;
36 
37 import java.util.ArrayList;
38 
39 /** Business logic to populate the list of apps that deal with domain urls. */
40 public class DomainAppPreferenceController extends PreferenceController<PreferenceGroup> {
41 
42     private final ApplicationsState mApplicationsState;
43     private final PackageManager mPm;
44     private final CarUserManagerHelper mCarUserManagerHelper;
45 
46     @VisibleForTesting
47     final ApplicationsState.Callbacks mApplicationStateCallbacks =
48             new ApplicationsState.Callbacks() {
49                 @Override
50                 public void onRunningStateChanged(boolean running) {
51                 }
52 
53                 @Override
54                 public void onPackageListChanged() {
55                 }
56 
57                 @Override
58                 public void onRebuildComplete(ArrayList<ApplicationsState.AppEntry> apps) {
59                     rebuildAppList(apps);
60                 }
61 
62                 @Override
63                 public void onPackageIconChanged() {
64                 }
65 
66                 @Override
67                 public void onPackageSizeChanged(String packageName) {
68                 }
69 
70                 @Override
71                 public void onAllSizesComputed() {
72                 }
73 
74                 @Override
75                 public void onLauncherInfoChanged() {
76                 }
77 
78                 @Override
79                 public void onLoadEntriesCompleted() {
80                     mSession.rebuild(ApplicationsState.FILTER_WITH_DOMAIN_URLS,
81                             ApplicationsState.ALPHA_COMPARATOR);
82                 }
83             };
84 
85     private ApplicationsState.Session mSession;
86     private ArrayMap<String, Preference> mPreferenceCache;
87 
DomainAppPreferenceController(Context context, String preferenceKey, FragmentController fragmentController, CarUxRestrictions uxRestrictions)88     public DomainAppPreferenceController(Context context, String preferenceKey,
89             FragmentController fragmentController, CarUxRestrictions uxRestrictions) {
90         super(context, preferenceKey, fragmentController, uxRestrictions);
91         mApplicationsState = ApplicationsState.getInstance(
92                 (Application) context.getApplicationContext());
93         mPm = context.getPackageManager();
94         mCarUserManagerHelper = new CarUserManagerHelper(context);
95     }
96 
97     @Override
getPreferenceType()98     protected Class<PreferenceGroup> getPreferenceType() {
99         return PreferenceGroup.class;
100     }
101 
102     @Override
checkInitialized()103     protected void checkInitialized() {
104         if (mSession == null) {
105             throw new IllegalStateException("session should be non null by this point");
106         }
107     }
108 
109     /** Sets the lifecycle to create a new session. */
setLifecycle(Lifecycle lifecycle)110     public void setLifecycle(Lifecycle lifecycle) {
111         mSession = mApplicationsState.newSession(mApplicationStateCallbacks, lifecycle);
112     }
113 
114     @Override
onStartInternal()115     protected void onStartInternal() {
116         // Resume the session earlier than the lifecycle so that cached information is updated
117         // even if settings is not resumed (for example in multi-display).
118         mSession.onResume();
119     }
120 
121     @Override
onStopInternal()122     protected void onStopInternal() {
123         // Since we resume early in onStart, make sure we clean up even if we don't receive onPause.
124         mSession.onPause();
125     }
126 
rebuildAppList(ArrayList<ApplicationsState.AppEntry> apps)127     private void rebuildAppList(ArrayList<ApplicationsState.AppEntry> apps) {
128         PreferenceGroup preferenceGroup = getPreference();
129         preferenceGroup.removeAll();
130         for (int i = 0; i < apps.size(); i++) {
131             ApplicationsState.AppEntry entry = apps.get(i);
132             preferenceGroup.addPreference(createPreference(entry));
133         }
134     }
135 
createPreference(ApplicationsState.AppEntry entry)136     private Preference createPreference(ApplicationsState.AppEntry entry) {
137         String key = entry.info.packageName + "|" + entry.info.uid;
138         IconDrawableFactory iconDrawableFactory = IconDrawableFactory.newInstance(getContext());
139         CarUiPreference preference = new CarUiPreference(getContext());
140         preference.setKey(key);
141         preference.setTitle(entry.label);
142         preference.setSummary(
143                 DomainUrlsUtils.getDomainsSummary(getContext(), entry.info.packageName,
144                         mCarUserManagerHelper.getCurrentProcessUserId(),
145                         DomainUrlsUtils.getHandledDomains(mPm, entry.info.packageName)));
146         preference.setIcon(iconDrawableFactory.getBadgedIcon(entry.info));
147         preference.setOnPreferenceClickListener(pref -> {
148             getFragmentController().launchFragment(
149                     ApplicationLaunchSettingsFragment.newInstance(entry.info.packageName));
150             return true;
151         });
152         return preference;
153     }
154 }
155