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

Commit 4292d79e authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Not to use handler thread in GnssGeofenceProvider"

parents d0e81d2f 6dc9f05f
Loading
Loading
Loading
Loading
+19 −34
Original line number Diff line number Diff line
package com.android.server.location;

import android.location.IGpsGeofenceHardware;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.util.Log;
import android.util.SparseArray;

import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

/**
 * Manages GNSS Geofence operations.
 */
@@ -34,26 +28,26 @@ class GnssGeofenceProvider extends IGpsGeofenceHardware.Stub {
        public boolean paused;
    }

    private final Object mLock = new Object();
    @GuardedBy("mLock")
    private final GnssGeofenceProviderNative mNative;
    @GuardedBy("mLock")
    private final SparseArray<GeofenceEntry> mGeofenceEntries = new SparseArray<>();
    private final Handler mHandler;

    GnssGeofenceProvider(Looper looper) {
        this(looper, new GnssGeofenceProviderNative());
    GnssGeofenceProvider() {
        this(new GnssGeofenceProviderNative());
    }

    @VisibleForTesting
    GnssGeofenceProvider(Looper looper, GnssGeofenceProviderNative gnssGeofenceProviderNative) {
        mHandler = new Handler(looper);
    GnssGeofenceProvider(GnssGeofenceProviderNative gnssGeofenceProviderNative) {
        mNative = gnssGeofenceProviderNative;
    }

    // TODO(b/37460011): use this method in HAL death recovery.
    void resumeIfStarted() {
        if (DEBUG) {
            Log.d(TAG, "resumeIfStarted");
        }
        mHandler.post(() -> {
        synchronized (mLock) {
            for (int i = 0; i < mGeofenceEntries.size(); i++) {
                GeofenceEntry entry = mGeofenceEntries.valueAt(i);
                boolean added = mNative.addGeofence(entry.geofenceId, entry.latitude,
@@ -65,30 +59,21 @@ class GnssGeofenceProvider extends IGpsGeofenceHardware.Stub {
                    mNative.pauseGeofence(entry.geofenceId);
                }
            }
        });
    }

    private boolean runOnHandlerThread(Callable<Boolean> callable) {
        FutureTask<Boolean> futureTask = new FutureTask<>(callable);
        mHandler.post(futureTask);
        try {
            return futureTask.get();
        } catch (InterruptedException | ExecutionException e) {
            Log.e(TAG, "Failed running callable.", e);
        }
        return false;
    }

    @Override
    public boolean isHardwareGeofenceSupported() {
        return runOnHandlerThread(mNative::isGeofenceSupported);
        synchronized (mLock) {
            return mNative.isGeofenceSupported();
        }
    }

    @Override
    public boolean addCircularHardwareGeofence(int geofenceId, double latitude,
            double longitude, double radius, int lastTransition, int monitorTransitions,
            int notificationResponsiveness, int unknownTimer) {
        return runOnHandlerThread(() -> {
        synchronized (mLock) {
            boolean added = mNative.addGeofence(geofenceId, latitude, longitude, radius,
                    lastTransition, monitorTransitions, notificationResponsiveness,
                    unknownTimer);
@@ -105,23 +90,23 @@ class GnssGeofenceProvider extends IGpsGeofenceHardware.Stub {
                mGeofenceEntries.put(geofenceId, entry);
            }
            return added;
        });
        }
    }

    @Override
    public boolean removeHardwareGeofence(int geofenceId) {
        return runOnHandlerThread(() -> {
        synchronized (mLock) {
            boolean removed = mNative.removeGeofence(geofenceId);
            if (removed) {
                mGeofenceEntries.remove(geofenceId);
            }
            return removed;
        });
        }
    }

    @Override
    public boolean pauseHardwareGeofence(int geofenceId) {
        return runOnHandlerThread(() -> {
        synchronized (mLock) {
            boolean paused = mNative.pauseGeofence(geofenceId);
            if (paused) {
                GeofenceEntry entry = mGeofenceEntries.get(geofenceId);
@@ -130,12 +115,12 @@ class GnssGeofenceProvider extends IGpsGeofenceHardware.Stub {
                }
            }
            return paused;
        });
        }
    }

    @Override
    public boolean resumeHardwareGeofence(int geofenceId, int monitorTransitions) {
        return runOnHandlerThread(() -> {
        synchronized (mLock) {
            boolean resumed = mNative.resumeGeofence(geofenceId, monitorTransitions);
            if (resumed) {
                GeofenceEntry entry = mGeofenceEntries.get(geofenceId);
@@ -145,7 +130,7 @@ class GnssGeofenceProvider extends IGpsGeofenceHardware.Stub {
                }
            }
            return resumed;
        });
        }
    }

    @VisibleForTesting
+52 −40
Original line number Diff line number Diff line
@@ -762,7 +762,7 @@ public class GnssLocationProvider extends LocationProviderInterface
                looper, this);
        mHandler.post(mGnssSatelliteBlacklistHelper::updateSatelliteBlacklist);
        mGnssBatchingProvider = new GnssBatchingProvider();
        mGnssGeofenceProvider = new GnssGeofenceProvider(looper);
        mGnssGeofenceProvider = new GnssGeofenceProvider();
    }

    /**
@@ -1824,7 +1824,7 @@ public class GnssLocationProvider extends LocationProviderInterface
    /**
     * Converts the GPS HAL status to the internal Geofence Hardware status.
     */
    private int getGeofenceStatus(int status) {
    private static int getGeofenceStatus(int status) {
        switch (status) {
            case GPS_GEOFENCE_OPERATION_SUCCESS:
                return GeofenceHardware.GEOFENCE_SUCCESS;
@@ -1849,6 +1849,7 @@ public class GnssLocationProvider extends LocationProviderInterface
     */
    private void reportGeofenceTransition(int geofenceId, Location location, int transition,
            long transitionTimestamp) {
        mHandler.post(() -> {
            if (mGeofenceHardwareImpl == null) {
                mGeofenceHardwareImpl = GeofenceHardwareImpl.getInstance(mContext);
            }
@@ -1860,12 +1861,14 @@ public class GnssLocationProvider extends LocationProviderInterface
                    transitionTimestamp,
                    GeofenceHardware.MONITORING_TYPE_GPS_HARDWARE,
                    FusedBatchOptions.SourceTechnologies.GNSS);
        });
    }

    /**
     * called from native code to report GPS status change.
     */
    private void reportGeofenceStatus(int status, Location location) {
        mHandler.post(() -> {
            if (mGeofenceHardwareImpl == null) {
                mGeofenceHardwareImpl = GeofenceHardwareImpl.getInstance(mContext);
            }
@@ -1878,46 +1881,55 @@ public class GnssLocationProvider extends LocationProviderInterface
                    monitorStatus,
                    location,
                    FusedBatchOptions.SourceTechnologies.GNSS);
        });
    }

    /**
     * called from native code - Geofence Add callback
     */
    private void reportGeofenceAddStatus(int geofenceId, int status) {
        mHandler.post(() -> {
            if (mGeofenceHardwareImpl == null) {
                mGeofenceHardwareImpl = GeofenceHardwareImpl.getInstance(mContext);
            }
            mGeofenceHardwareImpl.reportGeofenceAddStatus(geofenceId, getGeofenceStatus(status));
        });
    }

    /**
     * called from native code - Geofence Remove callback
     */
    private void reportGeofenceRemoveStatus(int geofenceId, int status) {
        mHandler.post(() -> {
            if (mGeofenceHardwareImpl == null) {
                mGeofenceHardwareImpl = GeofenceHardwareImpl.getInstance(mContext);
            }
            mGeofenceHardwareImpl.reportGeofenceRemoveStatus(geofenceId, getGeofenceStatus(status));
        });
    }

    /**
     * called from native code - Geofence Pause callback
     */
    private void reportGeofencePauseStatus(int geofenceId, int status) {
        mHandler.post(() -> {
            if (mGeofenceHardwareImpl == null) {
                mGeofenceHardwareImpl = GeofenceHardwareImpl.getInstance(mContext);
            }
            mGeofenceHardwareImpl.reportGeofencePauseStatus(geofenceId, getGeofenceStatus(status));
        });
    }

    /**
     * called from native code - Geofence Resume callback
     */
    private void reportGeofenceResumeStatus(int geofenceId, int status) {
        mHandler.post(() -> {
            if (mGeofenceHardwareImpl == null) {
                mGeofenceHardwareImpl = GeofenceHardwareImpl.getInstance(mContext);
            }
            mGeofenceHardwareImpl.reportGeofenceResumeStatus(geofenceId, getGeofenceStatus(status));
        });
    }

    //=============================================================
+1 −2
Original line number Diff line number Diff line
@@ -7,7 +7,6 @@ import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import android.os.Looper;
import android.os.RemoteException;
import android.platform.test.annotations.Presubmit;

@@ -44,7 +43,7 @@ public class GnssGeofenceProviderTest {
        when(mMockNative.pauseGeofence(anyInt())).thenReturn(true);
        when(mMockNative.removeGeofence(anyInt())).thenReturn(true);
        when(mMockNative.resumeGeofence(anyInt(), anyInt())).thenReturn(true);
        mTestProvider = new GnssGeofenceProvider(Looper.myLooper(), mMockNative);
        mTestProvider = new GnssGeofenceProvider(mMockNative);
        mTestProvider.addCircularHardwareGeofence(GEOFENCE_ID, LATITUDE,
                LONGITUDE, RADIUS, LAST_TRANSITION, MONITOR_TRANSITIONS,
                NOTIFICATION_RESPONSIVENESS,