LocationBlacklist.java revision 4035f5a7c191a68bc9a5912ce44c43c82e9e5dbf
1/*
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;
23import android.provider.Settings;
24import android.util.Log;
25import android.util.Slog;
26
27import com.android.server.LocationManagerService;
28
29import java.io.PrintWriter;
30import java.util.ArrayList;
31import java.util.Arrays;
32
33/**
34 * Allows applications to be blacklisted from location updates at run-time.
35 *
36 * This is a silent blacklist. Applications can still call Location Manager
37 * API's, but they just won't receive any locations.
38 */
39public final class LocationBlacklist extends ContentObserver {
40    private static final String TAG = "LocationBlacklist";
41    private static final boolean D = LocationManagerService.D;
42    private static final String BLACKLIST_CONFIG_NAME = "locationPackagePrefixBlacklist";
43    private static final String WHITELIST_CONFIG_NAME = "locationPackagePrefixWhitelist";
44
45    private final Context mContext;
46    private final Object mLock = new Object();
47
48    // all fields below synchronized on mLock
49    private String[] mWhitelist = new String[0];
50    private String[] mBlacklist = new String[0];
51
52    public LocationBlacklist(Context context, Handler handler) {
53        super(handler);
54        mContext = context;
55    }
56
57    public void init() {
58        mContext.getContentResolver().registerContentObserver(Settings.Secure.getUriFor(
59                BLACKLIST_CONFIG_NAME), false, this);
60//        mContext.getContentResolver().registerContentObserver(Settings.Secure.getUriFor(
61//                WHITELIST_CONFIG_NAME), false, this);
62        reloadBlacklist();
63    }
64
65    private void reloadBlacklist() {
66        String blacklist[] = getStringArray(BLACKLIST_CONFIG_NAME);
67        String whitelist[] = getStringArray(WHITELIST_CONFIG_NAME);
68        synchronized (mLock) {
69            mWhitelist = whitelist;
70            Slog.i(TAG, "whitelist: " + Arrays.toString(mWhitelist));
71            mBlacklist = blacklist;
72            Slog.i(TAG, "blacklist: " + Arrays.toString(mBlacklist));
73        }
74    }
75
76    /**
77     * Return true if in blacklist
78     * (package name matches blacklist, and does not match whitelist)
79     */
80    public boolean isBlacklisted(String packageName) {
81        synchronized (mLock) {
82            for (String black : mBlacklist) {
83                if (packageName.startsWith(black)) {
84                    if (inWhitelist(packageName)) {
85                        continue;
86                    } else {
87                        if (D) Log.d(TAG, "dropping location (blacklisted): "
88                                + packageName + " matches " + black);
89                        return true;
90                    }
91                }
92            }
93        }
94        return false;
95    }
96
97    /**
98     * Return true if any of packages are in whitelist
99     */
100    private boolean inWhitelist(String pkg) {
101        synchronized (mLock) {
102            for (String white : mWhitelist) {
103                if (pkg.startsWith(white)) return true;
104            }
105        }
106        return false;
107    }
108
109    @Override
110    public void onChange(boolean selfChange) {
111        reloadBlacklist();
112    }
113
114    private String[] getStringArray(String key) {
115        String flatString = Settings.Secure.getString(mContext.getContentResolver(), key);
116        if (flatString == null) {
117            return new String[0];
118        }
119        String[] splitStrings = flatString.split(",");
120        ArrayList<String> result = new ArrayList<String>();
121        for (String pkg : splitStrings) {
122            pkg = pkg.trim();
123            if (pkg.isEmpty()) {
124                continue;
125            }
126            result.add(pkg);
127        }
128        return result.toArray(new String[result.size()]);
129    }
130
131    public void dump(PrintWriter pw) {
132        pw.println("mWhitelist=" + Arrays.toString(mWhitelist) + " mBlacklist=" +
133                Arrays.toString(mBlacklist));
134    }
135}
136