Loading src/com/android/permissioncontroller/permission/data/AppPermGroupUiInfoLiveData.kt +32 −6 Original line number Diff line number Diff line Loading @@ -51,13 +51,18 @@ class AppPermGroupUiInfoLiveData private constructor( private val packageName: String, private val permGroupName: String, private val user: UserHandle ) : SmartUpdateMediatorLiveData<AppPermGroupUiInfo>() { ) : SmartUpdateMediatorLiveData<AppPermGroupUiInfo>(), LocationUtils.LocationListener { private var isSpecialLocation = false private val packageInfoLiveData = LightPackageInfoLiveData[packageName, user] private val permGroupLiveData = PermGroupLiveData[permGroupName] private val permissionStateLiveData = PermStateLiveData[packageName, permGroupName, user] init { isSpecialLocation = LocationUtils.isLocationGroupAndProvider(app, permGroupName, packageName) || LocationUtils.isLocationGroupAndControllerExtraPackage(app, permGroupName, packageName) addSource(packageInfoLiveData) { updateIfActive() } Loading Loading @@ -157,7 +162,7 @@ class AppPermGroupUiInfoLiveData private constructor( } if (groupInfo.packageName == Utils.OS_PKG && !Utils.isModernPermissionGroup(groupInfo.name)) { !isModernPermissionGroup(groupInfo.name)) { return false } return true Loading Loading @@ -212,6 +217,7 @@ class AppPermGroupUiInfoLiveData private constructor( allPermInfos: Map<String, LightPermInfo>, packageName: String ): PermGrantState { val specialLocationState = getIsSpecialLocationState() var hasPermWithBackground = false var isUserFixed = false Loading @@ -220,7 +226,8 @@ class AppPermGroupUiInfoLiveData private constructor( val permInfo = allPermInfos[permName] ?: continue permInfo.backgroundPermission?.let { backgroundPerm -> hasPermWithBackground = true if (permissionState[backgroundPerm]?.granted == true) { if (permissionState[backgroundPerm]?.granted == true && specialLocationState != false) { return PermGrantState.PERMS_ALLOWED_ALWAYS } } Loading @@ -230,7 +237,7 @@ class AppPermGroupUiInfoLiveData private constructor( permState.permFlags and PackageManager.FLAG_PERMISSION_ONE_TIME != 0 } val anyAllowed = getIsSpecialLocationState() ?: permissionState.any { it.value.granted } val anyAllowed = specialLocationState ?: permissionState.any { it.value.granted } if (anyAllowed && (hasPermWithBackground || shouldShowAsForegroundGroup())) { if (isOneTime) { return PermGrantState.PERMS_ASK Loading Loading @@ -259,8 +266,7 @@ class AppPermGroupUiInfoLiveData private constructor( private fun getIsSpecialLocationState(): Boolean? { val userContext = Utils.getUserContext(app, user) if (LocationUtils.isLocationGroupAndProvider(userContext, permGroupName, packageName)) { if (isSpecialLocation) { return LocationUtils.isLocationEnabled(userContext) } // The permission of the extra location controller package is determined by the Loading @@ -278,6 +284,26 @@ class AppPermGroupUiInfoLiveData private constructor( permGroupName.equals(Manifest.permission_group.MICROPHONE) } override fun onLocationStateChange(enabled: Boolean) { updateIfActive() } override fun onActive() { super.onActive() if (isSpecialLocation) { LocationUtils.addLocationListener(this) } } override fun onInactive() { super.onInactive() if (isSpecialLocation) { LocationUtils.removeLocationListener(this) } } /** * Repository for AppPermGroupUiInfoLiveDatas. * <p> Key value is a triple of string package name, string permission group name, and UserHandle, Loading src/com/android/permissioncontroller/permission/data/LightAppPermGroupLiveData.kt +27 −3 Original line number Diff line number Diff line Loading @@ -28,7 +28,6 @@ import com.android.permissioncontroller.permission.model.livedatatypes.LightAppP import com.android.permissioncontroller.permission.model.livedatatypes.LightPackageInfo import com.android.permissioncontroller.permission.model.livedatatypes.LightPermission import com.android.permissioncontroller.permission.utils.LocationUtils import com.android.permissioncontroller.permission.utils.SoftRestrictedPermissionPolicy import com.android.permissioncontroller.permission.utils.Utils import com.android.permissioncontroller.permission.utils.Utils.OS_PKG Loading @@ -45,16 +44,21 @@ class LightAppPermGroupLiveData private constructor( private val packageName: String, private val permGroupName: String, private val user: UserHandle ) : SmartUpdateMediatorLiveData<LightAppPermGroup?>() { ) : SmartUpdateMediatorLiveData<LightAppPermGroup?>(), LocationUtils.LocationListener { val LOG_TAG = this::class.java.simpleName private var isSpecialLocation = false private val permStateLiveData = PermStateLiveData[packageName, permGroupName, user] private val permGroupLiveData = PermGroupLiveData[permGroupName] private val packageInfoLiveData = LightPackageInfoLiveData[packageName, user] private val fgPermNamesLiveData = ForegroundPermNamesLiveData init { isSpecialLocation = LocationUtils.isLocationGroupAndProvider(app, permGroupName, packageName) || LocationUtils.isLocationGroupAndControllerExtraPackage(app, permGroupName, packageName) addSource(fgPermNamesLiveData) { updateIfActive() } Loading Loading @@ -113,7 +117,7 @@ class LightAppPermGroupLiveData private constructor( // Determine if this app permission group is a special location package or provider var specialLocationGrant: Boolean? = null val userContext = Utils.getUserContext(app, user) if (LocationUtils.isLocationGroupAndProvider(userContext, permGroupName, packageName)) { if (isSpecialLocation) { specialLocationGrant = LocationUtils.isLocationEnabled(app) } // The permission of the extra location controller package is determined by the status of Loading Loading @@ -172,6 +176,26 @@ class LightAppPermGroupLiveData private constructor( return false } override fun onLocationStateChange(enabled: Boolean) { updateIfActive() } override fun onActive() { super.onActive() if (isSpecialLocation) { LocationUtils.addLocationListener(this) } } override fun onInactive() { super.onInactive() if (isSpecialLocation) { LocationUtils.removeLocationListener(this) } } /** * Repository for AppPermGroupLiveDatas. * <p> Key value is a triple of string package name, string permission group name, and Loading src/com/android/permissioncontroller/permission/utils/LocationUtils.java +69 −0 Original line number Diff line number Diff line Loading @@ -15,13 +15,17 @@ */ package com.android.permissioncontroller.permission.utils; import static android.location.LocationManager.EXTRA_LOCATION_ENABLED; import android.Manifest; import android.app.AlertDialog; import android.content.ActivityNotFoundException; import android.content.BroadcastReceiver; import android.content.Context; import android.content.DialogInterface; import android.content.DialogInterface.OnClickListener; import android.content.Intent; import android.content.IntentFilter; import android.location.LocationManager; import android.os.UserHandle; import android.provider.Settings; Loading @@ -29,8 +33,11 @@ import android.util.Log; import androidx.annotation.NonNull; import com.android.permissioncontroller.PermissionControllerApplication; import com.android.permissioncontroller.R; import java.util.ArrayList; public class LocationUtils { public static final String LOCATION_PERMISSION = Manifest.permission_group.LOCATION; Loading Loading @@ -94,4 +101,66 @@ public class LocationUtils { } } /** * A Listener which responds to enabling or disabling of location on the device */ public interface LocationListener { /** * A callback run any time we receive a broadcast stating the location enable state has * changed. * @param enabled Whether or not location is enabled */ void onLocationStateChange(boolean enabled); } private static final ArrayList<LocationListener> sLocationListeners = new ArrayList<>(); private static BroadcastReceiver sLocationBroadcastReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { boolean isEnabled = intent.getBooleanExtra(EXTRA_LOCATION_ENABLED, true); synchronized (sLocationListeners) { for (LocationListener l: sLocationListeners) { l.onLocationStateChange(isEnabled); } } } }; /** * Add a LocationListener, which will be notified if the location provider is enabled or * disabled * @param listener the listener to add */ public static void addLocationListener(LocationListener listener) { synchronized (sLocationListeners) { boolean wasEmpty = sLocationListeners.isEmpty(); sLocationListeners.add(listener); if (wasEmpty) { IntentFilter intentFilter = new IntentFilter(LocationManager.MODE_CHANGED_ACTION); PermissionControllerApplication.get().getApplicationContext() .registerReceiverForAllUsers(sLocationBroadcastReceiver, intentFilter, null, null); } } } /** * Remove a LocationListener * @param listener The listener to remove * * @return True if it was successfully removed, false otherwise */ public static boolean removeLocationListener(LocationListener listener) { synchronized (sLocationListeners) { boolean success = sLocationListeners.remove(listener); if (success && sLocationListeners.isEmpty()) { PermissionControllerApplication.get().getApplicationContext() .unregisterReceiver(sLocationBroadcastReceiver); } return success; } } } Loading
src/com/android/permissioncontroller/permission/data/AppPermGroupUiInfoLiveData.kt +32 −6 Original line number Diff line number Diff line Loading @@ -51,13 +51,18 @@ class AppPermGroupUiInfoLiveData private constructor( private val packageName: String, private val permGroupName: String, private val user: UserHandle ) : SmartUpdateMediatorLiveData<AppPermGroupUiInfo>() { ) : SmartUpdateMediatorLiveData<AppPermGroupUiInfo>(), LocationUtils.LocationListener { private var isSpecialLocation = false private val packageInfoLiveData = LightPackageInfoLiveData[packageName, user] private val permGroupLiveData = PermGroupLiveData[permGroupName] private val permissionStateLiveData = PermStateLiveData[packageName, permGroupName, user] init { isSpecialLocation = LocationUtils.isLocationGroupAndProvider(app, permGroupName, packageName) || LocationUtils.isLocationGroupAndControllerExtraPackage(app, permGroupName, packageName) addSource(packageInfoLiveData) { updateIfActive() } Loading Loading @@ -157,7 +162,7 @@ class AppPermGroupUiInfoLiveData private constructor( } if (groupInfo.packageName == Utils.OS_PKG && !Utils.isModernPermissionGroup(groupInfo.name)) { !isModernPermissionGroup(groupInfo.name)) { return false } return true Loading Loading @@ -212,6 +217,7 @@ class AppPermGroupUiInfoLiveData private constructor( allPermInfos: Map<String, LightPermInfo>, packageName: String ): PermGrantState { val specialLocationState = getIsSpecialLocationState() var hasPermWithBackground = false var isUserFixed = false Loading @@ -220,7 +226,8 @@ class AppPermGroupUiInfoLiveData private constructor( val permInfo = allPermInfos[permName] ?: continue permInfo.backgroundPermission?.let { backgroundPerm -> hasPermWithBackground = true if (permissionState[backgroundPerm]?.granted == true) { if (permissionState[backgroundPerm]?.granted == true && specialLocationState != false) { return PermGrantState.PERMS_ALLOWED_ALWAYS } } Loading @@ -230,7 +237,7 @@ class AppPermGroupUiInfoLiveData private constructor( permState.permFlags and PackageManager.FLAG_PERMISSION_ONE_TIME != 0 } val anyAllowed = getIsSpecialLocationState() ?: permissionState.any { it.value.granted } val anyAllowed = specialLocationState ?: permissionState.any { it.value.granted } if (anyAllowed && (hasPermWithBackground || shouldShowAsForegroundGroup())) { if (isOneTime) { return PermGrantState.PERMS_ASK Loading Loading @@ -259,8 +266,7 @@ class AppPermGroupUiInfoLiveData private constructor( private fun getIsSpecialLocationState(): Boolean? { val userContext = Utils.getUserContext(app, user) if (LocationUtils.isLocationGroupAndProvider(userContext, permGroupName, packageName)) { if (isSpecialLocation) { return LocationUtils.isLocationEnabled(userContext) } // The permission of the extra location controller package is determined by the Loading @@ -278,6 +284,26 @@ class AppPermGroupUiInfoLiveData private constructor( permGroupName.equals(Manifest.permission_group.MICROPHONE) } override fun onLocationStateChange(enabled: Boolean) { updateIfActive() } override fun onActive() { super.onActive() if (isSpecialLocation) { LocationUtils.addLocationListener(this) } } override fun onInactive() { super.onInactive() if (isSpecialLocation) { LocationUtils.removeLocationListener(this) } } /** * Repository for AppPermGroupUiInfoLiveDatas. * <p> Key value is a triple of string package name, string permission group name, and UserHandle, Loading
src/com/android/permissioncontroller/permission/data/LightAppPermGroupLiveData.kt +27 −3 Original line number Diff line number Diff line Loading @@ -28,7 +28,6 @@ import com.android.permissioncontroller.permission.model.livedatatypes.LightAppP import com.android.permissioncontroller.permission.model.livedatatypes.LightPackageInfo import com.android.permissioncontroller.permission.model.livedatatypes.LightPermission import com.android.permissioncontroller.permission.utils.LocationUtils import com.android.permissioncontroller.permission.utils.SoftRestrictedPermissionPolicy import com.android.permissioncontroller.permission.utils.Utils import com.android.permissioncontroller.permission.utils.Utils.OS_PKG Loading @@ -45,16 +44,21 @@ class LightAppPermGroupLiveData private constructor( private val packageName: String, private val permGroupName: String, private val user: UserHandle ) : SmartUpdateMediatorLiveData<LightAppPermGroup?>() { ) : SmartUpdateMediatorLiveData<LightAppPermGroup?>(), LocationUtils.LocationListener { val LOG_TAG = this::class.java.simpleName private var isSpecialLocation = false private val permStateLiveData = PermStateLiveData[packageName, permGroupName, user] private val permGroupLiveData = PermGroupLiveData[permGroupName] private val packageInfoLiveData = LightPackageInfoLiveData[packageName, user] private val fgPermNamesLiveData = ForegroundPermNamesLiveData init { isSpecialLocation = LocationUtils.isLocationGroupAndProvider(app, permGroupName, packageName) || LocationUtils.isLocationGroupAndControllerExtraPackage(app, permGroupName, packageName) addSource(fgPermNamesLiveData) { updateIfActive() } Loading Loading @@ -113,7 +117,7 @@ class LightAppPermGroupLiveData private constructor( // Determine if this app permission group is a special location package or provider var specialLocationGrant: Boolean? = null val userContext = Utils.getUserContext(app, user) if (LocationUtils.isLocationGroupAndProvider(userContext, permGroupName, packageName)) { if (isSpecialLocation) { specialLocationGrant = LocationUtils.isLocationEnabled(app) } // The permission of the extra location controller package is determined by the status of Loading Loading @@ -172,6 +176,26 @@ class LightAppPermGroupLiveData private constructor( return false } override fun onLocationStateChange(enabled: Boolean) { updateIfActive() } override fun onActive() { super.onActive() if (isSpecialLocation) { LocationUtils.addLocationListener(this) } } override fun onInactive() { super.onInactive() if (isSpecialLocation) { LocationUtils.removeLocationListener(this) } } /** * Repository for AppPermGroupLiveDatas. * <p> Key value is a triple of string package name, string permission group name, and Loading
src/com/android/permissioncontroller/permission/utils/LocationUtils.java +69 −0 Original line number Diff line number Diff line Loading @@ -15,13 +15,17 @@ */ package com.android.permissioncontroller.permission.utils; import static android.location.LocationManager.EXTRA_LOCATION_ENABLED; import android.Manifest; import android.app.AlertDialog; import android.content.ActivityNotFoundException; import android.content.BroadcastReceiver; import android.content.Context; import android.content.DialogInterface; import android.content.DialogInterface.OnClickListener; import android.content.Intent; import android.content.IntentFilter; import android.location.LocationManager; import android.os.UserHandle; import android.provider.Settings; Loading @@ -29,8 +33,11 @@ import android.util.Log; import androidx.annotation.NonNull; import com.android.permissioncontroller.PermissionControllerApplication; import com.android.permissioncontroller.R; import java.util.ArrayList; public class LocationUtils { public static final String LOCATION_PERMISSION = Manifest.permission_group.LOCATION; Loading Loading @@ -94,4 +101,66 @@ public class LocationUtils { } } /** * A Listener which responds to enabling or disabling of location on the device */ public interface LocationListener { /** * A callback run any time we receive a broadcast stating the location enable state has * changed. * @param enabled Whether or not location is enabled */ void onLocationStateChange(boolean enabled); } private static final ArrayList<LocationListener> sLocationListeners = new ArrayList<>(); private static BroadcastReceiver sLocationBroadcastReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { boolean isEnabled = intent.getBooleanExtra(EXTRA_LOCATION_ENABLED, true); synchronized (sLocationListeners) { for (LocationListener l: sLocationListeners) { l.onLocationStateChange(isEnabled); } } } }; /** * Add a LocationListener, which will be notified if the location provider is enabled or * disabled * @param listener the listener to add */ public static void addLocationListener(LocationListener listener) { synchronized (sLocationListeners) { boolean wasEmpty = sLocationListeners.isEmpty(); sLocationListeners.add(listener); if (wasEmpty) { IntentFilter intentFilter = new IntentFilter(LocationManager.MODE_CHANGED_ACTION); PermissionControllerApplication.get().getApplicationContext() .registerReceiverForAllUsers(sLocationBroadcastReceiver, intentFilter, null, null); } } } /** * Remove a LocationListener * @param listener The listener to remove * * @return True if it was successfully removed, false otherwise */ public static boolean removeLocationListener(LocationListener listener) { synchronized (sLocationListeners) { boolean success = sLocationListeners.remove(listener); if (success && sLocationListeners.isEmpty()) { PermissionControllerApplication.get().getApplicationContext() .unregisterReceiver(sLocationBroadcastReceiver); } return success; } } }