auto import from //depot/cupcake/@137055
diff --git a/src/com/android/browser/AddBookmarkPage.java b/src/com/android/browser/AddBookmarkPage.java
index 23c0fac..cf3fe70 100644
--- a/src/com/android/browser/AddBookmarkPage.java
+++ b/src/com/android/browser/AddBookmarkPage.java
@@ -119,16 +119,13 @@
boolean emptyTitle = title.length() == 0;
boolean emptyUrl = unfilteredUrl.trim().length() == 0;
Resources r = getResources();
- if (emptyTitle) {
+ if (emptyTitle || emptyUrl) {
+ if (emptyTitle) {
+ mTitle.setError(r.getText(R.string.bookmark_needs_title));
+ }
if (emptyUrl) {
- setTitle(r.getText(R.string.empty_bookmark));
- return false;
- }
- setTitle(r.getText(R.string.bookmark_needs_title));
- return false;
- }
- if (emptyUrl) {
- setTitle(r.getText(R.string.bookmark_needs_url));
+ mAddress.setError(r.getText(R.string.bookmark_needs_url));
+ }
return false;
}
String url = unfilteredUrl;
@@ -138,11 +135,11 @@
try {
address = new WebAddress(unfilteredUrl);
} catch (ParseException e) {
- setTitle(r.getText(R.string.bookmark_url_not_valid));
+ mAddress.setError(r.getText(R.string.bookmark_url_not_valid));
return false;
}
if (address.mHost.length() == 0) {
- setTitle(r.getText(R.string.bookmark_url_not_valid));
+ mAddress.setError(r.getText(R.string.bookmark_url_not_valid));
return false;
}
url = address.toString();
diff --git a/src/com/android/browser/BrowserActivity.java b/src/com/android/browser/BrowserActivity.java
index 0ca4248..6179da2 100644
--- a/src/com/android/browser/BrowserActivity.java
+++ b/src/com/android/browser/BrowserActivity.java
@@ -1950,15 +1950,17 @@
public void run() {
// Remove the AnimatingView.
mContentView.removeView(view);
- // Make newIndex visible.
- mTabOverview.setCurrentIndex(newIndex);
- // Restore the listener.
- mTabOverview.setListener(mTabListener);
- // Change the menu to TAB_MENU if the
- // ImageGrid is interactive.
- if (mTabOverview.isLive()) {
- mMenuState = R.id.TAB_MENU;
- mTabOverview.requestFocus();
+ if (mTabOverview != null) {
+ // Make newIndex visible.
+ mTabOverview.setCurrentIndex(newIndex);
+ // Restore the listener.
+ mTabOverview.setListener(mTabListener);
+ // Change the menu to TAB_MENU if the
+ // ImageGrid is interactive.
+ if (mTabOverview.isLive()) {
+ mMenuState = R.id.TAB_MENU;
+ mTabOverview.requestFocus();
+ }
}
// If a remove was requested, remove the tab.
if (remove) {
@@ -1976,10 +1978,12 @@
if (currentTab != tab) {
mTabControl.setCurrentTab(currentTab);
}
- mTabOverview.remove(newIndex);
- // Make the current tab visible.
- mTabOverview.setCurrentIndex(
- mTabControl.getCurrentIndex());
+ if (mTabOverview != null) {
+ mTabOverview.remove(newIndex);
+ // Make the current tab visible.
+ mTabOverview.setCurrentIndex(
+ mTabControl.getCurrentIndex());
+ }
}
}
});
diff --git a/src/com/android/browser/BrowserHistoryPage.java b/src/com/android/browser/BrowserHistoryPage.java
index c529fe8..42ca848 100644
--- a/src/com/android/browser/BrowserHistoryPage.java
+++ b/src/com/android/browser/BrowserHistoryPage.java
@@ -115,11 +115,18 @@
addContentView(v, new LayoutParams(LayoutParams.FILL_PARENT,
LayoutParams.FILL_PARENT));
list.setEmptyView(v);
- list.post(new Runnable() {
- public void run() {
- list.expandGroup(0);
- }
- });
+ // Do not post the runnable if there is nothing in the list.
+ if (list.getExpandableListAdapter().getGroupCount() > 0) {
+ list.post(new Runnable() {
+ public void run() {
+ // In case the history gets cleared before this event
+ // happens.
+ if (list.getExpandableListAdapter().getGroupCount() > 0) {
+ list.expandGroup(0);
+ }
+ }
+ });
+ }
mMaxTabsOpen = getIntent().getBooleanExtra("maxTabsOpen", false);
CombinedBookmarkHistoryActivity.getIconListenerSet(getContentResolver())
.addListener(mIconReceiver);
@@ -258,9 +265,12 @@
private class HistoryAdapter implements ExpandableListAdapter {
- // Map of items. Negative values are labels, positive values
- // and zero are cursor offsets.
+ // Array for each of our bins. Each entry represents how many items are
+ // in that bin.
int mItemMap[];
+ // This is our GroupCount. We will have at most DateSorter.DAY_COUNT
+ // bins, less if the user has no items in one or more bins.
+ int mNumberOfBins;
Vector<DataSetObserver> mObservers;
Cursor mCursor;
@@ -295,12 +305,14 @@
for (int j = 0; j < DateSorter.DAY_COUNT; j++) {
array[j] = 0;
}
+ mNumberOfBins = 0;
int dateIndex = -1;
if (mCursor.moveToFirst() && mCursor.getCount() > 0) {
while (!mCursor.isAfterLast()) {
long date = mCursor.getLong(Browser.HISTORY_PROJECTION_DATE_INDEX);
int index = mDateSorter.getIndex(date);
if (index > dateIndex) {
+ mNumberOfBins++;
if (index == DateSorter.DAY_COUNT - 1) {
// We are already in the last bin, so it will
// include all the remaining items
@@ -316,9 +328,37 @@
}
mItemMap = array;
}
-
+
+ // This translates from a group position in the Adapter to a position in
+ // our array. This is necessary because some positions in the array
+ // have no history items, so we simply do not present those positions
+ // to the Adapter.
+ private int groupPositionToArrayPosition(int groupPosition) {
+ if (groupPosition < 0 || groupPosition >= DateSorter.DAY_COUNT) {
+ throw new AssertionError("group position out of range");
+ }
+ if (DateSorter.DAY_COUNT == mNumberOfBins || 0 == mNumberOfBins) {
+ // In the first case, we have exactly the same number of bins
+ // as our maximum possible, so there is no need to do a
+ // conversion
+ // The second statement is in case this method gets called when
+ // the array is empty, in which case the provided groupPosition
+ // will do fine.
+ return groupPosition;
+ }
+ int arrayPosition = -1;
+ while (groupPosition > -1) {
+ arrayPosition++;
+ if (mItemMap[arrayPosition] != 0) {
+ groupPosition--;
+ }
+ }
+ return arrayPosition;
+ }
+
public View getChildView(int groupPosition, int childPosition, boolean isLastChild,
View convertView, ViewGroup parent) {
+ groupPosition = groupPositionToArrayPosition(groupPosition);
HistoryItem item;
if (null == convertView || !(convertView instanceof HistoryItem)) {
item = new HistoryItem(BrowserHistoryPage.this);
@@ -347,6 +387,7 @@
}
public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
+ groupPosition = groupPositionToArrayPosition(groupPosition);
TextView item;
if (null == convertView || !(convertView instanceof TextView)) {
LayoutInflater factory =
@@ -369,11 +410,11 @@
}
public int getGroupCount() {
- return DateSorter.DAY_COUNT;
+ return mNumberOfBins;
}
public int getChildrenCount(int groupPosition) {
- return mItemMap[groupPosition];
+ return mItemMap[groupPositionToArrayPosition(groupPosition)];
}
public Object getGroup(int groupPosition) {
diff --git a/src/com/android/browser/BrowserHomepagePreference.java b/src/com/android/browser/BrowserHomepagePreference.java
index bc21143..d4708c3 100644
--- a/src/com/android/browser/BrowserHomepagePreference.java
+++ b/src/com/android/browser/BrowserHomepagePreference.java
@@ -48,8 +48,10 @@
AlertDialog dialog = (AlertDialog) getDialog();
// This callback is called before the dialog has been fully constructed
if (dialog != null) {
+ String url = s.toString();
dialog.getButton(DialogInterface.BUTTON_POSITIVE).setEnabled(
- Regex.WEB_URL_PATTERN.matcher(s.toString()).matches());
+ url.length() == 0 || url.equals("about:blank") ||
+ Regex.WEB_URL_PATTERN.matcher(url).matches());
}
}
diff --git a/src/com/android/browser/BrowserPreferencesPage.java b/src/com/android/browser/BrowserPreferencesPage.java
index b23f750..5d6795b 100644
--- a/src/com/android/browser/BrowserPreferencesPage.java
+++ b/src/com/android/browser/BrowserPreferencesPage.java
@@ -83,8 +83,7 @@
if (needUpdate) {
value = value.trim().replace(" ", "%20");
}
- Uri path = Uri.parse(value);
- if (path.getScheme() == null) {
+ if (value.length() != 0 && Uri.parse(value).getScheme() == null) {
value = "http://" + value;
needUpdate = true;
}
diff --git a/src/com/android/browser/FindDialog.java b/src/com/android/browser/FindDialog.java
index 44109ff..43cd1c4 100644
--- a/src/com/android/browser/FindDialog.java
+++ b/src/com/android/browser/FindDialog.java
@@ -17,6 +17,7 @@
package com.android.browser;
import android.app.Dialog;
+import android.content.Context;
import android.content.res.Configuration;
import android.os.Bundle;
import android.os.Handler;
@@ -30,6 +31,7 @@
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
+import android.view.inputmethod.InputMethodManager;
import android.webkit.WebView;
import android.widget.EditText;
import android.widget.TextView;
@@ -66,9 +68,19 @@
throw new AssertionError("No WebView for FindDialog::onClick");
}
mWebView.findNext(false);
+ hideSoftInput();
}
};
-
+
+ /*
+ * Remove the soft keyboard from the screen.
+ */
+ private void hideSoftInput() {
+ InputMethodManager imm = (InputMethodManager)
+ mBrowserActivity.getSystemService(Context.INPUT_METHOD_SERVICE);
+ imm.hideSoftInputFromWindow(mEditText.getWindowToken(), 0);
+ }
+
private void disableButtons() {
mPrevButton.setEnabled(false);
mNextButton.setEnabled(false);
@@ -157,8 +169,9 @@
throw new AssertionError("No WebView for FindDialog::findNext");
}
mWebView.findNext(true);
+ hideSoftInput();
}
-
+
public void show() {
super.show();
mEditText.requestFocus();
diff --git a/src/com/android/browser/GearsFilePickerDialog.java b/src/com/android/browser/GearsFilePickerDialog.java
deleted file mode 100644
index 10cc03f..0000000
--- a/src/com/android/browser/GearsFilePickerDialog.java
+++ /dev/null
@@ -1,930 +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.content.Context;
-import android.database.Cursor;
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
-import android.graphics.Color;
-import android.net.Uri;
-import android.os.Environment;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.Message;
-import android.provider.MediaStore;
-import android.provider.MediaStore.Images.Media;
-import android.util.Log;
-import android.view.LayoutInflater;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.AdapterView;
-import android.widget.BaseAdapter;
-import android.widget.GridView;
-import android.widget.ImageView;
-import android.widget.TextView;
-
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.RandomAccessFile;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Vector;
-
-import org.json.JSONArray;
-import org.json.JSONException;
-import org.json.JSONObject;
-
-/**
- * Gears FilePicker dialog
- */
-class GearsFilePickerDialog extends GearsBaseDialog
- implements View.OnTouchListener {
-
- private static final String TAG = "Gears FilePicker";
- private static Bitmap mDirectoryIcon;
- private static Bitmap mDefaultIcon;
- private static Bitmap mImageIcon;
- private static Bitmap mBackIcon;
-
- private static String MULTIPLE_FILES = "MULTIPLE_FILES";
- private static String SINGLE_FILE = "SINGLE_FILE";
-
- private static ImagesLoad mImagesLoader;
- private static SystemThumbnails mSystemThumbnails;
- private FilePickerAdapter mAdapter;
- private String mSelectionMode;
- private boolean mMultipleSelection;
- private String mCurrentPath;
-
- // Disable saving thumbnails until this is refactored to fit into
- // existing schemes.
- private static final boolean enableSavedThumbnails = false;
-
- public GearsFilePickerDialog(Activity activity,
- Handler handler,
- String arguments) {
- super (activity, handler, arguments);
- mAdapter = new FilePickerAdapter(activity);
- parseArguments();
- }
-
- public void parseArguments() {
- mSelectionMode = MULTIPLE_FILES;
- try {
- JSONObject json = new JSONObject(mDialogArguments);
-
- if (json.has("mode")) {
- mSelectionMode = json.getString("mode");
- }
- } catch (JSONException e) {
- Log.e(TAG, "exc: " + e);
- }
- if (mSelectionMode.equalsIgnoreCase(SINGLE_FILE)) {
- mMultipleSelection = false;
- } else {
- mMultipleSelection = true;
- }
- }
-
- public void setup() {
- inflate(R.layout.gears_dialog_filepicker, R.id.panel_content);
- setupButtons(0,
- R.string.filepicker_button_allow,
- R.string.filepicker_button_deny);
- setupDialog();
-
- TextView textViewPath = (TextView) findViewById(R.id.path_name);
- if (textViewPath != null) {
- textViewPath.setText(R.string.filepicker_path);
- }
-
- GridView view = (GridView) findViewById(R.id.files_list);
- view.setAdapter(mAdapter);
- view.setOnTouchListener(this);
-
- showView(null, R.id.selection);
- setSelectionText();
-
- mImagesLoader = new ImagesLoad(mAdapter);
- mImagesLoader.setAdapterView(view);
- Thread imagesLoaderThread = new Thread(mImagesLoader);
- imagesLoaderThread.setPriority(Thread.MIN_PRIORITY);
- imagesLoaderThread.start();
-
- mSystemThumbnails = new SystemThumbnails();
- Thread systemThumbnailsThread = new Thread(mSystemThumbnails);
- systemThumbnailsThread.setPriority(Thread.MIN_PRIORITY);
- systemThumbnailsThread.start();
- }
-
- public void setSelectionText() {
- Vector elements = mAdapter.selectedElements();
- if (elements == null)
- return;
- TextView info = (TextView) findViewById(R.id.selection);
- int nbElements = elements.size();
- if (nbElements == 0) {
- info.setText(R.string.filepicker_no_files_selected);
- } else if (nbElements == 1) {
- info.setText(R.string.filepicker_one_file_selected);
- } else {
- info.setText(nbElements + " " +
- mActivity.getString(
- R.string.filepicker_some_files_selected));
- }
- }
-
- public void setCurrentPath(String path) {
- if (path != null) {
- mCurrentPath = path;
- TextView textViewPath = (TextView) findViewById(R.id.current_path);
- if (textViewPath != null) {
- textViewPath.setText(path);
- }
- }
- }
-
- public void setupDialog(TextView message, ImageView icon) {
- message.setText(R.string.filepicker_message);
- message.setTextSize(24);
- icon.setImageResource(R.drawable.ic_dialog_menu_generic);
- }
-
- public boolean onTouch(View v, MotionEvent event) {
- mImagesLoader.pauseIconRequest();
- return false;
- }
-
- /**
- * Utility class encapsulating thumbnails information
- * for a file (file image id and magic number)
- */
- class SystemThumbnailInfo {
- private long mID;
- private long mMagicNumber;
- SystemThumbnailInfo(long anID, long magicNumber) {
- mID = anID;
- mMagicNumber = magicNumber;
- }
- public long getID() {
- return mID;
- }
- public long getMagicNumber() {
- return mMagicNumber;
- }
- }
-
- /**
- * Utility class to pre-fetch the thumbnails information
- */
- class SystemThumbnails implements Runnable {
- private Map<String, SystemThumbnailInfo> mThumbnails;
-
- SystemThumbnails() {
- mThumbnails = Collections.synchronizedMap(new HashMap());
- }
-
- public void run() {
- Uri query = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
- Cursor cursor = mActivity.managedQuery(query,
- new String[] { "_id", "mini_thumb_magic", "_data" },
- null, null, null);
-
- if (cursor != null) {
- int count = cursor.getCount();
- for (int i = 0; i < count; i++) {
- cursor.moveToPosition(i);
- SystemThumbnailInfo info = new SystemThumbnailInfo(cursor.getLong(0),
- cursor.getLong(1));
- mThumbnails.put(cursor.getString(2), info);
- }
- }
- }
-
- public SystemThumbnailInfo getThumb(String path) {
- SystemThumbnailInfo ret = mThumbnails.get(path);
- if (ret == null) {
- Uri query = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
- Cursor cursor = mActivity.managedQuery(query,
- new String[] { "_id", "mini_thumb_magic", "_data" },
- "_data = ?", new String[] { path }, null);
- if (cursor != null && cursor.moveToFirst()) {
- long longid = cursor.getLong(0);
- long miniThumbMagic = cursor.getLong(1);
- ret = new SystemThumbnailInfo(longid, miniThumbMagic);
- mThumbnails.put(path, ret);
- }
- }
- return ret;
- }
- }
-
- /**
- * Utility class to load and generate thumbnails
- * for image files
- */
- class ImagesLoad implements Runnable {
- private Vector mImagesPath;
- private BaseAdapter mAdapter;
- private AdapterView mAdapterView;
- private Vector<FilePickerElement> mElements;
- private Handler mLoaderHandler;
- // We use the same value as in Camera.app's ImageManager.java
- private static final int BYTES_PER_MINI_THUMB = 10000;
- private final byte[] mMiniThumbData = new byte[BYTES_PER_MINI_THUMB];
- private final int MINI_THUMB_DATA_FILE_VERSION = 3;
- private final int THUMBNAIL_SIZE = 128;
- private Map<Uri, RandomAccessFile> mThumbFiles;
-
- ImagesLoad(BaseAdapter adapter) {
- mAdapter = adapter;
- mThumbFiles = Collections.synchronizedMap(new HashMap());
- }
-
- public void signalChanges() {
- Message message = mHandler.obtainMessage(GearsBaseDialog.NEW_ICON,
- mAdapter);
- mHandler.sendMessage(message);
- }
-
- private String getMiniThumbFileFromUri(Uri uri) {
- if (uri == null) {
- return null;
- }
- String directoryName =
- Environment.getExternalStorageDirectory().toString() +
- "/dcim/.thumbnails";
- String path = directoryName + "/.thumbdata" +
- MINI_THUMB_DATA_FILE_VERSION + "-" + uri.hashCode();
- return path;
- }
-
- private Bitmap getMiniThumbFor(Uri uri, long longid, long magic) {
- RandomAccessFile thumbFile = mThumbFiles.get(uri);
- try {
- if (thumbFile == null) {
- String path = getMiniThumbFileFromUri(uri);
- File f = new File(path);
- if (f.exists()) {
- thumbFile = new RandomAccessFile(f, "rw");
- mThumbFiles.put(uri, thumbFile);
- }
- }
- } catch (IOException ex) {
- }
- if (thumbFile == null) {
- return null;
- }
- byte[] data = getMiniThumbFromFile(thumbFile, longid,
- mMiniThumbData, magic);
- if (data != null) {
- return BitmapFactory.decodeByteArray(data, 0, data.length);
- }
- return null;
- }
-
- private byte [] getMiniThumbFromFile(RandomAccessFile r,
- long id,
- byte [] data,
- long magicCheck) {
- if (r == null)
- return null;
- long pos = id * BYTES_PER_MINI_THUMB;
- RandomAccessFile f = r;
- synchronized (f) {
- try {
- f.seek(pos);
- if (f.readByte() == 1) {
- long magic = f.readLong();
- if (magic != magicCheck) {
- return null;
- }
- int length = f.readInt();
- f.read(data, 0, length);
- return data;
- } else {
- return null;
- }
- } catch (IOException ex) {
- long fileLength;
- try {
- fileLength = f.length();
- } catch (IOException ex1) {
- fileLength = -1;
- }
- return null;
- }
- }
- }
-
- /*
- * Returns a thumbnail saved by the Camera application
- * We pre-cached the information (image id and magic number)
- * when starting the filepicker.
- */
- public Bitmap getSystemThumbnail(FilePickerElement elem) {
- if (elem.askedForSystemThumbnail() == false) {
- elem.setAskedForSystemThumbnail(true);
- String path = elem.getPath();
- SystemThumbnailInfo thumbInfo = mSystemThumbnails.getThumb(path);
- if (thumbInfo != null) {
- Uri query = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
- Bitmap bmp = getMiniThumbFor(query, thumbInfo.getID(),
- thumbInfo.getMagicNumber());
- if (bmp != null) {
- return bmp;
- }
- }
- }
- return null;
- }
-
- /*
- * Generate a thumbnail for a given element
- */
- public Bitmap generateImage(FilePickerElement elem) {
- String path = elem.getPath();
- Bitmap finalImage = null;
- try {
-
- // First we try to get the thumbnail from the system
- // (created by the Camera application)
-
- finalImage = getSystemThumbnail(elem);
- if (finalImage != null) {
- return finalImage;
- }
-
- // No thumbnail was found, so we have to create one
- //
- // First we get the image information and
- // determine the sampleSize
-
- BitmapFactory.Options options = new BitmapFactory.Options();
- options.inJustDecodeBounds = true;
- BitmapFactory.decodeFile(path, options);
-
- int width = options.outWidth;
- int height = options.outHeight;
- int sampleSize = 1;
- if (width > THUMBNAIL_SIZE || height > THUMBNAIL_SIZE) {
- sampleSize = 2;
- while ((width / sampleSize > 2*THUMBNAIL_SIZE)
- || (height / sampleSize > 2*THUMBNAIL_SIZE)) {
- sampleSize += 2;
- }
- }
- options.inJustDecodeBounds = false;
- options.inSampleSize = sampleSize;
- Bitmap originalImage = BitmapFactory.decodeFile(path, options);
- if (originalImage == null) {
- return null;
- }
-
- // Let's rescale the image to a THUMBNAIL_SIZE
-
- width = originalImage.getWidth();
- height = originalImage.getHeight();
-
- if (width > height) {
- width = (int) (width * (THUMBNAIL_SIZE / (double) height));
- height = THUMBNAIL_SIZE;
- } else {
- height = (int) (height * (THUMBNAIL_SIZE / (double) width));
- width = THUMBNAIL_SIZE;
- }
- originalImage = Bitmap.createScaledBitmap(originalImage,
- width, height, true);
-
- // We can now crop the image to a THUMBNAIL_SIZE rectangle
-
- width = originalImage.getWidth();
- height = originalImage.getHeight();
- int d = 0;
- if (width > height) {
- d = (width - height) / 2;
- finalImage = Bitmap.createBitmap(originalImage, d, 0,
- THUMBNAIL_SIZE, THUMBNAIL_SIZE);
- } else {
- d = (height - width) / 2;
- finalImage = Bitmap.createBitmap(originalImage, 0, d,
- THUMBNAIL_SIZE, THUMBNAIL_SIZE);
- }
-
- originalImage.recycle();
- } catch (java.lang.OutOfMemoryError e) {
- Log.e(TAG, "Intercepted OOM ", e);
- }
- return finalImage;
- }
-
- public void pauseIconRequest() {
- Message message = Message.obtain(mLoaderHandler,
- GearsBaseDialog.PAUSE_REQUEST_ICON);
- mLoaderHandler.sendMessageAtFrontOfQueue(message);
- }
-
- public void clearIconRequests() {
- Message message = Message.obtain(mLoaderHandler,
- GearsBaseDialog.CLEAR_REQUEST_ICON);
- mLoaderHandler.sendMessageAtFrontOfQueue(message);
- }
-
- public void postIconRequest(FilePickerElement item,
- int position,
- boolean front) {
- if (item == null) {
- return;
- }
- if (item.isImage() && (item.getThumbnail() == null)) {
- Message message = mLoaderHandler.obtainMessage(
- GearsBaseDialog.REQUEST_ICON, position, 0, item);
- if (front) {
- mLoaderHandler.sendMessageAtFrontOfQueue(message);
- } else {
- mLoaderHandler.sendMessage(message);
- }
- }
- }
-
- public boolean generateIcon(FilePickerElement elem) {
- if (elem.isImage()) {
- if (elem.getThumbnail() == null) {
- Bitmap image = generateImage(elem);
- if (image != null) {
- elem.setThumbnail(image);
- return true;
- }
- }
- }
- return false;
- }
-
- public void setAdapterView(AdapterView view) {
- mAdapterView = view;
- }
-
- public void run() {
- Looper.prepare();
- mLoaderHandler = new Handler() {
- public void handleMessage(Message msg) {
- if (msg.what == GearsBaseDialog.CLEAR_REQUEST_ICON) {
- mLoaderHandler.removeMessages(
- GearsBaseDialog.PAUSE_REQUEST_ICON);
- mLoaderHandler.removeMessages(
- GearsBaseDialog.REQUEST_ICON);
- } else if (msg.what == GearsBaseDialog.PAUSE_REQUEST_ICON) {
- try {
- // We are busy (likely) scrolling the view,
- // so we just pause the loading.
- Thread.sleep(1000);
- mLoaderHandler.removeMessages(
- GearsBaseDialog.PAUSE_REQUEST_ICON);
- } catch (InterruptedException e) {
- Log.e(TAG, "InterruptedException ", e);
- }
- } else if (msg.what == GearsBaseDialog.REQUEST_ICON) {
- FilePickerElement elem = (FilePickerElement) msg.obj;
- if (generateIcon(elem)) {
- signalChanges();
- }
- try {
- Thread.sleep(50);
- } catch (InterruptedException e) {
- Log.e(TAG, "InterruptedException ", e);
- }
- }
- }
- };
- Looper.loop();
- }
- }
-
- /**
- * Utility class representing an element displayed in the
- * file picker, associated with an icon and/or thumbnail
- */
- class FilePickerElement {
- private File mPath;
- private String mName;
- private Bitmap mIcon;
- private boolean mIsSelected;
- private Vector mChildren;
- private FilePickerElement mParent;
- private boolean mIsParent;
- private BaseAdapter mAdapter;
- private String mExtension;
- private Bitmap mThumbnail;
- private boolean mIsImage;
- private boolean mAskedForSystemThumbnail;
-
- public FilePickerElement(String name, BaseAdapter adapter) {
- this(name, adapter, null);
- }
-
- public FilePickerElement(String path, String name, BaseAdapter adapter) {
- this(path, name, adapter, null);
- }
-
- public FilePickerElement(String name,
- BaseAdapter adapter,
- FilePickerElement parent) {
- mName = name;
- mAdapter = adapter;
- mParent = parent;
- mIsSelected = false;
- mChildren = null;
- mAskedForSystemThumbnail = false;
- }
-
- public FilePickerElement(String path,
- String name,
- BaseAdapter adapter,
- FilePickerElement parent) {
- mPath = new File(path);
- mName = name;
- mIsSelected = false;
- mChildren = null;
- mParent = parent;
- mAdapter = adapter;
- mExtension = null;
- mAskedForSystemThumbnail = false;
-
- setIcons();
- }
-
- public void setAskedForSystemThumbnail(boolean value) {
- mAskedForSystemThumbnail = value;
- }
-
- public boolean askedForSystemThumbnail() {
- return mAskedForSystemThumbnail;
- }
-
- public void setIcons() {
- if (mPath.isDirectory()) {
- if (mDirectoryIcon == null) {
- mDirectoryIcon = BitmapFactory.decodeResource(
- getResources(), R.drawable.gears_folder);
- }
- mIcon = mDirectoryIcon;
-
- } else {
- if (isImage()) {
- if (mImageIcon == null) {
- mImageIcon = BitmapFactory.decodeResource(
- getResources(), R.drawable.gears_file_image);
- }
- mIcon = mImageIcon;
- } else if (isAudio()) {
- mIcon = BitmapFactory.decodeResource(
- getResources(), R.drawable.gears_file_audio);
- } else if (isVideo()) {
- mIcon = BitmapFactory.decodeResource(
- getResources(), R.drawable.gears_file_video);
- } else {
- if (mDefaultIcon == null) {
- mDefaultIcon = BitmapFactory.decodeResource(
- getResources(), R.drawable.gears_file_unknown);
- }
- mIcon = mDefaultIcon;
- }
- }
- if (mBackIcon == null) {
- mBackIcon = BitmapFactory.decodeResource(getResources(),
- com.android.internal.R.drawable.ic_menu_back);
- }
- }
-
- public boolean isImage() {
- if (mIsImage) return mIsImage;
- String extension = getExtension();
- if (extension != null) {
- if (extension.equalsIgnoreCase("jpg") ||
- extension.equalsIgnoreCase("jpeg") ||
- extension.equalsIgnoreCase("png") ||
- extension.equalsIgnoreCase("gif")) {
- mIsImage = true;
- return true;
- }
- }
- return false;
- }
-
- public boolean isAudio() {
- String extension = getExtension();
- if (extension != null) {
- if (extension.equalsIgnoreCase("mp3") ||
- extension.equalsIgnoreCase("wav") ||
- extension.equalsIgnoreCase("aac")) {
- return true;
- }
- }
- return false;
- }
-
- public boolean isVideo() {
- String extension = getExtension();
- if (extension != null) {
- if (extension.equalsIgnoreCase("mpg") ||
- extension.equalsIgnoreCase("mpeg") ||
- extension.equalsIgnoreCase("mpe") ||
- extension.equalsIgnoreCase("divx") ||
- extension.equalsIgnoreCase("3gpp") ||
- extension.equalsIgnoreCase("avi")) {
- return true;
- }
- }
- return false;
- }
-
- public void setParent(boolean isParent) {
- mIsParent = isParent;
- }
-
- public boolean isDirectory() {
- return mPath.isDirectory();
- }
-
- public String getExtension() {
- if (isDirectory()) {
- return null;
- }
- if (mExtension == null) {
- String path = getPath();
- int index = path.lastIndexOf(".");
- if ((index != -1) && (index != path.length() - 1)){
- // if we find a dot that is not the last character
- mExtension = path.substring(index+1);
- return mExtension;
- }
- }
- return mExtension;
- }
-
- public void refresh() {
- mChildren = null;
- Vector children = getChildren();
- mImagesLoader.clearIconRequests();
- }
-
- public Vector getChildren() {
- if (isDirectory()) {
- if (mChildren == null) {
- mChildren = new Vector();
- File[] files = mPath.listFiles();
- if (mParent != null) {
- mChildren.add(mParent);
- mParent.setParent(true);
- }
- for (int i = 0; i < files.length; i++) {
- String name = files[i].getName();
- String fpath = files[i].getPath();
- if (!name.startsWith(".")) { // hide dotfiles
- FilePickerElement elem = new FilePickerElement(fpath, name,
- mAdapter, this);
- elem.setParent(false);
- mChildren.add(elem);
- }
- }
- }
- }
- return mChildren;
- }
-
- public FilePickerElement getChild(int position) {
- Vector children = getChildren();
- if (children != null) {
- FilePickerElement elem = (FilePickerElement) children.get(position);
- return elem;
- }
- return null;
- }
-
- /*
- * Depending on the type, we return either
- * the icon (mIcon) or the back icon (mBackIcon).
- * If we can load a system thumbnail we do this
- * synchronously and return it, else we ask the
- * mImagesLoader to generate a thumbnail for us.
- */
- public Bitmap getIcon(int position) {
- if (mIsParent) {
- return mBackIcon;
- }
- if (isImage()) {
- if (mThumbnail != null) {
- return mThumbnail;
- } else {
- Bitmap image = mImagesLoader.getSystemThumbnail(this);
- if (image != null) {
- mThumbnail = image;
- return mThumbnail;
- }
- mImagesLoader.postIconRequest(this, position, true);
- }
- }
- return mIcon;
- }
-
- public Bitmap getThumbnail() {
- return mThumbnail;
- }
-
- public void setThumbnail(Bitmap icon) {
- mThumbnail = icon;
- }
-
- public String getName() {
- return mName;
- }
-
- public String getPath() {
- return mPath.getPath();
- }
-
- public void toggleSelection() {
- mIsSelected = !mIsSelected;
- }
-
- public boolean isSelected() {
- return mIsSelected;
- }
-
- }
-
- /**
- * Adapter for the GridView
- */
- class FilePickerAdapter extends BaseAdapter {
- private Context mContext;
- private Map mImagesMap;
- private Map mImagesSelected;
-
- private Vector mImages;
- private Vector<FilePickerElement> mFiles;
-
- private FilePickerElement mRootElement;
- private FilePickerElement mCurrentElement;
-
- public FilePickerAdapter(Context context) {
- mContext = context;
- mImages = new Vector();
- mFiles = new Vector();
-
- mImagesMap = Collections.synchronizedMap(new HashMap());
- mImagesSelected = new HashMap();
-
- String startingPath = Environment.getExternalStorageDirectory().getPath();
- mRootElement = new FilePickerElement(startingPath, "SD Card", this);
- mCurrentElement = mRootElement;
- }
-
- public void addImage(String path) {
- mImages.add(path);
- Bitmap image = BitmapFactory.decodeResource(
- getResources(), R.drawable.gears_file_unknown);
- mImagesMap.put(path, image);
- mImagesSelected.put(path, Boolean.FALSE);
- }
-
- public int getCount() {
- Vector elems = mCurrentElement.getChildren();
- setCurrentPath(mCurrentElement.getPath());
- return elems.size();
- }
-
- public Object getItem(int position) {
- return position;
- }
-
- public long getItemId(int position) {
- return position;
- }
-
- public Vector selectedElements() {
- if (mCurrentElement == null) {
- return null;
- }
- Vector children = mCurrentElement.getChildren();
- Vector ret = new Vector();
- for (int i = 0; i < children.size(); i++) {
- FilePickerElement elem = (FilePickerElement) children.get(i);
- if (elem.isSelected()) {
- ret.add(elem);
- }
- }
- return ret;
- }
-
- public View getView(int position, View convertView, ViewGroup parent) {
- View cell = convertView;
- if (cell == null) {
- LayoutInflater inflater = (LayoutInflater) getSystemService(
- Context.LAYOUT_INFLATER_SERVICE);
- cell = inflater.inflate(R.layout.gears_dialog_filepicker_cell, null);
- }
- ImageView imageView = (ImageView) cell.findViewById(R.id.icon);
- TextView textView = (TextView) cell.findViewById(R.id.name);
- FilePickerElement elem = mCurrentElement.getChild(position);
- if (elem == null) {
- String message = "Could not get elem " + position;
- message += " for " + mCurrentElement.getPath();
- Log.e(TAG, message);
- return null;
- }
- String path = elem.getPath();
- textView.setText(elem.getName());
-
- View.OnClickListener listener = new View.OnClickListener() {
- public void onClick(View view) {
- int pos = (Integer) view.getTag();
- FilePickerElement elem = mCurrentElement.getChild(pos);
- if (elem.isDirectory()) {
- mCurrentElement = elem;
- mCurrentElement.refresh();
- } else {
- if (mMultipleSelection) {
- elem.toggleSelection();
- } else {
- Vector elems = selectedElements();
- if (elems != null) {
- if (elems.size() == 0) {
- elem.toggleSelection();
- } else if ((elems.size() == 1)
- && elem.isSelected()) {
- elem.toggleSelection();
- }
- }
- }
- }
- setSelectionText();
- notifyDataSetChanged();
- }
- };
- cell.setLayoutParams(new GridView.LayoutParams(96, 96));
- cell.setOnClickListener(listener);
- cell.setOnTouchListener(new View.OnTouchListener() {
- public boolean onTouch(View v, MotionEvent event) {
- if (event.getAction() == MotionEvent.ACTION_DOWN) {
- int color = getResources().getColor(R.color.icon_selection);
- v.setBackgroundColor(color);
- } else {
- v.setBackgroundColor(android.R.color.background_dark);
- }
- return false;
- }
- });
-
- cell.setTag(position);
-
- if (elem.isSelected()) {
- int color = getResources().getColor(R.color.icon_selection);
- cell.setBackgroundColor(color);
- } else {
- cell.setBackgroundColor(android.R.color.background_dark);
- }
- Bitmap bmp = elem.getIcon(position);
- if (bmp != null) {
- imageView.setImageBitmap(bmp);
- }
-
- return cell;
- }
- }
-
- private String selectedFiles() {
- Vector selection = mAdapter.selectedElements();
- JSONArray jsonSelection = new JSONArray();
- if (selection != null) {
- for (int i = 0; i < selection.size(); i++) {
- FilePickerElement elem = (FilePickerElement) selection.get(i);
- jsonSelection.put(elem.getPath());
- }
- }
- return jsonSelection.toString();
- }
-
- public String closeDialog(int closingType) {
- return selectedFiles();
- }
-}
diff --git a/src/com/android/browser/GearsNativeDialog.java b/src/com/android/browser/GearsNativeDialog.java
index c72ad8e..ecf166d 100644
--- a/src/com/android/browser/GearsNativeDialog.java
+++ b/src/com/android/browser/GearsNativeDialog.java
@@ -36,8 +36,6 @@
import com.android.browser.GearsBaseDialog;
import com.android.browser.GearsPermissionsDialog;
import com.android.browser.GearsSettingsDialog;
-import com.android.browser.GearsShortcutDialog;
-import com.android.browser.GearsFilePickerDialog;
/**
* Native dialog Activity used by gears
@@ -57,16 +55,12 @@
private int mDialogType;
private final int SETTINGS_DIALOG = 1;
private final int PERMISSION_DIALOG = 2;
- private final int SHORTCUT_DIALOG = 3;
- private final int LOCATION_DIALOG = 4;
- private final int FILEPICKER_DIALOG = 5;
+ private final int LOCATION_DIALOG = 3;
private final String VERSION_STRING = "version";
private final String SETTINGS_DIALOG_STRING = "settings_dialog";
private final String PERMISSION_DIALOG_STRING = "permissions_dialog";
- private final String SHORTCUT_DIALOG_STRING = "shortcuts_dialog";
private final String LOCATION_DIALOG_STRING = "locations_dialog";
- private final String FILEPICKER_DIALOG_STRING = "filepicker_dialog";
private boolean mDialogDismissed = false;
@@ -111,15 +105,9 @@
case PERMISSION_DIALOG:
dialog = new GearsPermissionsDialog(this, mHandler, mDialogArguments);
break;
- case SHORTCUT_DIALOG:
- dialog = new GearsShortcutDialog(this, mHandler, mDialogArguments);
- break;
case LOCATION_DIALOG:
dialog = new GearsPermissionsDialog(this, mHandler, mDialogArguments);
break;
- case FILEPICKER_DIALOG:
- dialog = new GearsFilePickerDialog(this, mHandler, mDialogArguments);
- break;
default:
dialog = new GearsBaseDialog(this, mHandler, mDialogArguments);
}
@@ -136,7 +124,7 @@
*/
private void getArguments() {
if (mDebug) {
- mDialogType = FILEPICKER_DIALOG +1;
+ mDialogType = LOCATION_DIALOG +1;
mockArguments();
return;
@@ -158,12 +146,8 @@
mGearsVersion = intent.getStringExtra(VERSION_STRING);
} else if (dialogTypeString.equalsIgnoreCase(PERMISSION_DIALOG_STRING)) {
mDialogType = PERMISSION_DIALOG;
- } else if (dialogTypeString.equalsIgnoreCase(SHORTCUT_DIALOG_STRING)) {
- mDialogType = SHORTCUT_DIALOG;
} else if (dialogTypeString.equalsIgnoreCase(LOCATION_DIALOG_STRING)) {
mDialogType = LOCATION_DIALOG;
- } else if (dialogTypeString.equalsIgnoreCase(FILEPICKER_DIALOG_STRING)) {
- mDialogType = FILEPICKER_DIALOG;
}
}
@@ -173,17 +157,6 @@
* Set mock arguments.
*/
private void mockArguments() {
- String argumentsShortcuts = "{ locale: \"en-US\","
- + "name: \"My Application\", link: \"http://www.google.com/\","
- + "description: \"This application does things does things!\","
- + "icon16x16: \"http://google-gears.googlecode.com/"
- + "svn/trunk/gears/test/manual/shortcuts/16.png\","
- + "icon32x32: \"http://google-gears.googlecode.com/"
- + "svn/trunk/gears/test/manual/shortcuts/32.png\","
- + "icon48x48: \"http://google-gears.googlecode.com/"
- + "svn/trunk/gears/test/manual/shortcuts/48.png\","
- + "icon128x128: \"http://google-gears.googlecode.com/"
- + "svn/trunk/gears/test/manual/shortcuts/128.png\"}";
String argumentsPermissions = "{ locale: \"en-US\", "
+ "origin: \"http://www.google.com\", dialogType: \"localData\","
@@ -215,16 +188,7 @@
+ "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;
- break;
case PERMISSION_DIALOG:
mDialogArguments = argumentsPermissions;
break;
@@ -234,8 +198,6 @@
case SETTINGS_DIALOG:
mDialogArguments = argumentsSettings;
break;
- case FILEPICKER_DIALOG:
- mDialogArguments = argumentsFilePicker2;
}
}
diff --git a/src/com/android/browser/GearsShortcutDialog.java b/src/com/android/browser/GearsShortcutDialog.java
deleted file mode 100644
index 11d936d..0000000
--- a/src/com/android/browser/GearsShortcutDialog.java
+++ /dev/null
@@ -1,151 +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.View;
-import android.widget.ImageView;
-import android.widget.TextView;
-
-import org.json.JSONException;
-import org.json.JSONObject;
-
-/**
- * Gears Shortcut dialog
- */
-class GearsShortcutDialog extends GearsBaseDialog {
-
- private static final String TAG = "GearsPermissionsDialog";
-
- private final String ICON_16 = "icon16x16";
- 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,
- String arguments) {
- super (activity, handler, arguments);
- }
-
- public void setup() {
- 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);
-
- try {
- JSONObject json = new JSONObject(mDialogArguments);
-
- String iconUrl = pickIconToRender(json);
- if (iconUrl != null) {
- downloadIcon(iconUrl);
- }
-
- setupDialog();
-
- 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_prompt);
- icon.setImageResource(R.drawable.ic_dialog_menu_generic);
- }
-
- /**
- * Utility method to validate an icon url. Used in the
- * shortcut dialog.
- */
- boolean validIcon(JSONObject json, String name) {
- try {
- if (json.has(name)) {
- String str = json.getString(name);
- if (str.length() > 0) {
- return true;
- }
- }
- } catch (JSONException e) {
- Log.e(TAG, "JSON exception", e);
- }
- return false;
- }
-
-
- /**
- * Utility method to pick the best indicated icon
- * from the dialogs' arguments. Used in the
- * shortcut dialog.
- */
- String pickIconToRender(JSONObject json) {
- try {
- if (validIcon(json, ICON_48)) { // ideal size
- mChoosenIconSize = 48;
- return json.getString(ICON_48);
- } else if (validIcon(json, ICON_32)) {
- mChoosenIconSize = 32;
- return json.getString(ICON_32);
- } else if (validIcon(json, ICON_128)) {
- mChoosenIconSize = 128;
- return json.getString(ICON_128);
- } else if (validIcon(json, ICON_16)) {
- mChoosenIconSize = 16;
- return json.getString(ICON_16);
- }
- } catch (JSONException e) {
- Log.e(TAG, "JSON exception", e);
- }
- mChoosenIconSize = 0;
- return null;
- }
-
- public String closeDialog(int closingType) {
- String ret = null;
- switch (closingType) {
- case ALWAYS_DENY:
- ret = "{\"allow\": false, \"permanently\": true }";
- break;
- case ALLOW:
- ret = "{\"allow\": true, \"locations\": 0 }";
- mNotification = R.string.shortcut_notification;
- break;
- case DENY:
- ret = null;
- break;
- }
- return ret;
- }
-
- public int notification() {
- return mNotification;
- }
-}