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         super(context, preferenceKey, fragmentController, uxRestrictions);
88         mApplicationsState = ApplicationsState.getInstance(
89                 (Application) context.getApplicationContext());
90         mPm = context.getPackageManager();
91     }
92 
93     @Override
getPreferenceType()94     protected Class<PreferenceGroup> getPreferenceType() {
95         return PreferenceGroup.class;
96     }
97 
98     @Override
checkInitialized()99     protected void checkInitialized() {
100         if (mSession == null) {
101             throw new IllegalStateException("session should be non null by this point");
102         }
103     }
104 
105     /** Sets the lifecycle to create a new session. */
setLifecycle(Lifecycle lifecycle)106     public void setLifecycle(Lifecycle lifecycle) {
107         mSession = mApplicationsState.newSession(mApplicationStateCallbacks, lifecycle);
108     }
109 
110     @Override
onStartInternal()111     protected void onStartInternal() {
112         // Resume the session earlier than the lifecycle so that cached information is updated
113         // even if settings is not resumed (for example in multi-display).
114         mSession.onResume();
115     }
116 
117     @Override
onStopInternal()118     protected void onStopInternal() {
119         // Since we resume early in onStart, make sure we clean up even if we don't receive onPause.
120         mSession.onPause();
121     }
122 
rebuildAppList(ArrayList<ApplicationsState.AppEntry> apps)123     private void rebuildAppList(ArrayList<ApplicationsState.AppEntry> apps) {
124         PreferenceGroup preferenceGroup = getPreference();
125         preferenceGroup.removeAll();
126         for (int i = 0; i < apps.size(); i++) {
127             ApplicationsState.AppEntry entry = apps.get(i);
128             preferenceGroup.addPreference(createPreference(entry));
129         }
130     }
131 
createPreference(ApplicationsState.AppEntry entry)132     private Preference createPreference(ApplicationsState.AppEntry entry) {
133         String key = entry.info.packageName + "|" + entry.info.uid;
134         IconDrawableFactory iconDrawableFactory = IconDrawableFactory.newInstance(getContext());
135         CarUiPreference preference = new CarUiPreference(getContext());
136         preference.setKey(key);
137         preference.setTitle(entry.label);
138         preference.setSummary(
139                 DomainUrlsUtils.getDomainsSummary(getContext(), entry.info.packageName,
140                         UserHandle.myUserId(),
141                         DomainUrlsUtils.getHandledDomains(mPm, entry.info.packageName)));
142         preference.setIcon(iconDrawableFactory.getBadgedIcon(entry.info));
143         preference.setOnPreferenceClickListener(pref -> {
144             getFragmentController().launchFragment(
145                     ApplicationLaunchSettingsFragment.newInstance(entry.info.packageName));
146             return true;
147         });
148         return preference;
149     }
150 }
151