am 27a76801: am c7e89dae: Update thumbnail if a picture is deleted in background.
* commit '27a768018b18f45b9dd912bafd09dea64460f852':
Update thumbnail if a picture is deleted in background.
diff --git a/gallerycommon/src/com/android/gallery3d/common/ApiHelper.java b/gallerycommon/src/com/android/gallery3d/common/ApiHelper.java
new file mode 100644
index 0000000..15026bb
--- /dev/null
+++ b/gallerycommon/src/com/android/gallery3d/common/ApiHelper.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2012 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.gallery3d.common;
+
+import android.provider.MediaStore.MediaColumns;
+import android.view.View;
+
+public class ApiHelper {
+
+ public static final boolean HAS_VIEW_SYSTEM_UI_FLAG_LAYOUT_STABLE =
+ hasField(View.class, "SYSTEM_UI_FLAG_LAYOUT_STABLE");
+
+ public static final boolean HAS_VIEW_SYSTEM_UI_FLAG_HIDE_NAVIGATION =
+ hasField(View.class, "SYSTEM_UI_FLAG_HIDE_NAVIGATION");
+
+ public static final boolean HAS_MEDIA_COLUMNS_WIDTH_AND_HEIGHT =
+ hasField(MediaColumns.class, "WIDTH");
+
+ private static boolean hasField(Class<?> klass, String fieldName) {
+ try {
+ klass.getDeclaredField(fieldName);
+ return true;
+ } catch (NoSuchFieldException e) {
+ return false;
+ }
+ }
+}
diff --git a/gallerycommon/src/com/android/gallery3d/common/LongSparseArray.java b/gallerycommon/src/com/android/gallery3d/common/LongSparseArray.java
new file mode 100644
index 0000000..b3298e6
--- /dev/null
+++ b/gallerycommon/src/com/android/gallery3d/common/LongSparseArray.java
@@ -0,0 +1,368 @@
+/*
+ * 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.gallery3d.common;
+
+
+// Copied from android.util.LongSparseArray for unbundling
+
+/**
+ * SparseArray mapping longs to Objects. Unlike a normal array of Objects,
+ * there can be gaps in the indices. It is intended to be more efficient
+ * than using a HashMap to map Longs to Objects.
+ */
+public class LongSparseArray<E> implements Cloneable {
+ private static final Object DELETED = new Object();
+ private boolean mGarbage = false;
+
+ private long[] mKeys;
+ private Object[] mValues;
+ private int mSize;
+
+ /**
+ * Creates a new LongSparseArray containing no mappings.
+ */
+ public LongSparseArray() {
+ this(10);
+ }
+
+ /**
+ * Creates a new LongSparseArray containing no mappings that will not
+ * require any additional memory allocation to store the specified
+ * number of mappings.
+ */
+ public LongSparseArray(int initialCapacity) {
+ initialCapacity = idealLongArraySize(initialCapacity);
+
+ mKeys = new long[initialCapacity];
+ mValues = new Object[initialCapacity];
+ mSize = 0;
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public LongSparseArray<E> clone() {
+ LongSparseArray<E> clone = null;
+ try {
+ clone = (LongSparseArray<E>) super.clone();
+ clone.mKeys = mKeys.clone();
+ clone.mValues = mValues.clone();
+ } catch (CloneNotSupportedException cnse) {
+ /* ignore */
+ }
+ return clone;
+ }
+
+ /**
+ * Gets the Object mapped from the specified key, or <code>null</code>
+ * if no such mapping has been made.
+ */
+ public E get(long key) {
+ return get(key, null);
+ }
+
+ /**
+ * Gets the Object mapped from the specified key, or the specified Object
+ * if no such mapping has been made.
+ */
+ @SuppressWarnings("unchecked")
+ public E get(long key, E valueIfKeyNotFound) {
+ int i = binarySearch(mKeys, 0, mSize, key);
+
+ if (i < 0 || mValues[i] == DELETED) {
+ return valueIfKeyNotFound;
+ } else {
+ return (E) mValues[i];
+ }
+ }
+
+ /**
+ * Removes the mapping from the specified key, if there was any.
+ */
+ public void delete(long key) {
+ int i = binarySearch(mKeys, 0, mSize, key);
+
+ if (i >= 0) {
+ if (mValues[i] != DELETED) {
+ mValues[i] = DELETED;
+ mGarbage = true;
+ }
+ }
+ }
+
+ /**
+ * Alias for {@link #delete(long)}.
+ */
+ public void remove(long key) {
+ delete(key);
+ }
+
+ /**
+ * Removes the mapping at the specified index.
+ */
+ public void removeAt(int index) {
+ if (mValues[index] != DELETED) {
+ mValues[index] = DELETED;
+ mGarbage = true;
+ }
+ }
+
+ private void gc() {
+ // Log.e("SparseArray", "gc start with " + mSize);
+
+ int n = mSize;
+ int o = 0;
+ long[] keys = mKeys;
+ Object[] values = mValues;
+
+ for (int i = 0; i < n; i++) {
+ Object val = values[i];
+
+ if (val != DELETED) {
+ if (i != o) {
+ keys[o] = keys[i];
+ values[o] = val;
+ values[i] = null;
+ }
+
+ o++;
+ }
+ }
+
+ mGarbage = false;
+ mSize = o;
+
+ // Log.e("SparseArray", "gc end with " + mSize);
+ }
+
+ /**
+ * Adds a mapping from the specified key to the specified value,
+ * replacing the previous mapping from the specified key if there
+ * was one.
+ */
+ public void put(long key, E value) {
+ int i = binarySearch(mKeys, 0, mSize, key);
+
+ if (i >= 0) {
+ mValues[i] = value;
+ } else {
+ i = ~i;
+
+ if (i < mSize && mValues[i] == DELETED) {
+ mKeys[i] = key;
+ mValues[i] = value;
+ return;
+ }
+
+ if (mGarbage && mSize >= mKeys.length) {
+ gc();
+
+ // Search again because indices may have changed.
+ i = ~binarySearch(mKeys, 0, mSize, key);
+ }
+
+ if (mSize >= mKeys.length) {
+ int n = idealLongArraySize(mSize + 1);
+
+ long[] nkeys = new long[n];
+ Object[] nvalues = new Object[n];
+
+ // Log.e("SparseArray", "grow " + mKeys.length + " to " + n);
+ System.arraycopy(mKeys, 0, nkeys, 0, mKeys.length);
+ System.arraycopy(mValues, 0, nvalues, 0, mValues.length);
+
+ mKeys = nkeys;
+ mValues = nvalues;
+ }
+
+ if (mSize - i != 0) {
+ // Log.e("SparseArray", "move " + (mSize - i));
+ System.arraycopy(mKeys, i, mKeys, i + 1, mSize - i);
+ System.arraycopy(mValues, i, mValues, i + 1, mSize - i);
+ }
+
+ mKeys[i] = key;
+ mValues[i] = value;
+ mSize++;
+ }
+ }
+
+ /**
+ * Returns the number of key-value mappings that this LongSparseArray
+ * currently stores.
+ */
+ public int size() {
+ if (mGarbage) {
+ gc();
+ }
+
+ return mSize;
+ }
+
+ /**
+ * Given an index in the range <code>0...size()-1</code>, returns
+ * the key from the <code>index</code>th key-value mapping that this
+ * LongSparseArray stores.
+ */
+ public long keyAt(int index) {
+ if (mGarbage) {
+ gc();
+ }
+
+ return mKeys[index];
+ }
+
+ /**
+ * Given an index in the range <code>0...size()-1</code>, returns
+ * the value from the <code>index</code>th key-value mapping that this
+ * LongSparseArray stores.
+ */
+ @SuppressWarnings("unchecked")
+ public E valueAt(int index) {
+ if (mGarbage) {
+ gc();
+ }
+
+ return (E) mValues[index];
+ }
+
+ /**
+ * Given an index in the range <code>0...size()-1</code>, sets a new
+ * value for the <code>index</code>th key-value mapping that this
+ * LongSparseArray stores.
+ */
+ public void setValueAt(int index, E value) {
+ if (mGarbage) {
+ gc();
+ }
+
+ mValues[index] = value;
+ }
+
+ /**
+ * Returns the index for which {@link #keyAt} would return the
+ * specified key, or a negative number if the specified
+ * key is not mapped.
+ */
+ public int indexOfKey(long key) {
+ if (mGarbage) {
+ gc();
+ }
+
+ return binarySearch(mKeys, 0, mSize, key);
+ }
+
+ /**
+ * Returns an index for which {@link #valueAt} would return the
+ * specified key, or a negative number if no keys map to the
+ * specified value.
+ * Beware that this is a linear search, unlike lookups by key,
+ * and that multiple keys can map to the same value and this will
+ * find only one of them.
+ */
+ public int indexOfValue(E value) {
+ if (mGarbage) {
+ gc();
+ }
+
+ for (int i = 0; i < mSize; i++)
+ if (mValues[i] == value)
+ return i;
+
+ return -1;
+ }
+
+ /**
+ * Removes all key-value mappings from this LongSparseArray.
+ */
+ public void clear() {
+ int n = mSize;
+ Object[] values = mValues;
+
+ for (int i = 0; i < n; i++) {
+ values[i] = null;
+ }
+
+ mSize = 0;
+ mGarbage = false;
+ }
+
+ /**
+ * Puts a key/value pair into the array, optimizing for the case where
+ * the key is greater than all existing keys in the array.
+ */
+ public void append(long key, E value) {
+ if (mSize != 0 && key <= mKeys[mSize - 1]) {
+ put(key, value);
+ return;
+ }
+
+ if (mGarbage && mSize >= mKeys.length) {
+ gc();
+ }
+
+ int pos = mSize;
+ if (pos >= mKeys.length) {
+ int n = idealLongArraySize(pos + 1);
+
+ long[] nkeys = new long[n];
+ Object[] nvalues = new Object[n];
+
+ // Log.e("SparseArray", "grow " + mKeys.length + " to " + n);
+ System.arraycopy(mKeys, 0, nkeys, 0, mKeys.length);
+ System.arraycopy(mValues, 0, nvalues, 0, mValues.length);
+
+ mKeys = nkeys;
+ mValues = nvalues;
+ }
+
+ mKeys[pos] = key;
+ mValues[pos] = value;
+ mSize = pos + 1;
+ }
+
+ private static int binarySearch(long[] a, int start, int len, long key) {
+ int high = start + len, low = start - 1, guess;
+
+ while (high - low > 1) {
+ guess = (high + low) / 2;
+
+ if (a[guess] < key)
+ low = guess;
+ else
+ high = guess;
+ }
+
+ if (high == start + len)
+ return ~(start + len);
+ else if (a[high] == key)
+ return high;
+ else
+ return ~high;
+ }
+
+ private static int idealByteArraySize(int need) {
+ for (int i = 4; i < 32; i++)
+ if (need <= (1 << i) - 12)
+ return (1 << i) - 12;
+
+ return need;
+ }
+
+ public static int idealLongArraySize(int need) {
+ return idealByteArraySize(need * 8) / 8;
+ }
+}
diff --git a/src/com/android/gallery3d/app/CropImage.java b/src/com/android/gallery3d/app/CropImage.java
index 4f450d8..294e285 100644
--- a/src/com/android/gallery3d/app/CropImage.java
+++ b/src/com/android/gallery3d/app/CropImage.java
@@ -16,6 +16,7 @@
package com.android.gallery3d.app;
+import android.annotation.TargetApi;
import android.app.ActionBar;
import android.app.ProgressDialog;
import android.app.WallpaperManager;
@@ -32,6 +33,7 @@
import android.graphics.RectF;
import android.media.ExifInterface;
import android.net.Uri;
+import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
@@ -45,6 +47,7 @@
import android.widget.Toast;
import com.android.gallery3d.R;
+import com.android.gallery3d.common.ApiHelper;
import com.android.gallery3d.common.BitmapUtils;
import com.android.gallery3d.common.Utils;
import com.android.gallery3d.data.DataManager;
@@ -96,10 +99,6 @@
private static final int DEFAULT_COMPRESS_QUALITY = 90;
private static final String TIME_STAMP_NAME = "'IMG'_yyyyMMdd_HHmmss";
- // Change these to Images.Media.WIDTH/HEIGHT after they are unhidden.
- private static final String WIDTH = "width";
- private static final String HEIGHT = "height";
-
public static final String KEY_RETURN_DATA = "return-data";
public static final String KEY_CROPPED_RECT = "cropped-rect";
public static final String KEY_ASPECT_X = "aspectX";
@@ -371,6 +370,15 @@
}
}
+ @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
+ private static void setImageSize(ContentValues values, int width, int height) {
+ // The two fields are available since ICS but got published in JB
+ if (ApiHelper.HAS_MEDIA_COLUMNS_WIDTH_AND_HEIGHT) {
+ values.put(Images.Media.WIDTH, width);
+ values.put(Images.Media.HEIGHT, height);
+ }
+ }
+
private Uri savePicasaImage(JobContext jc, Bitmap cropped) {
if (!DOWNLOAD_BUCKET.isDirectory() && !DOWNLOAD_BUCKET.mkdirs()) {
throw new RuntimeException("cannot create download folder");
@@ -395,8 +403,7 @@
values.put(Images.Media.ORIENTATION, 0);
values.put(Images.Media.DATA, output.getAbsolutePath());
values.put(Images.Media.SIZE, output.length());
- values.put(WIDTH, cropped.getWidth());
- values.put(HEIGHT, cropped.getHeight());
+ setImageSize(values, cropped.getWidth(), cropped.getHeight());
double latitude = PicasaSource.getLatitude(mMediaItem);
double longitude = PicasaSource.getLongitude(mMediaItem);
@@ -434,8 +441,8 @@
values.put(Images.Media.ORIENTATION, 0);
values.put(Images.Media.DATA, output.getAbsolutePath());
values.put(Images.Media.SIZE, output.length());
- values.put(WIDTH, cropped.getWidth());
- values.put(HEIGHT, cropped.getHeight());
+
+ setImageSize(values, cropped.getWidth(), cropped.getHeight());
if (GalleryUtils.isValidLocation(localImage.latitude, localImage.longitude)) {
values.put(Images.Media.LATITUDE, localImage.latitude);
@@ -467,8 +474,8 @@
values.put(Images.Media.ORIENTATION, 0);
values.put(Images.Media.DATA, output.getAbsolutePath());
values.put(Images.Media.SIZE, output.length());
- values.put(WIDTH, cropped.getWidth());
- values.put(HEIGHT, cropped.getHeight());
+
+ setImageSize(values, cropped.getWidth(), cropped.getHeight());
return getContentResolver().insert(
Images.Media.EXTERNAL_CONTENT_URI, values);
diff --git a/src/com/android/gallery3d/app/MovieActivity.java b/src/com/android/gallery3d/app/MovieActivity.java
index 78fe1ee..5f4db1d 100644
--- a/src/com/android/gallery3d/app/MovieActivity.java
+++ b/src/com/android/gallery3d/app/MovieActivity.java
@@ -16,6 +16,7 @@
package com.android.gallery3d.app;
+import android.annotation.TargetApi;
import android.app.ActionBar;
import android.app.Activity;
import android.content.AsyncQueryHandler;
@@ -27,6 +28,7 @@
import android.graphics.drawable.BitmapDrawable;
import android.media.AudioManager;
import android.net.Uri;
+import android.os.Build;
import android.os.Bundle;
import android.provider.MediaStore;
import android.provider.OpenableColumns;
@@ -39,6 +41,7 @@
import android.widget.ShareActionProvider;
import com.android.gallery3d.R;
+import com.android.gallery3d.common.ApiHelper;
import com.android.gallery3d.common.Utils;
/**
@@ -59,6 +62,15 @@
private Uri mUri;
private boolean mTreatUpAsBack;
+ @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
+ private void setSystemUiVisibility(View rootView) {
+ if (ApiHelper.HAS_VIEW_SYSTEM_UI_FLAG_LAYOUT_STABLE) {
+ rootView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE
+ | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
+ | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);
+ }
+ }
+
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@@ -68,9 +80,9 @@
setContentView(R.layout.movie_view);
View rootView = findViewById(R.id.movie_view_root);
- rootView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE
- | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
- | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);
+
+ setSystemUiVisibility(rootView);
+
Intent intent = getIntent();
initializeActionBar(intent);
mFinishOnCompletion = intent.getBooleanExtra(
diff --git a/src/com/android/gallery3d/app/MoviePlayer.java b/src/com/android/gallery3d/app/MoviePlayer.java
index 11b40bd..c0f0ce7 100644
--- a/src/com/android/gallery3d/app/MoviePlayer.java
+++ b/src/com/android/gallery3d/app/MoviePlayer.java
@@ -16,6 +16,7 @@
package com.android.gallery3d.app;
+import android.annotation.TargetApi;
import android.app.AlertDialog;
import android.content.BroadcastReceiver;
import android.content.Context;
@@ -28,6 +29,7 @@
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.net.Uri;
+import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.view.KeyEvent;
@@ -37,6 +39,7 @@
import android.widget.VideoView;
import com.android.gallery3d.R;
+import com.android.gallery3d.common.ApiHelper;
import com.android.gallery3d.common.BlobCache;
import com.android.gallery3d.util.CacheManager;
import com.android.gallery3d.util.GalleryUtils;
@@ -98,9 +101,10 @@
};
private final Runnable mRemoveBackground = new Runnable() {
+ @SuppressWarnings("deprecation")
@Override
public void run() {
- mRootView.setBackground(null);
+ mRootView.setBackgroundDrawable(null);
}
};
@@ -148,6 +152,37 @@
}
}, BLACK_TIMEOUT);
+ setOnSystemUiVisibilityChangeListener();
+ // Hide system UI by default
+ showSystemUi(false);
+
+ mAudioBecomingNoisyReceiver = new AudioBecomingNoisyReceiver();
+ mAudioBecomingNoisyReceiver.register();
+
+ Intent i = new Intent(SERVICECMD);
+ i.putExtra(CMDNAME, CMDPAUSE);
+ movieActivity.sendBroadcast(i);
+
+ if (savedInstance != null) { // this is a resumed activity
+ mVideoPosition = savedInstance.getInt(KEY_VIDEO_POSITION, 0);
+ mResumeableTime = savedInstance.getLong(KEY_RESUMEABLE_TIME, Long.MAX_VALUE);
+ mVideoView.start();
+ mVideoView.suspend();
+ mHasPaused = true;
+ } else {
+ final Integer bookmark = mBookmarker.getBookmark(mUri);
+ if (bookmark != null) {
+ showResumeDialog(movieActivity, bookmark);
+ } else {
+ startVideo();
+ }
+ }
+ }
+
+ @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
+ private void setOnSystemUiVisibilityChangeListener() {
+ if (!ApiHelper.HAS_VIEW_SYSTEM_UI_FLAG_HIDE_NAVIGATION) return;
+
// When the user touches the screen or uses some hard key, the framework
// will change system ui visibility from invisible to visible. We show
// the media control and enable system UI (e.g. ActionBar) to be visible at this point
@@ -176,37 +211,15 @@
}
}
});
-
- // Hide system UI by default
- showSystemUi(false);
-
- mAudioBecomingNoisyReceiver = new AudioBecomingNoisyReceiver();
- mAudioBecomingNoisyReceiver.register();
-
- Intent i = new Intent(SERVICECMD);
- i.putExtra(CMDNAME, CMDPAUSE);
- movieActivity.sendBroadcast(i);
-
- if (savedInstance != null) { // this is a resumed activity
- mVideoPosition = savedInstance.getInt(KEY_VIDEO_POSITION, 0);
- mResumeableTime = savedInstance.getLong(KEY_RESUMEABLE_TIME, Long.MAX_VALUE);
- mVideoView.start();
- mVideoView.suspend();
- mHasPaused = true;
- } else {
- final Integer bookmark = mBookmarker.getBookmark(mUri);
- if (bookmark != null) {
- showResumeDialog(movieActivity, bookmark);
- } else {
- startVideo();
- }
- }
}
+ @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
private void showSystemUi(boolean visible) {
+ if (!ApiHelper.HAS_VIEW_SYSTEM_UI_FLAG_LAYOUT_STABLE) return;
+
int flag = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
- | View.SYSTEM_UI_FLAG_LAYOUT_STABLE;
+ | View.SYSTEM_UI_FLAG_LAYOUT_STABLE;
if (!visible) {
flag |= View.SYSTEM_UI_FLAG_LOW_PROFILE | View.SYSTEM_UI_FLAG_FULLSCREEN
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
@@ -496,7 +509,7 @@
DataInputStream dis = new DataInputStream(
new ByteArrayInputStream(data));
- String uriString = dis.readUTF(dis);
+ String uriString = DataInputStream.readUTF(dis);
int bookmark = dis.readInt();
int duration = dis.readInt();
diff --git a/src/com/android/gallery3d/data/LocalImage.java b/src/com/android/gallery3d/data/LocalImage.java
index c3095a0..c432ab4 100644
--- a/src/com/android/gallery3d/data/LocalImage.java
+++ b/src/com/android/gallery3d/data/LocalImage.java
@@ -16,6 +16,7 @@
package com.android.gallery3d.data;
+import android.annotation.TargetApi;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.database.Cursor;
@@ -24,11 +25,14 @@
import android.graphics.BitmapRegionDecoder;
import android.media.ExifInterface;
import android.net.Uri;
+import android.os.Build;
import android.provider.MediaStore.Images;
import android.provider.MediaStore.Images.ImageColumns;
+import android.provider.MediaStore.MediaColumns;
import android.util.Log;
import com.android.gallery3d.app.GalleryApp;
+import com.android.gallery3d.common.ApiHelper;
import com.android.gallery3d.common.BitmapUtils;
import com.android.gallery3d.util.GalleryUtils;
import com.android.gallery3d.util.ThreadPool.Job;
@@ -74,10 +78,22 @@
ImageColumns.ORIENTATION, // 9
ImageColumns.BUCKET_ID, // 10
ImageColumns.SIZE, // 11
- ImageColumns.WIDTH, // 12
- ImageColumns.HEIGHT // 13
+ "0", // 12
+ "0" // 13
};
+ static {
+ updateWidthAndHeightProjection();
+ }
+
+ @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
+ private static void updateWidthAndHeightProjection() {
+ if (ApiHelper.HAS_MEDIA_COLUMNS_WIDTH_AND_HEIGHT) {
+ PROJECTION[INDEX_WIDTH] = MediaColumns.WIDTH;
+ PROJECTION[INDEX_HEIGHT] = MediaColumns.HEIGHT;
+ }
+ }
+
private final GalleryApp mApplication;
public int rotation;
diff --git a/src/com/android/gallery3d/gadget/PhotoAppWidgetProvider.java b/src/com/android/gallery3d/gadget/PhotoAppWidgetProvider.java
index c18652d..343b15a 100644
--- a/src/com/android/gallery3d/gadget/PhotoAppWidgetProvider.java
+++ b/src/com/android/gallery3d/gadget/PhotoAppWidgetProvider.java
@@ -66,6 +66,7 @@
super.onUpdate(context, appWidgetManager, appWidgetIds);
}
+ @SuppressWarnings("deprecation")
private static RemoteViews buildStackWidget(Context context, int widgetId, Entry entry) {
RemoteViews views = new RemoteViews(
context.getPackageName(), R.layout.appwidget_main);
@@ -76,7 +77,10 @@
intent.putExtra(WidgetService.EXTRA_ALBUM_PATH, entry.albumPath);
intent.setData(Uri.parse("widget://gallery/" + widgetId));
- views.setRemoteAdapter(R.id.appwidget_stack_view, intent);
+ // We use the deprecated API for backward compatibility
+ // The new API is available in ICE_CREAM_SANDWICH (15)
+ views.setRemoteAdapter(widgetId, R.id.appwidget_stack_view, intent);
+
views.setEmptyView(R.id.appwidget_stack_view, R.id.appwidget_empty_view);
Intent clickIntent = new Intent(context, WidgetClickHandler.class);
diff --git a/src/com/android/gallery3d/ui/GLRootView.java b/src/com/android/gallery3d/ui/GLRootView.java
index 99ed8cb..2068520 100644
--- a/src/com/android/gallery3d/ui/GLRootView.java
+++ b/src/com/android/gallery3d/ui/GLRootView.java
@@ -16,10 +16,12 @@
package com.android.gallery3d.ui;
+import android.annotation.TargetApi;
import android.content.Context;
import android.graphics.Matrix;
import android.graphics.PixelFormat;
import android.opengl.GLSurfaceView;
+import android.os.Build;
import android.os.Process;
import android.os.SystemClock;
import android.util.AttributeSet;
@@ -29,6 +31,7 @@
import com.android.gallery3d.R;
import com.android.gallery3d.anim.CanvasAnimation;
+import com.android.gallery3d.common.ApiHelper;
import com.android.gallery3d.common.Utils;
import com.android.gallery3d.util.GalleryUtils;
import com.android.gallery3d.util.Profile;
@@ -536,12 +539,15 @@
}
@Override
+ @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
public void setLightsOutMode(boolean enabled) {
- int flags = enabled
- ? SYSTEM_UI_FLAG_LOW_PROFILE
- | SYSTEM_UI_FLAG_FULLSCREEN
- | SYSTEM_UI_FLAG_LAYOUT_STABLE
- : 0;
+ int flags = 0;
+ if (enabled) {
+ flags = SYSTEM_UI_FLAG_LOW_PROFILE;
+ if (ApiHelper.HAS_VIEW_SYSTEM_UI_FLAG_LAYOUT_STABLE) {
+ flags |= (SYSTEM_UI_FLAG_FULLSCREEN | SYSTEM_UI_FLAG_LAYOUT_STABLE);
+ }
+ }
setSystemUiVisibility(flags);
}
diff --git a/src/com/android/gallery3d/ui/PositionController.java b/src/com/android/gallery3d/ui/PositionController.java
index d556caf..6d33470 100644
--- a/src/com/android/gallery3d/ui/PositionController.java
+++ b/src/com/android/gallery3d/ui/PositionController.java
@@ -110,11 +110,11 @@
private Listener mListener;
private volatile Rect mOpenAnimationRect;
- // Use a large enough value, so we won't see the gray shadown in the beginning.
+ // Use a large enough value, so we won't see the gray shadow in the beginning.
private int mViewW = 1200;
private int mViewH = 1200;
- // A scaling guesture is in progress.
+ // A scaling gesture is in progress.
private boolean mInScale;
// The focus point of the scaling gesture, relative to the center of the
// picture in bitmap pixels.
@@ -178,7 +178,7 @@
private RangeArray<Gap> mTempGaps =
new RangeArray<Gap>(-BOX_MAX, BOX_MAX - 1);
- // The output of the PositionController. Available throught getPosition().
+ // The output of the PositionController. Available through getPosition().
private RangeArray<Rect> mRects = new RangeArray<Rect>(-BOX_MAX, BOX_MAX);
// The direction of a new picture should appear. New pictures pop from top
@@ -211,7 +211,7 @@
mListener = listener;
mPageScroller = new FlingScroller();
mFilmScroller = new OverScroller(context,
- null /* default interpolator */, false /* no flywheel */);
+ null /* default interpolator */, 0, 0, false /* no flywheel */);
// Initialize the areas.
initPlatform();
@@ -519,7 +519,7 @@
Platform p = mPlatform;
// We want to keep the focus point (on the bitmap) the same as when we
- // begin the scale guesture, that is,
+ // begin the scale gesture, that is,
//
// (focusX' - currentX') / scale' = (focusX - currentX) / scale
//
@@ -1005,7 +1005,7 @@
// N N N N N N N -- all new boxes
// -3 -2 -1 0 1 2 3 -- nothing changed
// -2 -1 0 1 2 3 N -- focus goes to the next box
- // N -3 -2 -1 0 1 2 -- focuse goes to the previous box
+ // N -3 -2 -1 0 1 2 -- focus goes to the previous box
// -3 -2 -1 1 2 3 N -- the focused box was deleted.
//
// hasPrev/hasNext indicates if there are previous/next boxes for the
@@ -1019,7 +1019,7 @@
RangeIntArray from = new RangeIntArray(fromIndex, -BOX_MAX, BOX_MAX);
- // 1. Get the absolute X coordiates for the boxes.
+ // 1. Get the absolute X coordinates for the boxes.
layoutAndSetPosition();
for (int i = -BOX_MAX; i <= BOX_MAX; i++) {
Box b = mBoxes.get(i);
@@ -1366,7 +1366,7 @@
public int mAnimationKind;
public int mAnimationDuration;
- // This should be overidden in subclass to change the animation values
+ // This should be overridden in subclass to change the animation values
// give the progress value in [0, 1].
protected abstract boolean interpolate(float progress);
public abstract boolean startSnapback();
diff --git a/src/com/android/gallery3d/ui/TileImageView.java b/src/com/android/gallery3d/ui/TileImageView.java
index 0c6086d..adbf850 100644
--- a/src/com/android/gallery3d/ui/TileImageView.java
+++ b/src/com/android/gallery3d/ui/TileImageView.java
@@ -21,9 +21,9 @@
import android.graphics.Rect;
import android.graphics.RectF;
import android.util.FloatMath;
-import android.util.LongSparseArray;
import com.android.gallery3d.app.GalleryContext;
+import com.android.gallery3d.common.LongSparseArray;
import com.android.gallery3d.common.Utils;
import com.android.gallery3d.data.BitmapPool;
import com.android.gallery3d.data.DecodeUtils;