summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--AndroidManifest.xml55
-rw-r--r--src/com/android/camera/BitmapCache.java126
-rw-r--r--src/com/android/camera/DeleteImage.java83
-rw-r--r--src/com/android/camera/DrmWallpaper.java32
-rw-r--r--src/com/android/camera/GalleryPicker.java941
-rw-r--r--src/com/android/camera/GalleryPickerItem.java101
-rw-r--r--src/com/android/camera/GallerySettings.java32
-rw-r--r--src/com/android/camera/GridViewSpecial.java1169
-rw-r--r--src/com/android/camera/ImageGallery.java1020
-rw-r--r--src/com/android/camera/ImageLoader.java174
-rw-r--r--src/com/android/camera/ImageManager.java14
-rw-r--r--src/com/android/camera/MenuHelper.java63
-rw-r--r--src/com/android/camera/MovieView.java94
-rw-r--r--src/com/android/camera/MovieViewControl.java240
-rw-r--r--src/com/android/camera/PhotoAppWidgetBind.java76
-rw-r--r--src/com/android/camera/PhotoAppWidgetConfigure.java104
-rw-r--r--src/com/android/camera/PhotoAppWidgetProvider.java209
-rw-r--r--src/com/android/camera/PickWallpaper.java24
-rw-r--r--src/com/android/camera/Util.java10
-rw-r--r--src/com/android/camera/ViewImage.java1300
-rw-r--r--src/com/android/camera/Wallpaper.java75
-rw-r--r--src/com/android/camera/gallery/BaseImage.java4
-rw-r--r--src/com/android/camera/gallery/IImage.java1
-rw-r--r--src/com/android/camera/gallery/IImageList.java1
-rw-r--r--src/com/android/camera/gallery/ImageList.java20
-rw-r--r--src/com/android/camera/gallery/ImageListUber.java8
-rw-r--r--src/com/android/camera/gallery/SingleImageList.java4
-rw-r--r--src/com/android/camera/gallery/UriImage.java4
-rw-r--r--src/com/android/camera/gallery/VideoList.java21
-rw-r--r--src/com/android/camera/gallery/VideoObject.java7
-rw-r--r--tests/src/com/android/camera/gallery/ImageListUberUnitTests.java89
31 files changed, 127 insertions, 5974 deletions
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index efbaa3dc..ec72fb77 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -58,21 +58,6 @@
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
- <activity android:name="GalleryPicker" android:label="@string/gallery_picker_label"
- android:configChanges="orientation|keyboardHidden"
- android:icon="@drawable/ic_launcher_gallery"
- android:clearTaskOnLaunch="true"
- android:taskAffinity="android.task.pictures">
- </activity>
- <activity android:name="ImageGallery" android:label="@string/gallery_label"
- android:configChanges="orientation|keyboardHidden"
- android:icon="@drawable/ic_launcher_gallery">
- </activity>
- <activity android:name="CropImage"
- android:process=":CropImage"
- android:configChanges="orientation|keyboardHidden"
- android:label="@string/crop_label">
- </activity>
<activity android:name="ReviewImage"
android:label="@string/view_label"
android:theme="@style/CustomTheme"
@@ -80,46 +65,6 @@
android:configChanges="orientation|keyboardHidden"
android:exported="true">
</activity>
- <activity android:name="ViewImage"
- android:label="@string/view_label"
- android:screenOrientation="behind"
- android:configChanges="orientation|keyboardHidden">
- </activity>
- <activity android:name="MovieView"
- android:label="@string/movieviewlabel"
- android:screenOrientation="landscape"
- android:configChanges="orientation|keyboardHidden"
- android:theme="@android:style/Theme.Black.NoTitleBar.Fullscreen">
- </activity>
- <activity android:name=".DeleteImage"
- android:label="@string/delete_images_message"
- android:theme="@style/Theme.DeleteImageDialog">
- </activity>
-
- <activity android:name="GallerySettings" android:label="@string/preferences_label">
- </activity>
-
- <activity android:name=".Wallpaper"
- android:label="@string/camera_setas_wallpaper"
- android:icon="@drawable/ic_launcher_gallery">
- </activity>
-
- <activity android:name=".PickWallpaper"
- android:label="@string/camera_pick_wallpaper"
- android:icon="@drawable/ic_launcher_gallery">
- </activity>
-
- <!-- We configure a widget by asking to pick a photo, then crop it, and store the config internally -->
- <activity android:name="PhotoAppWidgetConfigure">
- </activity>
-
- <!-- We also allow direct binding where the caller provides a bitmap and
- appWidgetId to bind. We require the permission because this changes our
- internal database without user confirmation. -->
- <activity android:name="PhotoAppWidgetBind" android:exported="true"
- android:theme="@android:style/Theme.NoDisplay"
- android:permission="android.permission.BIND_APPWIDGET" />
-
</application>
</manifest>
diff --git a/src/com/android/camera/BitmapCache.java b/src/com/android/camera/BitmapCache.java
new file mode 100644
index 00000000..3476c71f
--- /dev/null
+++ b/src/com/android/camera/BitmapCache.java
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.camera;
+
+import android.graphics.Bitmap;
+
+class BitmapCache implements ImageViewTouchBase.Recycler {
+ public static class Entry {
+ int mPos;
+ Bitmap mBitmap;
+ public Entry() {
+ clear();
+ }
+ public void clear() {
+ mPos = -1;
+ mBitmap = null;
+ }
+ }
+
+ private final Entry[] mCache;
+
+ public BitmapCache(int size) {
+ mCache = new Entry[size];
+ for (int i = 0; i < mCache.length; i++) {
+ mCache[i] = new Entry();
+ }
+ }
+
+ // Given the position, find the associated entry. Returns null if there is
+ // no such entry.
+ private Entry findEntry(int pos) {
+ for (Entry e : mCache) {
+ if (pos == e.mPos) {
+ return e;
+ }
+ }
+ return null;
+ }
+
+ // Returns the thumb bitmap if we have it, otherwise return null.
+ public synchronized Bitmap getBitmap(int pos) {
+ Entry e = findEntry(pos);
+ if (e != null) {
+ return e.mBitmap;
+ }
+ return null;
+ }
+
+ public synchronized void put(int pos, Bitmap bitmap) {
+ // First see if we already have this entry.
+ if (findEntry(pos) != null) {
+ return;
+ }
+
+ // Find the best entry we should replace.
+ // See if there is any empty entry.
+ // Otherwise assuming sequential access, kick out the entry with the
+ // greatest distance.
+ Entry best = null;
+ int maxDist = -1;
+ for (Entry e : mCache) {
+ if (e.mPos == -1) {
+ best = e;
+ break;
+ } else {
+ int dist = Math.abs(pos - e.mPos);
+ if (dist > maxDist) {
+ maxDist = dist;
+ best = e;
+ }
+ }
+ }
+
+ // Recycle the image being kicked out.
+ // This only works because our current usage is sequential, so we
+ // do not happen to recycle the image being displayed.
+ if (best.mBitmap != null) {
+ best.mBitmap.recycle();
+ }
+
+ best.mPos = pos;
+ best.mBitmap = bitmap;
+ }
+
+ // Recycle all bitmaps in the cache and clear the cache.
+ public synchronized void clear() {
+ for (Entry e : mCache) {
+ if (e.mBitmap != null) {
+ e.mBitmap.recycle();
+ }
+ e.clear();
+ }
+ }
+
+ // Returns whether the bitmap is in the cache.
+ public synchronized boolean hasBitmap(int pos) {
+ Entry e = findEntry(pos);
+ return (e != null);
+ }
+
+ // Recycle the bitmap if it's not in the cache.
+ // The input must be non-null.
+ public synchronized void recycle(Bitmap b) {
+ for (Entry e : mCache) {
+ if (e.mPos != -1) {
+ if (e.mBitmap == b) {
+ return;
+ }
+ }
+ }
+ b.recycle();
+ }
+}
diff --git a/src/com/android/camera/DeleteImage.java b/src/com/android/camera/DeleteImage.java
deleted file mode 100644
index dec65ee2..00000000
--- a/src/com/android/camera/DeleteImage.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.camera;
-
-import android.app.Activity;
-import android.content.ContentResolver;
-import android.content.Intent;
-import android.net.Uri;
-import android.os.Bundle;
-import android.os.Handler;
-import android.widget.ProgressBar;
-
-import java.util.ArrayList;
-
-public class DeleteImage extends NoSearchActivity {
-
- @SuppressWarnings("unused")
- private static final String TAG = "DeleteImage";
- private ProgressBar mProgressBar;
- private ArrayList<Uri> mUriList; // a list of image uri
- private int mIndex = 0; // next image to delete
- private final Handler mHandler = new Handler();
- private final Runnable mDeleteNextRunnable = new Runnable() {
- public void run() {
- deleteNext();
- }
- };
- private ContentResolver mContentResolver;
- private boolean mPausing;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- Intent intent = getIntent();
- mUriList = intent.getParcelableArrayListExtra("delete-uris");
- if (mUriList == null) {
- finish();
- }
- setContentView(R.layout.delete_image);
- mProgressBar = (ProgressBar) findViewById(R.id.delete_progress);
- mContentResolver = getContentResolver();
- }
-
- @Override
- protected void onResume() {
- super.onResume();
- mPausing = false;
- mHandler.post(mDeleteNextRunnable);
- }
-
- private void deleteNext() {
- if (mPausing) return;
- if (mIndex >= mUriList.size()) {
- finish();
- return;
- }
- Uri uri = mUriList.get(mIndex++);
- // The max progress value of the bar is set to 10000 in the xml file.
- mProgressBar.setProgress(mIndex * 10000 / mUriList.size());
- mContentResolver.delete(uri, null, null);
- mHandler.post(mDeleteNextRunnable);
- }
-
- @Override
- protected void onPause() {
- super.onPause();
- mPausing = true;
- }
-}
diff --git a/src/com/android/camera/DrmWallpaper.java b/src/com/android/camera/DrmWallpaper.java
deleted file mode 100644
index 643b8769..00000000
--- a/src/com/android/camera/DrmWallpaper.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2007 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.camera;
-
-import android.content.Intent;
-
-/**
- * Wallpaper picker for DRM images. This just redirects to the standard pick
- * action.
- */
-public class DrmWallpaper extends Wallpaper {
-
- @Override
- protected void formatIntent(Intent intent) {
- super.formatIntent(intent);
- intent.putExtra("pick-drm", true);
- }
-}
diff --git a/src/com/android/camera/GalleryPicker.java b/src/com/android/camera/GalleryPicker.java
deleted file mode 100644
index 1a6db37d..00000000
--- a/src/com/android/camera/GalleryPicker.java
+++ /dev/null
@@ -1,941 +0,0 @@
-/*
- * Copyright (C) 2007 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.camera;
-
-import com.android.camera.gallery.IImage;
-import com.android.camera.gallery.IImageList;
-
-import android.app.Activity;
-import android.app.Dialog;
-import android.app.ProgressDialog;
-import android.content.BroadcastReceiver;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.res.Resources;
-import android.database.ContentObserver;
-import android.graphics.Bitmap;
-import android.graphics.Canvas;
-import android.graphics.Matrix;
-import android.graphics.Paint;
-import android.graphics.PorterDuff;
-import android.graphics.PorterDuffXfermode;
-import android.graphics.Rect;
-import android.graphics.drawable.Drawable;
-import android.net.Uri;
-import android.os.Bundle;
-import android.os.Environment;
-import android.os.Handler;
-import android.os.StatFs;
-import android.provider.MediaStore;
-import android.provider.MediaStore.Images;
-import android.util.Log;
-import android.view.ContextMenu;
-import android.view.LayoutInflater;
-import android.view.Menu;
-import android.view.MenuItem;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.ContextMenu.ContextMenuInfo;
-import android.view.MenuItem.OnMenuItemClickListener;
-import android.widget.AdapterView;
-import android.widget.BaseAdapter;
-import android.widget.GridView;
-import android.widget.TextView;
-import android.widget.Toast;
-import android.widget.AdapterView.AdapterContextMenuInfo;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * The GalleryPicker activity.
- */
-public class GalleryPicker extends NoSearchActivity {
- private static final String TAG = "GalleryPicker";
-
- Handler mHandler = new Handler(); // handler for the main thread
- Thread mWorkerThread;
- BroadcastReceiver mReceiver;
- ContentObserver mDbObserver;
- GridView mGridView;
- GalleryPickerAdapter mAdapter; // mAdapter is only accessed in main thread.
- boolean mScanning;
- boolean mUnmounted;
-
- @Override
- public void onCreate(Bundle icicle) {
- super.onCreate(icicle);
-
- setContentView(R.layout.gallerypicker);
-
- mGridView = (GridView) findViewById(R.id.albums);
-
- mGridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
- public void onItemClick(AdapterView<?> parent, View view,
- int position, long id) {
- launchFolderGallery(position);
- }
- });
-
- mGridView.setOnCreateContextMenuListener(
- new View.OnCreateContextMenuListener() {
- public void onCreateContextMenu(ContextMenu menu, View v,
- final ContextMenuInfo menuInfo) {
- onCreateGalleryPickerContextMenu(menu, menuInfo);
- }
- });
-
- mReceiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- onReceiveMediaBroadcast(intent);
- }
- };
-
- mDbObserver = new ContentObserver(mHandler) {
- @Override
- public void onChange(boolean selfChange) {
- rebake(false, ImageManager.isMediaScannerScanning(
- getContentResolver()));
- }
- };
-
- ImageManager.ensureOSXCompatibleFolder();
- }
-
- Dialog mMediaScanningDialog;
-
- // Display a dialog if the storage is being scanned now.
- public void updateScanningDialog(boolean scanning) {
- boolean prevScanning = (mMediaScanningDialog != null);
- if (prevScanning == scanning && mAdapter.mItems.size() == 0) return;
- // Now we are certain the state is changed.
- if (prevScanning) {
- mMediaScanningDialog.cancel();
- mMediaScanningDialog = null;
- } else if (scanning && mAdapter.mItems.size() == 0) {
- mMediaScanningDialog = ProgressDialog.show(
- this,
- null,
- getResources().getString(R.string.wait),
- true,
- true);
- }
- }
-
- private View mNoImagesView;
-
- // Show/Hide the "no images" icon and text. Load resources on demand.
- private void showNoImagesView() {
- if (mNoImagesView == null) {
- ViewGroup root = (ViewGroup) findViewById(R.id.root);
- getLayoutInflater().inflate(R.layout.gallerypicker_no_images, root);
- mNoImagesView = findViewById(R.id.no_images);
- }
- mNoImagesView.setVisibility(View.VISIBLE);
- }
-
- private void hideNoImagesView() {
- if (mNoImagesView != null) {
- mNoImagesView.setVisibility(View.GONE);
- }
- }
-
- // The storage status is changed, restart the worker or show "no images".
- private void rebake(boolean unmounted, boolean scanning) {
- if (unmounted == mUnmounted && scanning == mScanning) return;
- abortWorker();
- mUnmounted = unmounted;
- mScanning = scanning;
- updateScanningDialog(mScanning);
- if (mUnmounted) {
- showNoImagesView();
- } else {
- hideNoImagesView();
- startWorker();
- }
- }
-
- // This is called when we receive media-related broadcast.
- private void onReceiveMediaBroadcast(Intent intent) {
- String action = intent.getAction();
- if (action.equals(Intent.ACTION_MEDIA_MOUNTED)) {
- // SD card available
- // TODO put up a "please wait" message
- } else if (action.equals(Intent.ACTION_MEDIA_UNMOUNTED)) {
- // SD card unavailable
- rebake(true, false);
- } else if (action.equals(Intent.ACTION_MEDIA_SCANNER_STARTED)) {
- rebake(false, true);
- } else if (action.equals(
- Intent.ACTION_MEDIA_SCANNER_FINISHED)) {
- rebake(false, false);
- } else if (action.equals(Intent.ACTION_MEDIA_EJECT)) {
- rebake(true, false);
- }
- }
-
- private void launchFolderGallery(int position) {
- mAdapter.mItems.get(position).launch(this);
- }
-
- private void onCreateGalleryPickerContextMenu(ContextMenu menu,
- final ContextMenuInfo menuInfo) {
- int position = ((AdapterContextMenuInfo) menuInfo).position;
- menu.setHeaderTitle(mAdapter.baseTitleForPosition(position));
- // "Slide Show"
- if ((mAdapter.getIncludeMediaTypes(position)
- & ImageManager.INCLUDE_IMAGES) != 0) {
- menu.add(R.string.slide_show)
- .setOnMenuItemClickListener(new OnMenuItemClickListener() {
- public boolean onMenuItemClick(MenuItem item) {
- return onSlideShowClicked(menuInfo);
- }
- });
- }
- // "View"
- menu.add(R.string.view)
- .setOnMenuItemClickListener(new OnMenuItemClickListener() {
- public boolean onMenuItemClick(MenuItem item) {
- return onViewClicked(menuInfo);
- }
- });
- }
-
- // This is called when the user clicks "Slideshow" from the context menu.
- private boolean onSlideShowClicked(ContextMenuInfo menuInfo) {
- AdapterContextMenuInfo info = (AdapterContextMenuInfo) menuInfo;
- int position = info.position;
-
- if (position < 0 || position >= mAdapter.mItems.size()) {
- return true;
- }
- // Slide show starts from the first image on the list.
- Item item = mAdapter.mItems.get(position);
- Uri targetUri = item.mFirstImageUri;
-
- if (targetUri != null && item.mBucketId != null) {
- targetUri = targetUri.buildUpon()
- .appendQueryParameter("bucketId", item.mBucketId)
- .build();
- }
- Intent intent = new Intent(Intent.ACTION_VIEW, targetUri);
- intent.putExtra("slideshow", true);
- startActivity(intent);
- return true;
- }
-
- // This is called when the user clicks "View" from the context menu.
- private boolean onViewClicked(ContextMenuInfo menuInfo) {
- AdapterContextMenuInfo info = (AdapterContextMenuInfo) menuInfo;
- launchFolderGallery(info.position);
- return true;
- }
-
- @Override
- public void onStop() {
- super.onStop();
-
- abortWorker();
-
- unregisterReceiver(mReceiver);
- getContentResolver().unregisterContentObserver(mDbObserver);
-
- // free up some ram
- mAdapter = null;
- mGridView.setAdapter(null);
- unloadDrawable();
- }
-
- @Override
- public void onStart() {
- super.onStart();
-
- mAdapter = new GalleryPickerAdapter(getLayoutInflater());
- mGridView.setAdapter(mAdapter);
-
- // install an intent filter to receive SD card related events.
- IntentFilter intentFilter = new IntentFilter();
- intentFilter.addAction(Intent.ACTION_MEDIA_MOUNTED);
- intentFilter.addAction(Intent.ACTION_MEDIA_UNMOUNTED);
- intentFilter.addAction(Intent.ACTION_MEDIA_SCANNER_STARTED);
- intentFilter.addAction(Intent.ACTION_MEDIA_SCANNER_FINISHED);
- intentFilter.addAction(Intent.ACTION_MEDIA_EJECT);
- intentFilter.addDataScheme("file");
-
- registerReceiver(mReceiver, intentFilter);
-
- getContentResolver().registerContentObserver(
- MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
- true, mDbObserver);
-
- // Assume the storage is mounted and not scanning.
- mUnmounted = false;
- mScanning = false;
- startWorker();
- }
-
- // This is used to stop the worker thread.
- volatile boolean mAbort = false;
-
- // Create the worker thread.
- private void startWorker() {
- mAbort = false;
- mWorkerThread = new Thread("GalleryPicker Worker") {
- @Override
- public void run() {
- workerRun();
- }
- };
- BitmapManager.instance().allowThreadDecoding(mWorkerThread);
- mWorkerThread.start();
- }
-
- private void abortWorker() {
- if (mWorkerThread != null) {
- BitmapManager.instance().cancelThreadDecoding(mWorkerThread, getContentResolver());
- mAbort = true;
- try {
- mWorkerThread.join();
- } catch (InterruptedException ex) {
- Log.e(TAG, "join interrupted");
- }
- mWorkerThread = null;
- // Remove all runnables in mHandler.
- // (We assume that the "what" field in the messages are 0
- // for runnables).
- mHandler.removeMessages(0);
- mAdapter.clear();
- mAdapter.updateDisplay();
- clearImageLists();
- }
- }
-
- // This is run in the worker thread.
- private void workerRun() {
- // We collect items from checkImageList() and checkBucketIds() and
- // put them in allItems. Later we give allItems to checkThumbBitmap()
- // and generated thumbnail bitmaps for each item. We do this instead of
- // generating thumbnail bitmaps in checkImageList() and checkBucketIds()
- // because we want to show all the folders first, then update them with
- // the thumb bitmaps. (Generating thumbnail bitmaps takes some time.)
- ArrayList<Item> allItems = new ArrayList<Item>();
-
- checkScanning();
- if (mAbort) return;
-
- checkImageList(allItems);
- if (mAbort) return;
-
- checkBucketIds(allItems);
- if (mAbort) return;
-
- checkThumbBitmap(allItems);
- if (mAbort) return;
-
- checkLowStorage();
- }
-
- // This is run in the worker thread.
- private void checkScanning() {
- ContentResolver cr = getContentResolver();
- final boolean scanning =
- ImageManager.isMediaScannerScanning(cr);
- mHandler.post(new Runnable() {
- public void run() {
- checkScanningFinished(scanning);
- }
- });
- }
-
- // This is run in the main thread.
- private void checkScanningFinished(boolean scanning) {
- updateScanningDialog(scanning);
- }
-
- // This is run in the worker thread.
- private void checkImageList(ArrayList<Item> allItems) {
- int length = IMAGE_LIST_DATA.length;
- IImageList[] lists = new IImageList[length];
- for (int i = 0; i < length; i++) {
- ImageListData data = IMAGE_LIST_DATA[i];
- lists[i] = createImageList(data.mInclude, data.mBucketId,
- getContentResolver());
- if (mAbort) return;
- Item item = null;
-
- if (lists[i].isEmpty()) continue;
-
- // i >= 3 means we are looking at All Images/All Videos.
- // lists[i-3] is the corresponding Camera Images/Camera Videos.
- // We want to add the "All" list only if it's different from
- // the "Camera" list.
- if (i >= 3 && lists[i].getCount() == lists[i - 3].getCount()) {
- continue;
- }
-
- item = new Item(data.mType,
- data.mBucketId,
- getResources().getString(data.mStringId),
- lists[i]);
-
- allItems.add(item);
-
- final Item finalItem = item;
- mHandler.post(new Runnable() {
- public void run() {
- updateItem(finalItem);
- }
- });
- }
- }
-
- // This is run in the main thread.
- private void updateItem(Item item) {
- // Hide NoImageView if we are going to add the first item
- if (mAdapter.getCount() == 0) {
- hideNoImagesView();
- }
- mAdapter.addItem(item);
- mAdapter.updateDisplay();
- }
-
- private static final String CAMERA_BUCKET =
- ImageManager.CAMERA_IMAGE_BUCKET_ID;
-
- // This is run in the worker thread.
- private void checkBucketIds(ArrayList<Item> allItems) {
- final IImageList allImages;
- if (!mScanning && !mUnmounted) {
- allImages = ImageManager.makeImageList(
- getContentResolver(),
- ImageManager.DataLocation.ALL,
- ImageManager.INCLUDE_IMAGES | ImageManager.INCLUDE_VIDEOS,
- ImageManager.SORT_DESCENDING,
- null);
- } else {
- allImages = ImageManager.makeEmptyImageList();
- }
-
- if (mAbort) {
- allImages.close();
- return;
- }
-
- HashMap<String, String> hashMap = allImages.getBucketIds();
- allImages.close();
- if (mAbort) return;
-
- for (Map.Entry<String, String> entry : hashMap.entrySet()) {
- String key = entry.getKey();
- if (key == null) {
- continue;
- }
- if (!key.equals(CAMERA_BUCKET)) {
- IImageList list = createImageList(
- ImageManager.INCLUDE_IMAGES
- | ImageManager.INCLUDE_VIDEOS, key,
- getContentResolver());
- if (mAbort) return;
-
- Item item = new Item(Item.TYPE_NORMAL_FOLDERS, key,
- entry.getValue(), list);
-
- allItems.add(item);
-
- final Item finalItem = item;
- mHandler.post(new Runnable() {
- public void run() {
- updateItem(finalItem);
- }
- });
- }
- }
-
- mHandler.post(new Runnable() {
- public void run() {
- checkBucketIdsFinished();
- }
- });
- }
-
- // This is run in the main thread.
- private void checkBucketIdsFinished() {
-
- // If we just have one folder, open it.
- // If we have zero folder, show the "no images" icon.
- if (!mScanning) {
- int numItems = mAdapter.mItems.size();
- if (numItems == 0) {
- showNoImagesView();
- } else if (numItems == 1) {
- mAdapter.mItems.get(0).launch(this);
- finish();
- return;
- }
- }
- }
-
- private static final int THUMB_SIZE = 142;
- // This is run in the worker thread.
- private void checkThumbBitmap(ArrayList<Item> allItems) {
- for (Item item : allItems) {
- final Bitmap b = makeMiniThumbBitmap(THUMB_SIZE, THUMB_SIZE,
- item.mImageList);
- if (mAbort) {
- if (b != null) b.recycle();
- return;
- }
-
- final Item finalItem = item;
- mHandler.post(new Runnable() {
- public void run() {
- updateThumbBitmap(finalItem, b);
- }
- });
- }
- }
-
- // This is run in the main thread.
- private void updateThumbBitmap(Item item, Bitmap b) {
- item.setThumbBitmap(b);
- mAdapter.updateDisplay();
- }
-
- private static final long LOW_STORAGE_THRESHOLD = 1024 * 1024 * 2;
-
- // This is run in the worker thread.
- private void checkLowStorage() {
- // Check available space only if we are writable
- if (ImageManager.hasStorage()) {
- String storageDirectory = Environment
- .getExternalStorageDirectory().toString();
- StatFs stat = new StatFs(storageDirectory);
- long remaining = (long) stat.getAvailableBlocks()
- * (long) stat.getBlockSize();
- if (remaining < LOW_STORAGE_THRESHOLD) {
- mHandler.post(new Runnable() {
- public void run() {
- checkLowStorageFinished();
- }
- });
- }
- }
- }
-
- // This is run in the main thread.
- // This is called only if the storage is low.
- private void checkLowStorageFinished() {
- Toast.makeText(GalleryPicker.this, R.string.not_enough_space, 5000)
- .show();
- }
-
- // IMAGE_LIST_DATA stores the parameters for the four image lists
- // we are interested in. The order of the IMAGE_LIST_DATA array is
- // significant (See the implementation of GalleryPickerAdapter.init).
- private static final class ImageListData {
- ImageListData(int type, int include, String bucketId, int stringId) {
- mType = type;
- mInclude = include;
- mBucketId = bucketId;
- mStringId = stringId;
- }
- int mType;
- int mInclude;
- String mBucketId;
- int mStringId;
- }
-
- private static final ImageListData[] IMAGE_LIST_DATA = {
- // Camera Images
- new ImageListData(Item.TYPE_CAMERA_IMAGES,
- ImageManager.INCLUDE_IMAGES,
- ImageManager.CAMERA_IMAGE_BUCKET_ID,
- R.string.gallery_camera_bucket_name),
- // Camera Videos
- new ImageListData(Item.TYPE_CAMERA_VIDEOS,
- ImageManager.INCLUDE_VIDEOS,
- ImageManager.CAMERA_IMAGE_BUCKET_ID,
- R.string.gallery_camera_videos_bucket_name),
-
- // Camera Medias
- new ImageListData(Item.TYPE_CAMERA_MEDIAS,
- ImageManager.INCLUDE_VIDEOS | ImageManager.INCLUDE_IMAGES,
- ImageManager.CAMERA_IMAGE_BUCKET_ID,
- R.string.gallery_camera_media_bucket_name),
-
- // All Images
- new ImageListData(Item.TYPE_ALL_IMAGES,
- ImageManager.INCLUDE_IMAGES,
- null,
- R.string.all_images),
-
- // All Videos
- new ImageListData(Item.TYPE_ALL_VIDEOS,
- ImageManager.INCLUDE_VIDEOS,
- null,
- R.string.all_videos),
- };
-
-
- // These drawables are loaded on-demand.
- Drawable mFrameGalleryMask;
- Drawable mCellOutline;
- Drawable mVideoOverlay;
-
- private void loadDrawableIfNeeded() {
- if (mFrameGalleryMask != null) return; // already loaded
- Resources r = getResources();
- mFrameGalleryMask = r.getDrawable(
- R.drawable.frame_gallery_preview_album_mask);
- mCellOutline = r.getDrawable(android.R.drawable.gallery_thumb);
- mVideoOverlay = r.getDrawable(R.drawable.ic_gallery_video_overlay);
- }
-
- private void unloadDrawable() {
- mFrameGalleryMask = null;
- mCellOutline = null;
- mVideoOverlay = null;
- }
-
- private static void placeImage(Bitmap image, Canvas c, Paint paint,
- int imageWidth, int widthPadding, int imageHeight,
- int heightPadding, int offsetX, int offsetY,
- int pos) {
- int row = pos / 2;
- int col = pos - (row * 2);
-
- int xPos = (col * (imageWidth + widthPadding)) - offsetX;
- int yPos = (row * (imageHeight + heightPadding)) - offsetY;
-
- c.drawBitmap(image, xPos, yPos, paint);
- }
-
- // This is run in worker thread.
- private Bitmap makeMiniThumbBitmap(int width, int height,
- IImageList images) {
- int count = images.getCount();
- // We draw three different version of the folder image depending on the
- // number of images in the folder.
- // For a single image, that image draws over the whole folder.
- // For two or three images, we draw the two most recent photos.
- // For four or more images, we draw four photos.
- final int padding = 4;
- int imageWidth = width;
- int imageHeight = height;
- int offsetWidth = 0;
- int offsetHeight = 0;
-
- imageWidth = (imageWidth - padding) / 2; // 2 here because we show two
- // images
- imageHeight = (imageHeight - padding) / 2; // per row and column
-
- final Paint p = new Paint();
- final Bitmap b = Bitmap.createBitmap(width, height,
- Bitmap.Config.ARGB_8888);
- final Canvas c = new Canvas(b);
- final Matrix m = new Matrix();
-
- // draw the whole canvas as transparent
- p.setColor(0x00000000);
- c.drawPaint(p);
-
- // load the drawables
- loadDrawableIfNeeded();
-
- // draw the mask normally
- p.setColor(0xFFFFFFFF);
- mFrameGalleryMask.setBounds(0, 0, width, height);
- mFrameGalleryMask.draw(c);
-
- Paint pdpaint = new Paint();
- pdpaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
-
- pdpaint.setStyle(Paint.Style.FILL);
- c.drawRect(0, 0, width, height, pdpaint);
-
- for (int i = 0; i < 4; i++) {
- if (mAbort) {
- return null;
- }
-
- Bitmap temp = null;
- IImage image = i < count ? images.getImageAt(i) : null;
-
- if (image != null) {
- temp = image.miniThumbBitmap();
- }
-
- if (temp != null) {
- if (ImageManager.isVideo(image)) {
- Bitmap newMap = temp.copy(temp.getConfig(), true);
- Canvas overlayCanvas = new Canvas(newMap);
- int overlayWidth = mVideoOverlay.getIntrinsicWidth();
- int overlayHeight = mVideoOverlay.getIntrinsicHeight();
- int left = (newMap.getWidth() - overlayWidth) / 2;
- int top = (newMap.getHeight() - overlayHeight) / 2;
- Rect newBounds = new Rect(left, top, left + overlayWidth,
- top + overlayHeight);
- mVideoOverlay.setBounds(newBounds);
- mVideoOverlay.draw(overlayCanvas);
- temp.recycle();
- temp = newMap;
- }
-
- temp = Util.transform(m, temp, imageWidth,
- imageHeight, true, Util.RECYCLE_INPUT);
- }
-
- Bitmap thumb = Bitmap.createBitmap(imageWidth, imageHeight,
- Bitmap.Config.ARGB_8888);
- Canvas tempCanvas = new Canvas(thumb);
- if (temp != null) {
- tempCanvas.drawBitmap(temp, new Matrix(), new Paint());
- }
- mCellOutline.setBounds(0, 0, imageWidth, imageHeight);
- mCellOutline.draw(tempCanvas);
-
- placeImage(thumb, c, pdpaint, imageWidth, padding, imageHeight,
- padding, offsetWidth, offsetHeight, i);
-
- thumb.recycle();
-
- if (temp != null) {
- temp.recycle();
- }
- }
-
- return b;
- }
-
- @Override
- public boolean onCreateOptionsMenu(Menu menu) {
- super.onCreateOptionsMenu(menu);
-
- MenuHelper.addCaptureMenuItems(menu, this);
-
- menu.add(Menu.NONE, Menu.NONE, MenuHelper.POSITION_GALLERY_SETTING,
- R.string.camerasettings)
- .setOnMenuItemClickListener(new OnMenuItemClickListener() {
- public boolean onMenuItemClick(MenuItem item) {
- Intent preferences = new Intent();
- preferences.setClass(GalleryPicker.this,
- GallerySettings.class);
- startActivity(preferences);
- return true;
- }
- })
- .setAlphabeticShortcut('p')
- .setIcon(android.R.drawable.ic_menu_preferences);
-
- return true;
- }
-
- // image lists created by createImageList() are collected in mAllLists.
- // They will be closed in clearImageList, so they don't hold open files
- // on SD card. We will be killed if we don't close files when the SD card
- // is unmounted.
- ArrayList<IImageList> mAllLists = new ArrayList<IImageList>();
-
- private IImageList createImageList(int mediaTypes, String bucketId,
- ContentResolver cr) {
- IImageList list = ImageManager.makeImageList(
- cr,
- ImageManager.DataLocation.ALL,
- mediaTypes,
- ImageManager.SORT_DESCENDING,
- bucketId);
- mAllLists.add(list);
- return list;
- }
-
- private void clearImageLists() {
- for (IImageList list : mAllLists) {
- list.close();
- }
- mAllLists.clear();
- }
-}
-
-// Item is the underlying data for GalleryPickerAdapter.
-// It is passed from the activity to the adapter.
-class Item {
- public static final int TYPE_NONE = -1;
- public static final int TYPE_ALL_IMAGES = 0;
- public static final int TYPE_ALL_VIDEOS = 1;
- public static final int TYPE_CAMERA_IMAGES = 2;
- public static final int TYPE_CAMERA_VIDEOS = 3;
- public static final int TYPE_CAMERA_MEDIAS = 4;
- public static final int TYPE_NORMAL_FOLDERS = 5;
-
- public final int mType;
- public final String mBucketId;
- public final String mName;
- public final IImageList mImageList;
- public final int mCount;
- public final Uri mFirstImageUri; // could be null if the list is empty
-
- // The thumbnail bitmap is set by setThumbBitmap() later because we want
- // to let the user sees the folder icon as soon as possible (and possibly
- // select them), then present more detailed information when we have it.
- public Bitmap mThumbBitmap; // the thumbnail bitmap for the image list
-
- public Item(int type, String bucketId, String name, IImageList list) {
- mType = type;
- mBucketId = bucketId;
- mName = name;
- mImageList = list;
- mCount = list.getCount();
- if (mCount > 0) {
- mFirstImageUri = list.getImageAt(0).fullSizeImageUri();
- } else {
- mFirstImageUri = null;
- }
- }
-
- public void setThumbBitmap(Bitmap thumbBitmap) {
- mThumbBitmap = thumbBitmap;
- }
-
- public boolean needsBucketId() {
- return mType >= TYPE_CAMERA_IMAGES;
- }
-
- public void launch(Activity activity) {
- Uri uri = Images.Media.INTERNAL_CONTENT_URI;
- if (needsBucketId()) {
- uri = uri.buildUpon()
- .appendQueryParameter("bucketId", mBucketId).build();
- }
- Intent intent = new Intent(Intent.ACTION_VIEW, uri);
- intent.putExtra("windowTitle", mName);
- intent.putExtra("mediaTypes", getIncludeMediaTypes());
- activity.startActivity(intent);
- }
-
- public int getIncludeMediaTypes() {
- return convertItemTypeToIncludedMediaType(mType);
- }
-
- public static int convertItemTypeToIncludedMediaType(int itemType) {
- switch (itemType) {
- case TYPE_ALL_IMAGES:
- case TYPE_CAMERA_IMAGES:
- return ImageManager.INCLUDE_IMAGES;
- case TYPE_ALL_VIDEOS:
- case TYPE_CAMERA_VIDEOS:
- return ImageManager.INCLUDE_VIDEOS;
- case TYPE_NORMAL_FOLDERS:
- case TYPE_CAMERA_MEDIAS:
- default:
- return ImageManager.INCLUDE_IMAGES
- | ImageManager.INCLUDE_VIDEOS;
- }
- }
-
- public int getOverlay() {
- switch (mType) {
- case TYPE_ALL_IMAGES:
- case TYPE_CAMERA_IMAGES:
- return R.drawable.frame_overlay_gallery_camera;
- case TYPE_ALL_VIDEOS:
- case TYPE_CAMERA_VIDEOS:
- case TYPE_CAMERA_MEDIAS:
- return R.drawable.frame_overlay_gallery_video;
- case TYPE_NORMAL_FOLDERS:
- default:
- return R.drawable.frame_overlay_gallery_folder;
- }
- }
-}
-
-class GalleryPickerAdapter extends BaseAdapter {
- ArrayList<Item> mItems = new ArrayList<Item>();
- LayoutInflater mInflater;
-
- GalleryPickerAdapter(LayoutInflater inflater) {
- mInflater = inflater;
- }
-
- public void addItem(Item item) {
- mItems.add(item);
- }
-
- public void updateDisplay() {
- notifyDataSetChanged();
- }
-
- public void clear() {
- mItems.clear();
- }
-
- public int getCount() {
- return mItems.size();
- }
-
- public Object getItem(int position) {
- return null;
- }
-
- public long getItemId(int position) {
- return position;
- }
-
- public String baseTitleForPosition(int position) {
- return mItems.get(position).mName;
- }
-
- public int getIncludeMediaTypes(int position) {
- return mItems.get(position).getIncludeMediaTypes();
- }
-
- public View getView(final int position, View convertView,
- ViewGroup parent) {
- View v;
-
- if (convertView == null) {
- v = mInflater.inflate(R.layout.gallery_picker_item, null);
- } else {
- v = convertView;
- }
-
- TextView titleView = (TextView) v.findViewById(R.id.title);
-
- GalleryPickerItem iv =
- (GalleryPickerItem) v.findViewById(R.id.thumbnail);
- Item item = mItems.get(position);
- iv.setOverlay(item.getOverlay());
- if (item.mThumbBitmap != null) {
- iv.setImageBitmap(item.mThumbBitmap);
- String title = item.mName + " (" + item.mCount + ")";
- titleView.setText(title);
- } else {
- iv.setImageResource(android.R.color.transparent);
- titleView.setText(item.mName);
- }
-
- // An workaround due to a bug in TextView. If the length of text is
- // different from the previous in convertView, the layout would be
- // wrong.
- titleView.requestLayout();
-
- return v;
- }
-}
diff --git a/src/com/android/camera/GalleryPickerItem.java b/src/com/android/camera/GalleryPickerItem.java
deleted file mode 100644
index 99e4a586..00000000
--- a/src/com/android/camera/GalleryPickerItem.java
+++ /dev/null
@@ -1,101 +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.camera;
-
-import android.content.Context;
-import android.graphics.Canvas;
-import android.graphics.Rect;
-import android.graphics.drawable.Drawable;
-import android.util.AttributeSet;
-import android.widget.ImageView;
-
-class GalleryPickerItem extends ImageView {
- private Drawable mFrame;
- private Rect mFrameBounds = new Rect();
- private Drawable mOverlay;
-
- public GalleryPickerItem(Context context) {
- this(context, null);
- }
-
- public GalleryPickerItem(Context context, AttributeSet attrs) {
- this(context, attrs, 0);
- }
-
- public GalleryPickerItem(Context context,
- AttributeSet attrs,
- int defStyle) {
- super(context, attrs, defStyle);
-
- mFrame = getResources().getDrawable(R.drawable.frame_gallery_preview);
- mFrame.setCallback(this);
- }
-
- @Override
- protected boolean verifyDrawable(Drawable who) {
- return super.verifyDrawable(who) || (who == mFrame)
- || (who == mOverlay);
- }
-
- @Override
- protected void drawableStateChanged() {
- super.drawableStateChanged();
- if (mFrame != null) {
- int[] drawableState = getDrawableState();
- mFrame.setState(drawableState);
- }
- }
-
- @Override
- protected void onDraw(Canvas canvas) {
- super.onDraw(canvas);
- final Rect frameBounds = mFrameBounds;
- if (frameBounds.isEmpty()) {
- final int w = getWidth();
- final int h = getHeight();
-
- frameBounds.set(0, 0, w, h);
- mFrame.setBounds(frameBounds);
- if (mOverlay != null) {
- mOverlay.setBounds(w - mOverlay.getIntrinsicWidth(),
- h - mOverlay.getIntrinsicHeight(), w, h);
- }
- }
-
- mFrame.draw(canvas);
- if (mOverlay != null) {
- mOverlay.draw(canvas);
- }
- }
-
-
- @Override
- protected void onSizeChanged(int w, int h, int oldw, int oldh) {
- super.onSizeChanged(w, h, oldw, oldh);
-
- mFrameBounds.setEmpty();
- }
-
- public void setOverlay(int overlayId) {
- if (overlayId >= 0) {
- mOverlay = getResources().getDrawable(overlayId);
- mFrameBounds.setEmpty();
- } else {
- mOverlay = null;
- }
- }
-}
diff --git a/src/com/android/camera/GallerySettings.java b/src/com/android/camera/GallerySettings.java
deleted file mode 100644
index 32c806c1..00000000
--- a/src/com/android/camera/GallerySettings.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2007 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.camera;
-
-import android.os.Bundle;
-import android.preference.PreferenceActivity;
-
-// GallerySettings
-//
-// This is the setting screen for Gallery.
-// It reads the available settings from an XML resource.
-public class GallerySettings extends PreferenceActivity {
- @Override
- public void onCreate(Bundle icicle) {
- super.onCreate(icicle);
- addPreferencesFromResource(R.xml.gallery_preferences);
- }
-}
diff --git a/src/com/android/camera/GridViewSpecial.java b/src/com/android/camera/GridViewSpecial.java
deleted file mode 100644
index 5326ebb6..00000000
--- a/src/com/android/camera/GridViewSpecial.java
+++ /dev/null
@@ -1,1169 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.camera;
-
-import static com.android.camera.Util.Assert;
-
-import android.app.Activity;
-import android.content.Context;
-import android.graphics.Bitmap;
-import android.graphics.Canvas;
-import android.graphics.Paint;
-import android.graphics.Rect;
-import android.graphics.drawable.Drawable;
-import android.media.AudioManager;
-import android.os.Handler;
-import android.util.AttributeSet;
-import android.util.DisplayMetrics;
-import android.view.GestureDetector;
-import android.view.KeyEvent;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.ViewConfiguration;
-import android.view.GestureDetector.SimpleOnGestureListener;
-import android.widget.Scroller;
-
-import com.android.camera.gallery.IImage;
-import com.android.camera.gallery.IImageList;
-
-import java.util.HashMap;
-
-class GridViewSpecial extends View {
- @SuppressWarnings("unused")
- private static final String TAG = "GridViewSpecial";
- private static final float MAX_FLING_VELOCITY = 2500;
-
- public static interface Listener {
- public void onImageClicked(int index);
- public void onImageTapped(int index);
- public void onLayoutComplete(boolean changed);
-
- /**
- * Invoked when the <code>GridViewSpecial</code> scrolls.
- *
- * @param scrollPosition the position of the scroller in the range
- * [0, 1], when 0 means on the top and 1 means on the buttom
- */
- public void onScroll(float scrollPosition);
- }
-
- public static interface DrawAdapter {
- public void drawImage(Canvas canvas, IImage image,
- Bitmap b, int xPos, int yPos, int w, int h);
- public void drawDecoration(Canvas canvas, IImage image,
- int xPos, int yPos, int w, int h);
- public boolean needsDecoration();
- }
-
- public static final int INDEX_NONE = -1;
-
- // There are two cell size we will use. It can be set by setSizeChoice().
- // The mLeftEdgePadding fields is filled in onLayout(). See the comments
- // in onLayout() for details.
- static class LayoutSpec {
- LayoutSpec(int w, int h, int intercellSpacing, int leftEdgePadding,
- DisplayMetrics metrics) {
- mCellWidth = dpToPx(w, metrics);
- mCellHeight = dpToPx(h, metrics);
- mCellSpacing = dpToPx(intercellSpacing, metrics);
- mLeftEdgePadding = dpToPx(leftEdgePadding, metrics);
- }
- int mCellWidth, mCellHeight;
- int mCellSpacing;
- int mLeftEdgePadding;
- }
-
- private LayoutSpec [] mCellSizeChoices;
-
- private void initCellSize() {
- Activity a = (Activity) getContext();
- DisplayMetrics metrics = new DisplayMetrics();
- a.getWindowManager().getDefaultDisplay().getMetrics(metrics);
- mCellSizeChoices = new LayoutSpec[] {
- new LayoutSpec(67, 67, 8, 0, metrics),
- new LayoutSpec(92, 92, 8, 0, metrics),
- };
- }
-
- // Converts dp to pixel.
- private static int dpToPx(int dp, DisplayMetrics metrics) {
- return (int) (metrics.density * dp);
- }
-
- // These are set in init().
- private final Handler mHandler = new Handler();
- private GestureDetector mGestureDetector;
- private ImageBlockManager mImageBlockManager;
-
- // These are set in set*() functions.
- private ImageLoader mLoader;
- private Listener mListener = null;
- private DrawAdapter mDrawAdapter = null;
- private IImageList mAllImages = ImageManager.makeEmptyImageList();
- private int mSizeChoice = 1; // default is big cell size
-
- // These are set in onLayout().
- private LayoutSpec mSpec;
- private int mColumns;
- private int mMaxScrollY;
-
- // We can handle events only if onLayout() is completed.
- private boolean mLayoutComplete = false;
-
- // Selection state
- private int mCurrentSelection = INDEX_NONE;
- private int mCurrentPressState = 0;
- private static final int TAPPING_FLAG = 1;
- private static final int CLICKING_FLAG = 2;
-
- // These are cached derived information.
- private int mCount; // Cache mImageList.getCount();
- private int mRows; // Cache (mCount + mColumns - 1) / mColumns
- private int mBlockHeight; // Cache mSpec.mCellSpacing + mSpec.mCellHeight
-
- private boolean mRunning = false;
- private Scroller mScroller = null;
-
- public GridViewSpecial(Context context, AttributeSet attrs) {
- super(context, attrs);
- init(context);
- }
-
- private void init(Context context) {
- setVerticalScrollBarEnabled(true);
- initializeScrollbars(context.obtainStyledAttributes(
- android.R.styleable.View));
- mGestureDetector = new GestureDetector(context,
- new MyGestureDetector());
- setFocusableInTouchMode(true);
- initCellSize();
- }
-
- private final Runnable mRedrawCallback = new Runnable() {
- public void run() {
- invalidate();
- }
- };
-
- public void setLoader(ImageLoader loader) {
- Assert(mRunning == false);
- mLoader = loader;
- }
-
- public void setListener(Listener listener) {
- Assert(mRunning == false);
- mListener = listener;
- }
-
- public void setDrawAdapter(DrawAdapter adapter) {
- Assert(mRunning == false);
- mDrawAdapter = adapter;
- }
-
- public void setImageList(IImageList list) {
- Assert(mRunning == false);
- mAllImages = list;
- mCount = mAllImages.getCount();
- }
-
- public void setSizeChoice(int choice) {
- Assert(mRunning == false);
- if (mSizeChoice == choice) return;
- mSizeChoice = choice;
- }
-
- @Override
- public void onLayout(boolean changed, int left, int top,
- int right, int bottom) {
- super.onLayout(changed, left, top, right, bottom);
-
- if (!mRunning) {
- return;
- }
-
- mSpec = mCellSizeChoices[mSizeChoice];
-
- int width = right - left;
-
- // The width is divided into following parts:
- //
- // LeftEdgePadding CellWidth (CellSpacing CellWidth)* RightEdgePadding
- //
- // We determine number of cells (columns) first, then the left and right
- // padding are derived. We make left and right paddings the same size.
- //
- // The height is divided into following parts:
- //
- // CellSpacing (CellHeight CellSpacing)+
-
- mColumns = 1 + (width - mSpec.mCellWidth)
- / (mSpec.mCellWidth + mSpec.mCellSpacing);
-
- mSpec.mLeftEdgePadding = (width
- - ((mColumns - 1) * mSpec.mCellSpacing)
- - (mColumns * mSpec.mCellWidth)) / 2;
-
- mRows = (mCount + mColumns - 1) / mColumns;
- mBlockHeight = mSpec.mCellSpacing + mSpec.mCellHeight;
- mMaxScrollY = mSpec.mCellSpacing + (mRows * mBlockHeight)
- - (bottom - top);
-
- // Put mScrollY in the valid range. This matters if mMaxScrollY is
- // changed. For example, orientation changed from portrait to landscape.
- mScrollY = Math.max(0, Math.min(mMaxScrollY, mScrollY));
-
- generateOutlineBitmap();
-
- if (mImageBlockManager != null) {
- mImageBlockManager.recycle();
- }
-
- mImageBlockManager = new ImageBlockManager(mHandler, mRedrawCallback,
- mAllImages, mLoader, mDrawAdapter, mSpec, mColumns, width,
- mOutline[OUTLINE_EMPTY]);
-
- mListener.onLayoutComplete(changed);
-
- moveDataWindow();
-
- mLayoutComplete = true;
- }
-
- @Override
- protected int computeVerticalScrollRange() {
- return mMaxScrollY + getHeight();
- }
-
- // We cache the three outlines from NinePatch to Bitmap to speed up
- // drawing. The cache must be updated if the cell size is changed.
- public static final int OUTLINE_EMPTY = 0;
- public static final int OUTLINE_PRESSED = 1;
- public static final int OUTLINE_SELECTED = 2;
-
- public Bitmap mOutline[] = new Bitmap[3];
-
- private void generateOutlineBitmap() {
- int w = mSpec.mCellWidth;
- int h = mSpec.mCellHeight;
-
- for (int i = 0; i < mOutline.length; i++) {
- mOutline[i] = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
- }
-
- Drawable cellOutline;
- cellOutline = GridViewSpecial.this.getResources()
- .getDrawable(android.R.drawable.gallery_thumb);
- cellOutline.setBounds(0, 0, w, h);
- Canvas canvas = new Canvas();
-
- canvas.setBitmap(mOutline[OUTLINE_EMPTY]);
- cellOutline.setState(EMPTY_STATE_SET);
- cellOutline.draw(canvas);
-
- canvas.setBitmap(mOutline[OUTLINE_PRESSED]);
- cellOutline.setState(
- PRESSED_ENABLED_FOCUSED_SELECTED_WINDOW_FOCUSED_STATE_SET);
- cellOutline.draw(canvas);
-
- canvas.setBitmap(mOutline[OUTLINE_SELECTED]);
- cellOutline.setState(ENABLED_FOCUSED_SELECTED_WINDOW_FOCUSED_STATE_SET);
- cellOutline.draw(canvas);
- }
-
- private void moveDataWindow() {
- // Calculate visible region according to scroll position.
- int startRow = (mScrollY - mSpec.mCellSpacing) / mBlockHeight;
- int endRow = (mScrollY + getHeight() - mSpec.mCellSpacing - 1)
- / mBlockHeight + 1;
-
- // Limit startRow and endRow to the valid range.
- // Make sure we handle the mRows == 0 case right.
- startRow = Math.max(Math.min(startRow, mRows - 1), 0);
- endRow = Math.max(Math.min(endRow, mRows), 0);
- mImageBlockManager.setVisibleRows(startRow, endRow);
- }
-
- // In MyGestureDetector we have to check canHandleEvent() because
- // GestureDetector could queue events and fire them later. At that time
- // stop() may have already been called and we can't handle the events.
- private class MyGestureDetector extends SimpleOnGestureListener {
- private AudioManager mAudioManager;
-
- @Override
- public boolean onDown(MotionEvent e) {
- if (!canHandleEvent()) return false;
- if (mScroller != null && !mScroller.isFinished()) {
- mScroller.forceFinished(true);
- return false;
- }
- int index = computeSelectedIndex(e.getX(), e.getY());
- if (index >= 0 && index < mCount) {
- setSelectedIndex(index);
- } else {
- setSelectedIndex(INDEX_NONE);
- }
- return true;
- }
-
- @Override
- public boolean onFling(MotionEvent e1, MotionEvent e2,
- float velocityX, float velocityY) {
- if (!canHandleEvent()) return false;
- if (velocityY > MAX_FLING_VELOCITY) {
- velocityY = MAX_FLING_VELOCITY;
- } else if (velocityY < -MAX_FLING_VELOCITY) {
- velocityY = -MAX_FLING_VELOCITY;
- }
-
- setSelectedIndex(INDEX_NONE);
- mScroller = new Scroller(getContext());
- mScroller.fling(0, mScrollY, 0, -(int) velocityY, 0, 0, 0,
- mMaxScrollY);
- computeScroll();
-
- return true;
- }
-
- @Override
- public void onLongPress(MotionEvent e) {
- if (!canHandleEvent()) return;
- performLongClick();
- }
-
- @Override
- public boolean onScroll(MotionEvent e1, MotionEvent e2,
- float distanceX, float distanceY) {
- if (!canHandleEvent()) return false;
- setSelectedIndex(INDEX_NONE);
- scrollBy(0, (int) distanceY);
- invalidate();
- return true;
- }
-
- @Override
- public boolean onSingleTapConfirmed(MotionEvent e) {
- if (!canHandleEvent()) return false;
- int index = computeSelectedIndex(e.getX(), e.getY());
- if (index >= 0 && index < mCount) {
- // Play click sound.
- if (mAudioManager == null) {
- mAudioManager = (AudioManager) getContext()
- .getSystemService(Context.AUDIO_SERVICE);
- }
- mAudioManager.playSoundEffect(AudioManager.FX_KEY_CLICK);
-
- mListener.onImageTapped(index);
- return true;
- }
- return false;
- }
- }
-
- public int getCurrentSelection() {
- return mCurrentSelection;
- }
-
- public void invalidateImage(int index) {
- if (index != INDEX_NONE) {
- mImageBlockManager.invalidateImage(index);
- }
- }
-
- /**
- *
- * @param index <code>INDEX_NONE</code> (-1) means remove selection.
- */
- public void setSelectedIndex(int index) {
- // A selection box will be shown for the image that being selected,
- // (by finger or by the dpad center key). The selection box can be drawn
- // in two colors. One color (yellow) is used when the the image is
- // still being tapped or clicked (the finger is still on the touch
- // screen or the dpad center key is not released). Another color
- // (orange) is used after the finger leaves touch screen or the dpad
- // center key is released.
-
- if (mCurrentSelection == index) {
- return;
- }
- // This happens when the last picture is deleted.
- mCurrentSelection = Math.min(index, mCount - 1);
-
- if (mCurrentSelection != INDEX_NONE) {
- ensureVisible(mCurrentSelection);
- }
- invalidate();
- }
-
- public void scrollToImage(int index) {
- Rect r = getRectForPosition(index);
- scrollTo(0, r.top);
- }
-
- public void scrollToVisible(int index) {
- Rect r = getRectForPosition(index);
- int top = getScrollY();
- int bottom = getScrollY() + getHeight();
- if (r.bottom > bottom) {
- scrollTo(0, r.bottom - getHeight());
- } else if (r.top < top) {
- scrollTo(0, r.top);
- }
- }
-
- private void ensureVisible(int pos) {
- Rect r = getRectForPosition(pos);
- int top = getScrollY();
- int bot = top + getHeight();
-
- if (r.bottom > bot) {
- mScroller = new Scroller(getContext());
- mScroller.startScroll(mScrollX, mScrollY, 0,
- r.bottom - getHeight() - mScrollY, 200);
- computeScroll();
- } else if (r.top < top) {
- mScroller = new Scroller(getContext());
- mScroller.startScroll(mScrollX, mScrollY, 0, r.top - mScrollY, 200);
- computeScroll();
- }
- }
-
- public void start() {
- // These must be set before start().
- Assert(mLoader != null);
- Assert(mListener != null);
- Assert(mDrawAdapter != null);
- mRunning = true;
- requestLayout();
- }
-
- // If the the underlying data is changed, for example,
- // an image is deleted, or the size choice is changed,
- // The following sequence is needed:
- //
- // mGvs.stop();
- // mGvs.set...(...);
- // mGvs.set...(...);
- // mGvs.start();
- public void stop() {
- // Remove the long press callback from the queue if we are going to
- // stop.
- mHandler.removeCallbacks(mLongPressCallback);
- mScroller = null;
- if (mImageBlockManager != null) {
- mImageBlockManager.recycle();
- mImageBlockManager = null;
- }
- mRunning = false;
- mCurrentSelection = INDEX_NONE;
- }
-
- @Override
- public void onDraw(Canvas canvas) {
- super.onDraw(canvas);
- if (!canHandleEvent()) return;
- mImageBlockManager.doDraw(canvas, getWidth(), getHeight(), mScrollY);
- paintDecoration(canvas);
- paintSelection(canvas);
- moveDataWindow();
- }
-
- @Override
- public void computeScroll() {
- if (mScroller != null) {
- boolean more = mScroller.computeScrollOffset();
- scrollTo(0, mScroller.getCurrY());
- if (more) {
- invalidate(); // So we draw again
- } else {
- mScroller = null;
- }
- } else {
- super.computeScroll();
- }
- }
-
- // Return the rectange for the thumbnail in the given position.
- Rect getRectForPosition(int pos) {
- int row = pos / mColumns;
- int col = pos - (row * mColumns);
-
- int left = mSpec.mLeftEdgePadding
- + (col * (mSpec.mCellWidth + mSpec.mCellSpacing));
- int top = row * mBlockHeight;
-
- return new Rect(left, top,
- left + mSpec.mCellWidth + mSpec.mCellSpacing,
- top + mSpec.mCellHeight + mSpec.mCellSpacing);
- }
-
- // Inverse of getRectForPosition: from screen coordinate to image position.
- int computeSelectedIndex(float xFloat, float yFloat) {
- int x = (int) xFloat;
- int y = (int) yFloat;
-
- int spacing = mSpec.mCellSpacing;
- int leftSpacing = mSpec.mLeftEdgePadding;
-
- int row = (mScrollY + y - spacing) / (mSpec.mCellHeight + spacing);
- int col = Math.min(mColumns - 1,
- (x - leftSpacing) / (mSpec.mCellWidth + spacing));
- return (row * mColumns) + col;
- }
-
- @Override
- public boolean onTouchEvent(MotionEvent ev) {
- if (!canHandleEvent()) {
- return false;
- }
- switch (ev.getAction()) {
- case MotionEvent.ACTION_DOWN:
- mCurrentPressState |= TAPPING_FLAG;
- invalidate();
- break;
- case MotionEvent.ACTION_UP:
- mCurrentPressState &= ~TAPPING_FLAG;
- invalidate();
- break;
- }
- mGestureDetector.onTouchEvent(ev);
- // Consume all events
- return true;
- }
-
- @Override
- public void scrollBy(int x, int y) {
- scrollTo(mScrollX + x, mScrollY + y);
- }
-
- public void scrollTo(float scrollPosition) {
- scrollTo(0, Math.round(scrollPosition * mMaxScrollY));
- }
-
- @Override
- public void scrollTo(int x, int y) {
- y = Math.max(0, Math.min(mMaxScrollY, y));
- if (mSpec != null) {
- mListener.onScroll((float) mScrollY / mMaxScrollY);
- }
- super.scrollTo(x, y);
- }
-
- private boolean canHandleEvent() {
- return mRunning && mLayoutComplete;
- }
-
- private final Runnable mLongPressCallback = new Runnable() {
- public void run() {
- mCurrentPressState &= ~CLICKING_FLAG;
- showContextMenu();
- }
- };
-
- @Override
- public boolean onKeyDown(int keyCode, KeyEvent event) {
- if (!canHandleEvent()) return false;
- int sel = mCurrentSelection;
- if (sel != INDEX_NONE) {
- switch (keyCode) {
- case KeyEvent.KEYCODE_DPAD_RIGHT:
- if (sel != mCount - 1 && (sel % mColumns < mColumns - 1)) {
- sel += 1;
- }
- break;
- case KeyEvent.KEYCODE_DPAD_LEFT:
- if (sel > 0 && (sel % mColumns != 0)) {
- sel -= 1;
- }
- break;
- case KeyEvent.KEYCODE_DPAD_UP:
- if (sel >= mColumns) {
- sel -= mColumns;
- }
- break;
- case KeyEvent.KEYCODE_DPAD_DOWN:
- sel = Math.min(mCount - 1, sel + mColumns);
- break;
- case KeyEvent.KEYCODE_DPAD_CENTER:
- if (event.getRepeatCount() == 0) {
- mCurrentPressState |= CLICKING_FLAG;
- mHandler.postDelayed(mLongPressCallback,
- ViewConfiguration.getLongPressTimeout());
- }
- break;
- default:
- return super.onKeyDown(keyCode, event);
- }
- } else {
- switch (keyCode) {
- case KeyEvent.KEYCODE_DPAD_RIGHT:
- case KeyEvent.KEYCODE_DPAD_LEFT:
- case KeyEvent.KEYCODE_DPAD_UP:
- case KeyEvent.KEYCODE_DPAD_DOWN:
- int startRow =
- (mScrollY - mSpec.mCellSpacing) / mBlockHeight;
- int topPos = startRow * mColumns;
- Rect r = getRectForPosition(topPos);
- if (r.top < getScrollY()) {
- topPos += mColumns;
- }
- topPos = Math.min(mCount - 1, topPos);
- sel = topPos;
- break;
- default:
- return super.onKeyDown(keyCode, event);
- }
- }
- setSelectedIndex(sel);
- return true;
- }
-
- @Override
- public boolean onKeyUp(int keyCode, KeyEvent event) {
- if (!canHandleEvent()) return false;
-
- if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER) {
- mCurrentPressState &= ~CLICKING_FLAG;
- invalidate();
-
- // The keyUp doesn't get called when the longpress menu comes up. We
- // only get here when the user lets go of the center key before the
- // longpress menu comes up.
- mHandler.removeCallbacks(mLongPressCallback);
-
- // open the photo
- mListener.onImageClicked(mCurrentSelection);
- return true;
- }
- return super.onKeyUp(keyCode, event);
- }
-
- private void paintDecoration(Canvas canvas) {
- if (!mDrawAdapter.needsDecoration()) return;
-
- // Calculate visible region according to scroll position.
- int startRow = (mScrollY - mSpec.mCellSpacing) / mBlockHeight;
- int endRow = (mScrollY + getHeight() - mSpec.mCellSpacing - 1)
- / mBlockHeight + 1;
-
- // Limit startRow and endRow to the valid range.
- // Make sure we handle the mRows == 0 case right.
- startRow = Math.max(Math.min(startRow, mRows - 1), 0);
- endRow = Math.max(Math.min(endRow, mRows), 0);
-
- int startIndex = startRow * mColumns;
- int endIndex = Math.min(endRow * mColumns, mCount);
-
- int xPos = mSpec.mLeftEdgePadding;
- int yPos = mSpec.mCellSpacing + startRow * mBlockHeight;
- int off = 0;
- for (int i = startIndex; i < endIndex; i++) {
- IImage image = mAllImages.getImageAt(i);
-
- mDrawAdapter.drawDecoration(canvas, image, xPos, yPos,
- mSpec.mCellWidth, mSpec.mCellHeight);
-
- // Calculate next position
- off += 1;
- if (off == mColumns) {
- xPos = mSpec.mLeftEdgePadding;
- yPos += mBlockHeight;
- off = 0;
- } else {
- xPos += mSpec.mCellWidth + mSpec.mCellSpacing;
- }
- }
- }
-
- private void paintSelection(Canvas canvas) {
- if (mCurrentSelection == INDEX_NONE) return;
-
- int row = mCurrentSelection / mColumns;
- int col = mCurrentSelection - (row * mColumns);
-
- int spacing = mSpec.mCellSpacing;
- int leftSpacing = mSpec.mLeftEdgePadding;
- int xPos = leftSpacing + (col * (mSpec.mCellWidth + spacing));
- int yTop = spacing + (row * mBlockHeight);
-
- int type = OUTLINE_SELECTED;
- if (mCurrentPressState != 0) {
- type = OUTLINE_PRESSED;
- }
- canvas.drawBitmap(mOutline[type], xPos, yTop, null);
- }
-}
-
-class ImageBlockManager {
- @SuppressWarnings("unused")
- private static final String TAG = "ImageBlockManager";
-
- // Number of rows we want to cache.
- // Assume there are 6 rows per page, this caches 5 pages.
- private static final int CACHE_ROWS = 30;
-
- // mCache maps from row number to the ImageBlock.
- private final HashMap<Integer, ImageBlock> mCache;
-
- // These are parameters set in the constructor.
- private final Handler mHandler;
- private final Runnable mRedrawCallback; // Called after a row is loaded,
- // so GridViewSpecial can draw
- // again using the new images.
- private final IImageList mImageList;
- private final ImageLoader mLoader;
- private final GridViewSpecial.DrawAdapter mDrawAdapter;
- private final GridViewSpecial.LayoutSpec mSpec;
- private final int mColumns; // Columns per row.
- private final int mBlockWidth; // The width of an ImageBlock.
- private final Bitmap mOutline; // The outline bitmap put on top of each
- // image.
- private final int mCount; // Cache mImageList.getCount().
- private final int mRows; // Cache (mCount + mColumns - 1) / mColumns
- private final int mBlockHeight; // The height of an ImageBlock.
-
- // Visible row range: [mStartRow, mEndRow). Set by setVisibleRows().
- private int mStartRow = 0;
- private int mEndRow = 0;
-
- ImageBlockManager(Handler handler, Runnable redrawCallback,
- IImageList imageList, ImageLoader loader,
- GridViewSpecial.DrawAdapter adapter,
- GridViewSpecial.LayoutSpec spec,
- int columns, int blockWidth, Bitmap outline) {
- mHandler = handler;
- mRedrawCallback = redrawCallback;
- mImageList = imageList;
- mLoader = loader;
- mDrawAdapter = adapter;
- mSpec = spec;
- mColumns = columns;
- mBlockWidth = blockWidth;
- mOutline = outline;
- mBlockHeight = mSpec.mCellSpacing + mSpec.mCellHeight;
- mCount = imageList.getCount();
- mRows = (mCount + mColumns - 1) / mColumns;
- mCache = new HashMap<Integer, ImageBlock>();
- mPendingRequest = 0;
- initGraphics();
- }
-
- // Set the window of visible rows. Once set we will start to load them as
- // soon as possible (if they are not already in cache).
- public void setVisibleRows(int startRow, int endRow) {
- if (startRow != mStartRow || endRow != mEndRow) {
- mStartRow = startRow;
- mEndRow = endRow;
- startLoading();
- }
- }
-
- int mPendingRequest; // Number of pending requests (sent to ImageLoader).
- // We want to keep enough requests in ImageLoader's queue, but not too
- // many.
- static final int REQUESTS_LOW = 3;
- static final int REQUESTS_HIGH = 6;
-
- // After clear requests currently in queue, start loading the thumbnails.
- // We need to clear the queue first because the proper order of loading
- // may have changed (because the visible region changed, or some images
- // have been invalidated).
- private void startLoading() {
- clearLoaderQueue();
- continueLoading();
- }
-
- private void clearLoaderQueue() {
- int[] tags = mLoader.clearQueue();
- for (int pos : tags) {
- int row = pos / mColumns;
- int col = pos - row * mColumns;
- ImageBlock blk = mCache.get(row);
- Assert(blk != null); // We won't reuse the block if it has pending
- // requests. See getEmptyBlock().
- blk.cancelRequest(col);
- }
- }
-
- // Scan the cache and send requests to ImageLoader if needed.
- private void continueLoading() {
- // Check if we still have enough requests in the queue.
- if (mPendingRequest >= REQUESTS_LOW) return;
-
- // Scan the visible rows.
- for (int i = mStartRow; i < mEndRow; i++) {
- if (scanOne(i)) return;
- }
-
- int range = (CACHE_ROWS - (mEndRow - mStartRow)) / 2;
- // Scan other rows.
- // d is the distance between the row and visible region.
- for (int d = 1; d <= range; d++) {
- int after = mEndRow - 1 + d;
- int before = mStartRow - d;
- if (after >= mRows && before < 0) {
- break; // Nothing more the scan.
- }
- if (after < mRows && scanOne(after)) return;
- if (before >= 0 && scanOne(before)) return;
- }
- }
-
- // Returns true if we can stop scanning.
- private boolean scanOne(int i) {
- mPendingRequest += tryToLoad(i);
- return mPendingRequest >= REQUESTS_HIGH;
- }
-
- // Returns number of requests we issued for this row.
- private int tryToLoad(int row) {
- Assert(row >= 0 && row < mRows);
- ImageBlock blk = mCache.get(row);
- if (blk == null) {
- // Find an empty block
- blk = getEmptyBlock();
- blk.setRow(row);
- blk.invalidate();
- mCache.put(row, blk);
- }
- return blk.loadImages();
- }
-
- // Get an empty block for the cache.
- private ImageBlock getEmptyBlock() {
- // See if we can allocate a new block.
- if (mCache.size() < CACHE_ROWS) {
- return new ImageBlock();
- }
- // Reclaim the old block with largest distance from the visible region.
- int bestDistance = -1;
- int bestIndex = -1;
- for (int index : mCache.keySet()) {
- // Make sure we don't reclaim a block which still has pending
- // request.
- if (mCache.get(index).hasPendingRequests()) {
- continue;
- }
- int dist = 0;
- if (index >= mEndRow) {
- dist = index - mEndRow + 1;
- } else if (index < mStartRow) {
- dist = mStartRow - index;
- } else {
- // Inside the visible region.
- continue;
- }
- if (dist > bestDistance) {
- bestDistance = dist;
- bestIndex = index;
- }
- }
- return mCache.remove(bestIndex);
- }
-
- public void invalidateImage(int index) {
- int row = index / mColumns;
- int col = index - (row * mColumns);
- ImageBlock blk = mCache.get(row);
- if (blk == null) return;
- if ((blk.mCompletedMask & (1 << col)) != 0) {
- blk.mCompletedMask &= ~(1 << col);
- }
- startLoading();
- }
-
- // After calling recycle(), the instance should not be used anymore.
- public void recycle() {
- for (ImageBlock blk : mCache.values()) {
- blk.recycle();
- }
- mCache.clear();
- mEmptyBitmap.recycle();
- }
-
- // Draw the images to the given canvas.
- public void doDraw(Canvas canvas, int thisWidth, int thisHeight,
- int scrollPos) {
- final int height = mBlockHeight;
-
- // Note that currentBlock could be negative.
- int currentBlock = (scrollPos < 0)
- ? ((scrollPos - height + 1) / height)
- : (scrollPos / height);
-
- while (true) {
- final int yPos = currentBlock * height;
- if (yPos >= scrollPos + thisHeight) {
- break;
- }
-
- ImageBlock blk = mCache.get(currentBlock);
- if (blk != null) {
- blk.doDraw(canvas, 0, yPos);
- } else {
- drawEmptyBlock(canvas, 0, yPos, currentBlock);
- }
-
- currentBlock += 1;
- }
- }
-
- // Return number of columns in the given row. (This could be less than
- // mColumns for the last row).
- private int numColumns(int row) {
- return Math.min(mColumns, mCount - row * mColumns);
- }
-
- // Draw a block which has not been loaded.
- private void drawEmptyBlock(Canvas canvas, int xPos, int yPos, int row) {
- // Draw the background.
- canvas.drawRect(xPos, yPos, xPos + mBlockWidth, yPos + mBlockHeight,
- mBackgroundPaint);
-
- // Draw the empty images.
- int x = xPos + mSpec.mLeftEdgePadding;
- int y = yPos + mSpec.mCellSpacing;
- int cols = numColumns(row);
-
- for (int i = 0; i < cols; i++) {
- canvas.drawBitmap(mEmptyBitmap, x, y, null);
- x += (mSpec.mCellWidth + mSpec.mCellSpacing);
- }
- }
-
- // mEmptyBitmap is what we draw if we the wanted block hasn't been loaded.
- // (If the user scrolls too fast). It is a gray image with normal outline.
- // mBackgroundPaint is used to draw the (black) background outside
- // mEmptyBitmap.
- Paint mBackgroundPaint;
- private Bitmap mEmptyBitmap;
-
- private void initGraphics() {
- mBackgroundPaint = new Paint();
- mBackgroundPaint.setStyle(Paint.Style.FILL);
- mBackgroundPaint.setColor(0xFF000000); // black
- mEmptyBitmap = Bitmap.createBitmap(mSpec.mCellWidth, mSpec.mCellHeight,
- Bitmap.Config.RGB_565);
- Canvas canvas = new Canvas(mEmptyBitmap);
- canvas.drawRGB(0xDD, 0xDD, 0xDD);
- canvas.drawBitmap(mOutline, 0, 0, null);
- }
-
- // ImageBlock stores bitmap for one row. The loaded thumbnail images are
- // drawn to mBitmap. mBitmap is later used in onDraw() of GridViewSpecial.
- private class ImageBlock {
- private Bitmap mBitmap;
- private final Canvas mCanvas;
-
- // Columns which have been requested to the loader
- private int mRequestedMask;
-
- // Columns which have been completed from the loader
- private int mCompletedMask;
-
- // The row number this block represents.
- private int mRow;
-
- public ImageBlock() {
- mBitmap = Bitmap.createBitmap(mBlockWidth, mBlockHeight,
- Bitmap.Config.RGB_565);
- mCanvas = new Canvas(mBitmap);
- mRow = -1;
- }
-
- public void setRow(int row) {
- mRow = row;
- }
-
- public void invalidate() {
- // We do not change mRequestedMask or do cancelAllRequests()
- // because the data coming from pending requests are valid. (We only
- // invalidate data which has been drawn to the bitmap).
- mCompletedMask = 0;
- }
-
- // After recycle, the ImageBlock instance should not be accessed.
- public void recycle() {
- cancelAllRequests();
- mBitmap.recycle();
- mBitmap = null;
- }
-
- private boolean isVisible() {
- return mRow >= mStartRow && mRow < mEndRow;
- }
-
- // Returns number of requests submitted to ImageLoader.
- public int loadImages() {
- Assert(mRow != -1);
-
- int columns = numColumns(mRow);
-
- // Calculate what we need.
- int needMask = ((1 << columns) - 1)
- & ~(mCompletedMask | mRequestedMask);
-
- if (needMask == 0) {
- return 0;
- }
-
- int retVal = 0;
- int base = mRow * mColumns;
-
- for (int col = 0; col < columns; col++) {
- if ((needMask & (1 << col)) == 0) {
- continue;
- }
-
- int pos = base + col;
-
- final IImage image = mImageList.getImageAt(pos);
- if (image != null) {
- // This callback is passed to ImageLoader. It will invoke
- // loadImageDone() in the main thread. We limit the callback
- // thread to be in this very short function. All other
- // processing is done in the main thread.
- final int colFinal = col;
- ImageLoader.LoadedCallback cb =
- new ImageLoader.LoadedCallback() {
- public void run(final Bitmap b) {
- mHandler.post(new Runnable() {
- public void run() {
- loadImageDone(image, b,
- colFinal);
- }
- });
- }
- };
- // Load Image
- mLoader.getBitmap(image, cb, pos);
- mRequestedMask |= (1 << col);
- retVal += 1;
- }
- }
-
- return retVal;
- }
-
- // Whether this block has pending requests.
- public boolean hasPendingRequests() {
- return mRequestedMask != 0;
- }
-
- // Called when an image is loaded.
- private void loadImageDone(IImage image, Bitmap b,
- int col) {
- if (mBitmap == null) return; // This block has been recycled.
-
- int spacing = mSpec.mCellSpacing;
- int leftSpacing = mSpec.mLeftEdgePadding;
- final int yPos = spacing;
- final int xPos = leftSpacing
- + (col * (mSpec.mCellWidth + spacing));
-
- drawBitmap(image, b, xPos, yPos);
-
- if (b != null) {
- b.recycle();
- }
-
- int mask = (1 << col);
- Assert((mCompletedMask & mask) == 0);
- Assert((mRequestedMask & mask) != 0);
- mRequestedMask &= ~mask;
- mCompletedMask |= mask;
- mPendingRequest--;
-
- if (isVisible()) {
- mRedrawCallback.run();
- }
-
- // Kick start next block loading.
- continueLoading();
- }
-
- // Draw the loaded bitmap to the block bitmap.
- private void drawBitmap(
- IImage image, Bitmap b, int xPos, int yPos) {
- mDrawAdapter.drawImage(mCanvas, image, b, xPos, yPos,
- mSpec.mCellWidth, mSpec.mCellHeight);
- mCanvas.drawBitmap(mOutline, xPos, yPos, null);
- }
-
- // Draw the block bitmap to the specified canvas.
- public void doDraw(Canvas canvas, int xPos, int yPos) {
- int cols = numColumns(mRow);
-
- if (cols == mColumns) {
- canvas.drawBitmap(mBitmap, xPos, yPos, null);
- } else {
-
- // This must be the last row -- we draw only part of the block.
- // Draw the background.
- canvas.drawRect(xPos, yPos, xPos + mBlockWidth,
- yPos + mBlockHeight, mBackgroundPaint);
- // Draw part of the block.
- int w = mSpec.mLeftEdgePadding
- + cols * (mSpec.mCellWidth + mSpec.mCellSpacing);
- Rect srcRect = new Rect(0, 0, w, mBlockHeight);
- Rect dstRect = new Rect(srcRect);
- dstRect.offset(xPos, yPos);
- canvas.drawBitmap(mBitmap, srcRect, dstRect, null);
- }
-
- // Draw the part which has not been loaded.
- int isEmpty = ((1 << cols) - 1) & ~mCompletedMask;
-
- if (isEmpty != 0) {
- int x = xPos + mSpec.mLeftEdgePadding;
- int y = yPos + mSpec.mCellSpacing;
-
- for (int i = 0; i < cols; i++) {
- if ((isEmpty & (1 << i)) != 0) {
- canvas.drawBitmap(mEmptyBitmap, x, y, null);
- }
- x += (mSpec.mCellWidth + mSpec.mCellSpacing);
- }
- }
- }
-
- // Mark a request as cancelled. The request has already been removed
- // from the queue of ImageLoader, so we only need to mark the fact.
- public void cancelRequest(int col) {
- int mask = (1 << col);
- Assert((mRequestedMask & mask) != 0);
- mRequestedMask &= ~mask;
- mPendingRequest--;
- }
-
- // Try to cancel all pending requests for this block. After this
- // completes there could still be requests not cancelled (because it is
- // already in progress). We deal with that situation by setting mBitmap
- // to null in recycle() and check this in loadImageDone().
- private void cancelAllRequests() {
- for (int i = 0; i < mColumns; i++) {
- int mask = (1 << i);
- if ((mRequestedMask & mask) != 0) {
- int pos = (mRow * mColumns) + i;
- if (mLoader.cancel(mImageList.getImageAt(pos))) {
- mRequestedMask &= ~mask;
- mPendingRequest--;
- }
- }
- }
- }
- }
-}
diff --git a/src/com/android/camera/ImageGallery.java b/src/com/android/camera/ImageGallery.java
deleted file mode 100644
index 068ac114..00000000
--- a/src/com/android/camera/ImageGallery.java
+++ /dev/null
@@ -1,1020 +0,0 @@
-/*
- * Copyright (C) 2007 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.camera;
-
-import android.app.Activity;
-import android.app.AlertDialog;
-import android.app.Dialog;
-import android.app.ProgressDialog;
-import android.content.ActivityNotFoundException;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.SharedPreferences;
-import android.content.pm.ActivityInfo;
-import android.content.res.Configuration;
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
-import android.graphics.Canvas;
-import android.graphics.Paint;
-import android.graphics.Rect;
-import android.graphics.drawable.Drawable;
-import android.net.Uri;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.Parcelable;
-import android.preference.PreferenceManager;
-import android.provider.MediaStore;
-import android.util.Log;
-import android.view.ContextMenu;
-import android.view.KeyEvent;
-import android.view.Menu;
-import android.view.MenuItem;
-import android.view.View;
-import android.view.Window;
-import android.view.View.OnClickListener;
-import android.view.animation.Animation;
-import android.view.animation.AnimationUtils;
-import android.widget.Button;
-import android.widget.TextView;
-import android.widget.Toast;
-
-import com.android.camera.gallery.IImage;
-import com.android.camera.gallery.IImageList;
-import com.android.camera.gallery.VideoObject;
-
-import java.util.ArrayList;
-import java.util.HashSet;
-
-public class ImageGallery extends NoSearchActivity implements
- GridViewSpecial.Listener, GridViewSpecial.DrawAdapter {
- private static final String STATE_SCROLL_POSITION = "scroll_position";
- private static final String STATE_SELECTED_INDEX = "first_index";
-
- private static final String TAG = "ImageGallery";
- private static final float INVALID_POSITION = -1f;
- private ImageManager.ImageListParam mParam;
- private IImageList mAllImages;
- private int mInclusion;
- boolean mSortAscending = false;
- private View mNoImagesView;
- public static final int CROP_MSG = 2;
-
- private Dialog mMediaScanningDialog;
- private MenuItem mSlideShowItem;
- private SharedPreferences mPrefs;
- private long mVideoSizeLimit = Long.MAX_VALUE;
- private View mFooterOrganizeView;
-
- private BroadcastReceiver mReceiver = null;
-
- private final Handler mHandler = new Handler();
- private boolean mLayoutComplete;
- private boolean mPausing = true;
- private ImageLoader mLoader;
- private GridViewSpecial mGvs;
-
- private Uri mCropResultUri;
-
- // The index of the first picture in GridViewSpecial.
- private int mSelectedIndex = GridViewSpecial.INDEX_NONE;
- private float mScrollPosition = INVALID_POSITION;
- private boolean mConfigurationChanged = false;
-
- private HashSet<IImage> mMultiSelected = null;
-
- @Override
- public void onCreate(Bundle icicle) {
- super.onCreate(icicle);
-
- mPrefs = PreferenceManager.getDefaultSharedPreferences(this);
-
- // Must be called before setContentView().
- requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);
-
- setContentView(R.layout.image_gallery);
-
- getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE,
- R.layout.custom_gallery_title);
-
- mNoImagesView = findViewById(R.id.no_images);
-
- mGvs = (GridViewSpecial) findViewById(R.id.grid);
- mGvs.setListener(this);
-
- mFooterOrganizeView = findViewById(R.id.footer_organize);
-
- // consume all click events on the footer view
- mFooterOrganizeView.setOnClickListener(Util.getNullOnClickListener());
- initializeFooterButtons();
-
- if (isPickIntent()) {
- mVideoSizeLimit = getIntent().getLongExtra(
- MediaStore.EXTRA_SIZE_LIMIT, Long.MAX_VALUE);
- } else {
- mVideoSizeLimit = Long.MAX_VALUE;
- mGvs.setOnCreateContextMenuListener(
- new CreateContextMenuListener());
- }
-
- setupInclusion();
-
- mLoader = new ImageLoader(getContentResolver(), mHandler);
- }
-
- private void initializeFooterButtons() {
- Button deleteButton = (Button) findViewById(R.id.button_delete);
- deleteButton.setOnClickListener(new OnClickListener() {
- public void onClick(View v) {
- onDeleteMultipleClicked();
- }
- });
-
- Button shareButton = (Button) findViewById(R.id.button_share);
- shareButton.setOnClickListener(new OnClickListener() {
- public void onClick(View v) {
- onShareMultipleClicked();
- }
- });
-
- Button closeButton = (Button) findViewById(R.id.button_close);
- closeButton.setOnClickListener(new OnClickListener() {
- public void onClick(View v) {
- closeMultiSelectMode();
- }
- });
- }
-
- private MenuItem addSlideShowMenu(Menu menu) {
- return menu.add(Menu.NONE, Menu.NONE, MenuHelper.POSITION_SLIDESHOW,
- R.string.slide_show)
- .setOnMenuItemClickListener(
- new MenuItem.OnMenuItemClickListener() {
- public boolean onMenuItemClick(MenuItem item) {
- return onSlideShowClicked();
- }
- }).setIcon(android.R.drawable.ic_menu_slideshow);
- }
-
- public boolean onSlideShowClicked() {
- if (!canHandleEvent()) {
- return false;
- }
- IImage img = getCurrentImage();
- if (img == null) {
- img = mAllImages.getImageAt(0);
- if (img == null) {
- return true;
- }
- }
- Uri targetUri = img.fullSizeImageUri();
- Uri thisUri = getIntent().getData();
- if (thisUri != null) {
- String bucket = thisUri.getQueryParameter("bucketId");
- if (bucket != null) {
- targetUri = targetUri.buildUpon()
- .appendQueryParameter("bucketId", bucket)
- .build();
- }
- }
- Intent intent = new Intent(Intent.ACTION_VIEW, targetUri);
- intent.putExtra("slideshow", true);
- startActivity(intent);
- return true;
- }
-
- private final Runnable mDeletePhotoRunnable = new Runnable() {
- public void run() {
- if (!canHandleEvent()) return;
-
- IImage currentImage = getCurrentImage();
-
- // The selection will be cleared when mGvs.stop() is called, so
- // we need to call getCurrentImage() before mGvs.stop().
- mGvs.stop();
-
- if (currentImage != null) {
- mAllImages.removeImage(currentImage);
- }
- mGvs.setImageList(mAllImages);
- mGvs.start();
-
- mNoImagesView.setVisibility(mAllImages.isEmpty()
- ? View.VISIBLE
- : View.GONE);
- }
- };
-
- private Uri getCurrentImageUri() {
- IImage image = getCurrentImage();
- if (image != null) {
- return image.fullSizeImageUri();
- } else {
- return null;
- }
- }
-
- private IImage getCurrentImage() {
- int currentSelection = mGvs.getCurrentSelection();
- if (currentSelection < 0
- || currentSelection >= mAllImages.getCount()) {
- return null;
- } else {
- return mAllImages.getImageAt(currentSelection);
- }
- }
-
- @Override
- public void onConfigurationChanged(Configuration newConfig) {
- super.onConfigurationChanged(newConfig);
- mConfigurationChanged = true;
- }
-
- boolean canHandleEvent() {
- // Don't process event in pause state.
- return (!mPausing) && (mLayoutComplete);
- }
-
- @Override
- public boolean onKeyDown(int keyCode, KeyEvent event) {
- if (!canHandleEvent()) return false;
- switch (keyCode) {
- case KeyEvent.KEYCODE_DEL:
- IImage image = getCurrentImage();
- if (image != null) {
- MenuHelper.deleteImage(
- this, mDeletePhotoRunnable, getCurrentImage());
- }
- return true;
- }
- return super.onKeyDown(keyCode, event);
- }
-
- private boolean isPickIntent() {
- String action = getIntent().getAction();
- return (Intent.ACTION_PICK.equals(action)
- || Intent.ACTION_GET_CONTENT.equals(action));
- }
-
- private void launchCropperOrFinish(IImage img) {
- Bundle myExtras = getIntent().getExtras();
-
- long size = MenuHelper.getImageFileSize(img);
- if (size < 0) {
- // Return if the image file is not available.
- return;
- }
-
- if (size > mVideoSizeLimit) {
- DialogInterface.OnClickListener buttonListener =
- new DialogInterface.OnClickListener() {
- public void onClick(DialogInterface dialog, int which) {
- dialog.dismiss();
- }
- };
- new AlertDialog.Builder(this)
- .setIcon(android.R.drawable.ic_dialog_info)
- .setTitle(R.string.file_info_title)
- .setMessage(R.string.video_exceed_mms_limit)
- .setNeutralButton(R.string.details_ok, buttonListener)
- .show();
- return;
- }
-
- String cropValue = myExtras != null ? myExtras.getString("crop") : null;
- if (cropValue != null) {
- Bundle newExtras = new Bundle();
- if (cropValue.equals("circle")) {
- newExtras.putString("circleCrop", "true");
- }
-
- Intent cropIntent = new Intent();
- cropIntent.setData(img.fullSizeImageUri());
- cropIntent.setClass(this, CropImage.class);
- cropIntent.putExtras(newExtras);
-
- /* pass through any extras that were passed in */
- cropIntent.putExtras(myExtras);
- startActivityForResult(cropIntent, CROP_MSG);
- } else {
- Intent result = new Intent(null, img.fullSizeImageUri());
- if (myExtras != null && myExtras.getBoolean("return-data")) {
- // The size of a transaction should be below 100K.
- Bitmap bitmap = img.fullSizeBitmap(
- IImage.UNCONSTRAINED, 100 * 1024);
- if (bitmap != null) {
- result.putExtra("data", bitmap);
- }
- }
- setResult(RESULT_OK, result);
- finish();
- }
- }
-
- @Override
- protected void onActivityResult(int requestCode, int resultCode,
- Intent data) {
- switch (requestCode) {
- case MenuHelper.RESULT_COMMON_MENU_CROP: {
- if (resultCode == RESULT_OK) {
-
- // The CropImage activity passes back the Uri of the cropped
- // image as the Action rather than the Data.
- // We store this URI so we can move the selection box to it
- // later.
- mCropResultUri = Uri.parse(data.getAction());
- }
- break;
- }
- case CROP_MSG: {
- if (resultCode == RESULT_OK) {
- setResult(resultCode, data);
- finish();
- }
- break;
- }
- }
- }
-
- @Override
- public void onPause() {
- super.onPause();
- mPausing = true;
-
- mLoader.stop();
-
- mGvs.stop();
-
- if (mReceiver != null) {
- unregisterReceiver(mReceiver);
- mReceiver = null;
- }
-
- // Now that we've paused the threads that are using the cursor it is
- // safe to close it.
- mAllImages.close();
- mAllImages = null;
- }
-
- private void rebake(boolean unmounted, boolean scanning) {
- mGvs.stop();
- if (mAllImages != null) {
- mAllImages.close();
- mAllImages = null;
- }
-
- if (mMediaScanningDialog != null) {
- mMediaScanningDialog.cancel();
- mMediaScanningDialog = null;
- }
-
- if (scanning) {
- mMediaScanningDialog = ProgressDialog.show(
- this,
- null,
- getResources().getString(R.string.wait),
- true,
- true);
- }
-
- mParam = allImages(!unmounted && !scanning);
- mAllImages = ImageManager.makeImageList(getContentResolver(), mParam);
-
- mGvs.setImageList(mAllImages);
- mGvs.setDrawAdapter(this);
- mGvs.setLoader(mLoader);
- mGvs.start();
- mNoImagesView.setVisibility(mAllImages.getCount() > 0
- ? View.GONE
- : View.VISIBLE);
- }
-
- @Override
- protected void onSaveInstanceState(Bundle state) {
- super.onSaveInstanceState(state);
- state.putFloat(STATE_SCROLL_POSITION, mScrollPosition);
- state.putInt(STATE_SELECTED_INDEX, mSelectedIndex);
- }
-
- @Override
- protected void onRestoreInstanceState(Bundle state) {
- super.onRestoreInstanceState(state);
- mScrollPosition = state.getFloat(
- STATE_SCROLL_POSITION, INVALID_POSITION);
- mSelectedIndex = state.getInt(STATE_SELECTED_INDEX, 0);
- }
-
- @Override
- public void onResume() {
- super.onResume();
-
- mGvs.setSizeChoice(Integer.parseInt(
- mPrefs.getString("pref_gallery_size_key", "1")));
- mGvs.requestFocus();
-
- String sortOrder = mPrefs.getString("pref_gallery_sort_key", null);
- if (sortOrder != null) {
- mSortAscending = sortOrder.equals("ascending");
- }
-
- mPausing = false;
-
- // install an intent filter to receive SD card related events.
- IntentFilter intentFilter =
- new IntentFilter(Intent.ACTION_MEDIA_MOUNTED);
- intentFilter.addAction(Intent.ACTION_MEDIA_UNMOUNTED);
- intentFilter.addAction(Intent.ACTION_MEDIA_SCANNER_STARTED);
- intentFilter.addAction(Intent.ACTION_MEDIA_SCANNER_FINISHED);
- intentFilter.addAction(Intent.ACTION_MEDIA_EJECT);
- intentFilter.addDataScheme("file");
-
- mReceiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- String action = intent.getAction();
- if (action.equals(Intent.ACTION_MEDIA_MOUNTED)) {
- // SD card available
- // TODO put up a "please wait" message
- // TODO also listen for the media scanner finished message
- } else if (action.equals(Intent.ACTION_MEDIA_UNMOUNTED)) {
- // SD card unavailable
- rebake(true, false);
- } else if (action.equals(Intent.ACTION_MEDIA_SCANNER_STARTED)) {
- rebake(false, true);
- } else if (action.equals(
- Intent.ACTION_MEDIA_SCANNER_FINISHED)) {
- rebake(false, false);
- } else if (action.equals(Intent.ACTION_MEDIA_EJECT)) {
- rebake(true, false);
- }
- }
- };
- registerReceiver(mReceiver, intentFilter);
- rebake(false, ImageManager.isMediaScannerScanning(
- getContentResolver()));
- }
-
- @Override
- public boolean onCreateOptionsMenu(Menu menu) {
- if (isPickIntent()) {
- String type = getIntent().resolveType(this);
- if (type != null) {
- if (isImageType(type)) {
- MenuHelper.addCapturePictureMenuItems(menu, this);
- } else if (isVideoType(type)) {
- MenuHelper.addCaptureVideoMenuItems(menu, this);
- }
- }
- } else {
- MenuHelper.addCaptureMenuItems(menu, this);
- if ((mInclusion & ImageManager.INCLUDE_IMAGES) != 0) {
- mSlideShowItem = addSlideShowMenu(menu);
- }
-
- MenuItem item = menu.add(Menu.NONE, Menu.NONE,
- MenuHelper.POSITION_GALLERY_SETTING,
- R.string.camerasettings);
- item.setOnMenuItemClickListener(
- new MenuItem.OnMenuItemClickListener() {
- public boolean onMenuItemClick(MenuItem item) {
- Intent preferences = new Intent();
- preferences.setClass(ImageGallery.this,
- GallerySettings.class);
- startActivity(preferences);
- return true;
- }
- });
- item.setAlphabeticShortcut('p');
- item.setIcon(android.R.drawable.ic_menu_preferences);
-
- item = menu.add(Menu.NONE, Menu.NONE,
- MenuHelper.POSITION_MULTISELECT,
- R.string.multiselect);
- item.setOnMenuItemClickListener(
- new MenuItem.OnMenuItemClickListener() {
- public boolean onMenuItemClick(MenuItem item) {
- if (isInMultiSelectMode()) {
- closeMultiSelectMode();
- } else {
- openMultiSelectMode();
- }
- return true;
- }
- });
- item.setIcon(R.drawable.ic_menu_multiselect_gallery);
- }
- return true;
- }
-
- @Override
- public boolean onPrepareOptionsMenu(Menu menu) {
- if (!canHandleEvent()) return false;
- if ((mInclusion & ImageManager.INCLUDE_IMAGES) != 0) {
- boolean videoSelected = isVideoSelected();
- // TODO: Only enable slide show if there is at least one image in
- // the folder.
- if (mSlideShowItem != null) {
- mSlideShowItem.setEnabled(!videoSelected);
- }
- }
-
- return true;
- }
-
- private boolean isVideoSelected() {
- IImage image = getCurrentImage();
- return (image != null) && ImageManager.isVideo(image);
- }
-
- private boolean isImageType(String type) {
- return type.equals("vnd.android.cursor.dir/image")
- || type.equals("image/*");
- }
-
- private boolean isVideoType(String type) {
- return type.equals("vnd.android.cursor.dir/video")
- || type.equals("video/*");
- }
-
- // According to the intent, setup what we include (image/video) in the
- // gallery and the title of the gallery.
- private void setupInclusion() {
- mInclusion = ImageManager.INCLUDE_IMAGES | ImageManager.INCLUDE_VIDEOS;
-
- Intent intent = getIntent();
- if (intent != null) {
- String type = intent.resolveType(this);
- TextView leftText = (TextView) findViewById(R.id.left_text);
- if (type != null) {
- if (isImageType(type)) {
- mInclusion = ImageManager.INCLUDE_IMAGES;
- if (isPickIntent()) {
- leftText.setText(R.string.pick_photos_gallery_title);
- } else {
- leftText.setText(R.string.photos_gallery_title);
- }
- }
- if (isVideoType(type)) {
- mInclusion = ImageManager.INCLUDE_VIDEOS;
- if (isPickIntent()) {
- leftText.setText(R.string.pick_videos_gallery_title);
- } else {
- leftText.setText(R.string.videos_gallery_title);
- }
- }
- }
- Bundle extras = intent.getExtras();
- String title = (extras != null)
- ? extras.getString("windowTitle")
- : null;
- if (title != null && title.length() > 0) {
- leftText.setText(title);
- }
-
- if (extras != null) {
- mInclusion = (ImageManager.INCLUDE_IMAGES
- | ImageManager.INCLUDE_VIDEOS)
- & extras.getInt("mediaTypes", mInclusion);
- }
-
- if (extras != null && extras.getBoolean("pick-drm")) {
- Log.d(TAG, "pick-drm is true");
- mInclusion = ImageManager.INCLUDE_DRM_IMAGES;
- }
- }
- }
-
- // Returns the image list parameter which contains the subset of image/video
- // we want.
- private ImageManager.ImageListParam allImages(boolean storageAvailable) {
- if (!storageAvailable) {
- return ImageManager.getEmptyImageListParam();
- } else {
- Uri uri = getIntent().getData();
- return ImageManager.getImageListParam(
- ImageManager.DataLocation.EXTERNAL,
- mInclusion,
- mSortAscending
- ? ImageManager.SORT_ASCENDING
- : ImageManager.SORT_DESCENDING,
- (uri != null)
- ? uri.getQueryParameter("bucketId")
- : null);
- }
- }
-
- private void toggleMultiSelected(IImage image) {
- int original = mMultiSelected.size();
- if (!mMultiSelected.add(image)) {
- mMultiSelected.remove(image);
- }
- mGvs.invalidate();
- if (original == 0) showFooter();
- if (mMultiSelected.size() == 0) hideFooter();
- }
-
- public void onImageClicked(int index) {
- if (index < 0 || index >= mAllImages.getCount()) {
- return;
- }
- mSelectedIndex = index;
- mGvs.setSelectedIndex(index);
-
- IImage image = mAllImages.getImageAt(index);
-
- if (isInMultiSelectMode()) {
- toggleMultiSelected(image);
- return;
- }
-
- if (isPickIntent()) {
- launchCropperOrFinish(image);
- } else {
- Intent intent;
- if (image instanceof VideoObject) {
- intent = new Intent(
- Intent.ACTION_VIEW, image.fullSizeImageUri());
- intent.putExtra(MediaStore.EXTRA_SCREEN_ORIENTATION,
- ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
- } else {
- intent = new Intent(this, ViewImage.class);
- intent.putExtra(ViewImage.KEY_IMAGE_LIST, mParam);
- intent.setData(image.fullSizeImageUri());
- }
- startActivity(intent);
- }
- }
-
- public void onImageTapped(int index) {
- // In the multiselect mode, once the finger finishes tapping, we hide
- // the selection box by setting the selected index to none. However, if
- // we use the dpad center key, we will keep the selected index in order
- // to show the the selection box. We do this because we have the
- // multiselect marker on the images to indicate which of them are
- // selected, so we don't need the selection box, but in the dpad case
- // we still need the selection box to show as a "cursor".
-
- if (isInMultiSelectMode()) {
- mGvs.setSelectedIndex(GridViewSpecial.INDEX_NONE);
- toggleMultiSelected(mAllImages.getImageAt(index));
- } else {
- onImageClicked(index);
- }
- }
-
- private class CreateContextMenuListener implements
- View.OnCreateContextMenuListener {
- public void onCreateContextMenu(ContextMenu menu, View v,
- ContextMenu.ContextMenuInfo menuInfo) {
- if (!canHandleEvent()) return;
-
- IImage image = getCurrentImage();
-
- if (image == null) {
- return;
- }
-
- boolean isImage = ImageManager.isImage(image);
- if (isImage) {
- menu.add(R.string.view)
- .setOnMenuItemClickListener(
- new MenuItem.OnMenuItemClickListener() {
- public boolean onMenuItemClick(MenuItem item) {
- if (!canHandleEvent()) return false;
- onImageClicked(mGvs.getCurrentSelection());
- return true;
- }
- });
- }
-
- menu.setHeaderTitle(isImage
- ? R.string.context_menu_header
- : R.string.video_context_menu_header);
- if ((mInclusion & (ImageManager.INCLUDE_IMAGES
- | ImageManager.INCLUDE_VIDEOS)) != 0) {
- MenuHelper.MenuItemsResult r = MenuHelper.addImageMenuItems(
- menu,
- MenuHelper.INCLUDE_ALL,
- ImageGallery.this,
- mHandler,
- mDeletePhotoRunnable,
- new MenuHelper.MenuInvoker() {
- public void run(MenuHelper.MenuCallback cb) {
- if (!canHandleEvent()) {
- return;
- }
- cb.run(getCurrentImageUri(), getCurrentImage());
- mGvs.invalidateImage(mGvs.getCurrentSelection());
- }
- });
-
- if (r != null) {
- r.gettingReadyToOpen(menu, image);
- }
-
- if (isImage) {
- MenuHelper.enableShowOnMapMenuItem(
- menu, MenuHelper.hasLatLngData(image));
- addSlideShowMenu(menu);
- }
- }
- }
- }
-
- public void onLayoutComplete(boolean changed) {
- mLayoutComplete = true;
- if (mCropResultUri != null) {
- IImage image = mAllImages.getImageForUri(mCropResultUri);
- mCropResultUri = null;
- if (image != null) {
- mSelectedIndex = mAllImages.getImageIndex(image);
- }
- }
- mGvs.setSelectedIndex(mSelectedIndex);
- if (mScrollPosition == INVALID_POSITION) {
- if (mSortAscending) {
- mGvs.scrollTo(0, mGvs.getHeight());
- } else {
- mGvs.scrollToImage(0);
- }
- } else if (mConfigurationChanged) {
- mConfigurationChanged = false;
- mGvs.scrollTo(mScrollPosition);
- if (mGvs.getCurrentSelection() != GridViewSpecial.INDEX_NONE) {
- mGvs.scrollToVisible(mSelectedIndex);
- }
- } else {
- mGvs.scrollTo(mScrollPosition);
- }
- }
-
- public void onScroll(float scrollPosition) {
- mScrollPosition = scrollPosition;
- }
-
- private Drawable mVideoOverlay;
- private Drawable mVideoMmsErrorOverlay;
- private Drawable mMultiSelectTrue;
- private Drawable mMultiSelectFalse;
-
- // mSrcRect and mDstRect are only used in drawImage, but we put them as
- // instance variables to reduce the memory allocation overhead because
- // drawImage() is called a lot.
- private final Rect mSrcRect = new Rect();
- private final Rect mDstRect = new Rect();
-
- private final Paint mPaint = new Paint(Paint.FILTER_BITMAP_FLAG);
-
- public void drawImage(Canvas canvas, IImage image,
- Bitmap b, int xPos, int yPos, int w, int h) {
- if (b != null) {
- // if the image is close to the target size then crop,
- // otherwise scale both the bitmap and the view should be
- // square but I suppose that could change in the future.
-
- int bw = b.getWidth();
- int bh = b.getHeight();
-
- int deltaW = bw - w;
- int deltaH = bh - h;
-
- if (deltaW >= 0 && deltaW < 10 &&
- deltaH >= 0 && deltaH < 10) {
- int halfDeltaW = deltaW / 2;
- int halfDeltaH = deltaH / 2;
- mSrcRect.set(0 + halfDeltaW, 0 + halfDeltaH,
- bw - halfDeltaW, bh - halfDeltaH);
- mDstRect.set(xPos, yPos, xPos + w, yPos + h);
- canvas.drawBitmap(b, mSrcRect, mDstRect, null);
- } else {
- mSrcRect.set(0, 0, bw, bh);
- mDstRect.set(xPos, yPos, xPos + w, yPos + h);
- canvas.drawBitmap(b, mSrcRect, mDstRect, mPaint);
- }
- } else {
- // If the thumbnail cannot be drawn, put up an error icon
- // instead
- Bitmap error = getErrorBitmap(image);
- int width = error.getWidth();
- int height = error.getHeight();
- mSrcRect.set(0, 0, width, height);
- int left = (w - width) / 2 + xPos;
- int top = (w - height) / 2 + yPos;
- mDstRect.set(left, top, left + width, top + height);
- canvas.drawBitmap(error, mSrcRect, mDstRect, null);
- }
-
- if (ImageManager.isVideo(image)) {
- Drawable overlay = null;
- long size = MenuHelper.getImageFileSize(image);
- if (size >= 0 && size <= mVideoSizeLimit) {
- if (mVideoOverlay == null) {
- mVideoOverlay = getResources().getDrawable(
- R.drawable.ic_gallery_video_overlay);
- }
- overlay = mVideoOverlay;
- } else {
- if (mVideoMmsErrorOverlay == null) {
- mVideoMmsErrorOverlay = getResources().getDrawable(
- R.drawable.ic_error_mms_video_overlay);
- }
- overlay = mVideoMmsErrorOverlay;
- Paint paint = new Paint();
- paint.setARGB(0x80, 0x00, 0x00, 0x00);
- canvas.drawRect(xPos, yPos, xPos + w, yPos + h, paint);
- }
- int width = overlay.getIntrinsicWidth();
- int height = overlay.getIntrinsicHeight();
- int left = (w - width) / 2 + xPos;
- int top = (h - height) / 2 + yPos;
- mSrcRect.set(left, top, left + width, top + height);
- overlay.setBounds(mSrcRect);
- overlay.draw(canvas);
- }
- }
-
- public boolean needsDecoration() {
- return (mMultiSelected != null);
- }
-
- public void drawDecoration(Canvas canvas, IImage image,
- int xPos, int yPos, int w, int h) {
- if (mMultiSelected != null) {
- initializeMultiSelectDrawables();
-
- Drawable checkBox = mMultiSelected.contains(image)
- ? mMultiSelectTrue
- : mMultiSelectFalse;
- int width = checkBox.getIntrinsicWidth();
- int height = checkBox.getIntrinsicHeight();
- int left = 5 + xPos;
- int top = h - height - 5 + yPos;
- mSrcRect.set(left, top, left + width, top + height);
- checkBox.setBounds(mSrcRect);
- checkBox.draw(canvas);
- }
- }
-
- private void initializeMultiSelectDrawables() {
- if (mMultiSelectTrue == null) {
- mMultiSelectTrue = getResources()
- .getDrawable(R.drawable.btn_check_buttonless_on);
- }
- if (mMultiSelectFalse == null) {
- mMultiSelectFalse = getResources()
- .getDrawable(R.drawable.btn_check_buttonless_off);
- }
- }
-
- private Bitmap mMissingImageThumbnailBitmap;
- private Bitmap mMissingVideoThumbnailBitmap;
-
- // Create this bitmap lazily, and only once for all the ImageBlocks to
- // use
- public Bitmap getErrorBitmap(IImage image) {
- if (ImageManager.isImage(image)) {
- if (mMissingImageThumbnailBitmap == null) {
- mMissingImageThumbnailBitmap = BitmapFactory.decodeResource(
- getResources(),
- R.drawable.ic_missing_thumbnail_picture);
- }
- return mMissingImageThumbnailBitmap;
- } else {
- if (mMissingVideoThumbnailBitmap == null) {
- mMissingVideoThumbnailBitmap = BitmapFactory.decodeResource(
- getResources(), R.drawable.ic_missing_thumbnail_video);
- }
- return mMissingVideoThumbnailBitmap;
- }
- }
-
- private Animation mFooterAppear;
- private Animation mFooterDisappear;
-
- private void showFooter() {
- mFooterOrganizeView.setVisibility(View.VISIBLE);
- if (mFooterAppear == null) {
- mFooterAppear = AnimationUtils.loadAnimation(
- this, R.anim.footer_appear);
- }
- mFooterOrganizeView.startAnimation(mFooterAppear);
- }
-
- private void hideFooter() {
- if (mFooterOrganizeView.getVisibility() != View.GONE) {
- mFooterOrganizeView.setVisibility(View.GONE);
- if (mFooterDisappear == null) {
- mFooterDisappear = AnimationUtils.loadAnimation(
- this, R.anim.footer_disappear);
- }
- mFooterOrganizeView.startAnimation(mFooterDisappear);
- }
- }
-
- private String getShareMultipleMimeType() {
- final int FLAG_IMAGE = 1, FLAG_VIDEO = 2;
- int flag = 0;
- for (IImage image : mMultiSelected) {
- flag |= ImageManager.isImage(image) ? FLAG_IMAGE : FLAG_VIDEO;
- }
- return flag == FLAG_IMAGE
- ? "image/*"
- : flag == FLAG_VIDEO ? "video/*" : "*/*";
- }
-
- private void onShareMultipleClicked() {
- if (mMultiSelected == null) return;
- if (mMultiSelected.size() > 1) {
- Intent intent = new Intent();
- intent.setAction(Intent.ACTION_SEND_MULTIPLE);
-
- String mimeType = getShareMultipleMimeType();
- intent.setType(mimeType);
- ArrayList<Parcelable> list = new ArrayList<Parcelable>();
- for (IImage image : mMultiSelected) {
- list.add(image.fullSizeImageUri());
- }
- intent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, list);
- try {
- startActivity(Intent.createChooser(
- intent, getText(R.string.send_media_files)));
- } catch (android.content.ActivityNotFoundException ex) {
- Toast.makeText(this, R.string.no_way_to_share,
- Toast.LENGTH_SHORT).show();
- }
- } else if (mMultiSelected.size() == 1) {
- IImage image = mMultiSelected.iterator().next();
- Intent intent = new Intent();
- intent.setAction(Intent.ACTION_SEND);
- String mimeType = image.getMimeType();
- intent.setType(mimeType);
- intent.putExtra(Intent.EXTRA_STREAM, image.fullSizeImageUri());
- boolean isImage = ImageManager.isImage(image);
- try {
- startActivity(Intent.createChooser(intent, getText(
- isImage ? R.string.sendImage : R.string.sendVideo)));
- } catch (android.content.ActivityNotFoundException ex) {
- Toast.makeText(this, isImage
- ? R.string.no_way_to_share_image
- : R.string.no_way_to_share_video,
- Toast.LENGTH_SHORT).show();
- }
- }
- }
-
- private void onDeleteMultipleClicked() {
- if (mMultiSelected == null) return;
- Runnable action = new Runnable() {
- public void run() {
- ArrayList<Uri> uriList = new ArrayList<Uri>();
- for (IImage image : mMultiSelected) {
- uriList.add(image.fullSizeImageUri());
- }
- closeMultiSelectMode();
- Intent intent = new Intent(ImageGallery.this,
- DeleteImage.class);
- intent.putExtra("delete-uris", uriList);
- try {
- startActivity(intent);
- } catch (ActivityNotFoundException ex) {
- Log.e(TAG, "Delete images fail", ex);
- }
- }
- };
- MenuHelper.deleteMultiple(this, action);
- }
-
- private boolean isInMultiSelectMode() {
- return mMultiSelected != null;
- }
-
- private void closeMultiSelectMode() {
- if (mMultiSelected == null) return;
- mMultiSelected = null;
- mGvs.invalidate();
- hideFooter();
- }
-
- private void openMultiSelectMode() {
- if (mMultiSelected != null) return;
- mMultiSelected = new HashSet<IImage>();
- mGvs.invalidate();
- }
-
-}
diff --git a/src/com/android/camera/ImageLoader.java b/src/com/android/camera/ImageLoader.java
deleted file mode 100644
index a394508a..00000000
--- a/src/com/android/camera/ImageLoader.java
+++ /dev/null
@@ -1,174 +0,0 @@
-/*
- * Copyright (C) 2007 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.camera;
-
-import com.android.camera.gallery.IImage;
-
-import android.content.ContentResolver;
-import android.graphics.Bitmap;
-import android.os.Handler;
-import android.provider.MediaStore;
-import android.util.Log;
-
-import java.util.ArrayList;
-
-/**
- * A dedicated decoding thread used by ImageGallery.
- */
-public class ImageLoader {
- @SuppressWarnings("unused")
- private static final String TAG = "ImageLoader";
-
- // Queue of work to do in the worker thread. The work is done in order.
- private final ArrayList<WorkItem> mQueue = new ArrayList<WorkItem>();
-
- // the worker thread and a done flag so we know when to exit
- private boolean mDone;
- private Thread mDecodeThread;
- private ContentResolver mCr;
-
- public interface LoadedCallback {
- public void run(Bitmap result);
- }
-
- public void getBitmap(IImage image,
- LoadedCallback imageLoadedRunnable,
- int tag) {
- if (mDecodeThread == null) {
- start();
- }
- synchronized (mQueue) {
- WorkItem w = new WorkItem(image, imageLoadedRunnable, tag);
- mQueue.add(w);
- mQueue.notifyAll();
- }
- }
-
- public boolean cancel(final IImage image) {
- synchronized (mQueue) {
- int index = findItem(image);
- if (index >= 0) {
- mQueue.remove(index);
- return true;
- } else {
- return false;
- }
- }
- }
-
- // The caller should hold mQueue lock.
- private int findItem(IImage image) {
- for (int i = 0; i < mQueue.size(); i++) {
- if (mQueue.get(i).mImage == image) {
- return i;
- }
- }
- return -1;
- }
-
- // Clear the queue. Returns an array of tags that were in the queue.
- public int[] clearQueue() {
- synchronized (mQueue) {
- int n = mQueue.size();
- int[] tags = new int[n];
- for (int i = 0; i < n; i++) {
- tags[i] = mQueue.get(i).mTag;
- }
- mQueue.clear();
- return tags;
- }
- }
-
- private static class WorkItem {
- IImage mImage;
- LoadedCallback mOnLoadedRunnable;
- int mTag;
-
- WorkItem(IImage image, LoadedCallback onLoadedRunnable, int tag) {
- mImage = image;
- mOnLoadedRunnable = onLoadedRunnable;
- mTag = tag;
- }
- }
-
- public ImageLoader(ContentResolver cr, Handler handler) {
- mCr = cr;
- start();
- }
-
- private class WorkerThread implements Runnable {
-
- // Pick off items on the queue, one by one, and compute their bitmap.
- // Place the resulting bitmap in the cache, then call back by executing
- // the given runnable so things can get updated appropriately.
- public void run() {
- while (true) {
- WorkItem workItem = null;
- synchronized (mQueue) {
- if (mDone) {
- break;
- }
- if (!mQueue.isEmpty()) {
- workItem = mQueue.remove(0);
- } else {
- try {
- mQueue.wait();
- } catch (InterruptedException ex) {
- // ignore the exception
- }
- continue;
- }
- }
-
- final Bitmap b = workItem.mImage.miniThumbBitmap();
-
- if (workItem.mOnLoadedRunnable != null) {
- workItem.mOnLoadedRunnable.run(b);
- }
- }
- }
- }
-
- private void start() {
- if (mDecodeThread != null) {
- return;
- }
-
- mDone = false;
- Thread t = new Thread(new WorkerThread());
- t.setName("image-loader");
- mDecodeThread = t;
- t.start();
- }
-
- public void stop() {
- synchronized (mQueue) {
- mDone = true;
- mQueue.notifyAll();
- }
- if (mDecodeThread != null) {
- try {
- Thread t = mDecodeThread;
- BitmapManager.instance().cancelThreadDecoding(t, mCr);
- t.join();
- mDecodeThread = null;
- } catch (InterruptedException ex) {
- // so now what?
- }
- }
- }
-}
diff --git a/src/com/android/camera/ImageManager.java b/src/com/android/camera/ImageManager.java
index f2c931da..bdf78483 100644
--- a/src/com/android/camera/ImageManager.java
+++ b/src/com/android/camera/ImageManager.java
@@ -410,10 +410,6 @@ public class ImageManager {
public void close() {
}
- public HashMap<String, String> getBucketIds() {
- return new HashMap<String, String>();
- }
-
public int getCount() {
return 0;
}
@@ -459,12 +455,6 @@ public class ImageManager {
return param;
}
- public static ImageListParam getEmptyImageListParam() {
- ImageListParam param = new ImageListParam();
- param.mIsEmptyImageList = true;
- return param;
- }
-
public static IImageList makeImageList(ContentResolver cr,
DataLocation location, int inclusion, int sort, String bucketId) {
ImageListParam param = getImageListParam(location, inclusion, sort,
@@ -472,10 +462,6 @@ public class ImageManager {
return makeImageList(cr, param);
}
- public static IImageList makeEmptyImageList() {
- return makeImageList(null, getEmptyImageListParam());
- }
-
public static IImageList makeSingleImageList(ContentResolver cr, Uri uri) {
return makeImageList(cr, getSingleImageListParam(uri));
}
diff --git a/src/com/android/camera/MenuHelper.java b/src/com/android/camera/MenuHelper.java
index 453d6290..0d949b2b 100644
--- a/src/com/android/camera/MenuHelper.java
+++ b/src/com/android/camera/MenuHelper.java
@@ -887,20 +887,6 @@ public class MenuHelper {
}
}
- public static void deleteMultiple(Context context, Runnable action) {
- boolean needConfirm = PreferenceManager
- .getDefaultSharedPreferences(context)
- .getBoolean("pref_gallery_confirm_delete_key", true);
- if (!needConfirm) {
- if (action != null) action.run();
- } else {
- String title = context.getString(R.string.confirm_delete_title);
- String message = context.getString(
- R.string.confirm_delete_multiple_message);
- confirmAction(context, title, message, action);
- }
- }
-
public static void confirmAction(Context context, String title,
String message, final Runnable action) {
OnClickListener listener = new OnClickListener() {
@@ -969,55 +955,6 @@ public class MenuHelper {
}
}
- static void addCapturePictureMenuItems(Menu menu, final Activity activity) {
- menu.add(Menu.NONE, Menu.NONE, POSITION_CAPTURE_PICTURE,
- R.string.capture_picture)
- .setOnMenuItemClickListener(
- new MenuItem.OnMenuItemClickListener() {
- public boolean onMenuItemClick(MenuItem item) {
- return onCapturePictureClicked(activity);
- }
- }).setIcon(android.R.drawable.ic_menu_camera);
- }
-
- private static boolean onCapturePictureClicked(Activity activity) {
- Intent intent = new Intent(MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA);
- intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
- try {
- activity.startActivity(intent);
- } catch (android.content.ActivityNotFoundException e) {
- // Ignore exception
- }
- return true;
- }
-
- static void addCaptureVideoMenuItems(Menu menu, final Activity activity) {
- menu.add(Menu.NONE, Menu.NONE, POSITION_CAPTURE_VIDEO,
- R.string.capture_video)
- .setOnMenuItemClickListener(
- new MenuItem.OnMenuItemClickListener() {
- public boolean onMenuItemClick(MenuItem item) {
- return onCaptureVideoClicked(activity);
- }
- }).setIcon(R.drawable.ic_menu_camera_video_view);
- }
-
- private static boolean onCaptureVideoClicked(Activity activity) {
- Intent intent = new Intent(MediaStore.INTENT_ACTION_VIDEO_CAMERA);
- intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
- try {
- activity.startActivity(intent);
- } catch (android.content.ActivityNotFoundException e) {
- // Ignore exception
- }
- return true;
- }
-
- public static void addCaptureMenuItems(Menu menu, final Activity activity) {
- addCapturePictureMenuItems(menu, activity);
- addCaptureVideoMenuItems(menu, activity);
- }
-
public static String formatDuration(final Context context,
int durationMs) {
int duration = durationMs / 1000;
diff --git a/src/com/android/camera/MovieView.java b/src/com/android/camera/MovieView.java
deleted file mode 100644
index 0f4df52f..00000000
--- a/src/com/android/camera/MovieView.java
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Copyright (C) 2007 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.camera;
-
-
-import android.app.Activity;
-import android.content.Intent;
-import android.content.pm.ActivityInfo;
-import android.os.Bundle;
-import android.provider.MediaStore;
-import android.util.Log;
-import android.view.View;
-
-/**
- * This activity plays a video from a specified URI.
- */
-public class MovieView extends NoSearchActivity {
- private static final String TAG = "MovieView";
-
- private MovieViewControl mControl;
- private boolean mFinishOnCompletion;
- private boolean mResumed = false; // Whether this activity has been resumed.
- private boolean mFocused = false; // Whether this window has focus.
- private boolean mControlResumed = false; // Whether the MovieViewControl is resumed.
-
- @Override
- public void onCreate(Bundle icicle) {
- super.onCreate(icicle);
- setContentView(R.layout.movie_view);
- View rootView = findViewById(R.id.root);
- Intent intent = getIntent();
- mControl = new MovieViewControl(rootView, this, intent.getData()) {
- @Override
- public void onCompletion() {
- if (mFinishOnCompletion) {
- finish();
- }
- }
- };
- if (intent.hasExtra(MediaStore.EXTRA_SCREEN_ORIENTATION)) {
- int orientation = intent.getIntExtra(
- MediaStore.EXTRA_SCREEN_ORIENTATION,
- ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
- if (orientation != getRequestedOrientation()) {
- setRequestedOrientation(orientation);
- }
- }
- mFinishOnCompletion = intent.getBooleanExtra(
- MediaStore.EXTRA_FINISH_ON_COMPLETION, true);
- }
-
- @Override
- public void onPause() {
- super.onPause();
- mResumed = false;
- if (mControlResumed) {
- mControl.onPause();
- mControlResumed = false;
- }
- }
-
- @Override
- public void onResume() {
- super.onResume();
- mResumed = true;
- if (mFocused && mResumed && !mControlResumed) {
- mControl.onResume();
- mControlResumed = true;
- }
- }
-
- @Override
- public void onWindowFocusChanged(boolean hasFocus) {
- mFocused = hasFocus;
- if (mFocused && mResumed && !mControlResumed) {
- mControl.onResume();
- mControlResumed = true;
- }
- }
-}
diff --git a/src/com/android/camera/MovieViewControl.java b/src/com/android/camera/MovieViewControl.java
deleted file mode 100644
index 737433b7..00000000
--- a/src/com/android/camera/MovieViewControl.java
+++ /dev/null
@@ -1,240 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.camera;
-
-import android.app.AlertDialog;
-import android.content.ContentResolver;
-import android.content.ContentValues;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.content.Intent;
-import android.content.DialogInterface.OnCancelListener;
-import android.content.DialogInterface.OnClickListener;
-import android.database.Cursor;
-import android.database.sqlite.SQLiteException;
-import android.media.MediaPlayer;
-import android.net.Uri;
-import android.os.Handler;
-import android.provider.MediaStore;
-import android.provider.MediaStore.Video;
-import android.view.View;
-import android.widget.MediaController;
-import android.widget.VideoView;
-
-public class MovieViewControl implements MediaPlayer.OnErrorListener,
- MediaPlayer.OnCompletionListener {
-
- @SuppressWarnings("unused")
- private static final String TAG = "MovieViewControl";
-
- private static final int ONE_MINUTE = 60 * 1000;
- private static final int TWO_MINUTES = 2 * ONE_MINUTE;
- private static final int FIVE_MINUTES = 5 * ONE_MINUTE;
-
- // Copied from MediaPlaybackService in the Music Player app. Should be
- // public, but isn't.
- private static final String SERVICECMD =
- "com.android.music.musicservicecommand";
- private static final String CMDNAME = "command";
- private static final String CMDPAUSE = "pause";
-
- private final VideoView mVideoView;
- private final View mProgressView;
- private final Uri mUri;
- private final ContentResolver mContentResolver;
-
- // State maintained for proper onPause/OnResume behaviour.
- private int mPositionWhenPaused = -1;
- private boolean mWasPlayingWhenPaused = false;
- private MediaController mMediaController;
-
- Handler mHandler = new Handler();
-
- Runnable mPlayingChecker = new Runnable() {
- public void run() {
- if (mVideoView.isPlaying()) {
- mProgressView.setVisibility(View.GONE);
- } else {
- mHandler.postDelayed(mPlayingChecker, 250);
- }
- }
- };
-
- public MovieViewControl(View rootView, Context context, Uri videoUri) {
- mContentResolver = context.getContentResolver();
- mVideoView = (VideoView) rootView.findViewById(R.id.surface_view);
- mProgressView = rootView.findViewById(R.id.progress_indicator);
-
- mUri = videoUri;
-
- // For streams that we expect to be slow to start up, show a
- // progress spinner until playback starts.
- String scheme = mUri.getScheme();
- if ("http".equalsIgnoreCase(scheme)
- || "rtsp".equalsIgnoreCase(scheme)) {
- mHandler.postDelayed(mPlayingChecker, 250);
- } else {
- mProgressView.setVisibility(View.GONE);
- }
-
- mVideoView.setOnErrorListener(this);
- mVideoView.setOnCompletionListener(this);
- mVideoView.setVideoURI(mUri);
- mMediaController = new MediaController(context);
- mVideoView.setMediaController(mMediaController);
-
- // make the video view handle keys for seeking and pausing
- mVideoView.requestFocus();
-
- Intent i = new Intent(SERVICECMD);
- i.putExtra(CMDNAME, CMDPAUSE);
- context.sendBroadcast(i);
-
- final Integer bookmark = getBookmark();
- if (bookmark != null) {
- AlertDialog.Builder builder = new AlertDialog.Builder(context);
- builder.setTitle(R.string.resume_playing_title);
- builder.setMessage(String.format(
- context.getString(R.string.resume_playing_message),
- MenuHelper.formatDuration(context, bookmark)));
- builder.setOnCancelListener(new OnCancelListener() {
- public void onCancel(DialogInterface dialog) {
- onCompletion();
- }});
- builder.setPositiveButton(R.string.resume_playing_resume,
- new OnClickListener() {
- public void onClick(DialogInterface dialog, int which) {
- mVideoView.seekTo(bookmark);
- mVideoView.start();
- }});
- builder.setNegativeButton(R.string.resume_playing_restart,
- new OnClickListener() {
- public void onClick(DialogInterface dialog, int which) {
- mVideoView.start();
- }});
- builder.show();
- } else {
- mVideoView.start();
- }
- }
-
- private static boolean uriSupportsBookmarks(Uri uri) {
- String scheme = uri.getScheme();
- String authority = uri.getAuthority();
- return ("content".equalsIgnoreCase(scheme)
- && MediaStore.AUTHORITY.equalsIgnoreCase(authority));
- }
-
- private Integer getBookmark() {
- if (!uriSupportsBookmarks(mUri)) {
- return null;
- }
-
- String[] projection = new String[] {
- Video.VideoColumns.DURATION,
- Video.VideoColumns.BOOKMARK};
-
- try {
- Cursor cursor = mContentResolver.query(
- mUri, projection, null, null, null);
- if (cursor != null) {
- try {
- if (cursor.moveToFirst()) {
- int duration = getCursorInteger(cursor, 0);
- int bookmark = getCursorInteger(cursor, 1);
- if ((bookmark < TWO_MINUTES)
- || (duration < FIVE_MINUTES)
- || (bookmark > (duration - ONE_MINUTE))) {
- return null;
- }
- return Integer.valueOf(bookmark);
- }
- } finally {
- cursor.close();
- }
- }
- } catch (SQLiteException e) {
- // ignore
- }
-
- return null;
- }
-
- private static int getCursorInteger(Cursor cursor, int index) {
- try {
- return cursor.getInt(index);
- } catch (SQLiteException e) {
- return 0;
- } catch (NumberFormatException e) {
- return 0;
- }
-
- }
-
- private void setBookmark(int bookmark) {
- if (!uriSupportsBookmarks(mUri)) {
- return;
- }
-
- ContentValues values = new ContentValues();
- values.put(Video.VideoColumns.BOOKMARK, Integer.toString(bookmark));
- try {
- mContentResolver.update(mUri, values, null, null);
- } catch (SecurityException ex) {
- // Ignore, can happen if we try to set the bookmark on a read-only
- // resource such as a video attached to GMail.
- } catch (SQLiteException e) {
- // ignore. can happen if the content doesn't support a bookmark
- // column.
- } catch (UnsupportedOperationException e) {
- // ignore. can happen if the external volume is already detached.
- }
- }
-
- public void onPause() {
- mHandler.removeCallbacksAndMessages(null);
- setBookmark(mVideoView.getCurrentPosition());
-
- mPositionWhenPaused = mVideoView.getCurrentPosition();
- mWasPlayingWhenPaused = mVideoView.isPlaying();
- mVideoView.stopPlayback();
- }
-
- public void onResume() {
- if (mPositionWhenPaused >= 0) {
- mVideoView.setVideoURI(mUri);
- mVideoView.seekTo(mPositionWhenPaused);
- mPositionWhenPaused = -1;
- if (mWasPlayingWhenPaused) {
- mMediaController.show(0);
- }
- }
- }
-
- public boolean onError(MediaPlayer player, int arg1, int arg2) {
- mHandler.removeCallbacksAndMessages(null);
- mProgressView.setVisibility(View.GONE);
- return false;
- }
-
- public void onCompletion(MediaPlayer mp) {
- onCompletion();
- }
-
- public void onCompletion() {
- }
-}
diff --git a/src/com/android/camera/PhotoAppWidgetBind.java b/src/com/android/camera/PhotoAppWidgetBind.java
deleted file mode 100644
index 5c2aa50b..00000000
--- a/src/com/android/camera/PhotoAppWidgetBind.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.camera;
-
-import com.android.camera.PhotoAppWidgetProvider.PhotoDatabaseHelper;
-
-import android.app.Activity;
-import android.appwidget.AppWidgetManager;
-import android.content.Intent;
-import android.graphics.Bitmap;
-import android.os.Bundle;
-import android.util.Log;
-import android.widget.RemoteViews;
-
-import java.util.ArrayList;
-
-class PhotoAppWidgetBind extends NoSearchActivity {
- private static final String TAG = "PhotoAppWidgetBind";
- private static final String EXTRA_APPWIDGET_BITMAPS =
- "com.android.camera.appwidgetbitmaps";
-
- @Override
- protected void onCreate(Bundle icicle) {
- super.onCreate(icicle);
- finish();
-
- // The caller has requested that we bind a given bitmap to a specific
- // appWidgetId, which probably is happening during a Launcher upgrade.
- // This is dangerous because the caller could set bitmaps on
- // appWidgetIds they don't own, so we guard this call at the manifest
- // level by requiring the BIND_APPWIDGET permission.
-
- final Intent intent = getIntent();
- final Bundle extras = intent.getExtras();
-
- final int[] appWidgetIds =
- extras.getIntArray(AppWidgetManager.EXTRA_APPWIDGET_IDS);
- final ArrayList<Bitmap> bitmaps =
- extras.getParcelableArrayList(EXTRA_APPWIDGET_BITMAPS);
-
- if (appWidgetIds == null || bitmaps == null
- || appWidgetIds.length != bitmaps.size()) {
- Log.e(TAG, "Problem parsing photo widget bind request");
- return;
- }
-
- AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(this);
- PhotoDatabaseHelper helper = new PhotoDatabaseHelper(this);
- for (int i = 0; i < appWidgetIds.length; i++) {
- // Store the cropped photo in our database
- int appWidgetId = appWidgetIds[i];
- helper.setPhoto(appWidgetId, bitmaps.get(i));
-
- // Push newly updated widget to surface
- RemoteViews views =
- PhotoAppWidgetProvider.buildUpdate(this, appWidgetId,
- helper);
- appWidgetManager.updateAppWidget(new int[] { appWidgetId }, views);
- }
- helper.close();
- }
-}
diff --git a/src/com/android/camera/PhotoAppWidgetConfigure.java b/src/com/android/camera/PhotoAppWidgetConfigure.java
deleted file mode 100644
index 76174c79..00000000
--- a/src/com/android/camera/PhotoAppWidgetConfigure.java
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.camera;
-
-import com.android.camera.PhotoAppWidgetProvider.PhotoDatabaseHelper;
-
-import android.app.Activity;
-import android.appwidget.AppWidgetManager;
-import android.content.Intent;
-import android.graphics.Bitmap;
-import android.os.Bundle;
-import android.util.DisplayMetrics;
-import android.widget.RemoteViews;
-
-public class PhotoAppWidgetConfigure extends NoSearchActivity {
-
- @SuppressWarnings("unused")
- private static final String TAG = "PhotoAppWidgetConfigure";
- static final int REQUEST_GET_PHOTO = 2;
-
- int mAppWidgetId = -1;
-
- @Override
- protected void onCreate(Bundle icicle) {
- super.onCreate(icicle);
-
- // Someone is requesting that we configure the given mAppWidgetId, which
- // means we prompt the user to pick and crop a photo.
-
- mAppWidgetId = getIntent().getIntExtra(
- AppWidgetManager.EXTRA_APPWIDGET_ID, -1);
- if (mAppWidgetId == -1) {
- setResult(Activity.RESULT_CANCELED);
- finish();
- }
-
- // Assume the widget will be 1/4 of the screen.
- // This will be slightly too large, but there is not a good way to know the
- // actual widget size from here. The image will be scaled to fit since the layout
- // file specifies android:scaleType="centerCrop"
- DisplayMetrics display = getResources().getDisplayMetrics();
- int maxDimension = Math.max(display.heightPixels, display.widthPixels);
- maxDimension /= 2;
-
- // TODO: Adjust the PhotoFrame's image size to avoid on the fly scaling
- Intent intent = new Intent(Intent.ACTION_GET_CONTENT, null);
- intent.setType("image/*");
- intent.putExtra("crop", "true");
- intent.putExtra("aspectX", 1);
- intent.putExtra("aspectY", 1);
- intent.putExtra("outputX", maxDimension);
- intent.putExtra("outputY", maxDimension);
- intent.putExtra("noFaceDetection", true);
- intent.putExtra("return-data", true);
-
- startActivityForResult(intent, REQUEST_GET_PHOTO);
- }
-
- @Override
- protected void onActivityResult(int requestCode, int resultCode,
- Intent data) {
- if (resultCode == RESULT_OK && mAppWidgetId != -1) {
- // Store the cropped photo in our database
- Bitmap bitmap = (Bitmap) data.getParcelableExtra("data");
-
- PhotoDatabaseHelper helper = new PhotoDatabaseHelper(this);
- if (helper.setPhoto(mAppWidgetId, bitmap)) {
- resultCode = Activity.RESULT_OK;
-
- // Push newly updated widget to surface
- RemoteViews views = PhotoAppWidgetProvider.buildUpdate(this,
- mAppWidgetId, helper);
- AppWidgetManager appWidgetManager =
- AppWidgetManager.getInstance(this);
- appWidgetManager.updateAppWidget(new int[] {mAppWidgetId},
- views);
- }
- helper.close();
- } else {
- resultCode = Activity.RESULT_CANCELED;
- }
-
- // Make sure we pass back the original mAppWidgetId
- Intent resultValue = new Intent();
- resultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, mAppWidgetId);
- setResult(resultCode, resultValue);
- finish();
- }
-
-}
diff --git a/src/com/android/camera/PhotoAppWidgetProvider.java b/src/com/android/camera/PhotoAppWidgetProvider.java
deleted file mode 100644
index da680b41..00000000
--- a/src/com/android/camera/PhotoAppWidgetProvider.java
+++ /dev/null
@@ -1,209 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.camera;
-
-import android.appwidget.AppWidgetManager;
-import android.appwidget.AppWidgetProvider;
-import android.content.ContentValues;
-import android.content.Context;
-import android.database.Cursor;
-import android.database.sqlite.SQLiteDatabase;
-import android.database.sqlite.SQLiteException;
-import android.database.sqlite.SQLiteOpenHelper;
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
-import android.util.Log;
-import android.widget.RemoteViews;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-
-/**
- * Simple widget to show a user-selected picture.
- */
-public class PhotoAppWidgetProvider extends AppWidgetProvider {
- private static final String TAG = "PhotoAppWidgetProvider";
- private static final boolean LOGD = true;
-
- @Override
- public void onUpdate(Context context, AppWidgetManager appWidgetManager,
- int[] appWidgetIds) {
- // Update each requested appWidgetId with its unique photo
- PhotoDatabaseHelper helper = new PhotoDatabaseHelper(context);
- for (int appWidgetId : appWidgetIds) {
- int[] specificAppWidget = new int[] { appWidgetId };
- RemoteViews views = buildUpdate(context, appWidgetId, helper);
- if (LOGD) {
- Log.d(TAG, "sending out views=" + views
- + " for id=" + appWidgetId);
- }
- appWidgetManager.updateAppWidget(specificAppWidget, views);
- }
- helper.close();
- }
-
- @Override
- public void onDeleted(Context context, int[] appWidgetIds) {
- // Clean deleted photos out of our database
- PhotoDatabaseHelper helper = new PhotoDatabaseHelper(context);
- for (int appWidgetId : appWidgetIds) {
- helper.deletePhoto(appWidgetId);
- }
- helper.close();
- }
-
- /**
- * Load photo for given widget and build {@link RemoteViews} for it.
- */
- static RemoteViews buildUpdate(Context context, int appWidgetId,
- PhotoDatabaseHelper helper) {
- RemoteViews views = null;
- Bitmap bitmap = helper.getPhoto(appWidgetId);
- if (bitmap != null) {
- views = new RemoteViews(context.getPackageName(),
- R.layout.photo_frame);
- views.setImageViewBitmap(R.id.photo, bitmap);
- }
- return views;
- }
-
- static class PhotoDatabaseHelper extends SQLiteOpenHelper {
- private static final String DATABASE_NAME = "launcher.db";
-
- private static final int DATABASE_VERSION = 2;
-
- static final String TABLE_PHOTOS = "photos";
- static final String FIELD_APPWIDGET_ID = "appWidgetId";
- static final String FIELD_PHOTO_BLOB = "photoBlob";
-
- PhotoDatabaseHelper(Context context) {
- super(context, DATABASE_NAME, null, DATABASE_VERSION);
- }
-
- @Override
- public void onCreate(SQLiteDatabase db) {
- db.execSQL("CREATE TABLE " + TABLE_PHOTOS + " (" +
- FIELD_APPWIDGET_ID + " INTEGER PRIMARY KEY," +
- FIELD_PHOTO_BLOB + " BLOB" +
- ");");
- }
-
- @Override
- public void onUpgrade(SQLiteDatabase db, int oldVersion,
- int newVersion) {
- int version = oldVersion;
-
- if (version != DATABASE_VERSION) {
- Log.w(TAG, "Destroying all old data.");
- db.execSQL("DROP TABLE IF EXISTS " + TABLE_PHOTOS);
- onCreate(db);
- }
- }
-
- /**
- * Store the given bitmap in this database for the given appWidgetId.
- */
- public boolean setPhoto(int appWidgetId, Bitmap bitmap) {
- boolean success = false;
- try {
- // Try go guesstimate how much space the icon will take when
- // serialized to avoid unnecessary allocations/copies during
- // the write.
- int size = bitmap.getWidth() * bitmap.getHeight() * 4;
- ByteArrayOutputStream out = new ByteArrayOutputStream(size);
- bitmap.compress(Bitmap.CompressFormat.PNG, 100, out);
- out.flush();
- out.close();
-
- ContentValues values = new ContentValues();
- values.put(PhotoDatabaseHelper.FIELD_APPWIDGET_ID, appWidgetId);
- values.put(PhotoDatabaseHelper.FIELD_PHOTO_BLOB,
- out.toByteArray());
-
- SQLiteDatabase db = getWritableDatabase();
- db.insertOrThrow(PhotoDatabaseHelper.TABLE_PHOTOS, null,
- values);
-
- success = true;
- } catch (SQLiteException e) {
- Log.e(TAG, "Could not open database", e);
- } catch (IOException e) {
- Log.e(TAG, "Could not serialize photo", e);
- }
- if (LOGD) {
- Log.d(TAG, "setPhoto success=" + success);
- }
- return success;
- }
-
- static final String[] PHOTOS_PROJECTION = {
- FIELD_PHOTO_BLOB,
- };
-
- static final int INDEX_PHOTO_BLOB = 0;
-
- /**
- * Inflate and return a bitmap for the given appWidgetId.
- */
- public Bitmap getPhoto(int appWidgetId) {
- Cursor c = null;
- Bitmap bitmap = null;
- try {
- SQLiteDatabase db = getReadableDatabase();
- String selection = String.format("%s=%d", FIELD_APPWIDGET_ID,
- appWidgetId);
- c = db.query(TABLE_PHOTOS, PHOTOS_PROJECTION, selection, null,
- null, null, null, null);
-
- if (c != null && LOGD) {
- Log.d(TAG, "getPhoto query count=" + c.getCount());
- }
-
- if (c != null && c.moveToFirst()) {
- byte[] data = c.getBlob(INDEX_PHOTO_BLOB);
- if (data != null) {
- bitmap = BitmapFactory.decodeByteArray(data, 0,
- data.length);
- }
- }
- } catch (SQLiteException e) {
- Log.e(TAG, "Could not load photo from database", e);
- } finally {
- if (c != null) {
- c.close();
- }
- }
- return bitmap;
- }
-
- /**
- * Remove any bitmap associated with the given appWidgetId.
- */
- public void deletePhoto(int appWidgetId) {
- try {
- SQLiteDatabase db = getWritableDatabase();
- String whereClause = String.format("%s=%d", FIELD_APPWIDGET_ID,
- appWidgetId);
- db.delete(TABLE_PHOTOS, whereClause, null);
- } catch (SQLiteException e) {
- Log.e(TAG, "Could not delete photo from database", e);
- }
- }
- }
-
-}
-
diff --git a/src/com/android/camera/PickWallpaper.java b/src/com/android/camera/PickWallpaper.java
deleted file mode 100644
index b9bff5ac..00000000
--- a/src/com/android/camera/PickWallpaper.java
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright (C) 2007 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.camera;
-
-/**
- * Wallpaper picker for the camera application.
- * This just redirects to the standard pick action.
- */
-public class PickWallpaper extends Wallpaper {
-}
diff --git a/src/com/android/camera/Util.java b/src/com/android/camera/Util.java
index d44435aa..6f559e9c 100644
--- a/src/com/android/camera/Util.java
+++ b/src/com/android/camera/Util.java
@@ -361,16 +361,6 @@ public class Util {
}
}
- public static synchronized OnClickListener getNullOnClickListener() {
- if (sNullOnClickListener == null) {
- sNullOnClickListener = new OnClickListener() {
- public void onClick(View v) {
- }
- };
- }
- return sNullOnClickListener;
- }
-
public static void Assert(boolean cond) {
if (!cond) {
throw new AssertionError();
diff --git a/src/com/android/camera/ViewImage.java b/src/com/android/camera/ViewImage.java
deleted file mode 100644
index 7a334117..00000000
--- a/src/com/android/camera/ViewImage.java
+++ /dev/null
@@ -1,1300 +0,0 @@
-/*
- * Copyright (C) 2007 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.camera;
-
-import android.app.Activity;
-import android.content.Context;
-import android.content.Intent;
-import android.content.SharedPreferences;
-import android.graphics.Bitmap;
-import android.net.Uri;
-import android.os.Bundle;
-import android.preference.PreferenceManager;
-import android.provider.MediaStore;
-import android.util.AttributeSet;
-import android.util.Log;
-import android.view.GestureDetector;
-import android.view.KeyEvent;
-import android.view.Menu;
-import android.view.MenuItem;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.Window;
-import android.view.WindowManager;
-import android.view.View.OnTouchListener;
-import android.view.animation.AlphaAnimation;
-import android.view.animation.Animation;
-import android.view.animation.AnimationUtils;
-import android.widget.Toast;
-import android.widget.ZoomButtonsController;
-
-import com.android.camera.gallery.IImage;
-import com.android.camera.gallery.IImageList;
-import com.android.camera.gallery.VideoObject;
-
-import java.util.Random;
-
-// This activity can display a whole picture and navigate them in a specific
-// gallery. It has two modes: normal mode and slide show mode. In normal mode
-// the user view one image at a time, and can click "previous" and "next"
-// button to see the previous or next image. In slide show mode it shows one
-// image after another, with some transition effect.
-public class ViewImage extends NoSearchActivity implements View.OnClickListener {
- private static final String PREF_SLIDESHOW_REPEAT =
- "pref_gallery_slideshow_repeat_key";
- private static final String PREF_SHUFFLE_SLIDESHOW =
- "pref_gallery_slideshow_shuffle_key";
- private static final String STATE_URI = "uri";
- private static final String STATE_SLIDESHOW = "slideshow";
- private static final String EXTRA_SLIDESHOW = "slideshow";
- private static final String TAG = "ViewImage";
-
- private ImageGetter mGetter;
- private Uri mSavedUri;
- boolean mPaused = true;
- private boolean mShowControls = true;
-
- // Choices for what adjacents to load.
- private static final int[] sOrderAdjacents = new int[] {0, 1, -1};
- private static final int[] sOrderSlideshow = new int[] {0};
-
- final GetterHandler mHandler = new GetterHandler();
-
- private final Random mRandom = new Random(System.currentTimeMillis());
- private int [] mShuffleOrder = null;
- private boolean mUseShuffleOrder = false;
- private boolean mSlideShowLoop = false;
-
- static final int MODE_NORMAL = 1;
- static final int MODE_SLIDESHOW = 2;
- private int mMode = MODE_NORMAL;
-
- private boolean mFullScreenInNormalMode;
- private boolean mShowActionIcons;
- private View mActionIconPanel;
-
- private int mSlideShowInterval;
- private int mLastSlideShowImage;
- int mCurrentPosition = 0;
-
- // represents which style animation to use
- private int mAnimationIndex;
- private Animation [] mSlideShowInAnimation;
- private Animation [] mSlideShowOutAnimation;
-
- private SharedPreferences mPrefs;
-
- private View mNextImageView;
- private View mPrevImageView;
- private final Animation mHideNextImageViewAnimation =
- new AlphaAnimation(1F, 0F);
- private final Animation mHidePrevImageViewAnimation =
- new AlphaAnimation(1F, 0F);
- private final Animation mShowNextImageViewAnimation =
- new AlphaAnimation(0F, 1F);
- private final Animation mShowPrevImageViewAnimation =
- new AlphaAnimation(0F, 1F);
-
- public static final String KEY_IMAGE_LIST = "image_list";
- private static final String STATE_SHOW_CONTROLS = "show_controls";
-
- IImageList mAllImages;
-
- private ImageManager.ImageListParam mParam;
-
- private int mSlideShowImageCurrent = 0;
- private final ImageViewTouchBase [] mSlideShowImageViews =
- new ImageViewTouchBase[2];
-
- GestureDetector mGestureDetector;
- private ZoomButtonsController mZoomButtonsController;
-
- // The image view displayed for normal mode.
- private ImageViewTouch mImageView;
- // This is the cache for thumbnail bitmaps.
- private BitmapCache mCache;
- private MenuHelper.MenuItemsResult mImageMenuRunnable;
- private final Runnable mDismissOnScreenControlRunner = new Runnable() {
- public void run() {
- hideOnScreenControls();
- }
- };
-
- private void updateNextPrevControls() {
- boolean showPrev = mCurrentPosition > 0;
- boolean showNext = mCurrentPosition < mAllImages.getCount() - 1;
-
- boolean prevIsVisible = mPrevImageView.getVisibility() == View.VISIBLE;
- boolean nextIsVisible = mNextImageView.getVisibility() == View.VISIBLE;
-
- if (showPrev && !prevIsVisible) {
- Animation a = mShowPrevImageViewAnimation;
- a.setDuration(500);
- mPrevImageView.startAnimation(a);
- mPrevImageView.setVisibility(View.VISIBLE);
- } else if (!showPrev && prevIsVisible) {
- Animation a = mHidePrevImageViewAnimation;
- a.setDuration(500);
- mPrevImageView.startAnimation(a);
- mPrevImageView.setVisibility(View.GONE);
- }
-
- if (showNext && !nextIsVisible) {
- Animation a = mShowNextImageViewAnimation;
- a.setDuration(500);
- mNextImageView.startAnimation(a);
- mNextImageView.setVisibility(View.VISIBLE);
- } else if (!showNext && nextIsVisible) {
- Animation a = mHideNextImageViewAnimation;
- a.setDuration(500);
- mNextImageView.startAnimation(a);
- mNextImageView.setVisibility(View.GONE);
- }
- }
-
- private void hideOnScreenControls() {
- if (mShowActionIcons
- && mActionIconPanel.getVisibility() == View.VISIBLE) {
- Animation animation = new AlphaAnimation(1, 0);
- animation.setDuration(500);
- mActionIconPanel.startAnimation(animation);
- mActionIconPanel.setVisibility(View.INVISIBLE);
- }
-
- if (mNextImageView.getVisibility() == View.VISIBLE) {
- Animation a = mHideNextImageViewAnimation;
- a.setDuration(500);
- mNextImageView.startAnimation(a);
- mNextImageView.setVisibility(View.INVISIBLE);
- }
-
- if (mPrevImageView.getVisibility() == View.VISIBLE) {
- Animation a = mHidePrevImageViewAnimation;
- a.setDuration(500);
- mPrevImageView.startAnimation(a);
- mPrevImageView.setVisibility(View.INVISIBLE);
- }
-
- mZoomButtonsController.setVisible(false);
- }
-
- private void showOnScreenControls() {
- if (mPaused) return;
- // If the view has not been attached to the window yet, the
- // zoomButtonControls will not able to show up. So delay it until the
- // view has attached to window.
- if (mActionIconPanel.getWindowToken() == null) {
- mHandler.postGetterCallback(new Runnable() {
- public void run() {
- showOnScreenControls();
- }
- });
- return;
- }
- updateNextPrevControls();
-
- IImage image = mAllImages.getImageAt(mCurrentPosition);
- if (image instanceof VideoObject) {
- mZoomButtonsController.setVisible(false);
- } else {
- updateZoomButtonsEnabled();
- mZoomButtonsController.setVisible(true);
- }
-
- if (mShowActionIcons
- && mActionIconPanel.getVisibility() != View.VISIBLE) {
- Animation animation = new AlphaAnimation(0, 1);
- animation.setDuration(500);
- mActionIconPanel.startAnimation(animation);
- mActionIconPanel.setVisibility(View.VISIBLE);
- }
- }
-
- @Override
- public boolean dispatchTouchEvent(MotionEvent m) {
- if (mPaused) return true;
- if (mZoomButtonsController.isVisible()) {
- scheduleDismissOnScreenControls();
- }
- return super.dispatchTouchEvent(m);
- }
-
- private void updateZoomButtonsEnabled() {
- ImageViewTouch imageView = mImageView;
- float scale = imageView.getScale();
- mZoomButtonsController.setZoomInEnabled(scale < imageView.mMaxZoom);
- mZoomButtonsController.setZoomOutEnabled(scale > 1);
- }
-
- @Override
- protected void onDestroy() {
- // This is necessary to make the ZoomButtonsController unregister
- // its configuration change receiver.
- if (mZoomButtonsController != null) {
- mZoomButtonsController.setVisible(false);
- }
- super.onDestroy();
- }
-
- private void scheduleDismissOnScreenControls() {
- mHandler.removeCallbacks(mDismissOnScreenControlRunner);
- mHandler.postDelayed(mDismissOnScreenControlRunner, 2000);
- }
-
- private void setupOnScreenControls(View rootView, View ownerView) {
- mNextImageView = rootView.findViewById(R.id.next_image);
- mPrevImageView = rootView.findViewById(R.id.prev_image);
-
- mNextImageView.setOnClickListener(this);
- mPrevImageView.setOnClickListener(this);
-
- setupZoomButtonController(ownerView);
- setupOnTouchListeners(rootView);
- }
-
- private void setupZoomButtonController(final View ownerView) {
- mZoomButtonsController = new ZoomButtonsController(ownerView);
- mZoomButtonsController.setAutoDismissed(false);
- mZoomButtonsController.setZoomSpeed(100);
- mZoomButtonsController.setOnZoomListener(
- new ZoomButtonsController.OnZoomListener() {
- public void onVisibilityChanged(boolean visible) {
- if (visible) {
- updateZoomButtonsEnabled();
- }
- }
-
- public void onZoom(boolean zoomIn) {
- if (zoomIn) {
- mImageView.zoomIn();
- } else {
- mImageView.zoomOut();
- }
- mZoomButtonsController.setVisible(true);
- updateZoomButtonsEnabled();
- }
- });
- }
-
- private void setupOnTouchListeners(View rootView) {
- mGestureDetector = new GestureDetector(this, new MyGestureListener());
-
- // If the user touches anywhere on the panel (including the
- // next/prev button). We show the on-screen controls. In addition
- // to that, if the touch is not on the prev/next button, we
- // pass the event to the gesture detector to detect double tap.
- final OnTouchListener buttonListener = new OnTouchListener() {
- public boolean onTouch(View v, MotionEvent event) {
- scheduleDismissOnScreenControls();
- return false;
- }
- };
-
- OnTouchListener rootListener = new OnTouchListener() {
- public boolean onTouch(View v, MotionEvent event) {
- buttonListener.onTouch(v, event);
- mGestureDetector.onTouchEvent(event);
-
- // We do not use the return value of
- // mGestureDetector.onTouchEvent because we will not receive
- // the "up" event if we return false for the "down" event.
- return true;
- }
- };
-
- mNextImageView.setOnTouchListener(buttonListener);
- mPrevImageView.setOnTouchListener(buttonListener);
- rootView.setOnTouchListener(rootListener);
- }
-
- private class MyGestureListener extends
- GestureDetector.SimpleOnGestureListener {
-
- @Override
- public boolean onScroll(MotionEvent e1, MotionEvent e2,
- float distanceX, float distanceY) {
- if (mPaused) return false;
- ImageViewTouch imageView = mImageView;
- if (imageView.getScale() > 1F) {
- imageView.postTranslateCenter(-distanceX, -distanceY);
- }
- return true;
- }
-
- @Override
- public boolean onSingleTapUp(MotionEvent e) {
- if (mPaused) return false;
- setMode(MODE_NORMAL);
- return true;
- }
-
- @Override
- public boolean onSingleTapConfirmed(MotionEvent e) {
- if (mPaused) return false;
- showOnScreenControls();
- scheduleDismissOnScreenControls();
- return true;
- }
-
- @Override
- public boolean onDoubleTap(MotionEvent e) {
- if (mPaused) return false;
- ImageViewTouch imageView = mImageView;
-
- // Switch between the original scale and 3x scale.
- if (imageView.getScale() > 2F) {
- mImageView.zoomTo(1f);
- } else {
- mImageView.zoomToPoint(3f, e.getX(), e.getY());
- }
- return true;
- }
- }
-
- boolean isPickIntent() {
- String action = getIntent().getAction();
- return (Intent.ACTION_PICK.equals(action)
- || Intent.ACTION_GET_CONTENT.equals(action));
- }
-
- @Override
- public boolean onCreateOptionsMenu(Menu menu) {
- super.onCreateOptionsMenu(menu);
-
- MenuItem item = menu.add(Menu.NONE, Menu.NONE,
- MenuHelper.POSITION_SLIDESHOW,
- R.string.slide_show);
- item.setOnMenuItemClickListener(
- new MenuItem.OnMenuItemClickListener() {
- public boolean onMenuItemClick(MenuItem item) {
- setMode(MODE_SLIDESHOW);
- mLastSlideShowImage = mCurrentPosition;
- loadNextImage(mCurrentPosition, 0, true);
- return true;
- }
- });
- item.setIcon(android.R.drawable.ic_menu_slideshow);
-
- mImageMenuRunnable = MenuHelper.addImageMenuItems(
- menu,
- MenuHelper.INCLUDE_ALL,
- ViewImage.this,
- mHandler,
- mDeletePhotoRunnable,
- new MenuHelper.MenuInvoker() {
- public void run(final MenuHelper.MenuCallback cb) {
- if (mPaused) return;
- setMode(MODE_NORMAL);
-
- IImage image = mAllImages.getImageAt(mCurrentPosition);
- Uri uri = image.fullSizeImageUri();
- cb.run(uri, image);
-
- // We might have deleted all images in the callback, so
- // call setImage() only if we still have some images.
- if (mAllImages.getCount() > 0) {
- mImageView.clear();
- setImage(mCurrentPosition, false);
- }
- }
- });
-
- item = menu.add(Menu.NONE, Menu.NONE,
- MenuHelper.POSITION_GALLERY_SETTING, R.string.camerasettings);
- item.setOnMenuItemClickListener(
- new MenuItem.OnMenuItemClickListener() {
- public boolean onMenuItemClick(MenuItem item) {
- Intent preferences = new Intent();
- preferences.setClass(ViewImage.this, GallerySettings.class);
- startActivity(preferences);
- return true;
- }
- });
- item.setAlphabeticShortcut('p');
- item.setIcon(android.R.drawable.ic_menu_preferences);
-
- return true;
- }
-
- protected Runnable mDeletePhotoRunnable = new Runnable() {
- public void run() {
- mAllImages.removeImageAt(mCurrentPosition);
- if (mAllImages.getCount() == 0) {
- finish();
- return;
- } else {
- if (mCurrentPosition == mAllImages.getCount()) {
- mCurrentPosition -= 1;
- }
- }
- mImageView.clear();
- mCache.clear(); // Because the position number is changed.
- setImage(mCurrentPosition, true);
- }
- };
-
- @Override
- public boolean onPrepareOptionsMenu(Menu menu) {
-
- super.onPrepareOptionsMenu(menu);
- if (mPaused) return false;
-
- setMode(MODE_NORMAL);
- IImage image = mAllImages.getImageAt(mCurrentPosition);
-
- if (mImageMenuRunnable != null) {
- mImageMenuRunnable.gettingReadyToOpen(menu, image);
- }
-
- Uri uri = mAllImages.getImageAt(mCurrentPosition).fullSizeImageUri();
- MenuHelper.enableShareMenuItem(menu, MenuHelper.isWhiteListUri(uri));
-
- MenuHelper.enableShowOnMapMenuItem(menu, MenuHelper.hasLatLngData(image));
-
- return true;
- }
-
- @Override
- public boolean onMenuItemSelected(int featureId, MenuItem item) {
- boolean b = super.onMenuItemSelected(featureId, item);
- if (mImageMenuRunnable != null) {
- mImageMenuRunnable.aboutToCall(item,
- mAllImages.getImageAt(mCurrentPosition));
- }
- return b;
- }
-
- void setImage(int pos, boolean showControls) {
- mCurrentPosition = pos;
-
- Bitmap b = mCache.getBitmap(pos);
- if (b != null) {
- IImage image = mAllImages.getImageAt(pos);
- mImageView.setImageRotateBitmapResetBase(
- new RotateBitmap(b, image.getDegreesRotated()), true);
- updateZoomButtonsEnabled();
- }
-
- ImageGetterCallback cb = new ImageGetterCallback() {
- public void completed() {
- }
-
- public boolean wantsThumbnail(int pos, int offset) {
- return !mCache.hasBitmap(pos + offset);
- }
-
- public boolean wantsFullImage(int pos, int offset) {
- return offset == 0;
- }
-
- public int fullImageSizeToUse(int pos, int offset) {
- // this number should be bigger so that we can zoom. we may
- // need to get fancier and read in the fuller size image as the
- // user starts to zoom.
- // Originally the value is set to 480 in order to avoid OOM.
- // Now we set it to 2048 because of using
- // native memory allocation for Bitmaps.
- final int imageViewSize = 2048;
- return imageViewSize;
- }
-
- public int [] loadOrder() {
- return sOrderAdjacents;
- }
-
- public void imageLoaded(int pos, int offset, RotateBitmap bitmap,
- boolean isThumb) {
- // shouldn't get here after onPause()
-
- // We may get a result from a previous request. Ignore it.
- if (pos != mCurrentPosition) {
- bitmap.recycle();
- return;
- }
-
- if (isThumb) {
- mCache.put(pos + offset, bitmap.getBitmap());
- }
- if (offset == 0) {
- // isThumb: We always load thumb bitmap first, so we will
- // reset the supp matrix for then thumb bitmap, and keep
- // the supp matrix when the full bitmap is loaded.
- mImageView.setImageRotateBitmapResetBase(bitmap, isThumb);
- updateZoomButtonsEnabled();
- }
- }
- };
-
- // Could be null if we're stopping a slide show in the course of pausing
- if (mGetter != null) {
- mGetter.setPosition(pos, cb, mAllImages, mHandler);
- }
- updateActionIcons();
- if (showControls) showOnScreenControls();
- scheduleDismissOnScreenControls();
- }
-
- @Override
- public void onCreate(Bundle instanceState) {
- super.onCreate(instanceState);
-
- Intent intent = getIntent();
- mFullScreenInNormalMode = intent.getBooleanExtra(
- MediaStore.EXTRA_FULL_SCREEN, true);
- mShowActionIcons = intent.getBooleanExtra(
- MediaStore.EXTRA_SHOW_ACTION_ICONS, true);
-
- mPrefs = PreferenceManager.getDefaultSharedPreferences(this);
-
- setDefaultKeyMode(DEFAULT_KEYS_SHORTCUT);
- requestWindowFeature(Window.FEATURE_NO_TITLE);
- setContentView(R.layout.viewimage);
-
- mImageView = (ImageViewTouch) findViewById(R.id.image);
- mImageView.setEnableTrackballScroll(true);
- mCache = new BitmapCache(3);
- mImageView.setRecycler(mCache);
-
- makeGetter();
-
- mAnimationIndex = -1;
-
- mSlideShowInAnimation = new Animation[] {
- makeInAnimation(R.anim.transition_in),
- makeInAnimation(R.anim.slide_in),
- makeInAnimation(R.anim.slide_in_vertical),
- };
-
- mSlideShowOutAnimation = new Animation[] {
- makeOutAnimation(R.anim.transition_out),
- makeOutAnimation(R.anim.slide_out),
- makeOutAnimation(R.anim.slide_out_vertical),
- };
-
- mSlideShowImageViews[0] =
- (ImageViewTouchBase) findViewById(R.id.image1_slideShow);
- mSlideShowImageViews[1] =
- (ImageViewTouchBase) findViewById(R.id.image2_slideShow);
- for (ImageViewTouchBase v : mSlideShowImageViews) {
- v.setVisibility(View.INVISIBLE);
- v.setRecycler(mCache);
- }
-
- mActionIconPanel = findViewById(R.id.action_icon_panel);
-
- mParam = getIntent().getParcelableExtra(KEY_IMAGE_LIST);
-
- boolean slideshow;
- if (instanceState != null) {
- mSavedUri = instanceState.getParcelable(STATE_URI);
- slideshow = instanceState.getBoolean(STATE_SLIDESHOW, false);
- mShowControls = instanceState.getBoolean(STATE_SHOW_CONTROLS, true);
- } else {
- mSavedUri = getIntent().getData();
- slideshow = intent.getBooleanExtra(EXTRA_SLIDESHOW, false);
- }
-
- // We only show action icons for URIs that we know we can share and
- // delete. Although we get read permission (for the images) from
- // applications like MMS, we cannot pass the permission to other
- // activities due to the current framework design.
- if (!MenuHelper.isWhiteListUri(mSavedUri)) {
- mShowActionIcons = false;
- }
-
- if (mShowActionIcons) {
- int[] pickIds = {R.id.attach, R.id.cancel};
- int[] normalIds = {R.id.setas, R.id.play, R.id.share, R.id.discard};
- int[] connectIds = isPickIntent() ? pickIds : normalIds;
- for (int id : connectIds) {
- View view = mActionIconPanel.findViewById(id);
- view.setVisibility(View.VISIBLE);
- view.setOnClickListener(this);
- }
- }
-
- // Don't show the "delete" icon for SingleImageList.
- if (ImageManager.isSingleImageMode(mSavedUri.toString())) {
- mActionIconPanel.findViewById(R.id.discard)
- .setVisibility(View.GONE);
- }
-
- if (slideshow) {
- setMode(MODE_SLIDESHOW);
- } else {
- if (mFullScreenInNormalMode) {
- getWindow().addFlags(
- WindowManager.LayoutParams.FLAG_FULLSCREEN);
- }
- if (mShowActionIcons) {
- mActionIconPanel.setVisibility(View.VISIBLE);
- }
- }
-
- setupOnScreenControls(findViewById(R.id.rootLayout), mImageView);
- }
-
- private void updateActionIcons() {
- if (isPickIntent()) return;
-
- IImage image = mAllImages.getImageAt(mCurrentPosition);
- View panel = mActionIconPanel;
- if (image instanceof VideoObject) {
- panel.findViewById(R.id.setas).setVisibility(View.GONE);
- panel.findViewById(R.id.play).setVisibility(View.VISIBLE);
- } else {
- panel.findViewById(R.id.setas).setVisibility(View.VISIBLE);
- panel.findViewById(R.id.play).setVisibility(View.GONE);
- }
- }
-
- private Animation makeInAnimation(int id) {
- Animation inAnimation = AnimationUtils.loadAnimation(this, id);
- return inAnimation;
- }
-
- private Animation makeOutAnimation(int id) {
- Animation outAnimation = AnimationUtils.loadAnimation(this, id);
- return outAnimation;
- }
-
- private static int getPreferencesInteger(
- SharedPreferences prefs, String key, int defaultValue) {
- String value = prefs.getString(key, null);
- try {
- return value == null ? defaultValue : Integer.parseInt(value);
- } catch (NumberFormatException ex) {
- Log.e(TAG, "couldn't parse preference: " + value, ex);
- return defaultValue;
- }
- }
-
- void setMode(int mode) {
- if (mMode == mode) {
- return;
- }
- View slideshowPanel = findViewById(R.id.slideShowContainer);
- View normalPanel = findViewById(R.id.abs);
-
- Window win = getWindow();
- mMode = mode;
- if (mode == MODE_SLIDESHOW) {
- slideshowPanel.setVisibility(View.VISIBLE);
- normalPanel.setVisibility(View.GONE);
-
- win.addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN
- | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
-
- mImageView.clear();
- mActionIconPanel.setVisibility(View.GONE);
-
- slideshowPanel.getRootView().requestLayout();
-
- // The preferences we want to read:
- // mUseShuffleOrder
- // mSlideShowLoop
- // mAnimationIndex
- // mSlideShowInterval
-
- mUseShuffleOrder = mPrefs.getBoolean(PREF_SHUFFLE_SLIDESHOW, false);
- mSlideShowLoop = mPrefs.getBoolean(PREF_SLIDESHOW_REPEAT, false);
- mAnimationIndex = getPreferencesInteger(
- mPrefs, "pref_gallery_slideshow_transition_key", 0);
- mSlideShowInterval = getPreferencesInteger(
- mPrefs, "pref_gallery_slideshow_interval_key", 3) * 1000;
- } else {
- slideshowPanel.setVisibility(View.GONE);
- normalPanel.setVisibility(View.VISIBLE);
-
- win.clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
- if (mFullScreenInNormalMode) {
- win.addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
- } else {
- win.clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
- }
-
- if (mGetter != null) {
- mGetter.cancelCurrent();
- }
-
- if (mShowActionIcons) {
- Animation animation = new AlphaAnimation(0F, 1F);
- animation.setDuration(500);
- mActionIconPanel.setAnimation(animation);
- mActionIconPanel.setVisibility(View.VISIBLE);
- }
-
- ImageViewTouchBase dst = mImageView;
- dst.mLastXTouchPos = -1;
- dst.mLastYTouchPos = -1;
-
- for (ImageViewTouchBase ivt : mSlideShowImageViews) {
- ivt.clear();
- }
-
- mShuffleOrder = null;
-
- // mGetter null is a proxy for being paused
- if (mGetter != null) {
- setImage(mCurrentPosition, true);
- }
- }
- }
-
- private void generateShuffleOrder() {
- if (mShuffleOrder == null
- || mShuffleOrder.length != mAllImages.getCount()) {
- mShuffleOrder = new int[mAllImages.getCount()];
- for (int i = 0, n = mShuffleOrder.length; i < n; i++) {
- mShuffleOrder[i] = i;
- }
- }
-
- for (int i = mShuffleOrder.length - 1; i >= 0; i--) {
- int r = mRandom.nextInt(i + 1);
- if (r != i) {
- int tmp = mShuffleOrder[r];
- mShuffleOrder[r] = mShuffleOrder[i];
- mShuffleOrder[i] = tmp;
- }
- }
- }
-
- private void loadNextImage(final int requestedPos, final long delay,
- final boolean firstCall) {
- if (firstCall && mUseShuffleOrder) {
- generateShuffleOrder();
- }
-
- final long targetDisplayTime = System.currentTimeMillis() + delay;
-
- ImageGetterCallback cb = new ImageGetterCallback() {
- public void completed() {
- }
-
- public boolean wantsThumbnail(int pos, int offset) {
- return true;
- }
-
- public boolean wantsFullImage(int pos, int offset) {
- return false;
- }
-
- public int [] loadOrder() {
- return sOrderSlideshow;
- }
-
- public int fullImageSizeToUse(int pos, int offset) {
- return 480; // TODO compute this
- }
-
- public void imageLoaded(final int pos, final int offset,
- final RotateBitmap bitmap, final boolean isThumb) {
- long timeRemaining = Math.max(0,
- targetDisplayTime - System.currentTimeMillis());
- mHandler.postDelayedGetterCallback(new Runnable() {
- public void run() {
- if (mMode == MODE_NORMAL) {
- return;
- }
-
- ImageViewTouchBase oldView =
- mSlideShowImageViews[mSlideShowImageCurrent];
-
- if (++mSlideShowImageCurrent
- == mSlideShowImageViews.length) {
- mSlideShowImageCurrent = 0;
- }
-
- ImageViewTouchBase newView =
- mSlideShowImageViews[mSlideShowImageCurrent];
- newView.setVisibility(View.VISIBLE);
- newView.setImageRotateBitmapResetBase(bitmap, true);
- newView.bringToFront();
-
- int animation = 0;
-
- if (mAnimationIndex == -1) {
- int n = mRandom.nextInt(
- mSlideShowInAnimation.length);
- animation = n;
- } else {
- animation = mAnimationIndex;
- }
-
- Animation aIn = mSlideShowInAnimation[animation];
- newView.startAnimation(aIn);
- newView.setVisibility(View.VISIBLE);
-
- Animation aOut = mSlideShowOutAnimation[animation];
- oldView.setVisibility(View.INVISIBLE);
- oldView.startAnimation(aOut);
-
- mCurrentPosition = requestedPos;
-
- if (mCurrentPosition == mLastSlideShowImage
- && !firstCall) {
- if (mSlideShowLoop) {
- if (mUseShuffleOrder) {
- generateShuffleOrder();
- }
- } else {
- setMode(MODE_NORMAL);
- return;
- }
- }
-
- loadNextImage(
- (mCurrentPosition + 1) % mAllImages.getCount(),
- mSlideShowInterval, false);
- }
- }, timeRemaining);
- }
- };
- // Could be null if we're stopping a slide show in the course of pausing
- if (mGetter != null) {
- int pos = requestedPos;
- if (mShuffleOrder != null) {
- pos = mShuffleOrder[pos];
- }
- mGetter.setPosition(pos, cb, mAllImages, mHandler);
- }
- }
-
- private void makeGetter() {
- mGetter = new ImageGetter(getContentResolver());
- }
-
- private IImageList buildImageListFromUri(Uri uri) {
- String sortOrder = mPrefs.getString(
- "pref_gallery_sort_key", "descending");
- int sort = sortOrder.equals("ascending")
- ? ImageManager.SORT_ASCENDING
- : ImageManager.SORT_DESCENDING;
- return ImageManager.makeImageList(getContentResolver(), uri, sort);
- }
-
- private boolean init(Uri uri) {
- if (uri == null) return false;
- mAllImages = (mParam == null)
- ? buildImageListFromUri(uri)
- : ImageManager.makeImageList(getContentResolver(), mParam);
- IImage image = mAllImages.getImageForUri(uri);
- if (image == null) return false;
- mCurrentPosition = mAllImages.getImageIndex(image);
- mLastSlideShowImage = mCurrentPosition;
- return true;
- }
-
- private Uri getCurrentUri() {
- if (mAllImages.getCount() == 0) return null;
- IImage image = mAllImages.getImageAt(mCurrentPosition);
- if (image == null) return null;
- return image.fullSizeImageUri();
- }
-
- @Override
- public void onSaveInstanceState(Bundle b) {
- super.onSaveInstanceState(b);
- b.putParcelable(STATE_URI,
- mAllImages.getImageAt(mCurrentPosition).fullSizeImageUri());
- b.putBoolean(STATE_SLIDESHOW, mMode == MODE_SLIDESHOW);
- }
-
- @Override
- public void onStart() {
- super.onStart();
- mPaused = false;
-
- if (!init(mSavedUri)) {
- Log.w(TAG, "init failed: " + mSavedUri);
- finish();
- return;
- }
-
- // normally this will never be zero but if one "backs" into this
- // activity after removing the sdcard it could be zero. in that
- // case just "finish" since there's nothing useful that can happen.
- int count = mAllImages.getCount();
- if (count == 0) {
- finish();
- return;
- } else if (count <= mCurrentPosition) {
- mCurrentPosition = count - 1;
- }
-
- if (mGetter == null) {
- makeGetter();
- }
-
- if (mMode == MODE_SLIDESHOW) {
- loadNextImage(mCurrentPosition, 0, true);
- } else { // MODE_NORMAL
- setImage(mCurrentPosition, mShowControls);
- mShowControls = false;
- }
- }
-
- @Override
- public void onStop() {
- super.onStop();
- mPaused = true;
-
- // mGetter could be null if we call finish() and leave early in
- // onStart().
- if (mGetter != null) {
- mGetter.cancelCurrent();
- mGetter.stop();
- mGetter = null;
- }
- setMode(MODE_NORMAL);
-
- // removing all callback in the message queue
- mHandler.removeAllGetterCallbacks();
-
- if (mAllImages != null) {
- mSavedUri = getCurrentUri();
- mAllImages.close();
- mAllImages = null;
- }
-
- hideOnScreenControls();
- mImageView.clear();
- mCache.clear();
-
- for (ImageViewTouchBase iv : mSlideShowImageViews) {
- iv.clear();
- }
- }
-
- private void startShareMediaActivity(IImage image) {
- boolean isVideo = image instanceof VideoObject;
- Intent intent = new Intent();
- intent.setAction(Intent.ACTION_SEND);
- intent.setType(image.getMimeType());
- intent.putExtra(Intent.EXTRA_STREAM, image.fullSizeImageUri());
- try {
- startActivity(Intent.createChooser(intent, getText(
- isVideo ? R.string.sendVideo : R.string.sendImage)));
- } catch (android.content.ActivityNotFoundException ex) {
- Toast.makeText(this, isVideo
- ? R.string.no_way_to_share_image
- : R.string.no_way_to_share_video,
- Toast.LENGTH_SHORT).show();
- }
- }
-
- private void startPlayVideoActivity() {
- IImage image = mAllImages.getImageAt(mCurrentPosition);
- Intent intent = new Intent(
- Intent.ACTION_VIEW, image.fullSizeImageUri());
- try {
- startActivity(intent);
- } catch (android.content.ActivityNotFoundException ex) {
- Log.e(TAG, "Couldn't view video " + image.fullSizeImageUri(), ex);
- }
- }
-
- public void onClick(View v) {
- switch (v.getId()) {
- case R.id.discard:
- MenuHelper.deletePhoto(this, mDeletePhotoRunnable);
- break;
- case R.id.play:
- startPlayVideoActivity();
- break;
- case R.id.share: {
- IImage image = mAllImages.getImageAt(mCurrentPosition);
- if (!MenuHelper.isWhiteListUri(image.fullSizeImageUri())) {
- return;
- }
- startShareMediaActivity(image);
- break;
- }
- case R.id.setas: {
- IImage image = mAllImages.getImageAt(mCurrentPosition);
- Intent intent = Util.createSetAsIntent(image);
- try {
- startActivity(Intent.createChooser(
- intent, getText(R.string.setImage)));
- } catch (android.content.ActivityNotFoundException ex) {
- Toast.makeText(this, R.string.no_way_to_share_video,
- Toast.LENGTH_SHORT).show();
- }
- break;
- }
- case R.id.next_image:
- moveNextOrPrevious(1);
- break;
- case R.id.prev_image:
- moveNextOrPrevious(-1);
- break;
- }
- }
-
- private void moveNextOrPrevious(int delta) {
- int nextImagePos = mCurrentPosition + delta;
- if ((0 <= nextImagePos) && (nextImagePos < mAllImages.getCount())) {
- setImage(nextImagePos, true);
- showOnScreenControls();
- }
- }
-
- @Override
- protected void onActivityResult(int requestCode, int resultCode,
- Intent data) {
- switch (requestCode) {
- case MenuHelper.RESULT_COMMON_MENU_CROP:
- if (resultCode == RESULT_OK) {
- // The CropImage activity passes back the Uri of the
- // cropped image as the Action rather than the Data.
- mSavedUri = Uri.parse(data.getAction());
-
- // if onStart() runs before, then set the returned
- // image as currentImage.
- if (mAllImages != null) {
- IImage image = mAllImages.getImageForUri(mSavedUri);
- // image could be null if SD card is removed.
- if (image == null) {
- finish();
- } else {
- mCurrentPosition = mAllImages.getImageIndex(image);
- setImage(mCurrentPosition, false);
- }
- }
- }
- break;
- }
- }
-}
-
-class ImageViewTouch extends ImageViewTouchBase {
- private final ViewImage mViewImage;
- private boolean mEnableTrackballScroll;
-
- public ImageViewTouch(Context context) {
- super(context);
- mViewImage = (ViewImage) context;
- }
-
- public ImageViewTouch(Context context, AttributeSet attrs) {
- super(context, attrs);
- mViewImage = (ViewImage) context;
- }
-
- public void setEnableTrackballScroll(boolean enable) {
- mEnableTrackballScroll = enable;
- }
-
- protected void postTranslateCenter(float dx, float dy) {
- super.postTranslate(dx, dy);
- center(true, true);
- }
-
- private static final float PAN_RATE = 20;
-
- // This is the time we allow the dpad to change the image position again.
- private long mNextChangePositionTime;
-
- @Override
- public boolean onKeyDown(int keyCode, KeyEvent event) {
- if (mViewImage.mPaused) return false;
-
- // Don't respond to arrow keys if trackball scrolling is not enabled
- if (!mEnableTrackballScroll) {
- if ((keyCode >= KeyEvent.KEYCODE_DPAD_UP)
- && (keyCode <= KeyEvent.KEYCODE_DPAD_RIGHT)) {
- return super.onKeyDown(keyCode, event);
- }
- }
-
- int current = mViewImage.mCurrentPosition;
-
- int nextImagePos = -2; // default no next image
- try {
- switch (keyCode) {
- case KeyEvent.KEYCODE_DPAD_CENTER: {
- if (mViewImage.isPickIntent()) {
- IImage img = mViewImage.mAllImages
- .getImageAt(mViewImage.mCurrentPosition);
- mViewImage.setResult(ViewImage.RESULT_OK,
- new Intent().setData(img.fullSizeImageUri()));
- mViewImage.finish();
- }
- break;
- }
- case KeyEvent.KEYCODE_DPAD_LEFT: {
- if (getScale() <= 1F && event.getEventTime()
- >= mNextChangePositionTime) {
- nextImagePos = current - 1;
- mNextChangePositionTime = event.getEventTime() + 500;
- } else {
- panBy(PAN_RATE, 0);
- center(true, false);
- }
- return true;
- }
- case KeyEvent.KEYCODE_DPAD_RIGHT: {
- if (getScale() <= 1F && event.getEventTime()
- >= mNextChangePositionTime) {
- nextImagePos = current + 1;
- mNextChangePositionTime = event.getEventTime() + 500;
- } else {
- panBy(-PAN_RATE, 0);
- center(true, false);
- }
- return true;
- }
- case KeyEvent.KEYCODE_DPAD_UP: {
- panBy(0, PAN_RATE);
- center(false, true);
- return true;
- }
- case KeyEvent.KEYCODE_DPAD_DOWN: {
- panBy(0, -PAN_RATE);
- center(false, true);
- return true;
- }
- case KeyEvent.KEYCODE_DEL:
- MenuHelper.deletePhoto(
- mViewImage, mViewImage.mDeletePhotoRunnable);
- break;
- }
- } finally {
- if (nextImagePos >= 0
- && nextImagePos < mViewImage.mAllImages.getCount()) {
- synchronized (mViewImage) {
- mViewImage.setMode(ViewImage.MODE_NORMAL);
- mViewImage.setImage(nextImagePos, true);
- }
- } else if (nextImagePos != -2) {
- center(true, true);
- }
- }
-
- return super.onKeyDown(keyCode, event);
- }
-}
-
-// This is a cache for Bitmap displayed in ViewImage (normal mode, thumb only).
-class BitmapCache implements ImageViewTouchBase.Recycler {
- public static class Entry {
- int mPos;
- Bitmap mBitmap;
- public Entry() {
- clear();
- }
- public void clear() {
- mPos = -1;
- mBitmap = null;
- }
- }
-
- private final Entry[] mCache;
-
- public BitmapCache(int size) {
- mCache = new Entry[size];
- for (int i = 0; i < mCache.length; i++) {
- mCache[i] = new Entry();
- }
- }
-
- // Given the position, find the associated entry. Returns null if there is
- // no such entry.
- private Entry findEntry(int pos) {
- for (Entry e : mCache) {
- if (pos == e.mPos) {
- return e;
- }
- }
- return null;
- }
-
- // Returns the thumb bitmap if we have it, otherwise return null.
- public synchronized Bitmap getBitmap(int pos) {
- Entry e = findEntry(pos);
- if (e != null) {
- return e.mBitmap;
- }
- return null;
- }
-
- public synchronized void put(int pos, Bitmap bitmap) {
- // First see if we already have this entry.
- if (findEntry(pos) != null) {
- return;
- }
-
- // Find the best entry we should replace.
- // See if there is any empty entry.
- // Otherwise assuming sequential access, kick out the entry with the
- // greatest distance.
- Entry best = null;
- int maxDist = -1;
- for (Entry e : mCache) {
- if (e.mPos == -1) {
- best = e;
- break;
- } else {
- int dist = Math.abs(pos - e.mPos);
- if (dist > maxDist) {
- maxDist = dist;
- best = e;
- }
- }
- }
-
- // Recycle the image being kicked out.
- // This only works because our current usage is sequential, so we
- // do not happen to recycle the image being displayed.
- if (best.mBitmap != null) {
- best.mBitmap.recycle();
- }
-
- best.mPos = pos;
- best.mBitmap = bitmap;
- }
-
- // Recycle all bitmaps in the cache and clear the cache.
- public synchronized void clear() {
- for (Entry e : mCache) {
- if (e.mBitmap != null) {
- e.mBitmap.recycle();
- }
- e.clear();
- }
- }
-
- // Returns whether the bitmap is in the cache.
- public synchronized boolean hasBitmap(int pos) {
- Entry e = findEntry(pos);
- return (e != null);
- }
-
- // Recycle the bitmap if it's not in the cache.
- // The input must be non-null.
- public synchronized void recycle(Bitmap b) {
- for (Entry e : mCache) {
- if (e.mPos != -1) {
- if (e.mBitmap == b) {
- return;
- }
- }
- }
- b.recycle();
- }
-}
diff --git a/src/com/android/camera/Wallpaper.java b/src/com/android/camera/Wallpaper.java
deleted file mode 100644
index a715958a..00000000
--- a/src/com/android/camera/Wallpaper.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Copyright (C) 2007 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.camera;
-
-import android.app.Activity;
-import android.content.Intent;
-import android.net.Uri;
-import android.os.Bundle;
-
-/**
- * Wallpaper picker for the camera application. This just redirects to the
- * standard pick action.
- */
-public class Wallpaper extends NoSearchActivity {
- @SuppressWarnings("unused")
- private static final String TAG = "Wallpaper";
- private static final int PHOTO_PICKED = 1;
- private static final int CROP_DONE = 2;
-
- @Override
- protected void onCreate(Bundle icicle) {
- super.onCreate(icicle);
-
- Uri imageToUse = getIntent().getData();
- if (imageToUse != null) {
- Intent intent = new Intent();
- intent.setClassName("com.android.camera",
- "com.android.camera.CropImage");
- intent.setData(imageToUse);
- formatIntent(intent);
- startActivityForResult(intent, CROP_DONE);
- } else {
- Intent intent = new Intent(Intent.ACTION_GET_CONTENT, null);
- intent.setType("image/*");
- intent.putExtra("crop", "true");
- formatIntent(intent);
- startActivityForResult(intent, PHOTO_PICKED);
- }
- }
-
- protected void formatIntent(Intent intent) {
- int width = getWallpaperDesiredMinimumWidth();
- int height = getWallpaperDesiredMinimumHeight();
- intent.putExtra("outputX", width);
- intent.putExtra("outputY", height);
- intent.putExtra("aspectX", width);
- intent.putExtra("aspectY", height);
- intent.putExtra("scale", true);
- intent.putExtra("noFaceDetection", true);
- intent.putExtra("setWallpaper", true);
- }
-
- @Override
- protected void onActivityResult(int requestCode, int resultCode,
- Intent data) {
- if ((requestCode == PHOTO_PICKED || requestCode == CROP_DONE)) {
- setResult(resultCode);
- finish();
- }
- }
-}
diff --git a/src/com/android/camera/gallery/BaseImage.java b/src/com/android/camera/gallery/BaseImage.java
index 6e2f8f1a..42d0f66d 100644
--- a/src/com/android/camera/gallery/BaseImage.java
+++ b/src/com/android/camera/gallery/BaseImage.java
@@ -117,10 +117,6 @@ public abstract class BaseImage implements IImage {
}
}
- public long fullSizeImageId() {
- return mId;
- }
-
public Uri fullSizeImageUri() {
return mUri;
}
diff --git a/src/com/android/camera/gallery/IImage.java b/src/com/android/camera/gallery/IImage.java
index bad41ccc..8b443d6d 100644
--- a/src/com/android/camera/gallery/IImage.java
+++ b/src/com/android/camera/gallery/IImage.java
@@ -47,7 +47,6 @@ public interface IImage {
/** Get the input stream associated with a given full size image. */
public abstract InputStream fullSizeImageData();
- public abstract long fullSizeImageId();
public abstract Uri fullSizeImageUri();
/** Get the path of the (full size) image data. */
diff --git a/src/com/android/camera/gallery/IImageList.java b/src/com/android/camera/gallery/IImageList.java
index 07a6bb28..6ea1be06 100644
--- a/src/com/android/camera/gallery/IImageList.java
+++ b/src/com/android/camera/gallery/IImageList.java
@@ -44,7 +44,6 @@ import java.util.HashMap;
* The interface of all image collections used in gallery.
*/
public interface IImageList {
- public HashMap<String, String> getBucketIds();
/**
* Returns the count of image objects.
diff --git a/src/com/android/camera/gallery/ImageList.java b/src/com/android/camera/gallery/ImageList.java
index 9a47e55b..3dee3d16 100644
--- a/src/com/android/camera/gallery/ImageList.java
+++ b/src/com/android/camera/gallery/ImageList.java
@@ -35,26 +35,6 @@ public class ImageList extends BaseImageList implements IImageList {
private static final String[] ACCEPTABLE_IMAGE_TYPES =
new String[] { "image/jpeg", "image/png", "image/gif" };
- public HashMap<String, String> getBucketIds() {
- Uri uri = mBaseUri.buildUpon()
- .appendQueryParameter("distinct", "true").build();
- Cursor cursor = Media.query(
- mContentResolver, uri,
- new String[] {
- Media.BUCKET_DISPLAY_NAME,
- Media.BUCKET_ID},
- whereClause(), whereClauseArgs(), null);
- try {
- HashMap<String, String> hash = new HashMap<String, String>();
- while (cursor.moveToNext()) {
- hash.put(cursor.getString(1), cursor.getString(0));
- }
- return hash;
- } finally {
- cursor.close();
- }
- }
-
/**
* ImageList constructor.
*/
diff --git a/src/com/android/camera/gallery/ImageListUber.java b/src/com/android/camera/gallery/ImageListUber.java
index 95146ae3..85f93375 100644
--- a/src/com/android/camera/gallery/ImageListUber.java
+++ b/src/com/android/camera/gallery/ImageListUber.java
@@ -68,14 +68,6 @@ public class ImageListUber implements IImageList {
}
}
- public HashMap<String, String> getBucketIds() {
- HashMap<String, String> hashMap = new HashMap<String, String>();
- for (IImageList list : mSubList) {
- hashMap.putAll(list.getBucketIds());
- }
- return hashMap;
- }
-
public int getCount() {
int count = 0;
for (IImageList subList : mSubList) {
diff --git a/src/com/android/camera/gallery/SingleImageList.java b/src/com/android/camera/gallery/SingleImageList.java
index 8abb306f..7963cf85 100644
--- a/src/com/android/camera/gallery/SingleImageList.java
+++ b/src/com/android/camera/gallery/SingleImageList.java
@@ -38,10 +38,6 @@ public class SingleImageList implements IImageList {
mSingleImage = new UriImage(this, resolver, uri);
}
- public HashMap<String, String> getBucketIds() {
- throw new UnsupportedOperationException();
- }
-
public int getCount() {
return 1;
}
diff --git a/src/com/android/camera/gallery/UriImage.java b/src/com/android/camera/gallery/UriImage.java
index 0db1633c..0f27b240 100644
--- a/src/com/android/camera/gallery/UriImage.java
+++ b/src/com/android/camera/gallery/UriImage.java
@@ -156,10 +156,6 @@ class UriImage implements IImage {
return (options != null) ? options.outWidth : 0;
}
- public long fullSizeImageId() {
- return 0;
- }
-
public IImageList getContainer() {
return mContainer;
}
diff --git a/src/com/android/camera/gallery/VideoList.java b/src/com/android/camera/gallery/VideoList.java
index c22a206a..fc57baac 100644
--- a/src/com/android/camera/gallery/VideoList.java
+++ b/src/com/android/camera/gallery/VideoList.java
@@ -79,27 +79,6 @@ public class VideoList extends BaseImageList {
super(resolver, uri, sort, bucketId);
}
- public HashMap<String, String> getBucketIds() {
- Uri uri = mBaseUri.buildUpon()
- .appendQueryParameter("distinct", "true").build();
- Cursor c = Images.Media.query(
- mContentResolver, uri,
- new String[] {
- Media.BUCKET_DISPLAY_NAME,
- Media.BUCKET_ID
- },
- whereClause(), whereClauseArgs(), sortOrder());
- try {
- HashMap<String, String> hash = new HashMap<String, String>();
- while (c.moveToNext()) {
- hash.put(c.getString(1), c.getString(0));
- }
- return hash;
- } finally {
- c.close();
- }
- }
-
protected String whereClause() {
return mBucketId != null
? Images.Media.BUCKET_ID + " = '" + mBucketId + "'"
diff --git a/src/com/android/camera/gallery/VideoObject.java b/src/com/android/camera/gallery/VideoObject.java
index 589e42fc..d6e50606 100644
--- a/src/com/android/camera/gallery/VideoObject.java
+++ b/src/com/android/camera/gallery/VideoObject.java
@@ -79,11 +79,6 @@ public class VideoObject extends BaseImage implements IImage {
}
@Override
- public long fullSizeImageId() {
- return mId;
- }
-
- @Override
public int getHeight() {
return 0;
}
@@ -125,4 +120,4 @@ public class VideoObject extends BaseImage implements IImage {
public String toString() {
return new StringBuilder("VideoObject").append(mId).toString();
}
-} \ No newline at end of file
+}
diff --git a/tests/src/com/android/camera/gallery/ImageListUberUnitTests.java b/tests/src/com/android/camera/gallery/ImageListUberUnitTests.java
deleted file mode 100644
index 30487f29..00000000
--- a/tests/src/com/android/camera/gallery/ImageListUberUnitTests.java
+++ /dev/null
@@ -1,89 +0,0 @@
-package com.android.camera.gallery;
-
-import com.android.camera.ImageManager;
-
-import android.test.AndroidTestCase;
-
-public class ImageListUberUnitTests extends AndroidTestCase {
-
- public void testTheOrderOfGetImageAt() {
- MockImageList listA = new MockImageList();
- MockImageList listB = new MockImageList();
- listA.addImage(new MockImage(2, 2));
- listA.addImage(new MockImage(0, 0));
- listB.addImage(new MockImage(1, 1));
- ImageListUber uber = new ImageListUber(
- new IImageList[] {listA, listB}, ImageManager.SORT_DESCENDING);
-
- assertEquals(2, uber.getImageAt(0).fullSizeImageId());
- assertEquals(1, uber.getImageAt(1).fullSizeImageId());
- assertEquals(0, uber.getImageAt(2).fullSizeImageId());
- uber.close();
-
- uber = new ImageListUber(
- new IImageList[] {listA, listB}, ImageManager.SORT_DESCENDING);
- assertEquals(2, uber.getImageAt(0).fullSizeImageId());
- assertEquals(1, uber.getImageAt(1).fullSizeImageId());
- assertEquals(0, uber.getImageAt(2).fullSizeImageId());
- uber.close();
- }
-
- public void testTheOrderOfGetImageAtCaseTwo() {
- MockImageList listA = new MockImageList();
- MockImageList listB = new MockImageList();
- listA.addImage(new MockImage(2, 2));
- listA.addImage(new MockImage(1, 1));
- listB.addImage(new MockImage(0, 0));
- ImageListUber uber = new ImageListUber(
- new IImageList[] {listB, listA}, ImageManager.SORT_DESCENDING);
-
- assertEquals(2, uber.getImageAt(0).fullSizeImageId());
- assertEquals(1, uber.getImageAt(1).fullSizeImageId());
- assertEquals(0, uber.getImageAt(2).fullSizeImageId());
- uber.close();
-
- uber = new ImageListUber(
- new IImageList[] {listA, listB}, ImageManager.SORT_DESCENDING);
-
- assertEquals(2, uber.getImageAt(0).fullSizeImageId());
- assertEquals(1, uber.getImageAt(1).fullSizeImageId());
- assertEquals(0, uber.getImageAt(2).fullSizeImageId());
- uber.close();
- }
-
- public void testRemoveImage() {
- MockImageList listA = new MockImageList();
- MockImageList listB = new MockImageList();
- MockImage target = new MockImage(1, 1);
- listA.addImage(new MockImage(2, 2));
- listA.addImage(new MockImage(0, 0));
- listB.addImage(target);
- ImageListUber uber = new ImageListUber(
- new IImageList[] {listB, listA}, ImageManager.SORT_DESCENDING);
- uber.removeImage(target);
- assertEquals(2, uber.getImageAt(0).fullSizeImageId());
- assertEquals(0, uber.getImageAt(1).fullSizeImageId());
-
- assertEquals(0, uber.getImageIndex(uber.getImageAt(0)));
- assertEquals(1, uber.getImageIndex(uber.getImageAt(1)));
- uber.close();
- }
-
- public void testRemoveImageAt() {
- MockImageList listA = new MockImageList();
- MockImageList listB = new MockImageList();
- MockImage target = new MockImage(1, 1);
- listA.addImage(new MockImage(2, 2));
- listA.addImage(new MockImage(0, 0));
- listB.addImage(target);
- ImageListUber uber = new ImageListUber(
- new IImageList[] {listB, listA}, ImageManager.SORT_DESCENDING);
- uber.removeImageAt(1);
- assertEquals(2, uber.getImageAt(0).fullSizeImageId());
- assertEquals(0, uber.getImageAt(1).fullSizeImageId());
-
- assertEquals(0, uber.getImageIndex(uber.getImageAt(0)));
- assertEquals(1, uber.getImageIndex(uber.getImageAt(1)));
- uber.close();
- }
-}