summaryrefslogtreecommitdiffstats
path: root/carousel/java
diff options
context:
space:
mode:
authorJim Shuma <jshuma@google.com>2011-01-23 19:51:19 -0800
committerJim Shuma <jshuma@google.com>2011-01-23 19:58:40 -0800
commitec18350090abbba03c3f0c9f0511cfde4afee66f (patch)
tree8ec635f83bacbf8227bf8e2bfda0c3446fbc8024 /carousel/java
parent86018e0266578b120b9ad4133a6f189d2a3eac47 (diff)
downloadandroid_frameworks_ex-ec18350090abbba03c3f0c9f0511cfde4afee66f.tar.gz
android_frameworks_ex-ec18350090abbba03c3f0c9f0511cfde4afee66f.tar.bz2
android_frameworks_ex-ec18350090abbba03c3f0c9f0511cfde4afee66f.zip
Proper error checking for setting cards
When shrinking the cards array while invalidates are still in flight, it's possible to have an invalidate or texture set land on a nonexistent card, causing an out-of-bounds exception to be thrown, crashing the app. Frequently these invalidates come from the user dragging the carousel to another position, so it's not feasible to prevent invalidates from being sent when we're about to clear the cards array; nor is it feasible to empty any pending invalidates, since Renderscript does not provide any meaningful inspection of the event queue. Therefore, the only real way we can address the problem is by detecting these out-of-turn invalidates and handling the errors cleanly. In practice, since these events are typically to invalidate a nonexistent card, it's OK to just drop them, since each such card is already invalid because it does not exist. This fix factors out card-get and card-set logic into common methods, similar to card-set-or-create logic that's been present for a long time. Bug: 3381300 Change-Id: I037801de3b4c3bff514b1586fa16417e32c118df
Diffstat (limited to 'carousel/java')
-rw-r--r--carousel/java/com/android/ex/carousel/CarouselRS.java38
1 files changed, 28 insertions, 10 deletions
diff --git a/carousel/java/com/android/ex/carousel/CarouselRS.java b/carousel/java/com/android/ex/carousel/CarouselRS.java
index 0d921a7..4467fb3 100644
--- a/carousel/java/com/android/ex/carousel/CarouselRS.java
+++ b/carousel/java/com/android/ex/carousel/CarouselRS.java
@@ -672,21 +672,39 @@ public class CarouselRS {
return allocation;
}
- private ScriptField_Card.Item getOrCreateCard(int n) {
+ private ScriptField_Card.Item getCard(int n) {
ScriptField_Card.Item item;
try {
item = mCards.get(n);
}
catch (ArrayIndexOutOfBoundsException e) {
+ if (DBG) Log.v(TAG, "getCard(): no item at index " + n);
item = null;
}
+ return item;
+ }
+
+ private ScriptField_Card.Item getOrCreateCard(int n) {
+ ScriptField_Card.Item item = getCard(n);
if (item == null) {
- if (DBG) Log.v(TAG, "getOrCreateItem(): no item at index " + n);
+ if (DBG) Log.v(TAG, "getOrCreateCard(): no item at index " + n + "; creating new");
item = new ScriptField_Card.Item();
}
return item;
}
+ private void setCard(int n, ScriptField_Card.Item item) {
+ try {
+ mCards.set(item, n, false); // This is primarily used for reference counting.
+ }
+ catch (ArrayIndexOutOfBoundsException e) {
+ // The specified index didn't exist. This can happen when a stale invalidate
+ // request outlived an array resize request. Something might be getting dropped,
+ // but there's not much we can do about this at this point to recover.
+ Log.w(TAG, "setCard(" + n + "): Texture " + n + " doesn't exist");
+ }
+ }
+
public void setTexture(int n, Bitmap bitmap)
{
if (n < 0) throw new IllegalArgumentException("Index cannot be negative");
@@ -701,7 +719,7 @@ public class CarouselRS {
item.texture = null;
}
}
- mCards.set(item, n, false); // This is primarily used for reference counting.
+ setCard(n, item);
mScript.invoke_setTexture(n, item.texture);
}
}
@@ -727,7 +745,7 @@ public class CarouselRS {
item.detailTexture = null;
}
}
- mCards.set(item, n, false); // This is primarily used for reference counting.
+ setCard(n, item);
mScript.invoke_setDetailTexture(n, offx, offy, loffx, loffy, item.detailTexture);
}
}
@@ -737,7 +755,7 @@ public class CarouselRS {
if (n < 0) throw new IllegalArgumentException("Index cannot be negative");
synchronized(this) {
- ScriptField_Card.Item item = mCards.get(n);
+ ScriptField_Card.Item item = getCard(n);
if (item == null) {
// This card was never created, so there's nothing to invalidate.
return;
@@ -749,7 +767,7 @@ public class CarouselRS {
item.texture.destroy();
item.texture = null;
}
- mCards.set(item, n, false); // This is primarily used for reference counting.
+ setCard(n, item);
mScript.invoke_invalidateTexture(n, eraseCurrent);
}
}
@@ -759,7 +777,7 @@ public class CarouselRS {
if (n < 0) throw new IllegalArgumentException("Index cannot be negative");
synchronized(this) {
- ScriptField_Card.Item item = mCards.get(n);
+ ScriptField_Card.Item item = getCard(n);
if (item == null) {
// This card was never created, so there's nothing to invalidate.
return;
@@ -771,7 +789,7 @@ public class CarouselRS {
item.detailTexture.destroy();
item.detailTexture = null;
}
- mCards.set(item, n, false); // This is primarily used for reference counting.
+ setCard(n, item);
mScript.invoke_invalidateDetailTexture(n, eraseCurrent);
}
}
@@ -792,7 +810,7 @@ public class CarouselRS {
item.geometry = null;
}
}
- mCards.set(item, n, false);
+ setCard(n, item);
mScript.invoke_setGeometry(n, item.geometry);
}
}
@@ -809,7 +827,7 @@ public class CarouselRS {
if (DBG) Log.v(TAG, "unloading matrix " + n);
item.matrix = null;
}
- mCards.set(item, n, false);
+ setCard(n, item);
mScript.invoke_setMatrix(n, item.matrix);
}
}