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