Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4b6a8303 authored by Anil Admal's avatar Anil Admal
Browse files

Handle enable/disable of non-framework location attribution apps

Fixes: 130893365
Test: Tested on a Pixel device with Carrier Location attribution app.
Change-Id: I81f619284b6c6329f621451984bcd1041b30a209
parent 81894407
Loading
Loading
Loading
Loading
+39 −27
Original line number Original line Diff line number Diff line
@@ -22,6 +22,7 @@ import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Context;
import android.content.Intent;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.IntentFilter;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager;
import android.os.Handler;
import android.os.Handler;
import android.os.Looper;
import android.os.Looper;
@@ -135,6 +136,7 @@ class GnssVisibilityControl {
        intentFilter.addAction(Intent.ACTION_PACKAGE_ADDED);
        intentFilter.addAction(Intent.ACTION_PACKAGE_ADDED);
        intentFilter.addAction(Intent.ACTION_PACKAGE_REMOVED);
        intentFilter.addAction(Intent.ACTION_PACKAGE_REMOVED);
        intentFilter.addAction(Intent.ACTION_PACKAGE_REPLACED);
        intentFilter.addAction(Intent.ACTION_PACKAGE_REPLACED);
        intentFilter.addAction(Intent.ACTION_PACKAGE_CHANGED);
        intentFilter.addDataScheme("package");
        intentFilter.addDataScheme("package");
        mContext.registerReceiverAsUser(new BroadcastReceiver() {
        mContext.registerReceiverAsUser(new BroadcastReceiver() {
            @Override
            @Override
@@ -148,6 +150,7 @@ class GnssVisibilityControl {
                    case Intent.ACTION_PACKAGE_ADDED:
                    case Intent.ACTION_PACKAGE_ADDED:
                    case Intent.ACTION_PACKAGE_REMOVED:
                    case Intent.ACTION_PACKAGE_REMOVED:
                    case Intent.ACTION_PACKAGE_REPLACED:
                    case Intent.ACTION_PACKAGE_REPLACED:
                    case Intent.ACTION_PACKAGE_CHANGED:
                        String pkgName = intent.getData().getEncodedSchemeSpecificPart();
                        String pkgName = intent.getData().getEncodedSchemeSpecificPart();
                        handleProxyAppPackageUpdate(pkgName, action);
                        handleProxyAppPackageUpdate(pkgName, action);
                        break;
                        break;
@@ -162,10 +165,12 @@ class GnssVisibilityControl {
            return; // ignore, pkgName is not one of the proxy apps in our list.
            return; // ignore, pkgName is not one of the proxy apps in our list.
        }
        }


        Log.i(TAG, "Proxy app " + pkgName + " package changed: " + action);
        if (DEBUG) Log.d(TAG, "Proxy app " + pkgName + " package changed: " + action);
        final boolean updatedLocationPermission = hasLocationPermission(pkgName);
        final boolean updatedLocationPermission = shouldEnableLocationPermissionInGnssHal(pkgName);
        if (locationPermission != updatedLocationPermission) {
        if (locationPermission != updatedLocationPermission) {
            // Permission changed. So, update the GNSS HAL with the updated list.
            // Permission changed. So, update the GNSS HAL with the updated list.
            Log.i(TAG, "Proxy app " + pkgName + " location permission changed."
                    + " IsLocationPermissionEnabled: " + updatedLocationPermission);
            mProxyAppToLocationPermissions.put(pkgName, updatedLocationPermission);
            mProxyAppToLocationPermissions.put(pkgName, updatedLocationPermission);
            updateNfwLocationAccessProxyAppsInGnssHal();
            updateNfwLocationAccessProxyAppsInGnssHal();
        }
        }
@@ -192,8 +197,9 @@ class GnssVisibilityControl {
            mProxyAppToLocationPermissions.clear();
            mProxyAppToLocationPermissions.clear();
        }
        }


        for (String proxApp : nfwLocationAccessProxyApps) {
        for (String proxyAppPkgName : nfwLocationAccessProxyApps) {
            mProxyAppToLocationPermissions.put(proxApp, hasLocationPermission(proxApp));
            mProxyAppToLocationPermissions.put(proxyAppPkgName,
                    shouldEnableLocationPermissionInGnssHal(proxyAppPkgName));
        }
        }


        updateNfwLocationAccessProxyAppsInGnssHal();
        updateNfwLocationAccessProxyAppsInGnssHal();
@@ -308,37 +314,42 @@ class GnssVisibilityControl {
        }
        }


        for (Map.Entry<String, Boolean> entry : mProxyAppToLocationPermissions.entrySet()) {
        for (Map.Entry<String, Boolean> entry : mProxyAppToLocationPermissions.entrySet()) {
            // Cannot cache uid since the application could be uninstalled and reinstalled.
            final String proxyAppPkgName = entry.getKey();
            final String proxyApp = entry.getKey();
            final ApplicationInfo proxyAppInfo = getProxyAppInfo(proxyAppPkgName);
            final Integer nfwProxyAppUid = getApplicationUid(proxyApp);
            if (proxyAppInfo == null || proxyAppInfo.uid != uid) {
            if (nfwProxyAppUid == null || nfwProxyAppUid != uid) {
                continue;
                continue;
            }
            }


            final boolean isLocationPermissionEnabled = hasLocationPermission(proxyApp);
            final boolean isLocationPermissionEnabled = shouldEnableLocationPermissionInGnssHal(
                    proxyAppPkgName);
            if (isLocationPermissionEnabled != entry.getValue()) {
            if (isLocationPermissionEnabled != entry.getValue()) {
                Log.i(TAG, "Location permission setting is changed to "
                Log.i(TAG, "Proxy app " + proxyAppPkgName + " location permission changed."
                        + (isLocationPermissionEnabled ? "enabled" : "disabled")
                        + " IsLocationPermissionEnabled: " + isLocationPermissionEnabled);
                        + " for non-framework location access proxy app "
                        + proxyApp);
                entry.setValue(isLocationPermissionEnabled);
                entry.setValue(isLocationPermissionEnabled);
                updateNfwLocationAccessProxyAppsInGnssHal();
                updateNfwLocationAccessProxyAppsInGnssHal();
                return;
            }
            }
            return;
        }
        }
    }
    }


    private Integer getApplicationUid(String pkgName) {
    private ApplicationInfo getProxyAppInfo(String proxyAppPkgName) {
        try {
        try {
            return mPackageManager.getApplicationInfo(pkgName, 0).uid;
            return mPackageManager.getApplicationInfo(proxyAppPkgName, 0);
        } catch (PackageManager.NameNotFoundException e) {
        } catch (PackageManager.NameNotFoundException e) {
            if (DEBUG) {
            if (DEBUG) Log.d(TAG, "Proxy app " + proxyAppPkgName + " is not found.");
                Log.d(TAG, "Non-framework location access proxy app " + pkgName + " is not found.");
            }
            return null;
            return null;
        }
        }
    }
    }


    private boolean shouldEnableLocationPermissionInGnssHal(String proxyAppPkgName) {
        return isProxyAppInstalled(proxyAppPkgName) && hasLocationPermission(proxyAppPkgName);
    }

    private boolean isProxyAppInstalled(String pkgName) {
        ApplicationInfo proxyAppInfo = getProxyAppInfo(pkgName);
        return (proxyAppInfo != null) && proxyAppInfo.enabled;
    }

    private boolean hasLocationPermission(String pkgName) {
    private boolean hasLocationPermission(String pkgName) {
        return mPackageManager.checkPermission(LOCATION_PERMISSION_NAME, pkgName)
        return mPackageManager.checkPermission(LOCATION_PERMISSION_NAME, pkgName)
                == PackageManager.PERMISSION_GRANTED;
                == PackageManager.PERMISSION_GRANTED;
@@ -393,9 +404,9 @@ class GnssVisibilityControl {
            return;
            return;
        }
        }


        final String proxyAppPackageName = nfwNotification.mProxyAppPackageName;
        final String proxyAppPkgName = nfwNotification.mProxyAppPackageName;
        final Boolean isLocationPermissionEnabled = mProxyAppToLocationPermissions.get(
        final Boolean isLocationPermissionEnabled = mProxyAppToLocationPermissions.get(
                proxyAppPackageName);
                proxyAppPkgName);
        final boolean isLocationRequestAccepted = nfwNotification.isRequestAccepted();
        final boolean isLocationRequestAccepted = nfwNotification.isRequestAccepted();
        final boolean isPermissionMismatched =
        final boolean isPermissionMismatched =
                (isLocationPermissionEnabled == null) ? isLocationRequestAccepted
                (isLocationPermissionEnabled == null) ? isLocationRequestAccepted
@@ -425,7 +436,7 @@ class GnssVisibilityControl {
        }
        }


        if (isLocationPermissionEnabled == null) {
        if (isLocationPermissionEnabled == null) {
            Log.w(TAG, "Could not find proxy app with name: " + proxyAppPackageName + " in the "
            Log.w(TAG, "Could not find proxy app with name: " + proxyAppPkgName + " in the "
                    + "value specified for config parameter: "
                    + "value specified for config parameter: "
                    + GnssConfiguration.CONFIG_NFW_PROXY_APPS + ". AppOps service not notified "
                    + GnssConfiguration.CONFIG_NFW_PROXY_APPS + ". AppOps service not notified "
                    + "for non-framework location access notification: " + nfwNotification);
                    + "for non-framework location access notification: " + nfwNotification);
@@ -433,18 +444,19 @@ class GnssVisibilityControl {
        }
        }


        // Display location icon attributed to this proxy app.
        // Display location icon attributed to this proxy app.
        final Integer clsAppUid = getApplicationUid(proxyAppPackageName);
        final ApplicationInfo proxyAppInfo = getProxyAppInfo(proxyAppPkgName);
        if (clsAppUid == null) {
        if (proxyAppInfo == null) {
            Log.e(TAG, "Proxy app " + proxyAppPackageName + " is not found. AppOps service not "
            Log.e(TAG, "Proxy app " + proxyAppPkgName + " is not found. AppOps service not "
                    + "notified for non-framework location access notification: "
                    + "notified for non-framework location access notification: "
                    + nfwNotification);
                    + nfwNotification);
            return;
            return;
        }
        }
        mAppOps.noteOpNoThrow(AppOpsManager.OP_FINE_LOCATION, clsAppUid, proxyAppPackageName);

        mAppOps.noteOpNoThrow(AppOpsManager.OP_FINE_LOCATION, proxyAppInfo.uid, proxyAppPkgName);


        // Log proxy app permission mismatch between framework and GNSS HAL.
        // Log proxy app permission mismatch between framework and GNSS HAL.
        if (isPermissionMismatched) {
        if (isPermissionMismatched) {
            Log.w(TAG, "Permission mismatch. Framework proxy app " + proxyAppPackageName
            Log.w(TAG, "Permission mismatch. Framework proxy app " + proxyAppPkgName
                    + " location permission is set to " + isLocationPermissionEnabled
                    + " location permission is set to " + isLocationPermissionEnabled
                    + " but GNSS non-framework location access response type is "
                    + " but GNSS non-framework location access response type is "
                    + nfwNotification.getResponseTypeAsString() + " for notification: "
                    + nfwNotification.getResponseTypeAsString() + " for notification: "