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

Commit 75b9fd6d authored by Anil Admal's avatar Anil Admal
Browse files

Show location icon when reporting GNSS measurements/status

GNSS measurements and status can be used to compute user location.
Hence, the location icon must be turned on in the status bar to
notify the user every time the measurements are reported to an
application. Also, check for location permission before delivery
as the application may have lost location permission.

Bug: 113332106
Test: Tested it manually using GNSS logger application.
Change-Id: I985610cab207af50a84e7e47390c51359375bb78
parent 44be2074
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -439,7 +439,6 @@ java_defaults {
        "location/java/android/location/IGeocodeProvider.aidl",
        "location/java/android/location/IGeofenceProvider.aidl",
        "location/java/android/location/IGnssStatusListener.aidl",
        "location/java/android/location/IGnssStatusProvider.aidl",
        "location/java/android/location/IGnssMeasurementsListener.aidl",
        "location/java/android/location/IGnssNavigationMessageListener.aidl",
        "location/java/android/location/ILocationListener.aidl",
+0 −29
Original line number Diff line number Diff line
/*
 * Copyright (C) 2009 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.location;

import android.location.IGnssStatusListener;

/**
 * An interface for location providers that provide GNSS status information.
 *
 * {@hide}
 */
interface IGnssStatusProvider {
    void registerGnssStatusCallback(IGnssStatusListener callback);
    void unregisterGnssStatusCallback(IGnssStatusListener callback);
}
+22 −23
Original line number Diff line number Diff line
@@ -47,7 +47,6 @@ import android.location.IBatchedLocationCallback;
import android.location.IGnssMeasurementsListener;
import android.location.IGnssNavigationMessageListener;
import android.location.IGnssStatusListener;
import android.location.IGnssStatusProvider;
import android.location.IGpsGeofenceHardware;
import android.location.ILocationListener;
import android.location.ILocationManager;
@@ -92,6 +91,7 @@ import com.android.server.location.GnssBatchingProvider;
import com.android.server.location.GnssLocationProvider;
import com.android.server.location.GnssMeasurementsProvider;
import com.android.server.location.GnssNavigationMessageProvider;
import com.android.server.location.GnssStatusListenerHelper;
import com.android.server.location.LocationBlacklist;
import com.android.server.location.LocationFudger;
import com.android.server.location.LocationProviderInterface;
@@ -182,7 +182,7 @@ public class LocationManagerService extends ILocationManager.Stub {
    private ActivityManager mActivityManager;
    private UserManager mUserManager;
    private GeocoderProxy mGeocodeProvider;
    private IGnssStatusProvider mGnssStatusProvider;
    private GnssStatusListenerHelper mGnssStatusProvider;
    private INetInitiatedListener mNetInitiatedListener;
    private LocationWorkerHandler mLocationHandler;
    private PassiveProvider mPassiveProvider;  // track passive provider for special cases
@@ -463,14 +463,16 @@ public class LocationManagerService extends ILocationManager.Stub {
            }

            for (Entry<IBinder, Identity> entry : mGnssMeasurementsListeners.entrySet()) {
                if (entry.getValue().mUid == uid) {
                Identity callerIdentity = entry.getValue();
                if (callerIdentity.mUid == uid) {
                    if (D) {
                        Log.d(TAG, "gnss measurements listener from uid " + uid
                                + " is now " + (foreground ? "foreground" : "background)"));
                    }
                    if (foreground || isThrottlingExemptLocked(entry.getValue())) {
                        mGnssMeasurementsProvider.addListener(
                                IGnssMeasurementsListener.Stub.asInterface(entry.getKey()));
                                IGnssMeasurementsListener.Stub.asInterface(entry.getKey()),
                                callerIdentity.mUid, callerIdentity.mPackageName);
                    } else {
                        mGnssMeasurementsProvider.removeListener(
                                IGnssMeasurementsListener.Stub.asInterface(entry.getKey()));
@@ -479,7 +481,8 @@ public class LocationManagerService extends ILocationManager.Stub {
            }

            for (Entry<IBinder, Identity> entry : mGnssNavigationMessageListeners.entrySet()) {
                if (entry.getValue().mUid == uid) {
                Identity callerIdentity = entry.getValue();
                if (callerIdentity.mUid == uid) {
                    if (D) {
                        Log.d(TAG, "gnss navigation message listener from uid "
                                + uid + " is now "
@@ -487,13 +490,16 @@ public class LocationManagerService extends ILocationManager.Stub {
                    }
                    if (foreground || isThrottlingExemptLocked(entry.getValue())) {
                        mGnssNavigationMessageProvider.addListener(
                                IGnssNavigationMessageListener.Stub.asInterface(entry.getKey()));
                                IGnssNavigationMessageListener.Stub.asInterface(entry.getKey()),
                                callerIdentity.mUid, callerIdentity.mPackageName);
                    } else {
                        mGnssNavigationMessageProvider.removeListener(
                                IGnssNavigationMessageListener.Stub.asInterface(entry.getKey()));
                    }
                }
            }

            // TODO(b/120449926): The GNSS status listeners should be handled similar to the above.
        }
    }

@@ -2444,31 +2450,20 @@ public class LocationManagerService extends ILocationManager.Stub {
        }
    }


    @Override
    public boolean registerGnssStatusCallback(IGnssStatusListener callback, String packageName) {
        if (!hasGnssPermissions(packageName) || mGnssStatusProvider == null) {
            return false;
        }

        try {
            mGnssStatusProvider.registerGnssStatusCallback(callback);
        } catch (RemoteException e) {
            Slog.e(TAG, "mGpsStatusProvider.registerGnssStatusCallback failed", e);
            return false;
        }
        return true;
        // TODO(b/120449926): The GNSS status listeners should be handled similar to the GNSS
        // measurements listeners.
        return mGnssStatusProvider.addListener(callback, Binder.getCallingUid(), packageName);
    }

    @Override
    public void unregisterGnssStatusCallback(IGnssStatusListener callback) {
        synchronized (mLock) {
            try {
                mGnssStatusProvider.unregisterGnssStatusCallback(callback);
            } catch (Exception e) {
                Slog.e(TAG, "mGpsStatusProvider.unregisterGnssStatusCallback failed", e);
            }
        }
        mGnssStatusProvider.removeListener(callback);
    }

    @Override
@@ -2481,13 +2476,15 @@ public class LocationManagerService extends ILocationManager.Stub {
        synchronized (mLock) {
            Identity callerIdentity
                    = new Identity(Binder.getCallingUid(), Binder.getCallingPid(), packageName);
            // TODO(b/120481270): Register for client death notification and update map.
            mGnssMeasurementsListeners.put(listener.asBinder(), callerIdentity);
            long identity = Binder.clearCallingIdentity();
            try {
                if (isThrottlingExemptLocked(callerIdentity)
                        || isImportanceForeground(
                        mActivityManager.getPackageImportance(packageName))) {
                    return mGnssMeasurementsProvider.addListener(listener);
                    return mGnssMeasurementsProvider.addListener(listener,
                            callerIdentity.mUid, callerIdentity.mPackageName);
                }
            } finally {
                Binder.restoreCallingIdentity(identity);
@@ -2518,13 +2515,15 @@ public class LocationManagerService extends ILocationManager.Stub {
        synchronized (mLock) {
            Identity callerIdentity
                    = new Identity(Binder.getCallingUid(), Binder.getCallingPid(), packageName);
            // TODO(b/120481270): Register for client death notification and update map.
            mGnssNavigationMessageListeners.put(listener.asBinder(), callerIdentity);
            long identity = Binder.clearCallingIdentity();
            try {
                if (isThrottlingExemptLocked(callerIdentity)
                        || isImportanceForeground(
                        mActivityManager.getPackageImportance(packageName))) {
                    return mGnssNavigationMessageProvider.addListener(listener);
                    return mGnssNavigationMessageProvider.addListener(listener,
                            callerIdentity.mUid, callerIdentity.mPackageName);
                }
            } finally {
                Binder.restoreCallingIdentity(identity);
+9 −23
Original line number Diff line number Diff line
@@ -31,8 +31,6 @@ import android.location.FusedBatchOptions;
import android.location.GnssMeasurementsEvent;
import android.location.GnssNavigationMessage;
import android.location.GnssStatus;
import android.location.IGnssStatusListener;
import android.location.IGnssStatusProvider;
import android.location.IGpsGeofenceHardware;
import android.location.ILocationManager;
import android.location.INetInitiatedListener;
@@ -382,7 +380,7 @@ public class GnssLocationProvider extends LocationProviderInterface
    private final Context mContext;
    private final ILocationManager mILocationManager;
    private final LocationExtras mLocationExtras = new LocationExtras();
    private final GnssStatusListenerHelper mListenerHelper;
    private final GnssStatusListenerHelper mGnssStatusListenerHelper;
    private final GnssSatelliteBlacklistHelper mGnssSatelliteBlacklistHelper;
    private final GnssMeasurementsProvider mGnssMeasurementsProvider;
    private final GnssNavigationMessageProvider mGnssNavigationMessageProvider;
@@ -443,20 +441,8 @@ public class GnssLocationProvider extends LocationProviderInterface
    // GNSS Metrics
    private GnssMetrics mGnssMetrics;

    private final IGnssStatusProvider mGnssStatusProvider = new IGnssStatusProvider.Stub() {
        @Override
        public void registerGnssStatusCallback(IGnssStatusListener callback) {
            mListenerHelper.addListener(callback);
        }

        @Override
        public void unregisterGnssStatusCallback(IGnssStatusListener callback) {
            mListenerHelper.removeListener(callback);
        }
    };

    public IGnssStatusProvider getGnssStatusProvider() {
        return mGnssStatusProvider;
    public GnssStatusListenerHelper getGnssStatusProvider() {
        return mGnssStatusListenerHelper;
    }

    public IGpsGeofenceHardware getGpsGeofenceProxy() {
@@ -730,7 +716,7 @@ public class GnssLocationProvider extends LocationProviderInterface
                mNetInitiatedListener,
                mSuplEsEnabled);

        mListenerHelper = new GnssStatusListenerHelper(mHandler) {
        mGnssStatusListenerHelper = new GnssStatusListenerHelper(mContext, mHandler) {
            @Override
            protected boolean isAvailableInPlatform() {
                return isSupported();
@@ -749,7 +735,7 @@ public class GnssLocationProvider extends LocationProviderInterface
            }
        };

        mGnssNavigationMessageProvider = new GnssNavigationMessageProvider(mHandler) {
        mGnssNavigationMessageProvider = new GnssNavigationMessageProvider(mContext, mHandler) {
            @Override
            protected boolean isGpsEnabled() {
                return isEnabled();
@@ -1473,7 +1459,7 @@ public class GnssLocationProvider extends LocationProviderInterface
            }

            // notify status listeners
            mListenerHelper.onFirstFix(mTimeToFirstFix);
            mGnssStatusListenerHelper.onFirstFix(mTimeToFirstFix);
        }

        if (mSingleShot) {
@@ -1527,7 +1513,7 @@ public class GnssLocationProvider extends LocationProviderInterface
        }

        if (wasNavigating != mNavigating) {
            mListenerHelper.onStatusChanged(mNavigating);
            mGnssStatusListenerHelper.onStatusChanged(mNavigating);

            // send an intent to notify that the GPS has been enabled or disabled
            Intent intent = new Intent(LocationManager.GPS_ENABLED_CHANGE_ACTION);
@@ -1563,7 +1549,7 @@ public class GnssLocationProvider extends LocationProviderInterface
    }

    private void handleReportSvStatus(SvStatusInfo info) {
        mListenerHelper.onSvStatusChanged(
        mGnssStatusListenerHelper.onSvStatusChanged(
                info.mSvCount,
                info.mSvidWithFlags,
                info.mCn0s,
@@ -1636,7 +1622,7 @@ public class GnssLocationProvider extends LocationProviderInterface
        if (!mItarSpeedLimitExceeded) {
            int length = native_read_nmea(mNmeaBuffer, mNmeaBuffer.length);
            String nmea = new String(mNmeaBuffer, 0 /* offset */, length);
            mListenerHelper.onNmeaReceived(timestamp, nmea);
            mGnssStatusListenerHelper.onNmeaReceived(timestamp, nmea);
        }
    }

+10 −7
Original line number Diff line number Diff line
@@ -38,7 +38,6 @@ public abstract class GnssMeasurementsProvider extends
    private static final String TAG = "GnssMeasurementsProvider";
    private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);

    private final Context mContext;
    private final GnssMeasurementProviderNative mNative;

    private boolean mIsCollectionStarted;
@@ -51,8 +50,7 @@ public abstract class GnssMeasurementsProvider extends
    @VisibleForTesting
    GnssMeasurementsProvider(Context context, Handler handler,
            GnssMeasurementProviderNative aNative) {
        super(handler, TAG);
        mContext = context;
        super(context, handler, TAG);
        mNative = aNative;
    }

@@ -98,9 +96,13 @@ public abstract class GnssMeasurementsProvider extends
    }

    public void onMeasurementsAvailable(final GnssMeasurementsEvent event) {
        ListenerOperation<IGnssMeasurementsListener> operation =
                listener -> listener.onGnssMeasurementsReceived(event);
        foreach(operation);
        foreach((IGnssMeasurementsListener listener, int uid, String packageName) -> {
            if (!hasPermission(uid, packageName)) {
                logPermissionDisabledEventNotReported(TAG, packageName, "GNSS measurements");
                return;
            }
            listener.onGnssMeasurementsReceived(event);
        });
    }

    public void onCapabilitiesUpdated(boolean isGnssMeasurementsSupported) {
@@ -149,7 +151,8 @@ public abstract class GnssMeasurementsProvider extends
        }

        @Override
        public void execute(IGnssMeasurementsListener listener) throws RemoteException {
        public void execute(IGnssMeasurementsListener listener,
                int uid, String packageName) throws RemoteException {
            listener.onStatusChanged(mStatus);
        }
    }
Loading