1 /*
2  * Copyright (C) 2017 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
5  * except in compliance with the License. You may obtain a copy of the License at
6  *
7  *      http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software distributed under the
10  * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
11  * KIND, either express or implied. See the License for the specific language governing
12  * permissions and limitations under the License.
13  */
14 package com.android.settings.location;
15 
16 import android.content.Context;
17 import android.os.Bundle;
18 import android.os.UserHandle;
19 import android.os.UserManager;
20 
21 import androidx.annotation.VisibleForTesting;
22 import androidx.preference.Preference;
23 import androidx.preference.PreferenceCategory;
24 import androidx.preference.PreferenceScreen;
25 
26 import com.android.settings.R;
27 import com.android.settings.applications.appinfo.AppInfoDashboardFragment;
28 import com.android.settings.core.SubSettingLauncher;
29 import com.android.settings.dashboard.DashboardFragment;
30 import com.android.settings.dashboard.profileselector.ProfileSelectFragment;
31 import com.android.settingslib.location.RecentLocationApps;
32 import com.android.settingslib.widget.AppPreference;
33 
34 import java.util.ArrayList;
35 import java.util.List;
36 
37 public class RecentLocationRequestPreferenceController extends LocationBasePreferenceController {
38 
39     public static final int MAX_APPS = 3;
40     @VisibleForTesting
41     RecentLocationApps mRecentLocationApps;
42     private PreferenceCategory mCategoryRecentLocationRequests;
43     private int mType = ProfileSelectFragment.ProfileType.ALL;
44 
45     /** Used in this class and {@link RecentLocationRequestSeeAllPreferenceController} */
46     static class PackageEntryClickedListener implements Preference.OnPreferenceClickListener {
47         private final DashboardFragment mFragment;
48         private final String mPackage;
49         private final UserHandle mUserHandle;
50 
PackageEntryClickedListener(DashboardFragment fragment, String packageName, UserHandle userHandle)51         public PackageEntryClickedListener(DashboardFragment fragment, String packageName,
52                 UserHandle userHandle) {
53             mFragment = fragment;
54             mPackage = packageName;
55             mUserHandle = userHandle;
56         }
57 
58         @Override
onPreferenceClick(Preference preference)59         public boolean onPreferenceClick(Preference preference) {
60             // start new fragment to display extended information
61             final Bundle args = new Bundle();
62             args.putString(AppInfoDashboardFragment.ARG_PACKAGE_NAME, mPackage);
63             new SubSettingLauncher(mFragment.getContext())
64                     .setDestination(AppInfoDashboardFragment.class.getName())
65                     .setArguments(args)
66                     .setTitleRes(R.string.application_info_label)
67                     .setUserHandle(mUserHandle)
68                     .setSourceMetricsCategory(mFragment.getMetricsCategory())
69                     .launch();
70             return true;
71         }
72     }
73 
RecentLocationRequestPreferenceController(Context context, String key)74     public RecentLocationRequestPreferenceController(Context context, String key) {
75         super(context, key);
76         mRecentLocationApps = new RecentLocationApps(context);
77     }
78 
79     @Override
displayPreference(PreferenceScreen screen)80     public void displayPreference(PreferenceScreen screen) {
81         super.displayPreference(screen);
82         mCategoryRecentLocationRequests = screen.findPreference(getPreferenceKey());
83         final Context prefContext = mCategoryRecentLocationRequests.getContext();
84         final List<RecentLocationApps.Request> recentLocationRequests = new ArrayList<>();
85         final UserManager userManager = UserManager.get(mContext);
86         for (RecentLocationApps.Request request : mRecentLocationApps.getAppListSorted(
87                 false /* systemApps */)) {
88             if (isRequestMatchesProfileType(userManager, request, mType)) {
89                 recentLocationRequests.add(request);
90                 if (recentLocationRequests.size() == MAX_APPS) {
91                     break;
92                 }
93             }
94         }
95 
96         if (recentLocationRequests.size() > 0) {
97             // Add preferences to container in original order (already sorted by recency).
98             for (RecentLocationApps.Request request : recentLocationRequests) {
99                 mCategoryRecentLocationRequests.addPreference(
100                         createAppPreference(prefContext, request, mFragment));
101             }
102         } else {
103             // If there's no item to display, add a "No recent apps" item.
104             final Preference banner = new AppPreference(prefContext);
105             banner.setTitle(R.string.location_no_recent_apps);
106             banner.setSelectable(false);
107             mCategoryRecentLocationRequests.addPreference(banner);
108         }
109     }
110 
111     @Override
onLocationModeChanged(int mode, boolean restricted)112     public void onLocationModeChanged(int mode, boolean restricted) {
113         mCategoryRecentLocationRequests.setEnabled(mLocationEnabler.isEnabled(mode));
114     }
115 
116     /**
117      * Initialize {@link ProfileSelectFragment.ProfileType} of the controller
118      *
119      * @param type {@link ProfileSelectFragment.ProfileType} of the controller.
120      */
setProfileType(@rofileSelectFragment.ProfileType int type)121     public void setProfileType(@ProfileSelectFragment.ProfileType int type) {
122         mType = type;
123     }
124 
125     /**
126      * Create a {@link AppPreference}
127      */
createAppPreference(Context prefContext, RecentLocationApps.Request request, DashboardFragment fragment)128     public static AppPreference createAppPreference(Context prefContext,
129             RecentLocationApps.Request request, DashboardFragment fragment) {
130         final AppPreference pref = new AppPreference(prefContext);
131         pref.setIcon(request.icon);
132         pref.setTitle(request.label);
133         pref.setOnPreferenceClickListener(new PackageEntryClickedListener(
134                 fragment, request.packageName, request.userHandle));
135         return pref;
136     }
137 
138     /**
139      * Return if the {@link RecentLocationApps.Request} matches current UI
140      * {@ProfileSelectFragment.ProfileType}
141      */
isRequestMatchesProfileType(UserManager userManager, RecentLocationApps.Request request, @ProfileSelectFragment.ProfileType int type)142     public static boolean isRequestMatchesProfileType(UserManager userManager,
143             RecentLocationApps.Request request, @ProfileSelectFragment.ProfileType int type) {
144         final boolean isWorkProfile = userManager.isManagedProfile(
145                 request.userHandle.getIdentifier());
146         if (isWorkProfile && (type & ProfileSelectFragment.ProfileType.WORK) != 0) {
147             return true;
148         }
149         if (!isWorkProfile && (type & ProfileSelectFragment.ProfileType.PERSONAL) != 0) {
150             return true;
151         }
152         return false;
153     }
154 }
155