1 /* 2 * Copyright (C) 2019 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.location.GnssMeasurementCorrections; 20 import android.os.Handler; 21 import android.util.Log; 22 23 import com.android.internal.annotations.VisibleForTesting; 24 25 /** 26 * Manages GNSS measurement corrections. 27 * 28 * <p>Implements the framework side of the GNSS HAL interfaces {@code IMeasurementCorrections.hal} 29 * and {@code IMeasurementCorrectionsCallback.hal). 30 * 31 * @hide 32 */ 33 public class GnssMeasurementCorrectionsProvider { 34 private static final String TAG = "GnssMeasurementCorrectionsProvider"; 35 36 // These must match with the Capabilities enum in IMeasurementCorrectionsCallback.hal. 37 static final int CAPABILITY_LOS_SATS = 0x0000001; 38 static final int CAPABILITY_EXCESS_PATH_LENGTH = 0x0000002; 39 static final int CAPABILITY_REFLECTING_PLANE = 0x0000004; 40 41 private static final int INVALID_CAPABILITIES = 1 << 31; 42 43 private final Handler mHandler; 44 private final GnssMeasurementCorrectionsProviderNative mNative; 45 private volatile int mCapabilities = INVALID_CAPABILITIES; 46 GnssMeasurementCorrectionsProvider(Handler handler)47 GnssMeasurementCorrectionsProvider(Handler handler) { 48 this(handler, new GnssMeasurementCorrectionsProviderNative()); 49 } 50 51 @VisibleForTesting GnssMeasurementCorrectionsProvider(Handler handler, GnssMeasurementCorrectionsProviderNative aNative)52 GnssMeasurementCorrectionsProvider(Handler handler, 53 GnssMeasurementCorrectionsProviderNative aNative) { 54 mHandler = handler; 55 mNative = aNative; 56 } 57 58 /** 59 * Returns {@code true} if the GNSS HAL implementation supports measurement corrections. 60 */ isAvailableInPlatform()61 public boolean isAvailableInPlatform() { 62 return mNative.isMeasurementCorrectionsSupported(); 63 } 64 65 /** 66 * Injects GNSS measurement corrections into the GNSS chipset. 67 * 68 * @param measurementCorrections a {@link GnssMeasurementCorrections} object with the GNSS 69 * measurement corrections to be injected into the GNSS chipset. 70 */ injectGnssMeasurementCorrections( GnssMeasurementCorrections measurementCorrections)71 public void injectGnssMeasurementCorrections( 72 GnssMeasurementCorrections measurementCorrections) { 73 if (!isCapabilitiesReceived()) { 74 Log.w(TAG, "Failed to inject GNSS measurement corrections. Capabilities " 75 + "not received yet."); 76 return; 77 } 78 mHandler.post(() -> { 79 if (!mNative.injectGnssMeasurementCorrections(measurementCorrections)) { 80 Log.e(TAG, "Failure in injecting GNSS corrections."); 81 } 82 }); 83 } 84 85 /** Handle measurement corrections capabilities update from the GNSS HAL implementation. */ onCapabilitiesUpdated(int capabilities)86 boolean onCapabilitiesUpdated(int capabilities) { 87 if (hasCapability(capabilities, CAPABILITY_LOS_SATS) || hasCapability(capabilities, 88 CAPABILITY_EXCESS_PATH_LENGTH)) { 89 mCapabilities = capabilities; 90 return true; 91 } else { 92 Log.e(TAG, "Failed to set capabilities. Received capabilities 0x" 93 + Integer.toHexString(capabilities) + " does not contain the mandatory " 94 + "LOS_SATS or the EXCESS_PATH_LENGTH capability."); 95 return false; 96 } 97 } 98 99 /** 100 * Returns the measurement corrections specific capabilities of the GNSS HAL implementation. 101 */ getCapabilities()102 int getCapabilities() { 103 return mCapabilities; 104 } 105 106 /** 107 * Returns the string representation of the GNSS measurement capabilities. 108 */ toStringCapabilities()109 String toStringCapabilities() { 110 final int capabilities = getCapabilities(); 111 StringBuilder s = new StringBuilder(); 112 s.append("mCapabilities=0x").append(Integer.toHexString(capabilities)); 113 s.append(" ( "); 114 if (hasCapability(capabilities, CAPABILITY_LOS_SATS)) { 115 s.append("LOS_SATS "); 116 } 117 if (hasCapability(capabilities, CAPABILITY_EXCESS_PATH_LENGTH)) { 118 s.append("EXCESS_PATH_LENGTH "); 119 } 120 if (hasCapability(capabilities, CAPABILITY_REFLECTING_PLANE)) { 121 s.append("REFLECTING_PLANE "); 122 } 123 s.append(")"); 124 return s.toString(); 125 } 126 hasCapability(int halCapabilities, int capability)127 private static boolean hasCapability(int halCapabilities, int capability) { 128 return (halCapabilities & capability) != 0; 129 } 130 isCapabilitiesReceived()131 private boolean isCapabilitiesReceived() { 132 return mCapabilities != INVALID_CAPABILITIES; 133 } 134 135 @VisibleForTesting 136 static class GnssMeasurementCorrectionsProviderNative { isMeasurementCorrectionsSupported()137 public boolean isMeasurementCorrectionsSupported() { 138 return native_is_measurement_corrections_supported(); 139 } 140 injectGnssMeasurementCorrections( GnssMeasurementCorrections measurementCorrections)141 public boolean injectGnssMeasurementCorrections( 142 GnssMeasurementCorrections measurementCorrections) { 143 return native_inject_gnss_measurement_corrections(measurementCorrections); 144 } 145 } 146 native_is_measurement_corrections_supported()147 private static native boolean native_is_measurement_corrections_supported(); 148 native_inject_gnss_measurement_corrections( GnssMeasurementCorrections measurementCorrections)149 private static native boolean native_inject_gnss_measurement_corrections( 150 GnssMeasurementCorrections measurementCorrections); 151 } 152