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