Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 38645ee6 authored by Android (Google) Code Review's avatar Android (Google) Code Review
Browse files

Merge change 6759 into donut

* changes:
  Do not merge
parents d2cad295 15d21453
Loading
Loading
Loading
Loading
+218 −0
Original line number Diff line number Diff line
/*
 * 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.ContentValues;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.database.ContentObserver;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;
import android.database.sqlite.SQLiteStatement;
import android.os.Handler;
import android.preference.PreferenceManager;
import android.provider.Settings;
import android.util.Log;

import java.io.File;
import java.util.HashSet;

/**
 *  Donut-specific hack to keep Gears permissions in sync with the
 *  system location setting.
 */
class GearsPermissionsManager {
    // The application context.
    Context mContext;
    // The path to gears.so.
    private String mGearsPath;

    // The Gears permissions database directory.
    private final static String GEARS_DATABASE_DIR = "gears";
    // The Gears permissions database file name.
    private final static String GEARS_DATABASE_FILE = "permissions.db";
    // The Gears location permissions table.
    private final static String GEARS_LOCATION_ACCESS_TABLE_NAME =
        "LocationAccess";
    // The Gears storage access permissions table.
    private final static String GEARS_STORAGE_ACCESS_TABLE_NAME = "Access";
    // The Gears permissions db schema version table.
    private final static String GEARS_SCHEMA_VERSION_TABLE_NAME =
        "VersionInfo";
    // The shared pref name.
    private static final String LAST_KNOWN_LOCATION_SETTING =
        "lastKnownLocationSystemSetting";
    // The Browser package name.
    private static final String BROWSER_PACKAGE_NAME = "com.android.browser";
    // The Secure Settings observer that will be notified when the system
    // location setting changes.
    private SecureSettingsObserver mSettingsObserver;
    // The Google URLs whitelisted for Gears location access.
    private static HashSet<String> sGearsWhiteList;

    static {
        sGearsWhiteList = new HashSet<String>();
        // NOTE: DO NOT ADD A "/" AT THE END!
        sGearsWhiteList.add("http://www.google.com");
        sGearsWhiteList.add("http://www.google.co.uk");
    }

    private static final String LOGTAG = "webcore";
    static final boolean DEBUG = false;
    static final boolean LOGV_ENABLED = DEBUG;

    GearsPermissionsManager(Context context, String gearsPath) {
        mContext = context;
        mGearsPath = gearsPath;
    }

    public void doCheckAndStartObserver() {
     // Are we running in the browser?
        if (!BROWSER_PACKAGE_NAME.equals(mContext.getPackageName())) {
            return;
        }
        // Do the check.
        checkGearsPermissions();
        // Install the observer.
        mSettingsObserver = new SecureSettingsObserver();
        mSettingsObserver.observe();
    }

    private void checkGearsPermissions() {
        // Get the current system settings.
        int setting = Settings.Secure.getInt(mContext.getContentResolver(),
                Settings.Secure.USE_LOCATION_FOR_SERVICES, -1);
        // Check if we need to set the Gears permissions.
        if (setting != -1 && locationSystemSettingChanged(setting)) {
            setGearsPermissionForGoogleDomains(setting);
        }
    }

    private boolean locationSystemSettingChanged(int newSetting) {
        SharedPreferences prefs =
            PreferenceManager.getDefaultSharedPreferences(mContext);
        int oldSetting = 0;
        oldSetting = prefs.getInt(LAST_KNOWN_LOCATION_SETTING, oldSetting);
        if (oldSetting == newSetting) {
            return false;
        }
        Editor ed = prefs.edit();
        ed.putInt(LAST_KNOWN_LOCATION_SETTING, newSetting);
        ed.commit();
        return true;
    }

    private void setGearsPermissionForGoogleDomains(int systemPermission) {
        // Transform the system permission into a Gears permission
        int gearsPermission = (systemPermission == 1 ? 1 : 2);
        // Build the path to the Gears library.

        File file = new File(mGearsPath).getParentFile();
        if (file == null) {
            return;
        }
        // Build the Gears database file name.
        file = new File(file.getAbsolutePath() + File.separator
                + GEARS_DATABASE_DIR + File.separator + GEARS_DATABASE_FILE);
        // Remember whether or not we need to create the LocationAccess table.
        boolean needToCreateTables = !file.exists();
        // Try opening the Gears database.
        SQLiteDatabase permissions;
        try {
            permissions = SQLiteDatabase.openOrCreateDatabase(file, null);
        } catch (SQLiteException e) {
            if (LOGV_ENABLED) {
                Log.v(LOGTAG, "Could not open Gears permission DB: "
                        + e.getMessage());
            }
            // Just bail out.
            return;
        }
        // We now have a database open. Begin a transaction.
        permissions.beginTransaction();
        try {
            if (needToCreateTables) {
                // Create the tables. Note that this creates the
                // Gears tables for the permissions DB schema version 2.
                // The Gears schema upgrade process will take care of the rest.
                // First, the storage access table.
                SQLiteStatement statement = permissions.compileStatement(
                        "CREATE TABLE IF NOT EXISTS "
                        + GEARS_STORAGE_ACCESS_TABLE_NAME
                        + " (Name TEXT UNIQUE, Value)");
                statement.execute();
                // Next the location access table.
                statement = permissions.compileStatement(
                        "CREATE TABLE IF NOT EXISTS "
                        + GEARS_LOCATION_ACCESS_TABLE_NAME
                        + " (Name TEXT UNIQUE, Value)");
                statement.execute();
                // Finally, the schema version table.
                statement = permissions.compileStatement(
                        "CREATE TABLE IF NOT EXISTS "
                        + GEARS_SCHEMA_VERSION_TABLE_NAME
                        + " (Name TEXT UNIQUE, Value)");
                statement.execute();
                // Set the schema version to 2.
                ContentValues schema = new ContentValues();
                schema.put("Name", "Version");
                schema.put("Value", 2);
                permissions.insert(GEARS_SCHEMA_VERSION_TABLE_NAME, null,
                        schema);
            }

            ContentValues permissionValues = new ContentValues();

            for (String url : sGearsWhiteList) {
                permissionValues.put("Name", url);
                permissionValues.put("Value", gearsPermission);
                permissions.replace(GEARS_LOCATION_ACCESS_TABLE_NAME, null,
                        permissionValues);
                permissionValues.clear();
            }
            // Commit the transaction.
            permissions.setTransactionSuccessful();
        } catch (SQLiteException e) {
            if (LOGV_ENABLED) {
                Log.v(LOGTAG, "Could not set the Gears permissions: "
                        + e.getMessage());
            }
        } finally {
            permissions.endTransaction();
            permissions.close();
        }
    }

    class SecureSettingsObserver extends ContentObserver {
        SecureSettingsObserver() {
            super(new Handler());
        }

        void observe() {
            ContentResolver resolver = mContext.getContentResolver();
            resolver.registerContentObserver(Settings.Secure.getUriFor(
                    Settings.Secure.USE_LOCATION_FOR_SERVICES), false, this);
        }

        @Override
        public void onChange(boolean selfChange) {
            checkGearsPermissions();
        }
    }
}
+11 −160
Original line number Diff line number Diff line
@@ -16,27 +16,15 @@

package android.webkit;

import android.content.ContentValues;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Handler;
import android.os.Message;
import android.preference.PreferenceManager;
import android.provider.Checkin;
import android.provider.Settings;
import android.util.Log;

import java.io.File;
import java.lang.SecurityException;

import android.content.SharedPreferences.Editor;
import android.content.pm.PackageManager;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;
import android.database.sqlite.SQLiteStatement;

import java.util.HashSet;
import java.util.Locale;

/**
@@ -188,42 +176,8 @@ public class WebSettings {
    private boolean         mBuiltInZoomControls = false;
    private boolean         mAllowFileAccess = true;

    // Donut-specific hack to keep Gears permissions in sync with the
    // system location setting.
    // TODO: Make sure this hack is removed in  Eclair, when Gears
    // is also removed.
    // Used to remember if we checked the Gears permissions already.
    static boolean mCheckedGearsPermissions = false;
    // The Gears permissions database directory.
    private final static String GEARS_DATABASE_DIR = "gears";
    // The Gears permissions database file name.
    private final static String GEARS_DATABASE_FILE = "permissions.db";
    // The Gears location permissions table.
    private final static String GEARS_LOCATION_ACCESS_TABLE_NAME = 
        "LocationAccess";
    // The Gears storage access permissions table.
    private final static String GEARS_STORAGE_ACCESS_TABLE_NAME = "Access";
    // The Gears permissions db schema version table.
    private final static String GEARS_SCHEMA_VERSION_TABLE_NAME =
        "VersionInfo";
    // The shared pref name.
    private static final String LAST_KNOWN_LOCATION_SETTING =
        "lastKnownLocationSystemSetting";
    // The Browser package name.
    private static final String BROWSER_PACKAGE_NAME = "com.android.browser";
    // The Google URLs whitelisted for Gears location access.
    private static HashSet<String> sGearsWhiteList;

    static {
        sGearsWhiteList = new HashSet<String>();
        // NOTE: DO NOT ADD A "/" AT THE END!
        sGearsWhiteList.add("http://www.google.com");
        sGearsWhiteList.add("http://www.google.co.uk");
    }

    private static final String LOGTAG = "webcore";
    static final boolean DEBUG = false;
    static final boolean LOGV_ENABLED = DEBUG;
    // The Gears permissions manager. Only in Donut.
    static GearsPermissionsManager sGearsPermissionsManager;

    // Class to handle messages before WebCore is ready.
    private class EventHandler {
@@ -245,7 +199,6 @@ public class WebSettings {
                    switch (msg.what) {
                        case SYNC:
                            synchronized (WebSettings.this) {
                                checkGearsPermissions();
                                if (mBrowserFrame.mNativeFrame != 0) {
                                    nativeSync(mBrowserFrame.mNativeFrame);
                                }
@@ -1198,6 +1151,7 @@ public class WebSettings {
        if (WebView.DEBUG) {
            junit.framework.Assert.assertTrue(frame.mNativeFrame != 0);
        }
        checkGearsPermissions();
        nativeSync(frame.mNativeFrame);
        mSyncPending = false;
        mEventHandler.createHandler();
@@ -1214,125 +1168,22 @@ public class WebSettings {
    }

    private void checkGearsPermissions() {
        // Did we already check the permissions?
        if (mCheckedGearsPermissions) {
            return;
        }
        // Are we running in the browser?
        if (!BROWSER_PACKAGE_NAME.equals(mContext.getPackageName())) {
        // Did we already check the permissions at startup?
        if (sGearsPermissionsManager != null) {
            return;
        }
        // Is the pluginsPath sane?
        if (mPluginsPath == null || mPluginsPath.length() == 0) {
        String pluginsPath = getPluginsPath();
        if (pluginsPath == null || pluginsPath.length() == 0) {
            // We don't yet have a meaningful plugin path, so
            // we can't do anything about the Gears permissions.
            return;
        }
        // Remember we checked the Gears permissions.
        mCheckedGearsPermissions = true;
        // Get the current system settings.
        int setting = Settings.Secure.getInt(mContext.getContentResolver(),
                Settings.Secure.USE_LOCATION_FOR_SERVICES, -1);
        // Check if we need to set the Gears permissions.
        if (setting != -1 && locationSystemSettingChanged(setting)) {
            setGearsPermissionForGoogleDomains(setting);
        }
    }

    private boolean locationSystemSettingChanged(int newSetting) {
        SharedPreferences prefs =
            PreferenceManager.getDefaultSharedPreferences(mContext);
        int oldSetting = 0;
        oldSetting = prefs.getInt(LAST_KNOWN_LOCATION_SETTING, oldSetting);
        if (oldSetting == newSetting) {
            return false;
        }
        Editor ed = prefs.edit();
        ed.putInt(LAST_KNOWN_LOCATION_SETTING, newSetting);
        ed.commit();
        return true;
        sGearsPermissionsManager =
            new GearsPermissionsManager(mContext, pluginsPath);
        sGearsPermissionsManager.doCheckAndStartObserver();
    }

    private void setGearsPermissionForGoogleDomains(int systemPermission) {
        // Transform the system permission into a Gears permission
        int gearsPermission = (systemPermission == 1 ? 1 : 2);
        // Build the path to the Gears library.

        File file = new File(mPluginsPath).getParentFile();
        if (file == null) {
            return;
        }
        // Build the Gears database file name.
        file = new File(file.getAbsolutePath() + File.separator 
                + GEARS_DATABASE_DIR + File.separator + GEARS_DATABASE_FILE);
        // Remember whether or not we need to create the LocationAccess table.
        boolean needToCreateTables = !file.exists();
        // Try opening the Gears database.
        SQLiteDatabase permissions;
        try {
            permissions = SQLiteDatabase.openOrCreateDatabase(file, null);
        } catch (SQLiteException e) {
            if (LOGV_ENABLED) {
                Log.v(LOGTAG, "Could not open Gears permission DB: " +
                        e.getMessage());
            }
            // Just bail out.
            return;
        }
        // We now have a database open. Begin a transaction.
        permissions.beginTransaction();
        try {
            if (needToCreateTables) {
                // Create the tables. Note that this creates the
                // Gears tables for the permissions DB schema version 2.
                // The Gears schema upgrade process will take care of the rest.
                // First, the storage access table.
                SQLiteStatement statement = permissions.compileStatement(
                        "CREATE TABLE IF NOT EXISTS " +
                        GEARS_STORAGE_ACCESS_TABLE_NAME +
                        " (Name TEXT UNIQUE, Value)");
                statement.execute();
                // Next the location access table.
                statement = permissions.compileStatement(
                        "CREATE TABLE IF NOT EXISTS " +
                        GEARS_LOCATION_ACCESS_TABLE_NAME +
                        " (Name TEXT UNIQUE, Value)");
                statement.execute();
                // Finally, the schema version table.
                statement = permissions.compileStatement(
                        "CREATE TABLE IF NOT EXISTS " +
                        GEARS_SCHEMA_VERSION_TABLE_NAME +
                        " (Name TEXT UNIQUE, Value)");
                statement.execute();
                // Set the schema version to 2.
                ContentValues schema = new ContentValues();
                schema.put("Name", "Version");
                schema.put("Value", 2);
                permissions.insert(GEARS_SCHEMA_VERSION_TABLE_NAME, null,
                        schema);
            }

            ContentValues permissionValues = new ContentValues();

            for (String url : sGearsWhiteList) {
                permissionValues.put("Name", url);
                permissionValues.put("Value", gearsPermission);
                permissions.replace(GEARS_LOCATION_ACCESS_TABLE_NAME, null,
                        permissionValues);
                permissionValues.clear();
            }
            // Commit the transaction.
            permissions.setTransactionSuccessful();
        } catch (SQLiteException e) {
            if (LOGV_ENABLED) {
                Log.v(LOGTAG, "Could not set the Gears permissions: " +
                        e.getMessage());
            }
        } finally {
            permissions.endTransaction();
            permissions.close();
        }
    }
    /* Post a SYNC message to handle syncing the native settings. */
    private synchronized void postSync() {
        // Only post if a sync is not pending