diff options
Diffstat (limited to 'core/java/android/webkit/GoogleLocationSettingManager.java')
-rw-r--r-- | core/java/android/webkit/GoogleLocationSettingManager.java | 209 |
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); + } + } + } +} |