blob: 3f3f82871c0ff49b97181a19c201df050d0b5cc9 [file] [log] [blame]
Nick Pelly4035f5a2012-08-17 14:43:49 -07001/*
2 * Copyright (C) 2012 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
18package com.android.server.location;
19
20import android.content.Context;
21import android.database.ContentObserver;
22import android.os.Handler;
Victoria Lease83762d22012-10-03 13:51:17 -070023import android.os.UserHandle;
Nick Pelly4035f5a2012-08-17 14:43:49 -070024import android.provider.Settings;
25import android.util.Log;
26import android.util.Slog;
27
28import com.android.server.LocationManagerService;
29
30import java.io.PrintWriter;
31import java.util.ArrayList;
32import java.util.Arrays;
33
34/**
35 * Allows applications to be blacklisted from location updates at run-time.
36 *
37 * This is a silent blacklist. Applications can still call Location Manager
38 * API's, but they just won't receive any locations.
39 */
40public final class LocationBlacklist extends ContentObserver {
41 private static final String TAG = "LocationBlacklist";
42 private static final boolean D = LocationManagerService.D;
43 private static final String BLACKLIST_CONFIG_NAME = "locationPackagePrefixBlacklist";
44 private static final String WHITELIST_CONFIG_NAME = "locationPackagePrefixWhitelist";
45
46 private final Context mContext;
47 private final Object mLock = new Object();
48
49 // all fields below synchronized on mLock
50 private String[] mWhitelist = new String[0];
51 private String[] mBlacklist = new String[0];
Victoria Lease83762d22012-10-03 13:51:17 -070052
Xiaohui Chen98404fd2015-08-17 16:09:02 -070053 private int mCurrentUserId = UserHandle.USER_SYSTEM;
Nick Pelly4035f5a2012-08-17 14:43:49 -070054
55 public LocationBlacklist(Context context, Handler handler) {
56 super(handler);
57 mContext = context;
58 }
59
60 public void init() {
61 mContext.getContentResolver().registerContentObserver(Settings.Secure.getUriFor(
Victoria Lease83762d22012-10-03 13:51:17 -070062 BLACKLIST_CONFIG_NAME), false, this, UserHandle.USER_ALL);
Nick Pelly4035f5a2012-08-17 14:43:49 -070063// mContext.getContentResolver().registerContentObserver(Settings.Secure.getUriFor(
Victoria Lease83762d22012-10-03 13:51:17 -070064// WHITELIST_CONFIG_NAME), false, this, UserHandle.USER_ALL);
Nick Pelly4035f5a2012-08-17 14:43:49 -070065 reloadBlacklist();
66 }
67
Victoria Lease83762d22012-10-03 13:51:17 -070068 private void reloadBlacklistLocked() {
69 mWhitelist = getStringArrayLocked(WHITELIST_CONFIG_NAME);
Dianne Hackborn5e45ee62013-01-24 19:13:44 -080070 if (D) Slog.d(TAG, "whitelist: " + Arrays.toString(mWhitelist));
Victoria Lease83762d22012-10-03 13:51:17 -070071 mBlacklist = getStringArrayLocked(BLACKLIST_CONFIG_NAME);
Dianne Hackborn5e45ee62013-01-24 19:13:44 -080072 if (D) Slog.d(TAG, "blacklist: " + Arrays.toString(mBlacklist));
Victoria Lease83762d22012-10-03 13:51:17 -070073 }
74
Nick Pelly4035f5a2012-08-17 14:43:49 -070075 private void reloadBlacklist() {
Nick Pelly4035f5a2012-08-17 14:43:49 -070076 synchronized (mLock) {
Victoria Lease83762d22012-10-03 13:51:17 -070077 reloadBlacklistLocked();
Nick Pelly4035f5a2012-08-17 14:43:49 -070078 }
79 }
80
81 /**
82 * Return true if in blacklist
83 * (package name matches blacklist, and does not match whitelist)
84 */
85 public boolean isBlacklisted(String packageName) {
86 synchronized (mLock) {
87 for (String black : mBlacklist) {
88 if (packageName.startsWith(black)) {
89 if (inWhitelist(packageName)) {
90 continue;
91 } else {
92 if (D) Log.d(TAG, "dropping location (blacklisted): "
93 + packageName + " matches " + black);
94 return true;
95 }
96 }
97 }
98 }
Nick Pelly4035f5a2012-08-17 14:43:49 -070099 return false;
100 }
101
102 /**
103 * Return true if any of packages are in whitelist
104 */
105 private boolean inWhitelist(String pkg) {
106 synchronized (mLock) {
107 for (String white : mWhitelist) {
108 if (pkg.startsWith(white)) return true;
109 }
110 }
111 return false;
112 }
113
114 @Override
115 public void onChange(boolean selfChange) {
116 reloadBlacklist();
117 }
118
Victoria Lease83762d22012-10-03 13:51:17 -0700119 public void switchUser(int userId) {
120 synchronized(mLock) {
121 mCurrentUserId = userId;
122 reloadBlacklistLocked();
123 }
124 }
125
126 private String[] getStringArrayLocked(String key) {
127 String flatString;
128 synchronized(mLock) {
129 flatString = Settings.Secure.getStringForUser(mContext.getContentResolver(), key,
130 mCurrentUserId);
131 }
Nick Pelly4035f5a2012-08-17 14:43:49 -0700132 if (flatString == null) {
133 return new String[0];
134 }
135 String[] splitStrings = flatString.split(",");
136 ArrayList<String> result = new ArrayList<String>();
137 for (String pkg : splitStrings) {
138 pkg = pkg.trim();
139 if (pkg.isEmpty()) {
140 continue;
141 }
142 result.add(pkg);
143 }
144 return result.toArray(new String[result.size()]);
145 }
146
147 public void dump(PrintWriter pw) {
148 pw.println("mWhitelist=" + Arrays.toString(mWhitelist) + " mBlacklist=" +
149 Arrays.toString(mBlacklist));
150 }
151}