blob: 0add86315487bab618eb5183c265dabbac8d7ad7 [file] [log] [blame]
destradaaea8a8a62014-06-23 18:19:03 -07001/*
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
17package com.android.server.location;
18
Yu-Han Yang8de21502018-04-23 01:40:25 -070019import android.content.Context;
Lifu Tang818aa2c2016-02-01 01:52:00 -080020import android.location.GnssMeasurementsEvent;
21import android.location.IGnssMeasurementsListener;
destradaa6568d702014-10-27 12:47:41 -070022import android.os.Handler;
destradaaea8a8a62014-06-23 18:19:03 -070023import android.os.RemoteException;
Yu-Han Yang8de21502018-04-23 01:40:25 -070024import android.provider.Settings;
destradaa6568d702014-10-27 12:47:41 -070025import android.util.Log;
destradaaea8a8a62014-06-23 18:19:03 -070026
Yu-Han Yang8de21502018-04-23 01:40:25 -070027import com.android.internal.annotations.VisibleForTesting;
28
destradaaea8a8a62014-06-23 18:19:03 -070029/**
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 */
Yu-Han Yang8de21502018-04-23 01:40:25 -070036public abstract class GnssMeasurementsProvider extends
37 RemoteListenerHelper<IGnssMeasurementsListener> {
Lifu Tang818aa2c2016-02-01 01:52:00 -080038 private static final String TAG = "GnssMeasurementsProvider";
Yu-Han Yang8de21502018-04-23 01:40:25 -070039 private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
destradaa6568d702014-10-27 12:47:41 -070040
Yu-Han Yang8de21502018-04-23 01:40:25 -070041 private final Context mContext;
42 private final GnssMeasurementProviderNative mNative;
43
44 private boolean mIsCollectionStarted;
45 private boolean mEnableFullTracking;
46
47 protected GnssMeasurementsProvider(Context context, Handler handler) {
48 this(context, handler, new GnssMeasurementProviderNative());
49 }
50
51 @VisibleForTesting
52 GnssMeasurementsProvider(Context context, Handler handler,
53 GnssMeasurementProviderNative aNative) {
destradaa6568d702014-10-27 12:47:41 -070054 super(handler, TAG);
Yu-Han Yang8de21502018-04-23 01:40:25 -070055 mContext = context;
56 mNative = aNative;
57 }
58
59 // TODO(b/37460011): Use this with death recovery logic.
60 void resumeIfStarted() {
61 if (DEBUG) {
62 Log.d(TAG, "resumeIfStarted");
63 }
64 if (mIsCollectionStarted) {
65 mNative.startMeasurementCollection(mEnableFullTracking);
66 }
67 }
68
69 @Override
70 public boolean isAvailableInPlatform() {
71 return mNative.isMeasurementSupported();
72 }
73
74 @Override
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
93 protected void unregisterFromService() {
94 boolean stopped = mNative.stopMeasurementCollection();
95 if (stopped) {
96 mIsCollectionStarted = false;
97 }
destradaa4b3e3932014-07-21 18:01:47 -070098 }
destradaaea8a8a62014-06-23 18:19:03 -070099
Lifu Tang818aa2c2016-02-01 01:52:00 -0800100 public void onMeasurementsAvailable(final GnssMeasurementsEvent event) {
101 ListenerOperation<IGnssMeasurementsListener> operation =
Yu-Han Yang8de21502018-04-23 01:40:25 -0700102 listener -> listener.onGnssMeasurementsReceived(event);
destradaaea8a8a62014-06-23 18:19:03 -0700103 foreach(operation);
104 }
destradaa6568d702014-10-27 12:47:41 -0700105
Lifu Tang818aa2c2016-02-01 01:52:00 -0800106 public void onCapabilitiesUpdated(boolean isGnssMeasurementsSupported) {
107 setSupported(isGnssMeasurementsSupported);
destradaa13a60b02015-01-15 18:36:01 -0800108 updateResult();
109 }
110
111 public void onGpsEnabledChanged() {
Wyatt Rileyaa420d52017-07-03 15:14:42 -0700112 tryUpdateRegistrationWithService();
113 updateResult();
destradaa6568d702014-10-27 12:47:41 -0700114 }
115
116 @Override
Lifu Tang818aa2c2016-02-01 01:52:00 -0800117 protected ListenerOperation<IGnssMeasurementsListener> getHandlerOperation(int result) {
destradaa13a60b02015-01-15 18:36:01 -0800118 int status;
destradaa6568d702014-10-27 12:47:41 -0700119 switch (result) {
120 case RESULT_SUCCESS:
Lifu Tange8abe8e2016-04-01 10:32:05 -0700121 status = GnssMeasurementsEvent.Callback.STATUS_READY;
destradaa6568d702014-10-27 12:47:41 -0700122 break;
123 case RESULT_NOT_AVAILABLE:
124 case RESULT_NOT_SUPPORTED:
125 case RESULT_INTERNAL_ERROR:
Lifu Tange8abe8e2016-04-01 10:32:05 -0700126 status = GnssMeasurementsEvent.Callback.STATUS_NOT_SUPPORTED;
destradaa6568d702014-10-27 12:47:41 -0700127 break;
gomo48f1a642017-11-10 20:35:46 -0800128 case RESULT_NOT_ALLOWED:
129 status = GnssMeasurementsEvent.Callback.STATUS_NOT_ALLOWED;
130 break;
destradaa6568d702014-10-27 12:47:41 -0700131 case RESULT_GPS_LOCATION_DISABLED:
Lifu Tange8abe8e2016-04-01 10:32:05 -0700132 status = GnssMeasurementsEvent.Callback.STATUS_LOCATION_DISABLED;
destradaa6568d702014-10-27 12:47:41 -0700133 break;
destradaa13a60b02015-01-15 18:36:01 -0800134 case RESULT_UNKNOWN:
135 return null;
destradaa6568d702014-10-27 12:47:41 -0700136 default:
137 Log.v(TAG, "Unhandled addListener result: " + result);
138 return null;
139 }
140 return new StatusChangedOperation(status);
141 }
142
destradaa13a60b02015-01-15 18:36:01 -0800143 private static class StatusChangedOperation
Lifu Tang818aa2c2016-02-01 01:52:00 -0800144 implements ListenerOperation<IGnssMeasurementsListener> {
destradaa6568d702014-10-27 12:47:41 -0700145 private final int mStatus;
146
147 public StatusChangedOperation(int status) {
148 mStatus = status;
149 }
150
151 @Override
Lifu Tang818aa2c2016-02-01 01:52:00 -0800152 public void execute(IGnssMeasurementsListener listener) throws RemoteException {
destradaa6568d702014-10-27 12:47:41 -0700153 listener.onStatusChanged(mStatus);
154 }
155 }
Yu-Han Yang8de21502018-04-23 01:40:25 -0700156
157 @VisibleForTesting
158 static class GnssMeasurementProviderNative {
159 public boolean isMeasurementSupported() {
160 return native_is_measurement_supported();
161 }
162
163 public boolean startMeasurementCollection(boolean enableFullTracking) {
164 return native_start_measurement_collection(enableFullTracking);
165 }
166
167 public boolean stopMeasurementCollection() {
168 return native_stop_measurement_collection();
169 }
170 }
171
172 private static native boolean native_is_measurement_supported();
173
174 private static native boolean native_start_measurement_collection(boolean enableFullTracking);
175
176 private static native boolean native_stop_measurement_collection();
destradaaea8a8a62014-06-23 18:19:03 -0700177}