diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 50a7be0..7e98019 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -47,8 +47,6 @@
                   android:writePermission="com.android.browser.permission.WRITE_HISTORY_BOOKMARKS">
             <path-permission android:path="/bookmarks/search_suggest_query"
                     android:readPermission="android.permission.GLOBAL_SEARCH" />
-            <path-permission android:path="/geolocation"
-                    android:writePermission="com.android.browser.permission.WRITE_GEOLOCATION_PERMISSIONS" />
         </provider>
         <activity android:name="BrowserActivity"
                   android:label="@string/application_name"
diff --git a/src/com/android/browser/BrowserActivity.java b/src/com/android/browser/BrowserActivity.java
index ff16e4e..406132f 100644
--- a/src/com/android/browser/BrowserActivity.java
+++ b/src/com/android/browser/BrowserActivity.java
@@ -365,6 +365,11 @@
         }
         // 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 @@
         WebIconDatabase.getInstance().close();
 
         unregisterReceiver(mPackageInstallationReceiver);
+
+        // Stop watching the default geolocation permissions
+        mSystemAllowGeolocationOrigins.stop();
+        mSystemAllowGeolocationOrigins = null;
     }
 
     @Override
@@ -3872,6 +3881,8 @@
 
     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 501a52a..bf1f9d5 100644
--- a/src/com/android/browser/BrowserProvider.java
+++ b/src/com/android/browser/BrowserProvider.java
@@ -48,7 +48,6 @@
 import android.util.Log;
 import android.util.Patterns;
 import android.util.TypedValue;
-import android.webkit.GeolocationPermissions;
 
 
 import java.io.File;
@@ -71,7 +70,7 @@
             "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 @@
     // 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 @@
         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 @@
         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 @@
             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 @@
                 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 @@
             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 @@
         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 0000000..3f5a84e
--- /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();
+        }
+    }
+
+}
