• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022 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.location;
18 
19 import android.car.drivingstate.CarUxRestrictions;
20 import android.content.Context;
21 
22 import androidx.preference.PreferenceCategory;
23 
24 import com.android.car.settings.R;
25 import com.android.car.settings.common.FragmentController;
26 import com.android.car.ui.preference.CarUiPreference;
27 import com.android.internal.annotations.VisibleForTesting;
28 import com.android.settingslib.applications.RecentAppOpsAccess;
29 
30 import java.util.HashSet;
31 import java.util.List;
32 import java.util.Set;
33 
34 /**
35  * This controller displays a list of apps that recently access the location. Driver assistance apps
36  * are also included.
37  */
38 public class LocationRecentAccessesPreferenceController
39         extends LocationStateListenerBasePreferenceController<PreferenceCategory> {
40 
41     private final Set<CarUiPreference> mAddedPreferences = new HashSet<>();
42 
43     private final RecentAppOpsAccess mRecentLocationAccesses;
44     private final int mRecentAppsMaxCount;
45 
LocationRecentAccessesPreferenceController( Context context, String preferenceKey, FragmentController fragmentController, CarUxRestrictions uxRestrictions)46     public LocationRecentAccessesPreferenceController(
47             Context context,
48             String preferenceKey,
49             FragmentController fragmentController,
50             CarUxRestrictions uxRestrictions) {
51         this(
52                 context,
53                 preferenceKey,
54                 fragmentController,
55                 uxRestrictions,
56                 RecentAppOpsAccess.createForLocation(context),
57                 context.getResources().getInteger(
58                         R.integer.recent_location_access_apps_list_count));
59     }
60 
61     @VisibleForTesting
LocationRecentAccessesPreferenceController( Context context, String preferenceKey, FragmentController fragmentController, CarUxRestrictions uxRestrictions, RecentAppOpsAccess recentLocationAccesses, int recentAppsMaxCount)62     LocationRecentAccessesPreferenceController(
63             Context context,
64             String preferenceKey,
65             FragmentController fragmentController,
66             CarUxRestrictions uxRestrictions,
67             RecentAppOpsAccess recentLocationAccesses,
68             int recentAppsMaxCount) {
69         super(context, preferenceKey, fragmentController, uxRestrictions);
70         mRecentLocationAccesses = recentLocationAccesses;
71         mRecentAppsMaxCount = recentAppsMaxCount;
72     }
73 
74     @Override
getPreferenceType()75     protected Class<PreferenceCategory> getPreferenceType() {
76         return PreferenceCategory.class;
77     }
78 
79     @Override
onCreateInternal()80     protected void onCreateInternal() {
81         if (LocationUtil.isDriverWithAdasApps(getContext())) {
82             addDefaultBypassLocationStateListener();
83         }
84         addDefaultMainLocationStateListener();
85     }
86 
87     @Override
updateState(PreferenceCategory preference)88     protected void updateState(PreferenceCategory preference) {
89         boolean isVisible = getVisibility();
90         preference.setVisible(isVisible);
91         if (isVisible) {
92             updateUi(loadData());
93         }
94     }
95 
getVisibility()96     private boolean getVisibility() {
97         boolean isVisible = getLocationManager().isLocationEnabled();
98         if (LocationUtil.isDriverWithAdasApps(getContext())) {
99             isVisible = isVisible || getLocationManager().isAdasGnssLocationEnabled();
100         }
101         return isVisible;
102     }
103 
loadData()104     private List<RecentAppOpsAccess.Access> loadData() {
105         return mRecentLocationAccesses.getAppListSorted(/* showSystem= */ false);
106     }
107 
hasAtLeastOneRecentAppAccess()108     private boolean hasAtLeastOneRecentAppAccess() {
109         return !mRecentLocationAccesses.getAppListSorted(/* showSystem= */ true).isEmpty();
110     }
111 
updateUi(List<RecentAppOpsAccess.Access> sortedRecentLocationAccesses)112     private void updateUi(List<RecentAppOpsAccess.Access> sortedRecentLocationAccesses) {
113         // remove any already added preferences
114         for (CarUiPreference addedPreference : mAddedPreferences) {
115             getPreference().removePreference(addedPreference);
116         }
117         mAddedPreferences.clear();
118 
119         if (sortedRecentLocationAccesses.isEmpty()) {
120             CarUiPreference emptyPreference = createNoRecentAccessPreference();
121             getPreference().addPreference(emptyPreference);
122             mAddedPreferences.add(emptyPreference);
123         } else {
124             int count = Math.min(sortedRecentLocationAccesses.size(), mRecentAppsMaxCount);
125             for (int i = 0; i < count; i++) {
126                 RecentAppOpsAccess.Access request = sortedRecentLocationAccesses.get(i);
127                 CarUiPreference appPreference =
128                         LocationRecentAccessUtil.createAppPreference(getContext(), request);
129                 getPreference().addPreference(appPreference);
130                 mAddedPreferences.add(appPreference);
131             }
132         }
133 
134         if (hasAtLeastOneRecentAppAccess()) {
135             CarUiPreference viewAllPreference = createViewAllPreference();
136             getPreference().addPreference(viewAllPreference);
137             mAddedPreferences.add(viewAllPreference);
138         }
139     }
140 
createNoRecentAccessPreference()141     private CarUiPreference createNoRecentAccessPreference() {
142         CarUiPreference preference = new CarUiPreference(getContext());
143         preference.setTitle(R.string.location_no_recent_access);
144         preference.setSelectable(false);
145         return preference;
146     }
147 
createViewAllPreference()148     private CarUiPreference createViewAllPreference() {
149         CarUiPreference preference = new CarUiPreference(getContext());
150         preference.setTitle(R.string.location_settings_recently_accessed_view_all_title);
151         preference.setIcon(R.drawable.ic_apps);
152         preference.setOnPreferenceClickListener(
153                 p -> {
154                     getFragmentController()
155                             .launchFragment(new LocationRecentAccessViewAllFragment());
156                     return true;
157                 });
158         return preference;
159     }
160 }
161