• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2014 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.server.location;
18 
19 import android.content.Context;
20 import android.location.GnssMeasurementsEvent;
21 import android.location.IGnssMeasurementsListener;
22 import android.os.Handler;
23 import android.os.RemoteException;
24 import android.provider.Settings;
25 import android.util.Log;
26 
27 import com.android.internal.annotations.VisibleForTesting;
28 
29 /**
30  * An base implementation for GPS measurements provider.
31  * It abstracts out the responsibility of handling listeners, while still allowing technology
32  * specific implementations to be built.
33  *
34  * @hide
35  */
36 public abstract class GnssMeasurementsProvider extends
37         RemoteListenerHelper<IGnssMeasurementsListener> {
38     private static final String TAG = "GnssMeasurementsProvider";
39     private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
40 
41     private final Context mContext;
42     private final GnssMeasurementProviderNative mNative;
43 
44     private boolean mIsCollectionStarted;
45     private boolean mEnableFullTracking;
46 
GnssMeasurementsProvider(Context context, Handler handler)47     protected GnssMeasurementsProvider(Context context, Handler handler) {
48         this(context, handler, new GnssMeasurementProviderNative());
49     }
50 
51     @VisibleForTesting
GnssMeasurementsProvider(Context context, Handler handler, GnssMeasurementProviderNative aNative)52     GnssMeasurementsProvider(Context context, Handler handler,
53             GnssMeasurementProviderNative aNative) {
54         super(handler, TAG);
55         mContext = context;
56         mNative = aNative;
57     }
58 
59     // TODO(b/37460011): Use this with death recovery logic.
resumeIfStarted()60     void resumeIfStarted() {
61         if (DEBUG) {
62             Log.d(TAG, "resumeIfStarted");
63         }
64         if (mIsCollectionStarted) {
65             mNative.startMeasurementCollection(mEnableFullTracking);
66         }
67     }
68 
69     @Override
isAvailableInPlatform()70     public boolean isAvailableInPlatform() {
71         return mNative.isMeasurementSupported();
72     }
73 
74     @Override
registerWithService()75     protected int registerWithService() {
76         int devOptions = Settings.Secure.getInt(mContext.getContentResolver(),
77                 Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 0);
78         int fullTrackingToggled = Settings.Global.getInt(mContext.getContentResolver(),
79                 Settings.Global.ENABLE_GNSS_RAW_MEAS_FULL_TRACKING, 0);
80         boolean enableFullTracking = (devOptions == 1 /* Developer Mode enabled */)
81                 && (fullTrackingToggled == 1 /* Raw Measurements Full Tracking enabled */);
82         boolean result = mNative.startMeasurementCollection(enableFullTracking);
83         if (result) {
84             mIsCollectionStarted = true;
85             mEnableFullTracking = enableFullTracking;
86             return RemoteListenerHelper.RESULT_SUCCESS;
87         } else {
88             return RemoteListenerHelper.RESULT_INTERNAL_ERROR;
89         }
90     }
91 
92     @Override
unregisterFromService()93     protected void unregisterFromService() {
94         boolean stopped = mNative.stopMeasurementCollection();
95         if (stopped) {
96             mIsCollectionStarted = false;
97         }
98     }
99 
onMeasurementsAvailable(final GnssMeasurementsEvent event)100     public void onMeasurementsAvailable(final GnssMeasurementsEvent event) {
101         ListenerOperation<IGnssMeasurementsListener> operation =
102                 listener -> listener.onGnssMeasurementsReceived(event);
103         foreach(operation);
104     }
105 
onCapabilitiesUpdated(boolean isGnssMeasurementsSupported)106     public void onCapabilitiesUpdated(boolean isGnssMeasurementsSupported) {
107         setSupported(isGnssMeasurementsSupported);
108         updateResult();
109     }
110 
onGpsEnabledChanged()111     public void onGpsEnabledChanged() {
112         tryUpdateRegistrationWithService();
113         updateResult();
114     }
115 
116     @Override
getHandlerOperation(int result)117     protected ListenerOperation<IGnssMeasurementsListener> getHandlerOperation(int result) {
118         int status;
119         switch (result) {
120             case RESULT_SUCCESS:
121                 status = GnssMeasurementsEvent.Callback.STATUS_READY;
122                 break;
123             case RESULT_NOT_AVAILABLE:
124             case RESULT_NOT_SUPPORTED:
125             case RESULT_INTERNAL_ERROR:
126                 status = GnssMeasurementsEvent.Callback.STATUS_NOT_SUPPORTED;
127                 break;
128             case RESULT_NOT_ALLOWED:
129                 status = GnssMeasurementsEvent.Callback.STATUS_NOT_ALLOWED;
130                 break;
131             case RESULT_GPS_LOCATION_DISABLED:
132                 status = GnssMeasurementsEvent.Callback.STATUS_LOCATION_DISABLED;
133                 break;
134             case RESULT_UNKNOWN:
135                 return null;
136             default:
137                 Log.v(TAG, "Unhandled addListener result: " + result);
138                 return null;
139         }
140         return new StatusChangedOperation(status);
141     }
142 
143     private static class StatusChangedOperation
144             implements ListenerOperation<IGnssMeasurementsListener> {
145         private final int mStatus;
146 
StatusChangedOperation(int status)147         public StatusChangedOperation(int status) {
148             mStatus = status;
149         }
150 
151         @Override
execute(IGnssMeasurementsListener listener)152         public void execute(IGnssMeasurementsListener listener) throws RemoteException {
153             listener.onStatusChanged(mStatus);
154         }
155     }
156 
157     @VisibleForTesting
158     static class GnssMeasurementProviderNative {
isMeasurementSupported()159         public boolean isMeasurementSupported() {
160             return native_is_measurement_supported();
161         }
162 
startMeasurementCollection(boolean enableFullTracking)163         public boolean startMeasurementCollection(boolean enableFullTracking) {
164             return native_start_measurement_collection(enableFullTracking);
165         }
166 
stopMeasurementCollection()167         public boolean stopMeasurementCollection() {
168             return native_stop_measurement_collection();
169         }
170     }
171 
native_is_measurement_supported()172     private static native boolean native_is_measurement_supported();
173 
native_start_measurement_collection(boolean enableFullTracking)174     private static native boolean native_start_measurement_collection(boolean enableFullTracking);
175 
native_stop_measurement_collection()176     private static native boolean native_stop_measurement_collection();
177 }
178