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