1 package com.android.car.developeroptions.location; 2 3 import static android.Manifest.permission.ACCESS_COARSE_LOCATION; 4 import static android.Manifest.permission.ACCESS_FINE_LOCATION; 5 6 import android.content.BroadcastReceiver; 7 import android.content.Context; 8 import android.content.Intent; 9 import android.content.IntentFilter; 10 import android.location.LocationManager; 11 import android.permission.PermissionControllerManager; 12 13 import androidx.annotation.VisibleForTesting; 14 import androidx.preference.Preference; 15 16 import com.android.car.developeroptions.R; 17 import com.android.car.developeroptions.core.BasePreferenceController; 18 import com.android.settingslib.core.lifecycle.LifecycleObserver; 19 import com.android.settingslib.core.lifecycle.events.OnStart; 20 import com.android.settingslib.core.lifecycle.events.OnStop; 21 22 import java.util.Arrays; 23 24 public class TopLevelLocationPreferenceController extends BasePreferenceController implements 25 LifecycleObserver, OnStart, OnStop { 26 private static final IntentFilter INTENT_FILTER_LOCATION_MODE_CHANGED = 27 new IntentFilter(LocationManager.MODE_CHANGED_ACTION); 28 private final LocationManager mLocationManager; 29 /** Total number of apps that has location permission. */ 30 private int mNumTotal = -1; 31 private BroadcastReceiver mReceiver; 32 private Preference mPreference; 33 TopLevelLocationPreferenceController(Context context, String preferenceKey)34 public TopLevelLocationPreferenceController(Context context, String preferenceKey) { 35 super(context, preferenceKey); 36 mLocationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE); 37 } 38 39 @Override getAvailabilityStatus()40 public int getAvailabilityStatus() { 41 return AVAILABLE; 42 } 43 44 @Override getSummary()45 public CharSequence getSummary() { 46 if (mLocationManager.isLocationEnabled()) { 47 if (mNumTotal == -1) { 48 return mContext.getString(R.string.location_settings_loading_app_permission_stats); 49 } 50 return mContext.getResources().getQuantityString( 51 R.plurals.location_settings_summary_location_on, 52 mNumTotal, mNumTotal); 53 } else { 54 return mContext.getString(R.string.location_settings_summary_location_off); 55 } 56 } 57 58 @VisibleForTesting setLocationAppCount(int numApps)59 void setLocationAppCount(int numApps) { 60 mNumTotal = numApps; 61 refreshSummary(mPreference); 62 } 63 64 @Override updateState(Preference preference)65 public void updateState(Preference preference) { 66 super.updateState(preference); 67 mPreference = preference; 68 refreshSummary(preference); 69 // Bail out if location has been disabled. 70 if (!mLocationManager.isLocationEnabled()) { 71 return; 72 } 73 mContext.getSystemService(PermissionControllerManager.class).countPermissionApps( 74 Arrays.asList(ACCESS_FINE_LOCATION, ACCESS_COARSE_LOCATION), 0, 75 (numApps) -> { 76 setLocationAppCount(numApps); 77 }, null); 78 } 79 80 @Override onStart()81 public void onStart() { 82 if (mReceiver == null) { 83 mReceiver = new BroadcastReceiver() { 84 @Override 85 public void onReceive(Context context, Intent intent) { 86 refreshLocationMode(); 87 } 88 }; 89 } 90 mContext.registerReceiver(mReceiver, INTENT_FILTER_LOCATION_MODE_CHANGED); 91 refreshLocationMode(); 92 } 93 94 @Override onStop()95 public void onStop() { 96 mContext.unregisterReceiver(mReceiver); 97 } 98 refreshLocationMode()99 private void refreshLocationMode() { 100 // 'null' is checked inside updateState(), so no need to check here. 101 updateState(mPreference); 102 } 103 } 104