• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2024 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.location.gnss;
18 
19 import static android.location.provider.ProviderProperties.ACCURACY_FINE;
20 import static android.location.provider.ProviderProperties.POWER_USAGE_HIGH;
21 
22 import android.annotation.Nullable;
23 import android.content.Context;
24 import android.location.Location;
25 import android.location.LocationListener;
26 import android.location.LocationManager;
27 import android.location.LocationRequest;
28 import android.location.provider.LocationProviderBase;
29 import android.location.provider.ProviderProperties;
30 import android.location.provider.ProviderRequest;
31 import android.os.Bundle;
32 import android.util.SparseArray;
33 
34 
35 import com.android.internal.annotations.GuardedBy;
36 import com.android.internal.util.ConcurrentUtils;
37 
38 import java.util.List;
39 
40 /** Basic pass-through GNSS location provider implementation. */
41 public class GnssOverlayLocationProvider extends LocationProviderBase {
42 
43     private static final String TAG = "GnssOverlay";
44 
45     private static final ProviderProperties PROPERTIES = new ProviderProperties.Builder()
46                 .setHasAltitudeSupport(true)
47                 .setHasSpeedSupport(true)
48                 .setHasBearingSupport(true)
49                 .setPowerUsage(POWER_USAGE_HIGH)
50                 .setAccuracy(ACCURACY_FINE)
51                 .build();
52 
53     @GuardedBy("mPendingFlushes")
54     private final SparseArray<OnFlushCompleteCallback> mPendingFlushes = new SparseArray<>();
55 
56     private final LocationManager mLocationManager;
57 
58     private final GnssLocationListener mGnssLocationListener = new GnssLocationListener();
59 
60     @GuardedBy("mPendingFlushes")
61     private int mFlushCode = 0;
62 
63     /** Location listener for receiving locations from LocationManager. */
64     private class GnssLocationListener implements LocationListener {
65         @Override
onLocationChanged(Location location)66         public void onLocationChanged(Location location) {
67             reportLocation(location);
68         }
69 
70         @Override
onLocationChanged(List<Location> locations)71         public void onLocationChanged(List<Location> locations) {
72             reportLocations(locations);
73         }
74 
75         @Override
onFlushComplete(int requestCode)76         public void onFlushComplete(int requestCode) {
77             OnFlushCompleteCallback flushCompleteCallback;
78             synchronized (mPendingFlushes) {
79                 flushCompleteCallback = mPendingFlushes.get(requestCode);
80                 mPendingFlushes.remove(requestCode);
81             }
82             if (flushCompleteCallback != null) {
83                 flushCompleteCallback.onFlushComplete();
84             }
85         }
86     }
87 
GnssOverlayLocationProvider(Context context)88     public GnssOverlayLocationProvider(Context context) {
89         super(context, TAG, PROPERTIES);
90         mLocationManager = context.getSystemService(LocationManager.class);
91     }
92 
start()93     void start() {
94     }
95 
stop()96     void stop() {
97         mLocationManager.removeUpdates(mGnssLocationListener);
98     }
99 
100     @Override
onSendExtraCommand(String command, @Nullable Bundle extras)101     public void onSendExtraCommand(String command, @Nullable Bundle extras) {
102         mLocationManager.sendExtraCommand(LocationManager.GPS_HARDWARE_PROVIDER, command, extras);
103     }
104 
105     @Override
onFlush(OnFlushCompleteCallback callback)106     public void onFlush(OnFlushCompleteCallback callback) {
107         int flushCodeCopy;
108         synchronized (mPendingFlushes) {
109             flushCodeCopy = mFlushCode++;
110             mPendingFlushes.put(flushCodeCopy, callback);
111         }
112         mLocationManager.requestFlush(
113                 LocationManager.GPS_HARDWARE_PROVIDER, mGnssLocationListener, flushCodeCopy);
114     }
115 
116     @Override
onSetRequest(ProviderRequest request)117     public void onSetRequest(ProviderRequest request) {
118         if (request.isActive()) {
119             mLocationManager.requestLocationUpdates(
120                     LocationManager.GPS_HARDWARE_PROVIDER,
121                     new LocationRequest.Builder(request.getIntervalMillis())
122                             .setMaxUpdateDelayMillis(request.getMaxUpdateDelayMillis())
123                             .setLowPower(request.isLowPower())
124                             .setLocationSettingsIgnored(request.isLocationSettingsIgnored())
125                             .setWorkSource(request.getWorkSource())
126                             .setQuality(request.getQuality())
127                             .build(),
128                     ConcurrentUtils.DIRECT_EXECUTOR,
129                     mGnssLocationListener);
130         } else {
131             mLocationManager.removeUpdates(mGnssLocationListener);
132         }
133     }
134 }
135