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

Commit 01f6c698 authored by Soonil Nagarkar's avatar Soonil Nagarkar Committed by Android (Google) Code Review
Browse files

Merge "Deprecate high power location broadcast"

parents fa876b86 f7151138
Loading
Loading
Loading
Loading
+2 −0
Original line number Original line Diff line number Diff line
@@ -260,7 +260,9 @@ public class LocationManager {
     * {@code OP_MONITOR_HIGH_POWER_LOCATION}.
     * {@code OP_MONITOR_HIGH_POWER_LOCATION}.
     *
     *
     * @hide
     * @hide
     * @deprecated This action is unnecessary from Android S forward.
     */
     */
    @Deprecated
    public static final String HIGH_POWER_REQUEST_CHANGE_ACTION =
    public static final String HIGH_POWER_REQUEST_CHANGE_ACTION =
            "android.location.HIGH_POWER_REQUEST_CHANGE";
            "android.location.HIGH_POWER_REQUEST_CHANGE";


+6 −7
Original line number Original line Diff line number Diff line
@@ -21,9 +21,9 @@ import android.content.Context;
import android.os.Handler;
import android.os.Handler;
import android.os.Looper;
import android.os.Looper;
import android.os.UserHandle;
import android.os.UserHandle;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.ArraySet;
import android.util.Log;
import android.util.Log;
import android.util.SparseArray;


import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.annotations.VisibleForTesting;
@@ -57,12 +57,11 @@ public class AppOpsControllerImpl implements AppOpsController,
    private static final long NOTED_OP_TIME_DELAY_MS = 5000;
    private static final long NOTED_OP_TIME_DELAY_MS = 5000;
    private static final String TAG = "AppOpsControllerImpl";
    private static final String TAG = "AppOpsControllerImpl";
    private static final boolean DEBUG = false;
    private static final boolean DEBUG = false;
    private final Context mContext;


    private final AppOpsManager mAppOps;
    private final AppOpsManager mAppOps;
    private H mBGHandler;
    private H mBGHandler;
    private final List<AppOpsController.Callback> mCallbacks = new ArrayList<>();
    private final List<AppOpsController.Callback> mCallbacks = new ArrayList<>();
    private final ArrayMap<Integer, Set<Callback>> mCallbacksByCode = new ArrayMap<>();
    private final SparseArray<Set<Callback>> mCallbacksByCode = new SparseArray<>();
    private boolean mListening;
    private boolean mListening;


    @GuardedBy("mActiveItems")
    @GuardedBy("mActiveItems")
@@ -71,6 +70,7 @@ public class AppOpsControllerImpl implements AppOpsController,
    private final List<AppOpItem> mNotedItems = new ArrayList<>();
    private final List<AppOpItem> mNotedItems = new ArrayList<>();


    protected static final int[] OPS = new int[] {
    protected static final int[] OPS = new int[] {
            AppOpsManager.OP_MONITOR_HIGH_POWER_LOCATION,
            AppOpsManager.OP_CAMERA,
            AppOpsManager.OP_CAMERA,
            AppOpsManager.OP_SYSTEM_ALERT_WINDOW,
            AppOpsManager.OP_SYSTEM_ALERT_WINDOW,
            AppOpsManager.OP_RECORD_AUDIO,
            AppOpsManager.OP_RECORD_AUDIO,
@@ -83,7 +83,6 @@ public class AppOpsControllerImpl implements AppOpsController,
            Context context,
            Context context,
            @Background Looper bgLooper,
            @Background Looper bgLooper,
            DumpManager dumpManager) {
            DumpManager dumpManager) {
        mContext = context;
        mAppOps = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
        mAppOps = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
        mBGHandler = new H(bgLooper);
        mBGHandler = new H(bgLooper);
        final int numOps = OPS.length;
        final int numOps = OPS.length;
@@ -131,7 +130,7 @@ public class AppOpsControllerImpl implements AppOpsController,
        boolean added = false;
        boolean added = false;
        final int numCodes = opsCodes.length;
        final int numCodes = opsCodes.length;
        for (int i = 0; i < numCodes; i++) {
        for (int i = 0; i < numCodes; i++) {
            if (mCallbacksByCode.containsKey(opsCodes[i])) {
            if (mCallbacksByCode.contains(opsCodes[i])) {
                mCallbacksByCode.get(opsCodes[i]).add(callback);
                mCallbacksByCode.get(opsCodes[i]).add(callback);
                added = true;
                added = true;
            } else {
            } else {
@@ -155,7 +154,7 @@ public class AppOpsControllerImpl implements AppOpsController,
    public void removeCallback(int[] opsCodes, AppOpsController.Callback callback) {
    public void removeCallback(int[] opsCodes, AppOpsController.Callback callback) {
        final int numCodes = opsCodes.length;
        final int numCodes = opsCodes.length;
        for (int i = 0; i < numCodes; i++) {
        for (int i = 0; i < numCodes; i++) {
            if (mCallbacksByCode.containsKey(opsCodes[i])) {
            if (mCallbacksByCode.contains(opsCodes[i])) {
                mCallbacksByCode.get(opsCodes[i]).remove(callback);
                mCallbacksByCode.get(opsCodes[i]).remove(callback);
            }
            }
        }
        }
@@ -312,7 +311,7 @@ public class AppOpsControllerImpl implements AppOpsController,
    }
    }


    private void notifySuscribers(int code, int uid, String packageName, boolean active) {
    private void notifySuscribers(int code, int uid, String packageName, boolean active) {
        if (mCallbacksByCode.containsKey(code)) {
        if (mCallbacksByCode.contains(code)) {
            if (DEBUG) Log.d(TAG, "Notifying of change in package " + packageName);
            if (DEBUG) Log.d(TAG, "Notifying of change in package " + packageName);
            for (Callback cb: mCallbacksByCode.get(code)) {
            for (Callback cb: mCallbacksByCode.get(code)) {
                cb.onActiveStateChanged(code, uid, packageName, active);
                cb.onActiveStateChanged(code, uid, packageName, active);
+28 −49
Original line number Original line Diff line number Diff line
@@ -16,11 +16,11 @@


package com.android.systemui.statusbar.policy;
package com.android.systemui.statusbar.policy;


import static android.app.AppOpsManager.OP_MONITOR_HIGH_POWER_LOCATION;

import static com.android.settingslib.Utils.updateLocationEnabled;
import static com.android.settingslib.Utils.updateLocationEnabled;


import android.app.ActivityManager;
import android.app.ActivityManager;
import android.app.AppOpsManager;
import android.app.StatusBarManager;
import android.content.BroadcastReceiver;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Context;
import android.content.Intent;
import android.content.Intent;
@@ -36,8 +36,9 @@ import android.provider.Settings;
import androidx.annotation.VisibleForTesting;
import androidx.annotation.VisibleForTesting;


import com.android.systemui.BootCompleteCache;
import com.android.systemui.BootCompleteCache;
import com.android.systemui.appops.AppOpItem;
import com.android.systemui.appops.AppOpsController;
import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.dagger.qualifiers.Background;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.util.Utils;
import com.android.systemui.util.Utils;


@@ -51,41 +52,32 @@ import javax.inject.Singleton;
 * A controller to manage changes of location related states and update the views accordingly.
 * A controller to manage changes of location related states and update the views accordingly.
 */
 */
@Singleton
@Singleton
public class LocationControllerImpl extends BroadcastReceiver implements LocationController {
public class LocationControllerImpl extends BroadcastReceiver implements LocationController,

        AppOpsController.Callback {
    private static final int[] mHighPowerRequestAppOpArray
        = new int[] {AppOpsManager.OP_MONITOR_HIGH_POWER_LOCATION};


    private Context mContext;
    private final Context mContext;
    private final AppOpsController mAppOpsController;
    private final BootCompleteCache mBootCompleteCache;
    private final H mHandler;


    private AppOpsManager mAppOpsManager;
    private StatusBarManager mStatusBarManager;
    private BroadcastDispatcher mBroadcastDispatcher;
    private BootCompleteCache mBootCompleteCache;


    private boolean mAreActiveLocationRequests;
    private boolean mAreActiveLocationRequests;


    private final H mHandler;

    @Inject
    @Inject
    public LocationControllerImpl(Context context, @Main Looper mainLooper,
    public LocationControllerImpl(Context context, AppOpsController appOpsController,
            @Background Looper bgLooper, BroadcastDispatcher broadcastDispatcher,
            @Main Looper mainLooper, BroadcastDispatcher broadcastDispatcher,
            BootCompleteCache bootCompleteCache) {
            BootCompleteCache bootCompleteCache) {
        mContext = context;
        mContext = context;
        mBroadcastDispatcher = broadcastDispatcher;
        mAppOpsController = appOpsController;
        mBootCompleteCache = bootCompleteCache;
        mBootCompleteCache = bootCompleteCache;
        mHandler = new H(mainLooper);
        mHandler = new H(mainLooper);


        // Register to listen for changes in location settings.
        // Register to listen for changes in location settings.
        IntentFilter filter = new IntentFilter();
        IntentFilter filter = new IntentFilter();
        filter.addAction(LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION);
        filter.addAction(LocationManager.MODE_CHANGED_ACTION);
        filter.addAction(LocationManager.MODE_CHANGED_ACTION);
        mBroadcastDispatcher.registerReceiverWithHandler(this, filter,
        broadcastDispatcher.registerReceiverWithHandler(this, filter, mHandler, UserHandle.ALL);
                new Handler(bgLooper), UserHandle.ALL);


        mAppOpsManager = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
        mAppOpsController.addCallback(new int[]{OP_MONITOR_HIGH_POWER_LOCATION}, this);
        mStatusBarManager
                = (StatusBarManager) context.getSystemService(Context.STATUS_BAR_SERVICE);


        // Examine the current location state and initialize the status view.
        // Examine the current location state and initialize the status view.
        updateActiveLocationRequests();
        updateActiveLocationRequests();
@@ -160,29 +152,14 @@ public class LocationControllerImpl extends BroadcastReceiver implements Locatio
     */
     */
    @VisibleForTesting
    @VisibleForTesting
    protected boolean areActiveHighPowerLocationRequests() {
    protected boolean areActiveHighPowerLocationRequests() {
        List<AppOpsManager.PackageOps> packages
        List<AppOpItem> appOpsItems = mAppOpsController.getActiveAppOps();
            = mAppOpsManager.getPackagesForOps(mHighPowerRequestAppOpArray);

        // AppOpsManager can return null when there is no requested data.
        final int numItems = appOpsItems.size();
        if (packages != null) {
        for (int i = 0; i < numItems; i++) {
            final int numPackages = packages.size();
            if (appOpsItems.get(i).getCode() == OP_MONITOR_HIGH_POWER_LOCATION) {
            for (int packageInd = 0; packageInd < numPackages; packageInd++) {
                AppOpsManager.PackageOps packageOp = packages.get(packageInd);
                List<AppOpsManager.OpEntry> opEntries = packageOp.getOps();
                if (opEntries != null) {
                    final int numOps = opEntries.size();
                    for (int opInd = 0; opInd < numOps; opInd++) {
                        AppOpsManager.OpEntry opEntry = opEntries.get(opInd);
                        // AppOpsManager should only return OP_MONITOR_HIGH_POWER_LOCATION because
                        // of the mHighPowerRequestAppOpArray filter, but checking defensively.
                        if (opEntry.getOp() == AppOpsManager.OP_MONITOR_HIGH_POWER_LOCATION) {
                            if (opEntry.isRunning()) {
                return true;
                return true;
            }
            }
        }
        }
                    }
                }
            }
        }


        return false;
        return false;
    }
    }
@@ -198,14 +175,16 @@ public class LocationControllerImpl extends BroadcastReceiver implements Locatio


    @Override
    @Override
    public void onReceive(Context context, Intent intent) {
    public void onReceive(Context context, Intent intent) {
        final String action = intent.getAction();
        if (LocationManager.MODE_CHANGED_ACTION.equals(intent.getAction())) {
        if (LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)) {
            mHandler.locationSettingsChanged();
            updateActiveLocationRequests();
        } else if (LocationManager.MODE_CHANGED_ACTION.equals(action)) {
            mHandler.sendEmptyMessage(H.MSG_LOCATION_SETTINGS_CHANGED);
        }
        }
    }
    }


    @Override
    public void onActiveStateChanged(int code, int uid, String packageName, boolean active) {
        updateActiveLocationRequests();
    }

    private final class H extends Handler {
    private final class H extends Handler {
        private static final int MSG_LOCATION_SETTINGS_CHANGED = 1;
        private static final int MSG_LOCATION_SETTINGS_CHANGED = 1;
        private static final int MSG_LOCATION_ACTIVE_CHANGED = 2;
        private static final int MSG_LOCATION_ACTIVE_CHANGED = 2;
+29 −8
Original line number Original line Diff line number Diff line
@@ -15,12 +15,13 @@
package com.android.systemui.statusbar.policy;
package com.android.systemui.statusbar.policy;


import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;


import android.app.AppOpsManager;
import android.content.Intent;
import android.content.Intent;
import android.location.LocationManager;
import android.location.LocationManager;
import android.testing.AndroidTestingRunner;
import android.testing.AndroidTestingRunner;
@@ -31,12 +32,15 @@ import androidx.test.filters.SmallTest;


import com.android.systemui.BootCompleteCache;
import com.android.systemui.BootCompleteCache;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.appops.AppOpsController;
import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.statusbar.policy.LocationController.LocationChangeCallback;
import com.android.systemui.statusbar.policy.LocationController.LocationChangeCallback;


import org.junit.Before;
import org.junit.Before;
import org.junit.Test;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;


@RunWith(AndroidTestingRunner.class)
@RunWith(AndroidTestingRunner.class)
@RunWithLooper
@RunWithLooper
@@ -46,11 +50,15 @@ public class LocationControllerImplTest extends SysuiTestCase {
    private LocationControllerImpl mLocationController;
    private LocationControllerImpl mLocationController;
    private TestableLooper mTestableLooper;
    private TestableLooper mTestableLooper;


    @Mock private AppOpsController mAppOpsController;

    @Before
    @Before
    public void setup() {
    public void setup() {
        MockitoAnnotations.initMocks(this);

        mTestableLooper = TestableLooper.get(this);
        mTestableLooper = TestableLooper.get(this);
        mLocationController = spy(new LocationControllerImpl(mContext,
        mLocationController = spy(new LocationControllerImpl(mContext,
                mTestableLooper.getLooper(),
                mAppOpsController,
                mTestableLooper.getLooper(),
                mTestableLooper.getLooper(),
                mock(BroadcastDispatcher.class),
                mock(BroadcastDispatcher.class),
                mock(BootCompleteCache.class)));
                mock(BootCompleteCache.class)));
@@ -67,12 +75,12 @@ public class LocationControllerImplTest extends SysuiTestCase {
        mLocationController.addCallback(callback);
        mLocationController.addCallback(callback);
        mLocationController.addCallback(mock(LocationChangeCallback.class));
        mLocationController.addCallback(mock(LocationChangeCallback.class));


        when(mLocationController.areActiveHighPowerLocationRequests()).thenReturn(false);
        doReturn(false).when(mLocationController).areActiveHighPowerLocationRequests();
        mLocationController.onReceive(mContext, new Intent(
        mLocationController.onActiveStateChanged(AppOpsManager.OP_MONITOR_HIGH_POWER_LOCATION, 0,
                LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION));
                "", false);
        when(mLocationController.areActiveHighPowerLocationRequests()).thenReturn(true);
        doReturn(true).when(mLocationController).areActiveHighPowerLocationRequests();
        mLocationController.onReceive(mContext, new Intent(
        mLocationController.onActiveStateChanged(AppOpsManager.OP_MONITOR_HIGH_POWER_LOCATION, 0,
                LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION));
                "", true);


        mTestableLooper.processAllMessages();
        mTestableLooper.processAllMessages();
    }
    }
@@ -107,11 +115,22 @@ public class LocationControllerImplTest extends SysuiTestCase {
        LocationChangeCallback callback = mock(LocationChangeCallback.class);
        LocationChangeCallback callback = mock(LocationChangeCallback.class);


        mLocationController.addCallback(callback);
        mLocationController.addCallback(callback);

        mTestableLooper.processAllMessages();

        mLocationController.onReceive(mContext, new Intent(LocationManager.MODE_CHANGED_ACTION));
        mLocationController.onReceive(mContext, new Intent(LocationManager.MODE_CHANGED_ACTION));


        mTestableLooper.processAllMessages();
        mTestableLooper.processAllMessages();


        verify(callback, times(2)).onLocationSettingsChanged(anyBoolean());
        verify(callback, times(2)).onLocationSettingsChanged(anyBoolean());

        doReturn(true).when(mLocationController).areActiveHighPowerLocationRequests();
        mLocationController.onActiveStateChanged(AppOpsManager.OP_MONITOR_HIGH_POWER_LOCATION, 0,
                "", true);

        mTestableLooper.processAllMessages();

        verify(callback, times(1)).onLocationActiveChanged(anyBoolean());
    }
    }


    @Test
    @Test
@@ -124,6 +143,8 @@ public class LocationControllerImplTest extends SysuiTestCase {
        verify(callback).onLocationSettingsChanged(anyBoolean());
        verify(callback).onLocationSettingsChanged(anyBoolean());
        mLocationController.removeCallback(callback);
        mLocationController.removeCallback(callback);


        mTestableLooper.processAllMessages();

        mLocationController.onReceive(mContext, new Intent(LocationManager.MODE_CHANGED_ACTION));
        mLocationController.onReceive(mContext, new Intent(LocationManager.MODE_CHANGED_ACTION));


        mTestableLooper.processAllMessages();
        mTestableLooper.processAllMessages();
+0 −2
Original line number Original line Diff line number Diff line
@@ -232,7 +232,6 @@ import android.content.res.Resources;
import android.database.ContentObserver;
import android.database.ContentObserver;
import android.graphics.Rect;
import android.graphics.Rect;
import android.hardware.display.DisplayManagerInternal;
import android.hardware.display.DisplayManagerInternal;
import android.location.LocationManager;
import android.media.audiofx.AudioEffect;
import android.media.audiofx.AudioEffect;
import android.net.Proxy;
import android.net.Proxy;
import android.net.Uri;
import android.net.Uri;
@@ -15863,7 +15862,6 @@ public class ActivityManagerService extends IActivityManager.Stub
                || Intent.ACTION_FACTORY_RESET.equals(action)
                || Intent.ACTION_FACTORY_RESET.equals(action)
                || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
                || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
                || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
                || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
                || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)
                || TelephonyManager.ACTION_REQUEST_OMADM_CONFIGURATION_UPDATE.equals(action)
                || TelephonyManager.ACTION_REQUEST_OMADM_CONFIGURATION_UPDATE.equals(action)
                || SuggestionSpan.ACTION_SUGGESTION_PICKED.equals(action)
                || SuggestionSpan.ACTION_SUGGESTION_PICKED.equals(action)
                || AudioEffect.ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION.equals(action)
                || AudioEffect.ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION.equals(action)
Loading