diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/com/android/browser/BrowserActivity.java | 366 | ||||
-rw-r--r-- | src/com/android/browser/BrowserPluginList.java | 66 | ||||
-rw-r--r-- | src/com/android/browser/BrowserPreferencesPage.java | 21 | ||||
-rw-r--r-- | src/com/android/browser/BrowserSettings.java | 1 | ||||
-rw-r--r-- | src/com/android/browser/GearsBaseDialog.java | 473 | ||||
-rw-r--r-- | src/com/android/browser/GearsNativeDialog.java | 279 | ||||
-rw-r--r-- | src/com/android/browser/GearsPermissions.java | 196 | ||||
-rw-r--r-- | src/com/android/browser/GearsPermissionsDialog.java | 133 | ||||
-rw-r--r-- | src/com/android/browser/GearsSettingsDialog.java | 460 |
9 files changed, 1 insertions, 1994 deletions
diff --git a/src/com/android/browser/BrowserActivity.java b/src/com/android/browser/BrowserActivity.java index 5c2764b..244a903 100644 --- a/src/com/android/browser/BrowserActivity.java +++ b/src/com/android/browser/BrowserActivity.java @@ -274,371 +274,6 @@ public class BrowserActivity extends Activity mGlsConnection, Context.BIND_AUTO_CREATE); } - /** - * This class is in charge of installing pre-packaged plugins - * from the Browser assets directory to the user's data partition. - * Plugins are loaded from the "plugins" directory in the assets; - * Anything that is in this directory will be copied over to the - * user data partition in app_plugins. - */ - private static class CopyPlugins implements Runnable { - final static String TAG = "PluginsInstaller"; - final static String ZIP_FILTER = "assets/plugins/"; - final static String APK_PATH = "/system/app/Browser.apk"; - final static String PLUGIN_EXTENSION = ".so"; - final static String TEMPORARY_EXTENSION = "_temp"; - final static String BUILD_INFOS_FILE = "build.prop"; - final static String SYSTEM_BUILD_INFOS_FILE = "/system/" - + BUILD_INFOS_FILE; - final static int BUFSIZE = 4096; - boolean mDoOverwrite = false; - String pluginsPath; - Context mContext; - - public CopyPlugins (boolean overwrite, Context context) { - mDoOverwrite = overwrite; - mContext = context; - } - - /** - * Returned a filtered list of ZipEntry. - * We list all the files contained in the zip and - * only returns the ones starting with the ZIP_FILTER - * path. - * - * @param zip the zip file used. - */ - public Vector<ZipEntry> pluginsFilesFromZip(ZipFile zip) { - Vector<ZipEntry> list = new Vector<ZipEntry>(); - Enumeration entries = zip.entries(); - while (entries.hasMoreElements()) { - ZipEntry entry = (ZipEntry) entries.nextElement(); - if (entry.getName().startsWith(ZIP_FILTER)) { - list.add(entry); - } - } - return list; - } - - /** - * Utility method to copy the content from an inputstream - * to a file output stream. - */ - public void copyStreams(InputStream is, FileOutputStream fos) { - BufferedOutputStream os = null; - try { - byte data[] = new byte[BUFSIZE]; - int count; - os = new BufferedOutputStream(fos, BUFSIZE); - while ((count = is.read(data, 0, BUFSIZE)) != -1) { - os.write(data, 0, count); - } - os.flush(); - } catch (IOException e) { - Log.e(TAG, "Exception while copying: " + e); - } finally { - try { - if (os != null) { - os.close(); - } - } catch (IOException e2) { - Log.e(TAG, "Exception while closing the stream: " + e2); - } - } - } - - /** - * Returns a string containing the contents of a file - * - * @param file the target file - */ - private String contentsOfFile(File file) { - String ret = null; - FileInputStream is = null; - try { - byte[] buffer = new byte[BUFSIZE]; - int count; - is = new FileInputStream(file); - StringBuffer out = new StringBuffer(); - - while ((count = is.read(buffer, 0, BUFSIZE)) != -1) { - out.append(new String(buffer, 0, count)); - } - ret = out.toString(); - } catch (IOException e) { - Log.e(TAG, "Exception getting contents of file " + e); - } finally { - if (is != null) { - try { - is.close(); - } catch (IOException e2) { - Log.e(TAG, "Exception while closing the file: " + e2); - } - } - } - return ret; - } - - /** - * Utility method to initialize the user data plugins path. - */ - public void initPluginsPath() { - BrowserSettings s = BrowserSettings.getInstance(); - pluginsPath = s.getPluginsPath(); - if (pluginsPath == null) { - s.loadFromDb(mContext); - pluginsPath = s.getPluginsPath(); - } - if (LOGV_ENABLED) { - Log.v(TAG, "Plugin path: " + pluginsPath); - } - } - - /** - * Utility method to delete a file or a directory - * - * @param file the File to delete - */ - public void deleteFile(File file) { - File[] files = file.listFiles(); - if ((files != null) && files.length > 0) { - for (int i=0; i< files.length; i++) { - deleteFile(files[i]); - } - } - if (!file.delete()) { - Log.e(TAG, file.getPath() + " could not get deleted"); - } - } - - /** - * Clean the content of the plugins directory. - * We delete the directory, then recreate it. - */ - public void cleanPluginsDirectory() { - if (LOGV_ENABLED) { - Log.v(TAG, "delete plugins directory: " + pluginsPath); - } - File pluginsDirectory = new File(pluginsPath); - deleteFile(pluginsDirectory); - pluginsDirectory.mkdir(); - } - - - /** - * Copy the SYSTEM_BUILD_INFOS_FILE file containing the - * informations about the system build to the - * BUILD_INFOS_FILE in the plugins directory. - */ - public void copyBuildInfos() { - FileInputStream iStream = null; - FileOutputStream oStream = null; - try { - if (LOGV_ENABLED) { - Log.v(TAG, "Copy build infos to the plugins directory"); - } - File buildInfoFile = new File(SYSTEM_BUILD_INFOS_FILE); - File buildInfoPlugins = new File(pluginsPath, BUILD_INFOS_FILE); - iStream = new FileInputStream(buildInfoFile); - oStream = new FileOutputStream(buildInfoPlugins); - copyStreams(iStream, oStream); - } catch (IOException e) { - Log.e(TAG, "Exception while copying the build infos: " + e); - } finally { - try { - if (iStream != null) { - iStream.close(); - } - } catch (IOException e2) { - Log.e(TAG, "Exception while closing the input stream: " + e2); - } - try { - if (oStream != null) { - oStream.close(); - } - } catch (IOException e3) { - Log.e(TAG, "Exception while closing the output stream: " + e3); - } - } - } - - /** - * Returns true if the current system is newer than the - * system that installed the plugins. - * We determinate this by checking the build number of the system. - * - * At the end of the plugins copy operation, we copy the - * SYSTEM_BUILD_INFOS_FILE to the BUILD_INFOS_FILE. - * We then just have to load both and compare them -- if they - * are different the current system is newer. - * - * Loading and comparing the strings should be faster than - * creating a hash, the files being rather small. Extracting the - * version number would require some parsing which may be more - * brittle. - */ - public boolean newSystemImage() { - try { - File buildInfoFile = new File(SYSTEM_BUILD_INFOS_FILE); - File buildInfoPlugins = new File(pluginsPath, BUILD_INFOS_FILE); - if (!buildInfoPlugins.exists()) { - if (LOGV_ENABLED) { - Log.v(TAG, "build.prop in plugins directory " + pluginsPath - + " does not exist, therefore it's a new system image"); - } - return true; - } else { - String buildInfo = contentsOfFile(buildInfoFile); - String buildInfoPlugin = contentsOfFile(buildInfoPlugins); - if (buildInfo == null || buildInfoPlugin == null - || buildInfo.compareTo(buildInfoPlugin) != 0) { - if (LOGV_ENABLED) { - Log.v(TAG, "build.prop are different, " - + " therefore it's a new system image"); - } - return true; - } - } - } catch (Exception e) { - Log.e(TAG, "Exc in newSystemImage(): " + e); - } - return false; - } - - /** - * Check if the version of the plugins contained in the - * Browser assets is the same as the version of the plugins - * in the plugins directory. - * We simply iterate on every file in the assets/plugins - * and return false if a file listed in the assets does - * not exist in the plugins directory. - */ - private boolean checkIsDifferentVersions() { - try { - ZipFile zip = new ZipFile(APK_PATH); - Vector<ZipEntry> files = pluginsFilesFromZip(zip); - int zipFilterLength = ZIP_FILTER.length(); - - Enumeration entries = files.elements(); - while (entries.hasMoreElements()) { - ZipEntry entry = (ZipEntry) entries.nextElement(); - String path = entry.getName().substring(zipFilterLength); - File outputFile = new File(pluginsPath, path); - if (!outputFile.exists()) { - if (LOGV_ENABLED) { - Log.v(TAG, "checkIsDifferentVersions(): extracted file " - + path + " does not exist, we have a different version"); - } - return true; - } - } - } catch (IOException e) { - Log.e(TAG, "Exception in checkDifferentVersions(): " + e); - } - return false; - } - - /** - * Copy every files from the assets/plugins directory - * to the app_plugins directory in the data partition. - * Once copied, we copy over the SYSTEM_BUILD_INFOS file - * in the plugins directory. - * - * NOTE: we directly access the content from the Browser - * package (it's a zip file) and do not use AssetManager - * as there is a limit of 1Mb (see Asset.h) - */ - public void run() { - // Lower the priority - Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); - try { - if (pluginsPath == null) { - Log.e(TAG, "No plugins path found!"); - return; - } - - ZipFile zip = new ZipFile(APK_PATH); - Vector<ZipEntry> files = pluginsFilesFromZip(zip); - Vector<File> plugins = new Vector<File>(); - int zipFilterLength = ZIP_FILTER.length(); - - Enumeration entries = files.elements(); - while (entries.hasMoreElements()) { - ZipEntry entry = (ZipEntry) entries.nextElement(); - String path = entry.getName().substring(zipFilterLength); - File outputFile = new File(pluginsPath, path); - outputFile.getParentFile().mkdirs(); - - if (outputFile.exists() && !mDoOverwrite) { - if (LOGV_ENABLED) { - Log.v(TAG, path + " already extracted."); - } - } else { - if (path.endsWith(PLUGIN_EXTENSION)) { - // We rename plugins to be sure a half-copied - // plugin is not loaded by the browser. - plugins.add(outputFile); - outputFile = new File(pluginsPath, - path + TEMPORARY_EXTENSION); - } - FileOutputStream fos = new FileOutputStream(outputFile); - if (LOGV_ENABLED) { - Log.v(TAG, "copy " + entry + " to " - + pluginsPath + "/" + path); - } - copyStreams(zip.getInputStream(entry), fos); - } - } - - // We now rename the .so we copied, once all their resources - // are safely copied over to the user data partition. - Enumeration elems = plugins.elements(); - while (elems.hasMoreElements()) { - File renamedFile = (File) elems.nextElement(); - File sourceFile = new File(renamedFile.getPath() - + TEMPORARY_EXTENSION); - if (LOGV_ENABLED) { - Log.v(TAG, "rename " + sourceFile.getPath() - + " to " + renamedFile.getPath()); - } - sourceFile.renameTo(renamedFile); - } - - copyBuildInfos(); - } catch (IOException e) { - Log.e(TAG, "IO Exception: " + e); - } - } - }; - - /** - * Copy the content of assets/plugins/ to the app_plugins directory - * in the data partition. - * - * This function is called every time the browser is started. - * We first check if the system image is newer than the one that - * copied the plugins (if there's plugins in the data partition). - * If this is the case, we then check if the versions are different. - * If they are different, we clean the plugins directory in the - * data partition, then start a thread to copy the plugins while - * the browser continue to load. - * - * @param overwrite if true overwrite the files even if they are - * already present (to let the user "reset" the plugins if needed). - */ - private void copyPlugins(boolean overwrite) { - CopyPlugins copyPluginsFromAssets = new CopyPlugins(overwrite, this); - copyPluginsFromAssets.initPluginsPath(); - if (copyPluginsFromAssets.newSystemImage()) { - if (copyPluginsFromAssets.checkIsDifferentVersions()) { - copyPluginsFromAssets.cleanPluginsDirectory(); - Thread copyplugins = new Thread(copyPluginsFromAssets); - copyplugins.setName("CopyPlugins"); - copyplugins.start(); - } - } - } - private static class ClearThumbnails extends AsyncTask<File, Void, Void> { @Override public Void doInBackground(File... files) { @@ -845,7 +480,6 @@ public class BrowserActivity extends Activity && !mSettings.isLoginInitialized()) { setupHomePage(); } - copyPlugins(true); if (urlData.isEmpty()) { if (mSettings.isLoginInitialized()) { diff --git a/src/com/android/browser/BrowserPluginList.java b/src/com/android/browser/BrowserPluginList.java deleted file mode 100644 index 6689b0e..0000000 --- a/src/com/android/browser/BrowserPluginList.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (C) 2008 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.app.ListActivity; -import android.os.Bundle; -import android.view.View; -import android.view.ViewGroup; -import android.webkit.Plugin; -import android.webkit.PluginList; -import android.webkit.WebView; -import android.widget.ArrayAdapter; -import android.widget.LinearLayout; -import android.widget.LinearLayout.LayoutParams; -import android.widget.ListView; -import android.widget.TextView; -import java.util.ArrayList; -import java.util.List; - -// Manages the list of installed (and loaded) plugins. -public class BrowserPluginList extends ListActivity { - @Override - public void onCreate(Bundle icicle) { - super.onCreate(icicle); - // The list of plugins can change under us, as the plugins are - // loaded and unloaded in a different thread. We make a copy - // of the list here. - List loadedPlugins = WebView.getPluginList().getList(); - ArrayList localLoadedPluginList = new ArrayList(); - synchronized (loadedPlugins) { - localLoadedPluginList.addAll(loadedPlugins); - } - setListAdapter(new ArrayAdapter(this, - android.R.layout.simple_list_item_1, - localLoadedPluginList)); - setTitle(R.string.pref_plugin_installed); - // Add a text view to this ListActivity. This text view - // will be displayed when the list of plugins is empty. - TextView textView = new TextView(this); - textView.setId(android.R.id.empty); - textView.setText(R.string.pref_plugin_installed_empty_list); - addContentView(textView, new LinearLayout.LayoutParams( - ViewGroup.LayoutParams.FILL_PARENT, - ViewGroup.LayoutParams.WRAP_CONTENT)); - - } - - @Override - public void onListItemClick(ListView l, View v, int position, long id) { - WebView.getPluginList().pluginClicked(this, position); - } -} diff --git a/src/com/android/browser/BrowserPreferencesPage.java b/src/com/android/browser/BrowserPreferencesPage.java index 2348af0..ec3561f 100644 --- a/src/com/android/browser/BrowserPreferencesPage.java +++ b/src/com/android/browser/BrowserPreferencesPage.java @@ -30,13 +30,11 @@ import android.preference.PreferenceActivity; import android.preference.PreferenceScreen; import android.util.Log; import android.webkit.GeolocationPermissions; -import android.webkit.Plugin; import android.webkit.WebStorage; import android.webkit.WebView; public class BrowserPreferencesPage extends PreferenceActivity - implements Preference.OnPreferenceChangeListener, - Preference.OnPreferenceClickListener { + implements Preference.OnPreferenceChangeListener { String TAG = "BrowserPreferencesPage"; @@ -74,9 +72,6 @@ public class BrowserPreferencesPage extends PreferenceActivity addPreferencesFromResource(R.xml.debug_preferences); } - e = findPreference(BrowserSettings.PREF_GEARS_SETTINGS); - e.setOnPreferenceClickListener(this); - PreferenceScreen websiteSettings = (PreferenceScreen) findPreference(BrowserSettings.PREF_WEBSITE_SETTINGS); Intent intent = new Intent(this, WebsiteSettingsActivity.class); @@ -154,20 +149,6 @@ public class BrowserPreferencesPage extends PreferenceActivity return false; } - - public boolean onPreferenceClick(Preference pref) { - if (pref.getKey().equals(BrowserSettings.PREF_GEARS_SETTINGS)) { - List<Plugin> loadedPlugins = WebView.getPluginList().getList(); - for(Plugin p : loadedPlugins) { - if (p.getName().equals("gears")) { - p.dispatchClickEvent(this); - return true; - } - } - - } - return true; - } private CharSequence getVisualTextSizeName(String enumName) { CharSequence[] visualNames = getResources().getTextArray( diff --git a/src/com/android/browser/BrowserSettings.java b/src/com/android/browser/BrowserSettings.java index 6f5caed..aa54ccd 100644 --- a/src/com/android/browser/BrowserSettings.java +++ b/src/com/android/browser/BrowserSettings.java @@ -128,7 +128,6 @@ class BrowserSettings extends Observable { public final static String PREF_EXTRAS_RESET_DEFAULTS = "reset_default_preferences"; public final static String PREF_DEBUG_SETTINGS = "debug_menu"; - public final static String PREF_GEARS_SETTINGS = "gears_settings"; public final static String PREF_WEBSITE_SETTINGS = "website_settings"; public final static String PREF_TEXT_SIZE = "text_size"; public final static String PREF_DEFAULT_ZOOM = "default_zoom"; diff --git a/src/com/android/browser/GearsBaseDialog.java b/src/com/android/browser/GearsBaseDialog.java deleted file mode 100644 index 9a56cb8..0000000 --- a/src/com/android/browser/GearsBaseDialog.java +++ /dev/null @@ -1,473 +0,0 @@ -/* - * Copyright (C) 2008 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.app.Activity; -import android.app.Dialog; -import android.content.Context; -import android.content.res.Resources; -import android.graphics.Bitmap; -import android.graphics.BitmapFactory; -import android.os.Handler; -import android.text.Spannable; -import android.text.SpannableString; -import android.text.style.UnderlineSpan; -import android.util.Log; -import android.view.InflateException; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.Button; -import android.widget.ImageView; -import android.widget.TextView; - -import java.io.InputStream; -import java.io.IOException; -import java.lang.ClassCastException; -import java.net.HttpURLConnection; -import java.net.MalformedURLException; -import java.net.URL; - -import org.json.JSONException; -import org.json.JSONObject; - -/** - * Base dialog class for gears - */ -class GearsBaseDialog { - - private static final String TAG = "GearsNativeDialog"; - protected Handler mHandler; - protected Activity mActivity; - protected String mDialogArguments; - - private Bitmap mIcon; - private static final int MAX_ICON_SIZE = 64; - protected int mChoosenIconSize; - - // Dialog closing types - public static final int CANCEL = 0; - public static final int ALWAYS_DENY = 1; - public static final int ALLOW = 2; - public static final int DENY = 3; - public static final int NEW_ICON = 4; - public static final int UPDATE_ICON = 5; - public static final int REQUEST_ICON = 6; - public static final int PAUSE_REQUEST_ICON = 7; - public static final int CLEAR_REQUEST_ICON = 8; - - protected final String LOCAL_DATA_STRING = "localData"; - protected final String LOCAL_STORAGE_STRING = "localStorage"; - protected final String LOCATION_DATA_STRING = "locationData"; - - protected String mGearsVersion = "UNDEFINED"; - protected boolean mDebug = false; - - public GearsBaseDialog(Activity activity, Handler handler, String arguments) { - mActivity = activity; - mHandler = handler; - mDialogArguments = arguments; - } - - Resources getResources() { - return mActivity.getResources(); - } - - Object getSystemService(String name) { - return mActivity.getSystemService(name); - } - - View findViewById(int id) { - return mActivity.findViewById(id); - } - - private String getString(int id) { - return mActivity.getString(id); - } - - public void setDebug(boolean debug) { - mDebug = debug; - } - - public void setGearsVersion(String version) { - mGearsVersion = version; - } - - public String closeDialog(int closingType) { - return null; - } - - /* - * Utility methods for setting up the dialogs elements - */ - - /** - * Inflate a given layout in a view (which has to be - * a ViewGroup, e.g. LinearLayout). - * This is used to share the basic dialog outline among - * the different dialog types. - */ - void inflate(int layout, int viewID) { - LayoutInflater inflater = (LayoutInflater) getSystemService( - Context.LAYOUT_INFLATER_SERVICE); - View view = findViewById(viewID); - if (view != null) { - try { - ViewGroup viewGroup = (ViewGroup) view; - inflater.inflate(layout, viewGroup); - } catch (ClassCastException e) { - String msg = "exception, the view (" + view + ")"; - msg += " is not a ViewGroup"; - Log.e(TAG, msg, e); - } catch (InflateException e) { - Log.e(TAG, "exception while inflating the layout", e); - } - } else { - String msg = "problem, trying to inflate a non-existent view"; - msg += " (" + viewID + ")"; - Log.e(TAG, msg); - } - } - - /** - * Button setup. - * Set the button's text and its listener. If the text resource's id - * is 0, makes the button invisible. - */ - void setupButton(int buttonRscID, - int rscString, - View.OnClickListener listener, - boolean isLink, - boolean requestFocus) { - View view = findViewById(buttonRscID); - if (view == null) { - return; - } - - Button button = (Button) view; - - if (rscString == 0) { - button.setVisibility(View.GONE); - } else { - CharSequence text = getString(rscString); - button.setText(text); - button.setOnClickListener(listener); - if (isLink) { - displayAsLink(button); - } - if (requestFocus) { - button.requestFocus(); - } - } - } - - /** - * Button setup: as the above method, except that 'isLink' and - * 'requestFocus' default to false. - */ - void setupButton(int buttonRsc, int rsc, - View.OnClickListener listener) { - setupButton(buttonRsc, rsc, listener, false, false); - } - - /** - * Utility method to setup the three dialog buttons. - */ - void setupButtons(int alwaysDenyRsc, int allowRsc, int denyRsc) { - setupButton(R.id.button_alwaysdeny, alwaysDenyRsc, - new Button.OnClickListener() { - public void onClick(View v) { - mHandler.sendEmptyMessage(ALWAYS_DENY); - } - }); - - setupButton(R.id.button_allow, allowRsc, - new Button.OnClickListener() { - public void onClick(View v) { - mHandler.sendEmptyMessage(ALLOW); - } - }); - - setupButton(R.id.button_deny, denyRsc, - new Button.OnClickListener() { - public void onClick(View v) { - mHandler.sendEmptyMessage(DENY); - } - }); - } - - /** - * Display a button as an HTML link. Remove the background, set the - * text color to R.color.dialog_link and draw an underline - */ - void displayAsLink(Button button) { - if (button == null) { - return; - } - - CharSequence text = button.getText(); - button.setBackgroundDrawable(null); - int color = getResources().getColor(R.color.dialog_link); - button.setTextColor(color); - SpannableString str = new SpannableString(text); - str.setSpan(new UnderlineSpan(), 0, str.length(), - Spannable.SPAN_INCLUSIVE_INCLUSIVE); - button.setText(str); - button.setFocusable(false); - } - - /** - * Utility method to set elements' text indicated in - * the dialogs' arguments. - */ - void setLabel(JSONObject json, String name, int rsc) { - try { - if (json.has(name)) { - String text = json.getString(name); - View view = findViewById(rsc); - if (view != null && text != null) { - TextView textView = (TextView) view; - textView.setText(text); - textView.setVisibility(View.VISIBLE); - } - } - } catch (JSONException e) { - Log.e(TAG, "json exception", e); - } - } - - /** - * Utility method to hide a view. - */ - void hideView(View v, int rsc) { - if (rsc == 0) { - return; - } - View view; - if (v == null) { - view = findViewById(rsc); - } else { - view = v.findViewById(rsc); - } - if (view != null) { - view.setVisibility(View.GONE); - } - } - - /** - * Utility method to show a view. - */ - void showView(View v, int rsc) { - if (rsc == 0) { - return; - } - View view; - if (v == null) { - view = findViewById(rsc); - } else { - view = v.findViewById(rsc); - } - if (view != null) { - view.setVisibility(View.VISIBLE); - } - } - - /** - * Utility method to set a text. - */ - void setText(View v, int rsc, CharSequence text) { - if (rsc == 0) { - return; - } - View view = v.findViewById(rsc); - if (view != null) { - TextView textView = (TextView) view; - textView.setText(text); - textView.setVisibility(View.VISIBLE); - } - } - - /** - * Utility method to set a text. - */ - void setText(View v, int rsc, int txtRsc) { - if (rsc == 0) { - return; - } - View view = v.findViewById(rsc); - if (view != null) { - TextView textView = (TextView) view; - if (txtRsc == 0) { - textView.setVisibility(View.GONE); - } else { - CharSequence text = getString(txtRsc); - textView.setText(text); - textView.setVisibility(View.VISIBLE); - } - } - } - - /** - * Utility class to download an icon in the background. - * Once done ask the UI thread to update the icon. - */ - class IconDownload implements Runnable { - private String mUrlString; - - IconDownload(String url) { - mUrlString = url; - } - - public void run() { - if (mUrlString == null) { - return; - } - try { - URL url = new URL(mUrlString); - HttpURLConnection connection = (HttpURLConnection) url.openConnection(); - connection.setDoInput(true); - connection.connect(); - InputStream is = connection.getInputStream(); - Bitmap customIcon = BitmapFactory.decodeStream(is); - if (customIcon != null) { - mIcon = customIcon; - mHandler.sendEmptyMessage(UPDATE_ICON); - } - } catch (ClassCastException e) { - Log.e(TAG, "Class cast exception (" + mUrlString + ")", e); - } catch (MalformedURLException e) { - Log.e(TAG, "Malformed url (" + mUrlString + ") ", e); - } catch (IOException e) { - Log.e(TAG, "Exception downloading icon (" + mUrlString + ") ", e); - } - } - } - - /** - * Utility method to update the icon. - * Called on the UI thread. - */ - public void updateIcon() { - if (mIcon == null) { - return; - } - View view = findViewById(R.id.origin_icon); - if (view != null) { - ImageView imageView = (ImageView) view; - imageView.setMaxHeight(MAX_ICON_SIZE); - imageView.setMaxWidth(MAX_ICON_SIZE); - imageView.setScaleType(ImageView.ScaleType.FIT_XY); - imageView.setImageBitmap(mIcon); - imageView.setVisibility(View.VISIBLE); - } - } - - /** - * Utility method to download an icon from a url and set - * it to the GUI element R.id.origin_icon. - * It is used both in the shortcut dialog and the - * permission dialog. - * The actual download is done in the background via - * IconDownload; once the icon is downlowded the UI is updated - * via updateIcon(). - * The icon size is included in the layout with the choosen - * size, although not displayed, to limit text reflow once - * the icon is received. - */ - void downloadIcon(String url) { - if (url == null) { - return; - } - View view = findViewById(R.id.origin_icon); - if (view != null) { - view.setMinimumWidth(mChoosenIconSize); - view.setMinimumHeight(mChoosenIconSize); - view.setVisibility(View.INVISIBLE); - } - Thread thread = new Thread(new IconDownload(url)); - thread.start(); - } - - /** - * Utility method that get the dialogMessage - * and icon and ask the setupDialog(message,icon) - * method to set the values. - */ - public void setupDialog() { - TextView dialogMessage = null; - ImageView icon = null; - - View view = findViewById(R.id.dialog_message); - if (view != null) { - dialogMessage = (TextView) view; - } - - View iconView = findViewById(R.id.icon); - if (iconView != null) { - icon = (ImageView) iconView; - } - - if ((dialogMessage != null) && (icon != null)) { - setupDialog(dialogMessage, icon); - dialogMessage.setVisibility(View.VISIBLE); - } - } - - /* - * Set the message and icon of the dialog - */ - public void setupDialog(TextView message, ImageView icon) { - message.setText(R.string.unrecognized_dialog_message); - icon.setImageResource(R.drawable.ic_dialog_menu_generic); - message.setVisibility(View.VISIBLE); - } - - /** - * Setup the dialog - * By default, just display a simple message. - */ - public void setup() { - setupButtons(0, 0, R.string.default_button); - setupDialog(); - } - - /** - * Method called when the back button is pressed, - * allowing the dialog to intercept the default behaviour. - */ - public boolean handleBackButton() { - return false; - } - - /** - * Returns the resource string of the notification displayed - * after the dialog. By default, does not return one. - */ - public int notification() { - return 0; - } - - /** - * If a secondary dialog (e.g. a confirmation dialog) is created, - * GearsNativeDialog will call this method. - */ - public Dialog onCreateDialog(int id) { - // This should be redefined by subclasses as needed. - return null; - } - -} diff --git a/src/com/android/browser/GearsNativeDialog.java b/src/com/android/browser/GearsNativeDialog.java deleted file mode 100644 index 192108a..0000000 --- a/src/com/android/browser/GearsNativeDialog.java +++ /dev/null @@ -1,279 +0,0 @@ -/* - * Copyright (C) 2008 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.app.Activity; -import android.app.Dialog; -import android.content.Intent; -import android.net.Uri; -import android.os.Bundle; -import android.os.Handler; -import android.os.Message; -import android.util.Log; -import android.view.Gravity; -import android.view.KeyEvent; -import android.view.Window; -import android.widget.BaseAdapter; -import android.widget.Toast; - -import android.webkit.gears.NativeDialog; - -import com.android.browser.GearsBaseDialog; -import com.android.browser.GearsPermissionsDialog; -import com.android.browser.GearsSettingsDialog; - -/** - * Native dialog Activity used by gears - * TODO: rename in GearsNativeDialogActivity - * @hide - */ -public class GearsNativeDialog extends Activity { - - private static final String TAG = "GearsNativeDialog"; - - private String mDialogArguments; - - private String mGearsVersion = null; - - private boolean mDebug = false; - - private int mDialogType; - private static final int SETTINGS_DIALOG = 1; - private static final int PERMISSION_DIALOG = 2; - private static final int LOCATION_DIALOG = 3; - - private static final String VERSION_STRING = "version"; - private static final String SETTINGS_DIALOG_STRING = "settings_dialog"; - private static final String PERMISSION_DIALOG_STRING = "permissions_dialog"; - private static final String LOCATION_DIALOG_STRING = "locations_dialog"; - - private boolean mDialogDismissed = false; - - GearsBaseDialog dialog; - - // Handler for callbacks to the UI thread - final Handler mHandler = new Handler() { - public void handleMessage(Message msg) { - if (msg.what == GearsBaseDialog.NEW_ICON) { - BaseAdapter adapter = (BaseAdapter) msg.obj; - adapter.notifyDataSetChanged(); - } else if (msg.what == GearsBaseDialog.UPDATE_ICON) { - dialog.updateIcon(); - } else if (msg.what == GearsBaseDialog.ALWAYS_DENY) { - closeDialog(GearsBaseDialog.ALWAYS_DENY); - } else if (msg.what == GearsBaseDialog.ALLOW) { - closeDialog(GearsBaseDialog.ALLOW); - } else if (msg.what == GearsBaseDialog.DENY) { - closeDialog(GearsBaseDialog.DENY); - } - super.handleMessage(msg); - } - }; - - @Override - public void onCreate(Bundle icicle) { - getArguments(); - if (mDialogType == SETTINGS_DIALOG) { - setTheme(android.R.style.Theme); - } - super.onCreate(icicle); - if (mDialogType != SETTINGS_DIALOG) { - requestWindowFeature(Window.FEATURE_NO_TITLE); - setContentView(R.layout.gears_dialog); - } - - switch (mDialogType) { - case SETTINGS_DIALOG: - dialog = new GearsSettingsDialog(this, mHandler, mDialogArguments); - dialog.setGearsVersion(mGearsVersion); - break; - case PERMISSION_DIALOG: - dialog = new GearsPermissionsDialog(this, mHandler, mDialogArguments); - break; - case LOCATION_DIALOG: - dialog = new GearsPermissionsDialog(this, mHandler, mDialogArguments); - break; - default: - dialog = new GearsBaseDialog(this, mHandler, mDialogArguments); - } - dialog.setDebug(mDebug); - dialog.setup(); - } - - /** - * Get the arguments for the dialog - * - * The dialog needs a json string as an argument, as - * well as a dialogType. In debug mode the arguments - * are mocked. - */ - private void getArguments() { - if (mDebug) { - mDialogType = LOCATION_DIALOG +1; - mockArguments(); - - return; - } - - Intent intent = getIntent(); - mDialogArguments = intent.getStringExtra("dialogArguments"); - String dialogTypeString = intent.getStringExtra("dialogType"); - if (dialogTypeString == null) { - return; - } - - if (Browser.LOGV_ENABLED) { - Log.v(TAG, "dialogtype: " + dialogTypeString); - } - - if (dialogTypeString.equalsIgnoreCase(SETTINGS_DIALOG_STRING)) { - mDialogType = SETTINGS_DIALOG; - mGearsVersion = intent.getStringExtra(VERSION_STRING); - } else if (dialogTypeString.equalsIgnoreCase(PERMISSION_DIALOG_STRING)) { - mDialogType = PERMISSION_DIALOG; - } else if (dialogTypeString.equalsIgnoreCase(LOCATION_DIALOG_STRING)) { - mDialogType = LOCATION_DIALOG; - } - } - - /** - * Utility method for debugging the dialog. - * - * Set mock arguments. - */ - private void mockArguments() { - - String argumentsPermissions = "{ locale: \"en-US\", " - + "origin: \"http://www.google.com\", dialogType: \"localData\"," - + "customIcon: \"http://google-gears.googlecode.com/" - + "svn/trunk/gears/test/manual/shortcuts/32.png\"," - + "customName: \"My Application\"," - + "customMessage: \"Press the button to enable my " - + "application to run offline!\" };"; - - String argumentsPermissions2 = "{ locale: \"en-US\", " - + "origin: \"http://www.google.com\", dialogType: \"localData\" };"; - - String argumentsLocation = "{ locale: \"en-US\", " - + "origin: \"http://www.google.com\", dialogType: \"locationData\"," - + "customIcon: \"http://google-gears.googlecode.com/" - + "svn/trunk/gears/test/manual/shortcuts/32.png\"," - + "customName: \"My Application\"," - + "customMessage: \"Press the button to enable my " - + "application to run offline!\" };"; - - String argumentsSettings = "{ locale: \"en-US\", permissions: [ { " - + "name: \"http://www.google.com\", " - + "localStorage: { permissionState: 0 }, " - + "locationData: { permissionState: 1 } }, " - + "{ name: \"http://www.aaronboodman.com\", " - + "localStorage: { permissionState: 1 }, " - + "locationData: { permissionState: 2 } }, " - + "{ name: \"http://www.evil.org\", " - + "localStorage: { permissionState: 2 }, " - + "locationData: { permissionState: 2 } } ] }"; - - switch (mDialogType) { - case PERMISSION_DIALOG: - mDialogArguments = argumentsPermissions; - break; - case LOCATION_DIALOG: - mDialogArguments = argumentsLocation; - break; - case SETTINGS_DIALOG: - mDialogArguments = argumentsSettings; - break; - } - } - - /** - * Close the dialog and set the return string value. - */ - private void closeDialog(int closingType) { - String ret = dialog.closeDialog(closingType); - - if (mDebug) { - Log.v(TAG, "closeDialog ret value: " + ret); - } - - NativeDialog.closeDialog(ret); - notifyEndOfDialog(); - finish(); - - // If the dialog sets a notification, we display it. - int notification = dialog.notification(); - if (notification != 0) { - Toast toast = Toast.makeText(this, notification, Toast.LENGTH_LONG); - toast.setGravity(Gravity.BOTTOM, 0, 0); - toast.show(); - } - } - - @Override - public void onDestroy() { - super.onDestroy(); - // In case we reach this point without - // notifying NativeDialog, we do it now. - if (!mDialogDismissed) { - notifyEndOfDialog(); - } - } - - @Override - public void onPause(){ - super.onPause(); - if (!mDialogDismissed) { - closeDialog(GearsBaseDialog.CANCEL); - } - } - - /** - * Signal to NativeDialog that we are done. - */ - private void notifyEndOfDialog() { - NativeDialog.signalFinishedDialog(); - mDialogDismissed = true; - } - - /** - * Intercepts the back key to immediately notify - * NativeDialog that we are done. - */ - public boolean dispatchKeyEvent(KeyEvent event) { - if ((event.getKeyCode() == KeyEvent.KEYCODE_BACK) - && (event.getAction() == KeyEvent.ACTION_DOWN)) { - if (!dialog.handleBackButton()) { - // if the dialog doesn't do anything with the back button - closeDialog(GearsBaseDialog.CANCEL); - } - return true; // event consumed - } - return super.dispatchKeyEvent(event); - } - - /** - * If the dialog call showDialog() on ourself, we let - * it handle the creation of this secondary dialog. - * It is used in GearsSettingsDialog, to create the confirmation - * dialog when the user click on "Remove this site from Gears" - */ - @Override - protected Dialog onCreateDialog(int id) { - return dialog.onCreateDialog(id); - } - -} diff --git a/src/com/android/browser/GearsPermissions.java b/src/com/android/browser/GearsPermissions.java deleted file mode 100644 index e48e045..0000000 --- a/src/com/android/browser/GearsPermissions.java +++ /dev/null @@ -1,196 +0,0 @@ -/* - * Copyright (C) 2008 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.util.Log; - -import java.util.HashMap; -import java.util.Iterator; - -/** - * The permission mechanism works the following way: - * - * PermissionType allows to define a type of permission - * (e.g. localStorage/locationData), storing a name and a set of - * resource ids corresponding to the GUI resources. - * - * Permission defines an actual permission instance, with a type and a value. - * - * OriginPermissions holds an origin with a set of Permission objects - */ -class GearsPermissions { - - private static final String TAG = "GearsPermissions"; - - /** - * Defines a type of permission - * - * Store the permission's name (used in the json result) - * Graphically, each permission is a label followed by two radio buttons. - * We store the resources ids here. - */ - public static class PermissionType { - public static final int PERMISSION_NOT_SET = 0; - public static final int PERMISSION_ALLOWED = 1; - public static final int PERMISSION_DENIED = 2; - - String mName; - int mTitleRsc; - int mSubtitleOnRsc; - int mSubtitleOffRsc; - - PermissionType(String name) { - mName = name; - } - - public void setResources(int titleRsc, - int subtitleOnRsc, int subtitleOffRsc) { - mTitleRsc = titleRsc; - mSubtitleOnRsc = subtitleOnRsc; - mSubtitleOffRsc = subtitleOffRsc; - } - - public String getName() { - return mName; - } - - public int getTitleRsc() { - return mTitleRsc; - } - - public int getSubtitleOnRsc() { - return mSubtitleOnRsc; - } - - public int getSubtitleOffRsc() { - return mSubtitleOffRsc; - } - - } - - /** - * Simple class to store an instance of a permission - * - * i.e. a permission type and a value - * Value can be either PERMISSION_NOT_SET, - * PERMISSION_ALLOWED or PERMISSION_DENIED - * (defined in PermissionType). - */ - public static class Permission { - PermissionType mType; - int mValue; - - Permission(PermissionType type, int value) { - mType = type; - mValue = value; - } - - Permission(PermissionType type) { - mType = type; - mValue = 0; - } - - public PermissionType getType() { - return mType; - } - - public void setValue(int value) { - mValue = value; - } - - public int getValue() { - return mValue; - } - } - - /** - * Interface used by the GearsNativeDialog implementation - * to listen to changes in the permissions. - */ - public interface PermissionsChangesListener { - public boolean setPermission(PermissionType type, int perm); - } - - /** - * Holds the model for an origin -- each origin has a set of - * permissions. - */ - public static class OriginPermissions { - HashMap<PermissionType, Permission> mPermissions; - String mOrigin; - public static PermissionsChangesListener mListener; - - public static void setListener(PermissionsChangesListener listener) { - mListener = listener; - } - - OriginPermissions(String anOrigin) { - mOrigin = anOrigin; - mPermissions = new HashMap<PermissionType, Permission>(); - } - - OriginPermissions(OriginPermissions perms) { - mOrigin = perms.getOrigin(); - mPermissions = new HashMap<PermissionType, Permission>(); - HashMap<PermissionType, Permission> permissions = perms.getPermissions(); - Iterator<PermissionType> iterator = permissions.keySet().iterator(); - while (iterator.hasNext()) { - Permission permission = permissions.get(iterator.next()); - int value = permission.getValue(); - setPermission(permission.getType(), value); - } - } - - public String getOrigin() { - return mOrigin; - } - - public HashMap<PermissionType, Permission> getPermissions() { - return mPermissions; - } - - public int getPermission(PermissionType type) { - return mPermissions.get(type).getValue(); - } - - public void setPermission(PermissionType type, int perm) { - if (mPermissions.get(type) == null) { - Permission permission = new Permission(type, perm); - mPermissions.put(type, permission); - return; - } - - if (mListener != null) { - mListener.setPermission(type, perm); - } - - mPermissions.get(type).setValue(perm); - } - - public void print() { - Log.v(TAG, "Permissions for " + mOrigin); - Iterator<PermissionType> iterator = mPermissions.keySet().iterator(); - while (iterator.hasNext()) { - Permission permission = mPermissions.get(iterator.next()); - String name = permission.getType().getName(); - int value = permission.getValue(); - Log.v(TAG, " " + name + ": " + value); - } - } - } - -} diff --git a/src/com/android/browser/GearsPermissionsDialog.java b/src/com/android/browser/GearsPermissionsDialog.java deleted file mode 100644 index dbec363..0000000 --- a/src/com/android/browser/GearsPermissionsDialog.java +++ /dev/null @@ -1,133 +0,0 @@ -/* - * Copyright (C) 2008 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.app.Activity; -import android.os.Handler; -import android.util.Log; -import android.view.Gravity; -import android.view.View; -import android.widget.ImageView; -import android.widget.TextView; - -import org.json.JSONException; -import org.json.JSONObject; - -/** - * Gears permission dialog - */ -class GearsPermissionsDialog extends GearsBaseDialog { - - private static final String TAG = "GearsPermissionsDialog"; - - private String mDialogType; - private int mNotification = 0; - - public GearsPermissionsDialog(Activity activity, - Handler handler, - String arguments) { - super (activity, handler, arguments); - } - - public void setup() { - inflate(R.layout.gears_dialog_permission, R.id.panel_content); - setupButtons(R.string.permission_button_alwaysdeny, - R.string.permission_button_allow, - R.string.permission_button_deny); - - try { - JSONObject json = new JSONObject(mDialogArguments); - - if (json.has("dialogType")) { - mDialogType = json.getString("dialogType"); - setupDialog(); - } - - if (!json.has("customName")) { - setLabel(json, "origin", R.id.origin_title); - View titleView = findViewById(R.id.origin_title); - if (titleView != null) { - TextView title = (TextView) titleView; - title.setGravity(Gravity.CENTER); - } - } else { - setLabel(json, "customName", R.id.origin_title); - setLabel(json, "origin", R.id.origin_subtitle); - setLabel(json, "customMessage", R.id.origin_message); - } - - if (json.has("customIcon")) { - String iconUrl = json.getString("customIcon"); - mChoosenIconSize = 32; - downloadIcon(iconUrl); - } - - View msg = findViewById(R.id.permission_dialog_message); - if (msg != null) { - TextView dialogMessage = (TextView) msg; - if (mDialogType.equalsIgnoreCase(LOCAL_DATA_STRING)) { - dialogMessage.setText(R.string.query_data_message); - } else if (mDialogType.equalsIgnoreCase(LOCATION_DATA_STRING)) { - dialogMessage.setText(R.string.location_message); - } - } - - } catch (JSONException e) { - Log.e(TAG, "JSON exception ", e); - } - } - - public void setupDialog(TextView message, ImageView icon) { - if (mDialogType.equalsIgnoreCase(LOCAL_DATA_STRING)) { - message.setText(R.string.query_data_prompt); - icon.setImageResource(android.R.drawable.ic_popup_disk_full); - } else if (mDialogType.equalsIgnoreCase(LOCATION_DATA_STRING)) { - message.setText(R.string.location_prompt); - icon.setImageResource(R.drawable.ic_dialog_menu_generic); - } - } - - public String closeDialog(int closingType) { - String ret = null; - switch (closingType) { - case ALWAYS_DENY: - ret = "{\"allow\": false, \"permanently\": true }"; - if (mDialogType.equalsIgnoreCase(LOCAL_DATA_STRING)) { - mNotification = R.string.storage_notification_alwaysdeny; - } else if (mDialogType.equalsIgnoreCase(LOCATION_DATA_STRING)) { - mNotification = R.string.location_notification_alwaysdeny; - } - break; - case ALLOW: - ret = "{\"allow\": true, \"permanently\": true }"; - if (mDialogType.equalsIgnoreCase(LOCAL_DATA_STRING)) { - mNotification = R.string.storage_notification; - } else if (mDialogType.equalsIgnoreCase(LOCATION_DATA_STRING)) { - mNotification = R.string.location_notification; - } - break; - case DENY: - ret = "{\"allow\": false, \"permanently\": false }"; - break; - } - return ret; - } - - public int notification() { - return mNotification; - } -} diff --git a/src/com/android/browser/GearsSettingsDialog.java b/src/com/android/browser/GearsSettingsDialog.java deleted file mode 100644 index 5ea2342..0000000 --- a/src/com/android/browser/GearsSettingsDialog.java +++ /dev/null @@ -1,460 +0,0 @@ -/* - * Copyright (C) 2008 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.app.Activity; -import android.app.AlertDialog; -import android.app.Dialog; -import android.content.Context; -import android.content.DialogInterface; -import android.os.Handler; -import android.util.Log; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.ArrayAdapter; -import android.widget.AdapterView; -import android.widget.AdapterView.OnItemClickListener; -import android.widget.BaseAdapter; -import android.widget.Button; -import android.widget.CheckBox; -import android.widget.CompoundButton; -import android.widget.ImageView; -import android.widget.ListAdapter; -import android.widget.ListView; -import android.widget.RadioButton; -import android.widget.TextView; - -import com.android.browser.GearsPermissions.OriginPermissions; -import com.android.browser.GearsPermissions.Permission; -import com.android.browser.GearsPermissions.PermissionsChangesListener; -import com.android.browser.GearsPermissions.PermissionType; - -import java.util.Vector; -import java.util.List; - -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; - -/** - * Gears Settings dialog - */ -class GearsSettingsDialog extends GearsBaseDialog - implements PermissionsChangesListener { - - private static final String TAG = "GearsPermissionsDialog"; - private Vector<OriginPermissions> mSitesPermissions = null; - private Vector<OriginPermissions> mOriginalPermissions = null; - private Vector<OriginPermissions> mCurrentPermissions = null; - - private Vector<PermissionType> mPermissions; - private static final int CONFIRMATION_REMOVE_DIALOG = 1; - - // We declare the permissions globally to simplify the code - private final PermissionType LOCAL_STORAGE = - new PermissionType(LOCAL_STORAGE_STRING); - private final PermissionType LOCATION_DATA = - new PermissionType(LOCATION_DATA_STRING); - - private boolean mChanges = false; - - SettingsAdapter mListAdapter; - - public GearsSettingsDialog(Activity activity, - Handler handler, - String arguments) { - super (activity, handler, arguments); - activity.setContentView(R.layout.gears_settings); - } - - public void setup() { - // First let's add the permissions' resources - LOCAL_STORAGE.setResources(R.string.settings_storage_title, - R.string.settings_storage_subtitle_on, - R.string.settings_storage_subtitle_off); - LOCATION_DATA.setResources(R.string.settings_location_title, - R.string.settings_location_subtitle_on, - R.string.settings_location_subtitle_off); - // add the permissions to the list of permissions. - mPermissions = new Vector<PermissionType>(); - mPermissions.add(LOCAL_STORAGE); - mPermissions.add(LOCATION_DATA); - OriginPermissions.setListener(this); - - - setupDialog(); - - // We manage the permissions using three vectors, mSitesPermissions, - // mOriginalPermissions and mCurrentPermissions. - // The dialog's arguments are parsed and a list of permissions is - // generated and stored in those three vectors. - // mOriginalPermissions is a separate copy and will not be modified; - // mSitesPermissions contains the current permissions _only_ -- - // if an origin is removed, it is also removed from mSitesPermissions. - // Finally, mCurrentPermissions contains the current permissions and - // is a clone of mSitesPermissions, but removed sites aren't removed, - // their permissions are simply set to PERMISSION_NOT_SET. This - // allows us to easily generate the final difference between the - // original permissions and the final permissions, while directly - // using mSitesPermissions for the listView adapter (SettingsAdapter). - - mSitesPermissions = new Vector<OriginPermissions>(); - mOriginalPermissions = new Vector<OriginPermissions>(); - - try { - JSONObject json = new JSONObject(mDialogArguments); - if (json.has("permissions")) { - JSONArray jsonArray = json.getJSONArray("permissions"); - for (int i = 0; i < jsonArray.length(); i++) { - JSONObject infos = jsonArray.getJSONObject(i); - String name = null; - int localStorage = PermissionType.PERMISSION_NOT_SET; - int locationData = PermissionType.PERMISSION_NOT_SET; - if (infos.has("name")) { - name = infos.getString("name"); - } - if (infos.has(LOCAL_STORAGE_STRING)) { - JSONObject perm = infos.getJSONObject(LOCAL_STORAGE_STRING); - if (perm.has("permissionState")) { - localStorage = perm.getInt("permissionState"); - } - } - if (infos.has(LOCATION_DATA_STRING)) { - JSONObject perm = infos.getJSONObject(LOCATION_DATA_STRING); - if (perm.has("permissionState")) { - locationData = perm.getInt("permissionState"); - } - } - OriginPermissions perms = new OriginPermissions(name); - perms.setPermission(LOCAL_STORAGE, localStorage); - perms.setPermission(LOCATION_DATA, locationData); - - mSitesPermissions.add(perms); - mOriginalPermissions.add(new OriginPermissions(perms)); - } - } - } catch (JSONException e) { - Log.e(TAG, "JSON exception ", e); - } - mCurrentPermissions = (Vector<OriginPermissions>)mSitesPermissions.clone(); - - View listView = findViewById(R.id.sites_list); - if (listView != null) { - ListView list = (ListView) listView; - mListAdapter = new SettingsAdapter(mActivity, mSitesPermissions); - list.setAdapter(mListAdapter); - list.setScrollBarStyle(android.view.View.SCROLLBARS_OUTSIDE_INSET); - list.setOnItemClickListener(mListAdapter); - } - if (mDebug) { - printPermissions(); - } - } - - private void setMainTitle() { - String windowTitle = mActivity.getString(R.string.pref_extras_gears_settings); - mActivity.setTitle(windowTitle); - } - - public void setupDialog() { - setMainTitle(); - } - - /** - * GearsPermissions.PermissionsChangesListener delegate - */ - public boolean setPermission(PermissionType type, int perm) { - if (mChanges == false) { - mChanges = true; - } - return mChanges; - } - - public boolean handleBackButton() { - return mListAdapter.backButtonPressed(); - } - - /** - * We use this to create a confirmation dialog when the user - * clicks on "remove this site from gears" - */ - public Dialog onCreateDialog(int id) { - return new AlertDialog.Builder(mActivity) - .setTitle(R.string.settings_confirmation_remove_title) - .setMessage(R.string.settings_confirmation_remove) - .setPositiveButton(android.R.string.ok, - new AlertDialog.OnClickListener() { - public void onClick(DialogInterface dlg, int which) { - mListAdapter.removeCurrentSite(); - } - }) - .setNegativeButton(android.R.string.cancel, null) - .setIcon(android.R.drawable.ic_dialog_alert) - .create(); - } - - /** - * Adapter class for the list view in the settings dialog - * - * We first display a list of all the origins (sites), or - * a message saying that no permission is set if the list is empty. - * When the user click on one of the origin, we then display - * the list of the permissions existing for that origin. - * Each permission can be either allowed or denied by clicking - * on the checkbox. - * The last row is a special case, allowing to remove the entire origin. - */ - class SettingsAdapter extends BaseAdapter - implements AdapterView.OnItemClickListener { - private Activity mContext; - private List mItems; - private OriginPermissions mCurrentSite; - private Vector mCurrentPermissions; - private int MAX_ROW_HEIGHT = 64; - - SettingsAdapter(Activity context, List items) { - mContext = context; - mItems = items; - mCurrentSite = null; - } - - public int getCount() { - if (mCurrentSite == null) { - int size = mItems.size(); - if (size == 0) { - return 1; - } else { - return size; - } - } - return mCurrentPermissions.size() + 1; - } - - public long getItemId(int position) { - return position; - } - - private String shortName(String url) { - // We remove the http and https prefix - if (url.startsWith("http://")) { - return url.substring(7); - } - if (url.startsWith("https://")) { - return url.substring(8); - } - return url; - } - - public Object getItem(int position) { - if (mCurrentSite == null) { - if (mItems.size() == 0) { - return null; - } else { - return mItems.get(position); - } - } - return mCurrentPermissions.get(position); - } - - public View getView(int position, View convertView, ViewGroup parent) { - View row = convertView; - if (row == null) { // no cached view, we create one - LayoutInflater inflater = (LayoutInflater) getSystemService( - Context.LAYOUT_INFLATER_SERVICE); - row = inflater.inflate(R.layout.gears_settings_row, null); - } - row.setMinimumHeight(MAX_ROW_HEIGHT); - - if (mCurrentSite == null) { - if (mItems.size() == 0) { - hideView(row, R.id.title); - hideView(row, R.id.subtitle); - hideView(row, R.id.checkbox); - hideView(row, R.id.icon); - setText(row, R.id.info, R.string.settings_empty); - } else { - hideView(row, R.id.subtitle); - hideView(row, R.id.info); - hideView(row, R.id.checkbox); - OriginPermissions perms = (OriginPermissions) mItems.get(position); - setText(row, R.id.title, shortName(perms.getOrigin())); - showView(row, R.id.icon); - } - } else { - if (position == getCount() - 1) { - // last position: "remove this site from gears" - hideView(row, R.id.subtitle); - hideView(row, R.id.info); - hideView(row, R.id.checkbox); - hideView(row, R.id.icon); - setText(row, R.id.title, R.string.settings_remove_site); - } else { - hideView(row, R.id.info); - hideView(row, R.id.icon); - showView(row, R.id.checkbox); - - PermissionType type = - (PermissionType) mCurrentPermissions.get(position); - setText(row, R.id.title, type.getTitleRsc()); - - View checkboxView = row.findViewById(R.id.checkbox); - if (checkboxView != null) { - CheckBox checkbox = (CheckBox) checkboxView; - int perm = mCurrentSite.getPermission(type); - if (perm == PermissionType.PERMISSION_DENIED) { - setText(row, R.id.subtitle, type.getSubtitleOffRsc()); - checkbox.setChecked(false); - } else { - setText(row, R.id.subtitle, type.getSubtitleOnRsc()); - checkbox.setChecked(true); - } - } - } - } - return row; - } - - public void removeCurrentSite() { - mCurrentSite.setPermission(LOCAL_STORAGE, - PermissionType.PERMISSION_NOT_SET); - mCurrentSite.setPermission(LOCATION_DATA, - PermissionType.PERMISSION_NOT_SET); - mSitesPermissions.remove(mCurrentSite); - mCurrentSite = null; - setMainTitle(); - notifyDataSetChanged(); - } - - public void onItemClick(AdapterView<?> parent, - View view, - int position, - long id) { - if (mItems.size() == 0) { - return; - } - if (mCurrentSite == null) { - mCurrentSite = (OriginPermissions) mItems.get(position); - mCurrentPermissions = new Vector(); - for (int i = 0; i < mPermissions.size(); i++) { - PermissionType type = mPermissions.get(i); - int perm = mCurrentSite.getPermission(type); - if (perm != PermissionType.PERMISSION_NOT_SET) { - mCurrentPermissions.add(type); - } - } - mContext.setTitle(shortName(mCurrentSite.getOrigin())); - } else { - if (position == getCount() - 1) { // last item (remove site) - // Ask the user to confirm - // If yes, removeCurrentSite() will be called via the dialog callback. - mActivity.showDialog(CONFIRMATION_REMOVE_DIALOG); - } else { - PermissionType type = - (PermissionType) mCurrentPermissions.get(position); - if (mCurrentSite.getPermission(type) == - PermissionType.PERMISSION_ALLOWED) { - mCurrentSite.setPermission(type, PermissionType.PERMISSION_DENIED); - } else { - mCurrentSite.setPermission(type, PermissionType.PERMISSION_ALLOWED); - } - } - } - notifyDataSetChanged(); - } - - public boolean backButtonPressed() { - if (mCurrentSite != null) { // we intercept the back button - mCurrentSite = null; - setMainTitle(); - notifyDataSetChanged(); - return true; - } - return false; - } - - } - - /** - * Utility method used in debug mode to print the list of - * permissions (original values and current values). - */ - public void printPermissions() { - Log.v(TAG, "Original Permissions: "); - for (int i = 0; i < mOriginalPermissions.size(); i++) { - OriginPermissions p = mOriginalPermissions.get(i); - p.print(); - } - Log.v(TAG, "Current Permissions: "); - for (int i = 0; i < mSitesPermissions.size(); i++) { - OriginPermissions p = mSitesPermissions.get(i); - p.print(); - } - } - - /** - * Computes the difference between the original permissions and the - * current ones. Returns a json-formatted string. - * It is used by the Settings dialog. - */ - public String computeDiff(boolean modif) { - String ret = null; - try { - JSONObject results = new JSONObject(); - JSONArray permissions = new JSONArray(); - - for (int i = 0; modif && i < mOriginalPermissions.size(); i++) { - OriginPermissions original = mOriginalPermissions.get(i); - OriginPermissions current = mCurrentPermissions.get(i); - JSONObject permission = new JSONObject(); - boolean modifications = false; - - for (int j = 0; j < mPermissions.size(); j++) { - PermissionType type = mPermissions.get(j); - - if (current.getPermission(type) != original.getPermission(type)) { - JSONObject state = new JSONObject(); - state.put("permissionState", current.getPermission(type)); - permission.put(type.getName(), state); - modifications = true; - } - } - - if (modifications) { - permission.put("name", current.getOrigin()); - permissions.put(permission); - } - } - results.put("modifiedOrigins", permissions); - ret = results.toString(); - } catch (JSONException e) { - Log.e(TAG, "JSON exception ", e); - } - return ret; - } - - public String closeDialog(int closingType) { - String ret = computeDiff(mChanges); - - if (mDebug) { - printPermissions(); - } - - return ret; - } - -} |