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.GnssCapabilities;
20 import android.util.Log;
21 
22 import com.android.internal.annotations.GuardedBy;
23 
24 /**
25  * Provides GNSS capabilities supported by the GNSS HAL implementation.
26  */
27 public class GnssCapabilitiesProvider {
28     private static final String TAG = "GnssCapabilitiesProvider";
29     private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
30 
31     private static final long GNSS_CAPABILITIES_TOP_HAL =
32             GnssCapabilities.LOW_POWER_MODE | GnssCapabilities.SATELLITE_BLACKLIST
33                     | GnssCapabilities.GEOFENCING | GnssCapabilities.MEASUREMENTS
34                     | GnssCapabilities.NAV_MESSAGES;
35 
36     private static final long GNSS_CAPABILITIES_SUB_HAL_MEASUREMENT_CORRECTIONS =
37             GnssCapabilities.MEASUREMENT_CORRECTIONS
38                     | GnssCapabilities.MEASUREMENT_CORRECTIONS_LOS_SATS
39                     | GnssCapabilities.MEASUREMENT_CORRECTIONS_EXCESS_PATH_LENGTH
40                     | GnssCapabilities.MEASUREMENT_CORRECTIONS_REFLECTING_PLANE;
41 
42     // Capabilities in {@link android.location.GnssCapabilities} supported by GNSS chipset.
43     @GuardedBy("this")
44     private long mGnssCapabilities;
45 
46     /**
47      * Returns the capabilities supported by the GNSS chipset.
48      *
49      * <p>The capabilities are described in {@link android.location.GnssCapabilities} and
50      * their integer values correspond to the bit positions in the returned {@code long} value.
51      */
getGnssCapabilities()52     public long getGnssCapabilities() {
53         synchronized (this) {
54             return mGnssCapabilities;
55         }
56     }
57 
58     /**
59      * Updates the general capabilities exposed through {@link android.location.GnssCapabilities}.
60      */
setTopHalCapabilities(int topHalCapabilities)61     void setTopHalCapabilities(int topHalCapabilities) {
62         long gnssCapabilities = 0;
63         if (hasCapability(topHalCapabilities,
64                 GnssLocationProvider.GPS_CAPABILITY_LOW_POWER_MODE)) {
65             gnssCapabilities |= GnssCapabilities.LOW_POWER_MODE;
66         }
67         if (hasCapability(topHalCapabilities,
68                 GnssLocationProvider.GPS_CAPABILITY_SATELLITE_BLACKLIST)) {
69             gnssCapabilities |= GnssCapabilities.SATELLITE_BLACKLIST;
70         }
71         if (hasCapability(topHalCapabilities, GnssLocationProvider.GPS_CAPABILITY_GEOFENCING)) {
72             gnssCapabilities |= GnssCapabilities.GEOFENCING;
73         }
74         if (hasCapability(topHalCapabilities, GnssLocationProvider.GPS_CAPABILITY_MEASUREMENTS)) {
75             gnssCapabilities |= GnssCapabilities.MEASUREMENTS;
76         }
77         if (hasCapability(topHalCapabilities, GnssLocationProvider.GPS_CAPABILITY_NAV_MESSAGES)) {
78             gnssCapabilities |= GnssCapabilities.NAV_MESSAGES;
79         }
80 
81         synchronized (this) {
82             mGnssCapabilities &= ~GNSS_CAPABILITIES_TOP_HAL;
83             mGnssCapabilities |= gnssCapabilities;
84             if (DEBUG) {
85                 Log.d(TAG, "setTopHalCapabilities, mGnssCapabilities=0x" + Long.toHexString(
86                         mGnssCapabilities) + ", " + GnssCapabilities.of(mGnssCapabilities));
87             }
88         }
89     }
90 
91     /**
92      * Updates the measurement corrections related capabilities exposed through
93      * {@link android.location.GnssCapabilities}.
94      */
setSubHalMeasurementCorrectionsCapabilities(int measurementCorrectionsCapabilities)95     void setSubHalMeasurementCorrectionsCapabilities(int measurementCorrectionsCapabilities) {
96         long gnssCapabilities = GnssCapabilities.MEASUREMENT_CORRECTIONS;
97         if (hasCapability(measurementCorrectionsCapabilities,
98                 GnssMeasurementCorrectionsProvider.CAPABILITY_LOS_SATS)) {
99             gnssCapabilities |= GnssCapabilities.MEASUREMENT_CORRECTIONS_LOS_SATS;
100         }
101         if (hasCapability(measurementCorrectionsCapabilities,
102                 GnssMeasurementCorrectionsProvider.CAPABILITY_EXCESS_PATH_LENGTH)) {
103             gnssCapabilities |= GnssCapabilities.MEASUREMENT_CORRECTIONS_EXCESS_PATH_LENGTH;
104         }
105         if (hasCapability(measurementCorrectionsCapabilities,
106                 GnssMeasurementCorrectionsProvider.CAPABILITY_REFLECTING_PLANE)) {
107             gnssCapabilities |= GnssCapabilities.MEASUREMENT_CORRECTIONS_REFLECTING_PLANE;
108         }
109 
110         synchronized (this) {
111             mGnssCapabilities &= ~GNSS_CAPABILITIES_SUB_HAL_MEASUREMENT_CORRECTIONS;
112             mGnssCapabilities |= gnssCapabilities;
113             if (DEBUG) {
114                 Log.d(TAG, "setSubHalMeasurementCorrectionsCapabilities, mGnssCapabilities=0x"
115                         + Long.toHexString(mGnssCapabilities) + ", " + GnssCapabilities.of(
116                         mGnssCapabilities));
117             }
118         }
119     }
120 
hasCapability(int halCapabilities, int capability)121     private static  boolean hasCapability(int halCapabilities, int capability) {
122         return (halCapabilities & capability) != 0;
123     }
124 }
125