diff options
Diffstat (limited to 'src/com/android')
| -rw-r--r-- | src/com/android/browser/BrowserActivity.java | 11 | ||||
| -rw-r--r-- | src/com/android/browser/BrowserProvider.java | 39 | ||||
| -rw-r--r-- | src/com/android/browser/SystemAllowGeolocationOrigins.java | 204 |
3 files changed, 216 insertions, 38 deletions
diff --git a/src/com/android/browser/BrowserActivity.java b/src/com/android/browser/BrowserActivity.java index ff16e4e87..406132f5e 100644 --- a/src/com/android/browser/BrowserActivity.java +++ b/src/com/android/browser/BrowserActivity.java @@ -365,6 +365,11 @@ public class BrowserActivity extends Activity } // Work out which packages are installed on the system. getInstalledPackages(); + + // Start watching the default geolocation permissions + mSystemAllowGeolocationOrigins + = new SystemAllowGeolocationOrigins(getApplicationContext()); + mSystemAllowGeolocationOrigins.start(); } /** @@ -981,6 +986,10 @@ public class BrowserActivity extends Activity WebIconDatabase.getInstance().close(); unregisterReceiver(mPackageInstallationReceiver); + + // Stop watching the default geolocation permissions + mSystemAllowGeolocationOrigins.stop(); + mSystemAllowGeolocationOrigins = null; } @Override @@ -3872,6 +3881,8 @@ public class BrowserActivity extends Activity private BroadcastReceiver mPackageInstallationReceiver; + private SystemAllowGeolocationOrigins mSystemAllowGeolocationOrigins; + // activity requestCode final static int COMBO_PAGE = 1; final static int DOWNLOAD_PAGE = 2; diff --git a/src/com/android/browser/BrowserProvider.java b/src/com/android/browser/BrowserProvider.java index 501a52a73..bf1f9d5b3 100644 --- a/src/com/android/browser/BrowserProvider.java +++ b/src/com/android/browser/BrowserProvider.java @@ -48,7 +48,6 @@ import android.text.TextUtils; import android.util.Log; import android.util.Patterns; import android.util.TypedValue; -import android.webkit.GeolocationPermissions; import java.io.File; @@ -71,7 +70,7 @@ public class BrowserProvider extends ContentProvider { "viewer?source=androidclient"; private static final String[] TABLE_NAMES = new String[] { - "bookmarks", "searches", "geolocation" + "bookmarks", "searches" }; private static final String[] SUGGEST_PROJECTION = new String[] { "_id", "url", "title", "bookmark", "user_entered" @@ -113,7 +112,6 @@ public class BrowserProvider extends ContentProvider { // make sure that these match the index of TABLE_NAMES private static final int URI_MATCH_BOOKMARKS = 0; private static final int URI_MATCH_SEARCHES = 1; - private static final int URI_MATCH_GEOLOCATION = 2; // (id % 10) should match the table name index private static final int URI_MATCH_BOOKMARKS_ID = 10; private static final int URI_MATCH_SEARCHES_ID = 11; @@ -138,8 +136,6 @@ public class BrowserProvider extends ContentProvider { URI_MATCHER.addURI("browser", TABLE_NAMES[URI_MATCH_BOOKMARKS] + "/" + SearchManager.SUGGEST_URI_PATH_QUERY, URI_MATCH_BOOKMARKS_SUGGEST); - URI_MATCHER.addURI("browser", TABLE_NAMES[URI_MATCH_GEOLOCATION], - URI_MATCH_GEOLOCATION); } // 1 -> 2 add cache table @@ -839,9 +835,6 @@ public class BrowserProvider extends ContentProvider { if (match == -1) { throw new IllegalArgumentException("Unknown URL"); } - if (match == URI_MATCH_GEOLOCATION) { - throw new UnsupportedOperationException("query() not supported for geolocation"); - } if (match == URI_MATCH_SUGGEST && mResultsCursor != null) { Cursor results = mResultsCursor; mResultsCursor = null; @@ -942,9 +935,6 @@ public class BrowserProvider extends ContentProvider { case URI_MATCH_SUGGEST: return SearchManager.SUGGEST_MIME_TYPE; - case URI_MATCH_GEOLOCATION: - return "vnd.android.cursor.dir/geolocation"; - default: throw new IllegalArgumentException("Unknown URL"); } @@ -981,16 +971,6 @@ public class BrowserProvider extends ContentProvider { break; } - case URI_MATCH_GEOLOCATION: - String origin = initialValues.getAsString(Browser.GeolocationColumns.ORIGIN); - if (TextUtils.isEmpty(origin)) { - throw new IllegalArgumentException("Empty origin"); - } - GeolocationPermissions.getInstance().allow(origin); - // TODO: Should we have one URI per permission? - uri = Browser.GEOLOCATION_URI; - break; - default: throw new IllegalArgumentException("Unknown URL"); } @@ -1020,10 +1000,6 @@ public class BrowserProvider extends ContentProvider { throw new IllegalArgumentException("Unknown URL"); } - if (match == URI_MATCH_GEOLOCATION) { - return deleteGeolocation(url, where, whereArgs); - } - // need to know whether it's the bookmarks table for a couple of reasons boolean isBookmarkTable = (match == URI_MATCH_BOOKMARKS_ID); String id = null; @@ -1062,19 +1038,6 @@ public class BrowserProvider extends ContentProvider { return count; } - private int deleteGeolocation(Uri uri, String where, String[] whereArgs) { - if (whereArgs.length != 1) { - throw new IllegalArgumentException("Bad where arguments"); - } - String origin = whereArgs[0]; - if (TextUtils.isEmpty(origin)) { - throw new IllegalArgumentException("Empty origin"); - } - GeolocationPermissions.getInstance().clear(origin); - getContext().getContentResolver().notifyChange(Browser.GEOLOCATION_URI, null); - return 1; // We always return 1, to avoid having to check whether anything was actually removed - } - @Override public int update(Uri url, ContentValues values, String where, String[] whereArgs) { diff --git a/src/com/android/browser/SystemAllowGeolocationOrigins.java b/src/com/android/browser/SystemAllowGeolocationOrigins.java new file mode 100644 index 000000000..3f5a84eeb --- /dev/null +++ b/src/com/android/browser/SystemAllowGeolocationOrigins.java @@ -0,0 +1,204 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.browser; + +import android.content.Context; +import android.content.SharedPreferences; +import android.database.ContentObserver; +import android.net.Uri; +import android.os.AsyncTask; +import android.os.Handler; +import android.preference.PreferenceManager; +import android.provider.Settings; +import android.text.TextUtils; +import android.webkit.GeolocationPermissions; +import android.webkit.ValueCallback; + +import java.util.HashSet; +import java.util.Set; + +/** + * Manages the interaction between the secure system setting for default geolocation + * permissions and the browser. + */ +class SystemAllowGeolocationOrigins { + + // Preference key for the value of the system setting last read by the browser + private final static String LAST_READ_ALLOW_GEOLOCATION_ORIGINS = + "last_read_allow_geolocation_origins"; + + // The application context + private final Context mContext; + + // The observer used to listen to the system setting. + private final SettingObserver mSettingObserver; + + public SystemAllowGeolocationOrigins(Context context) { + mContext = context; + mSettingObserver = new SettingObserver(); + } + + /** + * Checks whether the setting has changed and installs an observer to listen for + * future changes. Must be called on the application main thread. + */ + public void start() { + // Register to receive notifications when the system settings change. + Uri uri = Settings.Secure.getUriFor(Settings.Secure.ALLOWED_GEOLOCATION_ORIGINS); + mContext.getContentResolver().registerContentObserver(uri, false, mSettingObserver); + + // Read and apply the setting if needed. + maybeApplySettingAsync(); + } + + /** + * Stops the manager. + */ + public void stop() { + mContext.getContentResolver().unregisterContentObserver(mSettingObserver); + } + + void maybeApplySettingAsync() { + new AsyncTask<Void,Void,Void>() { + @Override + protected Void doInBackground(Void... params) { + maybeApplySetting(); + return null; + } + }.execute(); + } + + /** + * Checks to see if the system setting has changed and if so, + * updates the Geolocation permissions accordingly. + */ + private void maybeApplySetting() { + // Get the new value + String newSetting = getSystemSetting(); + + // Get the last read value + SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(mContext); + String lastReadSetting = + preferences.getString(LAST_READ_ALLOW_GEOLOCATION_ORIGINS, ""); + + // If the new value is the same as the last one we read, we're done. + if (TextUtils.equals(lastReadSetting, newSetting)) { + return; + } + + // Save the new value as the last read value + preferences.edit() + .putString(LAST_READ_ALLOW_GEOLOCATION_ORIGINS, newSetting) + .commit(); + + Set<String> oldOrigins = parseAllowGeolocationOrigins(lastReadSetting); + Set<String> newOrigins = parseAllowGeolocationOrigins(newSetting); + Set<String> addedOrigins = setMinus(newOrigins, oldOrigins); + Set<String> removedOrigins = setMinus(oldOrigins, newOrigins); + + // Remove the origins in the last read value + removeOrigins(removedOrigins); + + // Add the origins in the new value + addOrigins(addedOrigins); + } + + /** + * Parses the value of the default geolocation permissions setting. + * + * @param setting A space-separated list of origins. + * @return A mutable set of origins. + */ + private static HashSet<String> parseAllowGeolocationOrigins(String setting) { + HashSet<String> origins = new HashSet<String>(); + if (!TextUtils.isEmpty(setting)) { + for (String origin : setting.split("\\s+")) { + if (!TextUtils.isEmpty(origin)) { + origins.add(origin); + } + } + } + return origins; + } + + /** + * Gets the difference between two sets. Does not modify any of the arguments. + * + * @return A set containing all elements in {@code x} that are not in {@code y}. + */ + private <A> Set<A> setMinus(Set<A> x, Set<A> y) { + HashSet<A> z = new HashSet<A>(x.size()); + for (A a : x) { + if (!y.contains(a)) { + z.add(a); + } + } + return z; + } + + /** + * Gets the current system setting for default allowed geolocation origins. + * + * @return The default allowed origins. Returns {@code ""} if not set. + */ + private String getSystemSetting() { + String value = Settings.Secure.getString(mContext.getContentResolver(), + Settings.Secure.ALLOWED_GEOLOCATION_ORIGINS); + return value == null ? "" : value; + } + + /** + * Adds geolocation permissions for the given origins. + */ + private void addOrigins(Set<String> origins) { + for (String origin : origins) { + GeolocationPermissions.getInstance().allow(origin); + } + } + + /** + * Removes geolocation permissions for the given origins, if they are allowed. + * If they are denied or not set, nothing is done. + */ + private void removeOrigins(Set<String> origins) { + for (final String origin : origins) { + GeolocationPermissions.getInstance().getAllowed(origin, new ValueCallback<Boolean>() { + public void onReceiveValue(Boolean value) { + if (value != null && value.booleanValue()) { + GeolocationPermissions.getInstance().clear(origin); + } + } + }); + } + } + + /** + * Listens for changes to the system setting. + */ + private class SettingObserver extends ContentObserver { + + SettingObserver() { + super(new Handler()); + } + + @Override + public void onChange(boolean selfChange) { + maybeApplySettingAsync(); + } + } + +} |
