diff options
author | The Android Open Source Project <initial-contribution@android.com> | 2009-02-13 12:57:52 -0800 |
---|---|---|
committer | The Android Open Source Project <initial-contribution@android.com> | 2009-02-13 12:57:52 -0800 |
commit | fbb2a3ac0739da8207174943c08a289dcddcfab6 (patch) | |
tree | 1befea471c038bb7a5c77c96a74bb04c94c679ad /src/com | |
parent | b7775e1e46a6c8ce0f07747d44c1b1792bb0ce1c (diff) | |
download | packages_apps_Browser-fbb2a3ac0739da8207174943c08a289dcddcfab6.zip packages_apps_Browser-fbb2a3ac0739da8207174943c08a289dcddcfab6.tar.gz packages_apps_Browser-fbb2a3ac0739da8207174943c08a289dcddcfab6.tar.bz2 |
auto import from //branches/cupcake/...@131421
Diffstat (limited to 'src/com')
-rw-r--r-- | src/com/android/browser/BrowserActivity.java | 43 | ||||
-rw-r--r-- | src/com/android/browser/BrowserSettings.java | 2 | ||||
-rw-r--r-- | src/com/android/browser/FakeWebView.java | 11 | ||||
-rw-r--r-- | src/com/android/browser/GearsBaseDialog.java | 93 | ||||
-rw-r--r-- | src/com/android/browser/GearsFilePickerDialog.java | 6 | ||||
-rw-r--r-- | src/com/android/browser/GearsNativeDialog.java | 58 | ||||
-rw-r--r-- | src/com/android/browser/GearsPermissions.java | 32 | ||||
-rw-r--r-- | src/com/android/browser/GearsPermissionsDialog.java | 45 | ||||
-rw-r--r-- | src/com/android/browser/GearsSettingsDialog.java | 422 | ||||
-rw-r--r-- | src/com/android/browser/GearsShortcutDialog.java | 30 | ||||
-rw-r--r-- | src/com/android/browser/MostVisitedActivity.java | 8 |
11 files changed, 453 insertions, 297 deletions
diff --git a/src/com/android/browser/BrowserActivity.java b/src/com/android/browser/BrowserActivity.java index b6942d2..d8fd3fa 100644 --- a/src/com/android/browser/BrowserActivity.java +++ b/src/com/android/browser/BrowserActivity.java @@ -120,6 +120,7 @@ import android.widget.FrameLayout; import android.widget.LinearLayout; import android.widget.TextView; import android.widget.Toast; +import android.widget.ZoomRingController; import com.google.android.googleapps.IGoogleLoginService; import com.google.android.googlelogin.GoogleLoginServiceConstants; @@ -131,6 +132,7 @@ import java.io.FileOutputStream; import java.io.InputStream; import java.io.IOException; import java.net.MalformedURLException; +import java.net.URI; import java.net.URL; import java.net.URLEncoder; import java.text.ParseException; @@ -743,6 +745,9 @@ public class BrowserActivity extends Activity } } }; + + // Show a tutorial for the new zoom interaction (the method ensure we only show it once) + ZoomRingController.showZoomTutorialOnce(this); } @Override @@ -3389,10 +3394,44 @@ public class BrowserActivity extends Activity return; } + // java.net.URI is a lot stricter than KURL so we have to undo + // KURL's percent-encoding and redo the encoding using java.net.URI. + URI uri = null; + try { + // Undo the percent-encoding that KURL may have done. + String newUrl = new String(URLUtil.decode(url.getBytes())); + // Parse the url into pieces + WebAddress w = new WebAddress(newUrl); + String frag = null; + String query = null; + String path = w.mPath; + // Break the path into path, query, and fragment + if (path.length() > 0) { + // Strip the fragment + int idx = path.lastIndexOf('#'); + if (idx != -1) { + frag = path.substring(idx + 1); + path = path.substring(0, idx); + } + idx = path.lastIndexOf('?'); + if (idx != -1) { + query = path.substring(idx + 1); + path = path.substring(0, idx); + } + } + uri = new URI(w.mScheme, w.mAuthInfo, w.mHost, w.mPort, path, + query, frag); + } catch (Exception e) { + Log.e(LOGTAG, "Could not parse url for download: " + url, e); + return; + } + + // XXX: Have to use the old url since the cookies were stored using the + // old percent-encoded url. String cookies = CookieManager.getInstance().getCookie(url); ContentValues values = new ContentValues(); - values.put(Downloads.URI, url); + values.put(Downloads.URI, uri.toString()); values.put(Downloads.COOKIE_DATA, cookies); values.put(Downloads.USER_AGENT, userAgent); values.put(Downloads.NOTIFICATION_PACKAGE, @@ -3402,7 +3441,7 @@ public class BrowserActivity extends Activity values.put(Downloads.VISIBILITY, Downloads.VISIBILITY_VISIBLE_NOTIFY_COMPLETED); values.put(Downloads.MIMETYPE, mimetype); values.put(Downloads.FILENAME_HINT, filename); - values.put(Downloads.DESCRIPTION, Uri.parse(url).getHost()); + values.put(Downloads.DESCRIPTION, uri.getHost()); if (contentLength > 0) { values.put(Downloads.TOTAL_BYTES, contentLength); } diff --git a/src/com/android/browser/BrowserSettings.java b/src/com/android/browser/BrowserSettings.java index 5038a4e..06ccf01 100644 --- a/src/com/android/browser/BrowserSettings.java +++ b/src/com/android/browser/BrowserSettings.java @@ -334,6 +334,8 @@ class BrowserSettings extends Observable { public void toggleDebugSettings() { showDebugSettings = !showDebugSettings; + navDump = showDebugSettings; + update(); } /** diff --git a/src/com/android/browser/FakeWebView.java b/src/com/android/browser/FakeWebView.java index 7997672..633b799 100644 --- a/src/com/android/browser/FakeWebView.java +++ b/src/com/android/browser/FakeWebView.java @@ -34,10 +34,12 @@ import android.util.Log; */ public class FakeWebView extends ImageView { private TabControl.Tab mTab; + private Picture mPicture; private boolean mUsesResource; private class Listener implements WebView.PictureListener { public void onNewPicture(WebView view, Picture p) { + FakeWebView.this.mPicture = p; FakeWebView.this.invalidate(); } }; @@ -69,13 +71,12 @@ public class FakeWebView extends ImageView { if (mTab != null) { final WebView w = mTab.getTopWindow(); if (w != null) { - Picture p = w.capturePicture(); - if (p != null) { + if (mPicture != null) { canvas.save(); float scale = getWidth() * w.getScale() / w.getWidth(); canvas.scale(scale, scale); canvas.translate(-w.getScrollX(), -w.getScrollY()); - canvas.drawPicture(p); + canvas.drawPicture(mPicture); canvas.restore(); } } @@ -99,10 +100,12 @@ public class FakeWebView extends ImageView { mTab = t; if (t != null && t.getWebView() != null) { Listener l = new Listener(); - t.getWebView().setPictureListener(l); if (t.getSubWebView() != null) { t.getSubWebView().setPictureListener(l); + } else { + t.getWebView().setPictureListener(l); } + mPicture = mTab.getTopWindow().capturePicture(); } } } diff --git a/src/com/android/browser/GearsBaseDialog.java b/src/com/android/browser/GearsBaseDialog.java index afd0dd2..3379537 100644 --- a/src/com/android/browser/GearsBaseDialog.java +++ b/src/com/android/browser/GearsBaseDialog.java @@ -17,6 +17,7 @@ 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; @@ -191,14 +192,14 @@ class GearsBaseDialog { public void onClick(View v) { mHandler.sendEmptyMessage(ALWAYS_DENY); } - }, true, false); + }); setupButton(R.id.button_allow, allowRsc, new Button.OnClickListener() { public void onClick(View v) { mHandler.sendEmptyMessage(ALLOW); } - }, false, true); + }); setupButton(R.id.button_deny, denyRsc, new Button.OnClickListener() { @@ -249,6 +250,67 @@ class GearsBaseDialog { } /** + * Utility method to hide a view. + */ + void hideView(View v, int rsc) { + if (rsc == 0) { + return; + } + View 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 = 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. */ @@ -360,7 +422,7 @@ class GearsBaseDialog { */ public void setupDialog(TextView message, ImageView icon) { message.setText(R.string.unrecognized_dialog_message); - icon.setImageResource(R.drawable.gears_icon_48x48); + icon.setImageResource(R.drawable.ic_dialog_menu_generic); message.setVisibility(View.VISIBLE); } @@ -373,4 +435,29 @@ class GearsBaseDialog { 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/GearsFilePickerDialog.java b/src/com/android/browser/GearsFilePickerDialog.java index d84a970..0bb28d4 100644 --- a/src/com/android/browser/GearsFilePickerDialog.java +++ b/src/com/android/browser/GearsFilePickerDialog.java @@ -155,7 +155,7 @@ class GearsFilePickerDialog extends GearsBaseDialog public void setupDialog(TextView message, ImageView icon) { message.setText(R.string.filepicker_message); message.setTextSize(24); - icon.setImageResource(R.drawable.gears_icon_32x32); + icon.setImageResource(R.drawable.ic_dialog_menu_generic); } public boolean onTouch(View v, MotionEvent event) { @@ -684,7 +684,7 @@ class GearsFilePickerDialog extends GearsBaseDialog int color = getResources().getColor(R.color.icon_selection); v.setBackgroundColor(color); } else { - v.setBackgroundColor(Color.WHITE); + v.setBackgroundColor(android.R.color.background_dark); } return false; } @@ -696,7 +696,7 @@ class GearsFilePickerDialog extends GearsBaseDialog int color = getResources().getColor(R.color.icon_selection); cell.setBackgroundColor(color); } else { - cell.setBackgroundColor(Color.WHITE); + cell.setBackgroundColor(android.R.color.background_dark); } Bitmap bmp = elem.getIcon(position); if (bmp != null) { diff --git a/src/com/android/browser/GearsNativeDialog.java b/src/com/android/browser/GearsNativeDialog.java index c8ae741..c72ad8e 100644 --- a/src/com/android/browser/GearsNativeDialog.java +++ b/src/com/android/browser/GearsNativeDialog.java @@ -17,6 +17,7 @@ package com.android.browser; import android.app.Activity; +import android.app.Dialog; import android.content.Intent; import android.net.Uri; import android.os.Bundle; @@ -24,9 +25,11 @@ import android.os.Handler; import android.os.Message; import android.util.Config; 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; @@ -90,10 +93,15 @@ public class GearsNativeDialog extends Activity { @Override public void onCreate(Bundle icicle) { - super.onCreate(icicle); - requestWindowFeature(Window.FEATURE_NO_TITLE); - setContentView(R.layout.gears_dialog); 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: @@ -185,6 +193,9 @@ public class GearsNativeDialog extends Activity { + "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/" @@ -195,8 +206,8 @@ public class GearsNativeDialog extends Activity { String argumentsSettings = "{ locale: \"en-US\", permissions: [ { " + "name: \"http://www.google.com\", " - + "localStorage: { permissionState: 1 }, " - + "locationData: { permissionState: 0 } }, " + + "localStorage: { permissionState: 0 }, " + + "locationData: { permissionState: 1 } }, " + "{ name: \"http://www.aaronboodman.com\", " + "localStorage: { permissionState: 1 }, " + "locationData: { permissionState: 2 } }, " @@ -204,6 +215,12 @@ public class GearsNativeDialog extends Activity { + "localStorage: { permissionState: 2 }, " + "locationData: { permissionState: 2 } } ] }"; + String argumentsFilePicker = "{ \"cameraMode\" : \"OFF\", \"filters\"" + + ": [ \"text/html\", \".txt\" ], \"mode\" : \"MULTIPLE_FILES\" }\""; + + String argumentsFilePicker2 = "{ \"cameraMode\" : \"OFF\", \"filters\"" + + ": [ \"text/html\", \".txt\" ], \"mode\" : \"SINGLE_FILE\" }\""; + switch (mDialogType) { case SHORTCUT_DIALOG: mDialogArguments = argumentsShortcuts; @@ -216,6 +233,9 @@ public class GearsNativeDialog extends Activity { break; case SETTINGS_DIALOG: mDialogArguments = argumentsSettings; + break; + case FILEPICKER_DIALOG: + mDialogArguments = argumentsFilePicker2; } } @@ -232,6 +252,14 @@ public class GearsNativeDialog extends Activity { 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 @@ -265,10 +293,26 @@ public class GearsNativeDialog extends Activity { * NativeDialog that we are done. */ public boolean dispatchKeyEvent(KeyEvent event) { - if (event.getKeyCode() == KeyEvent.KEYCODE_BACK && event.isDown()) { - closeDialog(GearsBaseDialog.CANCEL); + 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 index cd46324..e48e045 100644 --- a/src/com/android/browser/GearsPermissions.java +++ b/src/com/android/browser/GearsPermissions.java @@ -49,35 +49,35 @@ class GearsPermissions { public static final int PERMISSION_DENIED = 2; String mName; - int mRowRsc; - int mAllowedButtonRsc; - int mDeniedButtonRsc; + int mTitleRsc; + int mSubtitleOnRsc; + int mSubtitleOffRsc; PermissionType(String name) { mName = name; } - public void setResources(int rowRsc, int allowedButtonRsc, - int deniedButtonRsc) { - mRowRsc = rowRsc; - mAllowedButtonRsc = allowedButtonRsc; - mDeniedButtonRsc = deniedButtonRsc; + public void setResources(int titleRsc, + int subtitleOnRsc, int subtitleOffRsc) { + mTitleRsc = titleRsc; + mSubtitleOnRsc = subtitleOnRsc; + mSubtitleOffRsc = subtitleOffRsc; } - public int getRowRsc() { - return mRowRsc; + public String getName() { + return mName; } - public int getAllowedButtonRsc() { - return mAllowedButtonRsc; + public int getTitleRsc() { + return mTitleRsc; } - public int getDeniedButtonRsc() { - return mDeniedButtonRsc; + public int getSubtitleOnRsc() { + return mSubtitleOnRsc; } - public String getName() { - return mName; + public int getSubtitleOffRsc() { + return mSubtitleOffRsc; } } diff --git a/src/com/android/browser/GearsPermissionsDialog.java b/src/com/android/browser/GearsPermissionsDialog.java index b57ab0b..dbec363 100644 --- a/src/com/android/browser/GearsPermissionsDialog.java +++ b/src/com/android/browser/GearsPermissionsDialog.java @@ -35,6 +35,7 @@ class GearsPermissionsDialog extends GearsBaseDialog { private static final String TAG = "GearsPermissionsDialog"; private String mDialogType; + private int mNotification = 0; public GearsPermissionsDialog(Activity activity, Handler handler, @@ -48,15 +49,6 @@ class GearsPermissionsDialog extends GearsBaseDialog { R.string.permission_button_allow, R.string.permission_button_deny); - View contentBorder = findViewById(R.id.content_border); - if (contentBorder != null) { - contentBorder.setBackgroundResource(R.color.permission_border); - } - View contentBackground = findViewById(R.id.content_background); - if (contentBackground != null) { - contentBackground.setBackgroundResource(R.color.permission_background); - } - try { JSONObject json = new JSONObject(mDialogArguments); @@ -84,6 +76,16 @@ class GearsPermissionsDialog extends GearsBaseDialog { 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); } @@ -91,15 +93,11 @@ class GearsPermissionsDialog extends GearsBaseDialog { public void setupDialog(TextView message, ImageView icon) { if (mDialogType.equalsIgnoreCase(LOCAL_DATA_STRING)) { - message.setText(R.string.query_data_message); - icon.setImageResource(R.drawable.gears_local_data); + 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_message); - icon.setImageResource(R.drawable.gears_location_data); - View privacyPolicyLabel = findViewById(R.id.privacy_policy_label); - if (privacyPolicyLabel != null) { - privacyPolicyLabel.setVisibility(View.VISIBLE); - } + message.setText(R.string.location_prompt); + icon.setImageResource(R.drawable.ic_dialog_menu_generic); } } @@ -108,9 +106,19 @@ class GearsPermissionsDialog extends GearsBaseDialog { 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 }"; @@ -119,4 +127,7 @@ class GearsPermissionsDialog extends GearsBaseDialog { return ret; } + public int notification() { + return mNotification; + } } diff --git a/src/com/android/browser/GearsSettingsDialog.java b/src/com/android/browser/GearsSettingsDialog.java index 56a1d8d..5ea2342 100644 --- a/src/com/android/browser/GearsSettingsDialog.java +++ b/src/com/android/browser/GearsSettingsDialog.java @@ -17,14 +17,21 @@ 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; @@ -33,6 +40,7 @@ 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; @@ -55,6 +63,7 @@ class GearsSettingsDialog extends GearsBaseDialog 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 = @@ -64,23 +73,23 @@ class GearsSettingsDialog extends GearsBaseDialog 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.id.local_storage_choice, - R.id.local_storage_allowed, - R.id.local_storage_denied); - - LOCATION_DATA.setResources(R.id.location_data_choice, - R.id.location_data_allowed, - R.id.location_data_denied); - + 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); @@ -88,25 +97,7 @@ class GearsSettingsDialog extends GearsBaseDialog OriginPermissions.setListener(this); - inflate(R.layout.gears_dialog_settings, R.id.panel_content); setupDialog(); - setupButtons(0, - R.string.settings_button_allow, - R.string.settings_button_deny); - - // by default disable the allow button (it will get enabled if - // something is changed by the user) - View buttonView = findViewById(R.id.button_allow); - if (buttonView != null) { - Button button = (Button) buttonView; - button.setEnabled(false); - } - - View gearsVersionView = findViewById(R.id.gears_version); - if (gearsVersionView != null) { - TextView gearsVersion = (TextView) gearsVersionView; - gearsVersion.setText(mGearsVersion); - } // We manage the permissions using three vectors, mSitesPermissions, // mOriginalPermissions and mCurrentPermissions. @@ -165,32 +156,23 @@ class GearsSettingsDialog extends GearsBaseDialog View listView = findViewById(R.id.sites_list); if (listView != null) { ListView list = (ListView) listView; - list.setAdapter(new SettingsAdapter(mActivity, mSitesPermissions)); + 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() { - View dialogTitleView = findViewById(R.id.dialog_title); - if (dialogTitleView != null) { - TextView dialogTitle = (TextView) dialogTitleView; - dialogTitle.setText(R.string.settings_title); - dialogTitle.setVisibility(View.VISIBLE); - } - View dialogSubtitleView = findViewById(R.id.dialog_subtitle); - if (dialogSubtitleView != null) { - TextView dialogSubtitle = (TextView) dialogSubtitleView; - dialogSubtitle.setText(R.string.settings_message); - dialogSubtitle.setVisibility(View.VISIBLE); - } - View iconView = findViewById(R.id.icon); - if (iconView != null) { - ImageView icon = (ImageView) iconView; - icon.setImageResource(R.drawable.gears_icon_32x32); - } + setMainTitle(); } /** @@ -198,164 +180,95 @@ class GearsSettingsDialog extends GearsBaseDialog */ public boolean setPermission(PermissionType type, int perm) { if (mChanges == false) { - signalChanges(); + mChanges = true; } return mChanges; } + public boolean handleBackButton() { + return mListAdapter.backButtonPressed(); + } + /** - * Controller class for binding the model (OriginPermissions) with - * the UI. + * We use this to create a confirmation dialog when the user + * clicks on "remove this site from gears" */ - class PermissionController { - final static int ALLOWED_BUTTON = 1; - final static int DENIED_BUTTON = 2; - private int mButtonType; - private PermissionType mPermissionType; - private OriginPermissions mPermissions; - - PermissionController(PermissionType permissionType, int buttonType, - OriginPermissions permissions) { - mPermissionType = permissionType; - mButtonType = buttonType; - mPermissions = permissions; - } - - public boolean isChecked() { - boolean checked = false; - - switch (mButtonType) { - case ALLOWED_BUTTON: - if (mPermissions.getPermission(mPermissionType) == - PermissionType.PERMISSION_ALLOWED) { - checked = true; - } break; - case DENIED_BUTTON: - if (mPermissions.getPermission(mPermissionType) == - PermissionType.PERMISSION_DENIED) { - checked = true; + 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(); } - } - return checked; - } - - public String print() { - return printType() + " for " + mPermissions.getOrigin(); - } - - private String printType() { - switch (mButtonType) { - case ALLOWED_BUTTON: - return "ALLOWED_BUTTON"; - case DENIED_BUTTON: - return "DENIED_BUTTON"; - } - return "UNKNOWN BUTTON"; - } - - public void changed(boolean isChecked) { - if (isChecked == isChecked()) { - return; // already set - } - - switch (mButtonType) { - case ALLOWED_BUTTON: - mPermissions.setPermission(mPermissionType, - PermissionType.PERMISSION_ALLOWED); - break; - case DENIED_BUTTON: - mPermissions.setPermission(mPermissionType, - PermissionType.PERMISSION_DENIED); - break; - } - } + }) + .setNegativeButton(android.R.string.cancel, null) + .setIcon(android.R.drawable.ic_dialog_alert) + .create(); } - - /** * Adapter class for the list view in the settings dialog * - * Every row in the settings dialog display the permissions - * for a given origin. For every type of permission - * (location, local data...) there is two radio buttons to - * authorize or deny the permission. - * A remove button is also present to let the user remove - * all the authorization of an origin in one step. + * 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 ArrayAdapter { + 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) { - super(context, R.layout.gears_dialog_settings_row, items); mContext = context; mItems = items; + mCurrentSite = null; } - /* - * setup the necessary listeners for the radiobuttons - * When the buttons are clicked the permissions change. - */ - private void createAndSetButtonListener(View buttonView, - OriginPermissions perms, PermissionType permissionType, - int buttonType) { - if (buttonView == null) { - return; - } - RadioButton button = (RadioButton) buttonView; - - button.setOnCheckedChangeListener(null); - PermissionController p = new PermissionController(permissionType, - buttonType, perms); - button.setTag(p); - - CompoundButton.OnCheckedChangeListener listener = - new CompoundButton.OnCheckedChangeListener() { - public void onCheckedChanged(CompoundButton buttonView, - boolean isChecked) { - PermissionController perm = (PermissionController)buttonView.getTag(); - perm.changed(isChecked); + public int getCount() { + if (mCurrentSite == null) { + int size = mItems.size(); + if (size == 0) { + return 1; + } else { + return size; } - }; + } + return mCurrentPermissions.size() + 1; + } - button.setOnCheckedChangeListener(listener); + public long getItemId(int position) { + return position; + } - if (p.isChecked() != button.isChecked()) { - button.setChecked(p.isChecked()); - } + 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; } - /* - * setup the remove button for an origin: each row has a global - * remove button in addition to the radio buttons controlling the - * permissions. - */ - private void setRemoveButton(Button button, OriginPermissions perms) { - Button.OnClickListener listener = new Button.OnClickListener() { - public void onClick(View buttonView) { - if (mChanges == false) { - signalChanges(); - } - OriginPermissions perm = (OriginPermissions) buttonView.getTag(); - perm.setPermission(LOCAL_STORAGE, PermissionType.PERMISSION_NOT_SET); - perm.setPermission(LOCATION_DATA, PermissionType.PERMISSION_NOT_SET); - mSitesPermissions.remove(perm); - - View view = findViewById(R.id.sites_list); - if (view != null) { - ListView listView = (ListView) view; - ListAdapter listAdapter = listView.getAdapter(); - if (listAdapter != null) { - SettingsAdapter settingsAdapter = (SettingsAdapter) listAdapter; - settingsAdapter.notifyDataSetChanged(); - } - } + public Object getItem(int position) { + if (mCurrentSite == null) { + if (mItems.size() == 0) { + return null; + } else { + return mItems.get(position); } - }; - button.setTag(perms); - button.setOnClickListener(listener); - displayAsLink(button); + } + return mCurrentPermissions.get(position); } public View getView(int position, View convertView, ViewGroup parent) { @@ -363,46 +276,117 @@ class GearsSettingsDialog extends GearsBaseDialog if (row == null) { // no cached view, we create one LayoutInflater inflater = (LayoutInflater) getSystemService( Context.LAYOUT_INFLATER_SERVICE); - row = inflater.inflate(R.layout.gears_dialog_settings_row, null); + row = inflater.inflate(R.layout.gears_settings_row, null); } - - OriginPermissions perms = (OriginPermissions) mItems.get(position); - - View nameView = row.findViewById(R.id.origin_name); - if (nameView != null) { - TextView originName = (TextView) nameView; - originName.setText(perms.getOrigin()); + 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; + } - View removeButtonView = row.findViewById(R.id.origin_remove); - if (removeButtonView != null) { - Button removeButton = (Button) removeButtonView; - setRemoveButton(removeButton, perms); - } + 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(); + } - for (int i = 0; i < mPermissions.size(); i++) { - PermissionType type = mPermissions.get(i); - int rowRsc = type.getRowRsc(); - int allowedButtonRsc = type.getAllowedButtonRsc(); - int deniedButtonRsc = type.getDeniedButtonRsc(); - - View rowView = row.findViewById(rowRsc); - if (rowView != null) { - int perm = perms.getPermission(type); - if (perm != PermissionType.PERMISSION_NOT_SET) { - createAndSetButtonListener(row.findViewById(allowedButtonRsc), - perms, type, PermissionController.ALLOWED_BUTTON); - createAndSetButtonListener(row.findViewById(deniedButtonRsc), - perms, type, PermissionController.DENIED_BUTTON); - rowView.setVisibility(View.VISIBLE); + 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 { - rowView.setVisibility(View.GONE); + mCurrentSite.setPermission(type, PermissionType.PERMISSION_ALLOWED); } } } + notifyDataSetChanged(); + } - return row; + public boolean backButtonPressed() { + if (mCurrentSite != null) { // we intercept the back button + mCurrentSite = null; + setMainTitle(); + notifyDataSetChanged(); + return true; + } + return false; } + } /** @@ -423,21 +407,6 @@ class GearsSettingsDialog extends GearsBaseDialog } /** - * Utility method used by the settings dialog, signaling - * the user the settings have been modified. - * We reflect this by enabling the Allow button (disabled - * by default). - */ - public void signalChanges() { - View view = findViewById(R.id.button_allow); - if (view != null) { - Button button = (Button) view; - button.setEnabled(true); - } - mChanges = true; - } - - /** * Computes the difference between the original permissions and the * current ones. Returns a json-formatted string. * It is used by the Settings dialog. @@ -479,18 +448,7 @@ class GearsSettingsDialog extends GearsBaseDialog } public String closeDialog(int closingType) { - String ret = null; - switch (closingType) { - case ALWAYS_DENY: - ret = "{\"allow\": false }"; - break; - case ALLOW: - ret = computeDiff(true); - break; - case DENY: - ret = computeDiff(false); - break; - } + String ret = computeDiff(mChanges); if (mDebug) { printPermissions(); diff --git a/src/com/android/browser/GearsShortcutDialog.java b/src/com/android/browser/GearsShortcutDialog.java index deede12..11d936d 100644 --- a/src/com/android/browser/GearsShortcutDialog.java +++ b/src/com/android/browser/GearsShortcutDialog.java @@ -37,6 +37,7 @@ class GearsShortcutDialog extends GearsBaseDialog { private final String ICON_32 = "icon32x32"; private final String ICON_48 = "icon48x48"; private final String ICON_128 = "icon128x128"; + private int mNotification = 0; public GearsShortcutDialog(Activity activity, Handler handler, @@ -45,20 +46,11 @@ class GearsShortcutDialog extends GearsBaseDialog { } public void setup() { - inflate(R.layout.gears_dialog_permission, R.id.panel_content); + inflate(R.layout.gears_dialog_shortcut, R.id.panel_content); setupButtons(R.string.shortcut_button_alwaysdeny, R.string.shortcut_button_allow, R.string.shortcut_button_deny); - View contentBorder = findViewById(R.id.content_border); - if (contentBorder != null) { - contentBorder.setBackgroundResource(R.color.shortcut_border); - } - View contentBackground = findViewById(R.id.content_background); - if (contentBackground != null) { - contentBackground.setBackgroundResource(R.color.shortcut_background); - } - try { JSONObject json = new JSONObject(mDialogArguments); @@ -69,17 +61,25 @@ class GearsShortcutDialog extends GearsBaseDialog { setupDialog(); - setLabel(json, "name", R.id.origin_title); + setLabel(json, "name", R.id.shortcut_name); setLabel(json, "link", R.id.origin_subtitle); setLabel(json, "description", R.id.origin_message); } catch (JSONException e) { Log.e(TAG, "JSON exception", e); } + + TextView msg = (TextView) findViewById(R.id.permission_dialog_message); + msg.setText(R.string.shortcut_message); + + View shortcutIcon = findViewById(R.id.shortcut_panel); + if (shortcutIcon != null) { + shortcutIcon.setVisibility(View.VISIBLE); + } } public void setupDialog(TextView message, ImageView icon) { - message.setText(R.string.shortcut_message); - icon.setImageResource(R.drawable.gears_icon_48x48); + message.setText(R.string.shortcut_prompt); + icon.setImageResource(R.drawable.ic_dialog_menu_generic); } /** @@ -136,6 +136,7 @@ class GearsShortcutDialog extends GearsBaseDialog { break; case ALLOW: ret = "{\"allow\": true, \"locations\": 0 }"; + mNotification = R.string.shortcut_notification; break; case DENY: ret = null; @@ -144,4 +145,7 @@ class GearsShortcutDialog extends GearsBaseDialog { return ret; } + public int notification() { + return mNotification; + } } diff --git a/src/com/android/browser/MostVisitedActivity.java b/src/com/android/browser/MostVisitedActivity.java index aeaf2a6..704ee27 100644 --- a/src/com/android/browser/MostVisitedActivity.java +++ b/src/com/android/browser/MostVisitedActivity.java @@ -31,8 +31,10 @@ import android.widget.ListAdapter; import android.widget.ListView; import android.widget.SimpleCursorAdapter; import android.widget.TextView; +import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import android.view.ViewGroup.LayoutParams; import java.util.Vector; @@ -47,6 +49,12 @@ public class MostVisitedActivity extends ListActivity { CombinedBookmarkHistoryActivity.getIconListenerSet(getContentResolver()) .addListener(new IconReceiver()); setListAdapter(mAdapter); + ListView list = getListView(); + LayoutInflater factory = LayoutInflater.from(this); + View v = factory.inflate(R.layout.empty_history, null); + addContentView(v, new LayoutParams(LayoutParams.FILL_PARENT, + LayoutParams.FILL_PARENT)); + list.setEmptyView(v); } private class IconReceiver implements IconListener { |