• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 import android.provider.DeviceConfig;
21 import android.provider.Settings;
22 
23 import androidx.annotation.VisibleForTesting;
24 import androidx.preference.Preference;
25 import androidx.preference.PreferenceCategory;
26 import androidx.preference.PreferenceScreen;
27 
28 import com.android.internal.config.sysui.SystemUiDeviceConfigFlags;
29 import com.android.settings.R;
30 import com.android.settings.applications.appinfo.AppInfoDashboardFragment;
31 import com.android.settings.core.SubSettingLauncher;
32 import com.android.settings.dashboard.DashboardFragment;
33 import com.android.settings.dashboard.profileselector.ProfileSelectFragment;
34 import com.android.settingslib.location.RecentLocationApps;
35 import com.android.settingslib.widget.AppPreference;
36 
37 import java.util.ArrayList;
38 import java.util.List;
39 
40 public class RecentLocationRequestPreferenceController extends LocationBasePreferenceController {
41 
42     public static final int MAX_APPS = 3;
43     @VisibleForTesting
44     RecentLocationApps mRecentLocationApps;
45     private PreferenceCategory mCategoryRecentLocationRequests;
46     private int mType = ProfileSelectFragment.ProfileType.ALL;
47 
48     /** Used in this class and {@link RecentLocationRequestSeeAllPreferenceController} */
49     static class PackageEntryClickedListener implements Preference.OnPreferenceClickListener {
50         private final DashboardFragment mFragment;
51         private final String mPackage;
52         private final UserHandle mUserHandle;
53 
PackageEntryClickedListener(DashboardFragment fragment, String packageName, UserHandle userHandle)54         public PackageEntryClickedListener(DashboardFragment fragment, String packageName,
55                 UserHandle userHandle) {
56             mFragment = fragment;
57             mPackage = packageName;
58             mUserHandle = userHandle;
59         }
60 
61         @Override
onPreferenceClick(Preference preference)62         public boolean onPreferenceClick(Preference preference) {
63             // start new fragment to display extended information
64             final Bundle args = new Bundle();
65             args.putString(AppInfoDashboardFragment.ARG_PACKAGE_NAME, mPackage);
66             new SubSettingLauncher(mFragment.getContext())
67                     .setDestination(AppInfoDashboardFragment.class.getName())
68                     .setArguments(args)
69                     .setTitleRes(R.string.application_info_label)
70                     .setUserHandle(mUserHandle)
71                     .setSourceMetricsCategory(mFragment.getMetricsCategory())
72                     .launch();
73             return true;
74         }
75     }
76 
RecentLocationRequestPreferenceController(Context context, String key)77     public RecentLocationRequestPreferenceController(Context context, String key) {
78         super(context, key);
79         mRecentLocationApps = new RecentLocationApps(context);
80     }
81 
82     @Override
displayPreference(PreferenceScreen screen)83     public void displayPreference(PreferenceScreen screen) {
84         super.displayPreference(screen);
85         mCategoryRecentLocationRequests = screen.findPreference(getPreferenceKey());
86         final Context prefContext = mCategoryRecentLocationRequests.getContext();
87         final List<RecentLocationApps.Request> recentLocationRequests = new ArrayList<>();
88         final UserManager userManager = UserManager.get(mContext);
89         final boolean showSystem = DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_PRIVACY,
90                 SystemUiDeviceConfigFlags.PROPERTY_LOCATION_INDICATORS_SMALL_ENABLED, false)
91                 ? Settings.Secure.getInt(mContext.getContentResolver(),
92                 Settings.Secure.LOCATION_SHOW_SYSTEM_OPS, 0) == 1
93                 : false;
94 
95         for (RecentLocationApps.Request request : mRecentLocationApps.getAppListSorted(
96                 showSystem)) {
97             if (isRequestMatchesProfileType(userManager, request, mType)) {
98                 recentLocationRequests.add(request);
99                 if (recentLocationRequests.size() == MAX_APPS) {
100                     break;
101                 }
102             }
103         }
104 
105         if (recentLocationRequests.size() > 0) {
106             // Add preferences to container in original order (already sorted by recency).
107             for (RecentLocationApps.Request request : recentLocationRequests) {
108                 mCategoryRecentLocationRequests.addPreference(
109                         createAppPreference(prefContext, request, mFragment));
110             }
111         } else {
112             // If there's no item to display, add a "No recent apps" item.
113             final Preference banner = new AppPreference(prefContext);
114             banner.setTitle(R.string.location_no_recent_apps);
115             banner.setSelectable(false);
116             mCategoryRecentLocationRequests.addPreference(banner);
117         }
118     }
119 
120     @Override
onLocationModeChanged(int mode, boolean restricted)121     public void onLocationModeChanged(int mode, boolean restricted) {
122         mCategoryRecentLocationRequests.setEnabled(mLocationEnabler.isEnabled(mode));
123     }
124 
125     /**
126      * Initialize {@link ProfileSelectFragment.ProfileType} of the controller
127      *
128      * @param type {@link ProfileSelectFragment.ProfileType} of the controller.
129      */
setProfileType(@rofileSelectFragment.ProfileType int type)130     public void setProfileType(@ProfileSelectFragment.ProfileType int type) {
131         mType = type;
132     }
133 
134     /**
135      * Create a {@link AppPreference}
136      */
createAppPreference(Context prefContext, RecentLocationApps.Request request, DashboardFragment fragment)137     public static AppPreference createAppPreference(Context prefContext,
138             RecentLocationApps.Request request, DashboardFragment fragment) {
139         final AppPreference pref = new AppPreference(prefContext);
140         pref.setIcon(request.icon);
141         pref.setTitle(request.label);
142         pref.setOnPreferenceClickListener(new PackageEntryClickedListener(
143                 fragment, request.packageName, request.userHandle));
144         return pref;
145     }
146 
147     /**
148      * Return if the {@link RecentLocationApps.Request} matches current UI
149      * {@ProfileSelectFragment.ProfileType}
150      */
isRequestMatchesProfileType(UserManager userManager, RecentLocationApps.Request request, @ProfileSelectFragment.ProfileType int type)151     public static boolean isRequestMatchesProfileType(UserManager userManager,
152             RecentLocationApps.Request request, @ProfileSelectFragment.ProfileType int type) {
153         final boolean isWorkProfile = userManager.isManagedProfile(
154                 request.userHandle.getIdentifier());
155         if (isWorkProfile && (type & ProfileSelectFragment.ProfileType.WORK) != 0) {
156             return true;
157         }
158         if (!isWorkProfile && (type & ProfileSelectFragment.ProfileType.PERSONAL) != 0) {
159             return true;
160         }
161         return false;
162     }
163 }
164