• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2020 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.gnss;
18 
19 import android.content.ContentResolver;
20 import android.content.Context;
21 import android.database.ContentObserver;
22 import android.os.Handler;
23 import android.os.Looper;
24 import android.os.UserHandle;
25 import android.provider.Settings;
26 import android.util.Log;
27 
28 import com.android.internal.annotations.VisibleForTesting;
29 
30 import java.util.ArrayList;
31 import java.util.List;
32 
33 /**
34  * Detects denylist change and updates the denylist.
35  */
36 class GnssSatelliteBlocklistHelper {
37 
38     private static final String TAG = "GnssBlocklistHelper";
39     private static final String BLOCKLIST_DELIMITER = ",";
40 
41     private final Context mContext;
42     private final GnssSatelliteBlocklistCallback mCallback;
43 
44     interface GnssSatelliteBlocklistCallback {
onUpdateSatelliteBlocklist(int[] constellations, int[] svids)45         void onUpdateSatelliteBlocklist(int[] constellations, int[] svids);
46     }
47 
GnssSatelliteBlocklistHelper(Context context, Looper looper, GnssSatelliteBlocklistCallback callback)48     GnssSatelliteBlocklistHelper(Context context, Looper looper,
49             GnssSatelliteBlocklistCallback callback) {
50         mContext = context;
51         mCallback = callback;
52         ContentObserver contentObserver = new ContentObserver(new Handler(looper)) {
53             @Override
54             public void onChange(boolean selfChange) {
55                 updateSatelliteBlocklist();
56             }
57         };
58         mContext.getContentResolver().registerContentObserver(
59                 Settings.Global.getUriFor(
60                         Settings.Global.GNSS_SATELLITE_BLOCKLIST),
61                 true,
62                 contentObserver, UserHandle.USER_ALL);
63     }
64 
updateSatelliteBlocklist()65     void updateSatelliteBlocklist() {
66         ContentResolver resolver = mContext.getContentResolver();
67         String blocklist = Settings.Global.getString(
68                 resolver,
69                 Settings.Global.GNSS_SATELLITE_BLOCKLIST);
70         if (blocklist == null) {
71             blocklist = "";
72         }
73         Log.i(TAG, String.format("Update GNSS satellite blocklist: %s", blocklist));
74 
75         List<Integer> blocklistValues;
76         try {
77             blocklistValues = parseSatelliteBlocklist(blocklist);
78         } catch (NumberFormatException e) {
79             Log.e(TAG, "Exception thrown when parsing blocklist string.", e);
80             return;
81         }
82 
83         if (blocklistValues.size() % 2 != 0) {
84             Log.e(TAG, "blocklist string has odd number of values."
85                     + "Aborting updateSatelliteBlocklist");
86             return;
87         }
88 
89         int length = blocklistValues.size() / 2;
90         int[] constellations = new int[length];
91         int[] svids = new int[length];
92         for (int i = 0; i < length; i++) {
93             constellations[i] = blocklistValues.get(i * 2);
94             svids[i] = blocklistValues.get(i * 2 + 1);
95         }
96         mCallback.onUpdateSatelliteBlocklist(constellations, svids);
97     }
98 
99     @VisibleForTesting
parseSatelliteBlocklist(String blocklist)100     static List<Integer> parseSatelliteBlocklist(String blocklist) throws NumberFormatException {
101         String[] strings = blocklist.split(BLOCKLIST_DELIMITER);
102         List<Integer> parsed = new ArrayList<>(strings.length);
103         for (String string : strings) {
104             string = string.trim();
105             if (!"".equals(string)) {
106                 int value = Integer.parseInt(string);
107                 if (value < 0) {
108                     throw new NumberFormatException("Negative value is invalid.");
109                 }
110                 parsed.add(value);
111             }
112         }
113         return parsed;
114     }
115 }
116