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