summaryrefslogtreecommitdiffstats
path: root/core/java/android/webkit/GoogleLocationSettingManager.java
diff options
context:
space:
mode:
Diffstat (limited to 'core/java/android/webkit/GoogleLocationSettingManager.java')
-rw-r--r--core/java/android/webkit/GoogleLocationSettingManager.java209
1 files changed, 209 insertions, 0 deletions
diff --git a/core/java/android/webkit/GoogleLocationSettingManager.java b/core/java/android/webkit/GoogleLocationSettingManager.java
new file mode 100644
index 0000000..ecac70a
--- /dev/null
+++ b/core/java/android/webkit/GoogleLocationSettingManager.java
@@ -0,0 +1,209 @@
+/*
+ * Copyright (C) 2009 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 android.webkit;
+
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.content.SharedPreferences.Editor;
+import android.database.ContentObserver;
+import android.os.Handler;
+import android.preference.PreferenceManager;
+import android.provider.Settings;
+
+import java.util.HashSet;
+
+/**
+ * A class to manage the interaction between the system setting 'Location &
+ * Security - Share with Google' and the browser. When this setting is set
+ * to true, we allow Geolocation for Google origins. When this setting is
+ * set to false, we clear Geolocation permissions for Google origins.
+ */
+class GoogleLocationSettingManager {
+ // The observer used to listen to the system setting.
+ private GoogleLocationSettingObserver mSettingObserver;
+
+ // The value of the system setting that indicates true.
+ private final static int sSystemSettingTrue = 1;
+ // The value of the system setting that indicates false.
+ private final static int sSystemSettingFalse = 0;
+ // The value of the USE_LOCATION_FOR_SERVICES system setting last read
+ // by the browser.
+ private final static String LAST_READ_USE_LOCATION_FOR_SERVICES =
+ "lastReadUseLocationForServices";
+ // The Browser package name.
+ private static final String BROWSER_PACKAGE_NAME = "com.android.browser";
+ // The Google origins we consider.
+ private static HashSet<String> sGoogleOrigins;
+ static {
+ sGoogleOrigins = new HashSet<String>();
+ // NOTE: DO NOT ADD A "/" AT THE END!
+ sGoogleOrigins.add("http://www.google.com");
+ sGoogleOrigins.add("http://www.google.co.uk");
+ }
+
+ private static GoogleLocationSettingManager sGoogleLocationSettingManager = null;
+ private static int sRefCount = 0;
+
+ static GoogleLocationSettingManager getInstance() {
+ if (sGoogleLocationSettingManager == null) {
+ sGoogleLocationSettingManager = new GoogleLocationSettingManager();
+ }
+ return sGoogleLocationSettingManager;
+ }
+
+ private GoogleLocationSettingManager() {}
+
+ /**
+ * Starts the manager. Checks whether the setting has changed and
+ * installs an observer to listen for future changes.
+ */
+ public void start(Context context) {
+ // Are we running in the browser?
+ if (context == null || !BROWSER_PACKAGE_NAME.equals(context.getPackageName())) {
+ return;
+ }
+ // Increase the refCount
+ sRefCount++;
+ // Are we already registered?
+ if (mSettingObserver != null) {
+ return;
+ }
+ // Read and apply the settings if needed.
+ maybeApplySetting(context);
+ // Register to receive notifications when the system settings change.
+ mSettingObserver = new GoogleLocationSettingObserver();
+ mSettingObserver.observe(context);
+ }
+
+ /**
+ * Stops the manager.
+ */
+ public void stop() {
+ // Are we already registered?
+ if (mSettingObserver == null) {
+ return;
+ }
+ if (--sRefCount == 0) {
+ mSettingObserver.doNotObserve();
+ mSettingObserver = null;
+ }
+ }
+ /**
+ * Checks to see if the system setting has changed and if so,
+ * updates the Geolocation permissions accordingly.
+ * @param the Application context
+ */
+ private void maybeApplySetting(Context context) {
+ int setting = getSystemSetting(context);
+ if (settingChanged(setting, context)) {
+ applySetting(setting);
+ }
+ }
+
+ /**
+ * Gets the current system setting for 'Use location for Google services'.
+ * @param the Application context
+ * @return The system setting.
+ */
+ private int getSystemSetting(Context context) {
+ return Settings.Secure.getInt(context.getContentResolver(),
+ Settings.Secure.USE_LOCATION_FOR_SERVICES,
+ sSystemSettingFalse);
+ }
+
+ /**
+ * Determines whether the supplied setting has changed from the last
+ * value read by the browser.
+ * @param setting The setting.
+ * @param the Application context
+ * @return Whether the setting has changed from the last value read
+ * by the browser.
+ */
+ private boolean settingChanged(int setting, Context context) {
+ SharedPreferences preferences =
+ PreferenceManager.getDefaultSharedPreferences(context);
+ // Default to false. If the system setting is false the first time it is ever read by the
+ // browser, there's nothing to do.
+ int lastReadSetting = sSystemSettingFalse;
+ lastReadSetting = preferences.getInt(LAST_READ_USE_LOCATION_FOR_SERVICES,
+ lastReadSetting);
+
+ if (lastReadSetting == setting) {
+ return false;
+ }
+
+ Editor editor = preferences.edit();
+ editor.putInt(LAST_READ_USE_LOCATION_FOR_SERVICES, setting);
+ editor.commit();
+ return true;
+ }
+
+ /**
+ * Applies the supplied setting to the Geolocation permissions.
+ * @param setting The setting.
+ */
+ private void applySetting(int setting) {
+ for (String origin : sGoogleOrigins) {
+ if (setting == sSystemSettingTrue) {
+ GeolocationPermissions.getInstance().allow(origin);
+ } else {
+ GeolocationPermissions.getInstance().clear(origin);
+ }
+ }
+ }
+
+ /**
+ * This class implements an observer to listen for changes to the
+ * system setting.
+ */
+ private class GoogleLocationSettingObserver extends ContentObserver {
+ private Context mContext;
+
+ GoogleLocationSettingObserver() {
+ super(new Handler());
+ }
+
+ void observe(Context context) {
+ if (mContext != null) {
+ return;
+ }
+ ContentResolver resolver = context.getContentResolver();
+ resolver.registerContentObserver(Settings.Secure.getUriFor(
+ Settings.Secure.USE_LOCATION_FOR_SERVICES), false, this);
+ mContext = context;
+ }
+
+ void doNotObserve() {
+ if (mContext == null) {
+ return;
+ }
+ ContentResolver resolver = mContext.getContentResolver();
+ resolver.unregisterContentObserver(this);
+ mContext = null;
+ }
+
+ @Override
+ public void onChange(boolean selfChange) {
+ // This may come after the call to doNotObserve() above,
+ // so mContext may be null.
+ if (mContext != null) {
+ maybeApplySetting(mContext);
+ }
+ }
+ }
+}