diff options
| author | 2014-06-16 15:28:50 -0700 | |
|---|---|---|
| committer | 2014-06-16 15:28:50 -0700 | |
| commit | b8802b1293c05a14399005aeaeb93b82ec2e2f27 (patch) | |
| tree | ffd7a0ff6151c002ec7d799035eaa257b24be238 | |
| parent | 5d140e4b1b1d43c742a7d67dd5f9d394c846945f (diff) | |
Add atlas map pointer validation
Bug: 15425820
This just prevents the crash, it's still unclear how bad pointers
are getting into the map in the first place
Change-Id: I3acffaae09548ec48973035b7fcf5f35606bad60
| -rw-r--r-- | core/java/android/view/HardwareRenderer.java | 5 | ||||
| -rw-r--r-- | core/java/android/view/ThreadedRenderer.java | 40 | ||||
| -rw-r--r-- | core/java/android/view/ViewRootImpl.java | 2 |
3 files changed, 41 insertions, 6 deletions
diff --git a/core/java/android/view/HardwareRenderer.java b/core/java/android/view/HardwareRenderer.java index 3de81443d818..c0e42a393380 100644 --- a/core/java/android/view/HardwareRenderer.java +++ b/core/java/android/view/HardwareRenderer.java @@ -16,6 +16,7 @@ package android.view; +import android.content.Context; import android.graphics.Bitmap; import android.graphics.Rect; import android.graphics.SurfaceTexture; @@ -452,10 +453,10 @@ public abstract class HardwareRenderer { * * @return A hardware renderer backed by OpenGL. */ - static HardwareRenderer create(boolean translucent) { + static HardwareRenderer create(Context context, boolean translucent) { HardwareRenderer renderer = null; if (GLES20Canvas.isAvailable()) { - renderer = new ThreadedRenderer(translucent); + renderer = new ThreadedRenderer(context, translucent); } return renderer; } diff --git a/core/java/android/view/ThreadedRenderer.java b/core/java/android/view/ThreadedRenderer.java index 2bfbd650c050..166edc247176 100644 --- a/core/java/android/view/ThreadedRenderer.java +++ b/core/java/android/view/ThreadedRenderer.java @@ -16,21 +16,29 @@ package android.view; +import android.content.Context; +import android.content.res.Resources; import android.graphics.Bitmap; import android.graphics.Rect; import android.graphics.SurfaceTexture; +import android.graphics.drawable.Drawable; import android.os.IBinder; import android.os.RemoteException; import android.os.ServiceManager; import android.os.SystemProperties; import android.os.Trace; import android.util.Log; +import android.util.LongSparseArray; import android.util.TimeUtils; import android.view.Surface.OutOfResourcesException; import android.view.View.AttachInfo; import java.io.FileDescriptor; import java.io.PrintWriter; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashSet; /** * Hardware renderer that proxies the rendering to a render thread. Most calls @@ -71,8 +79,8 @@ public class ThreadedRenderer extends HardwareRenderer { private Choreographer mChoreographer; private boolean mProfilingEnabled; - ThreadedRenderer(boolean translucent) { - AtlasInitializer.sInstance.init(); + ThreadedRenderer(Context context, boolean translucent) { + AtlasInitializer.sInstance.init(context); long rootNodePtr = nCreateRootRenderNode(); mRootNode = RenderNode.adopt(rootNodePtr); @@ -334,7 +342,7 @@ public class ThreadedRenderer extends HardwareRenderer { private AtlasInitializer() {} - synchronized void init() { + synchronized void init(Context context) { if (mInitialized) return; IBinder binder = ServiceManager.getService("assetatlas"); if (binder == null) return; @@ -346,6 +354,8 @@ public class ThreadedRenderer extends HardwareRenderer { if (buffer != null) { long[] map = atlas.getMap(); if (map != null) { + // TODO Remove after fixing b/15425820 + validateMap(context, map); nSetAtlas(buffer, map); mInitialized = true; } @@ -361,6 +371,30 @@ public class ThreadedRenderer extends HardwareRenderer { Log.w(LOG_TAG, "Could not acquire atlas", e); } } + + private static void validateMap(Context context, long[] map) { + Log.d("Atlas", "Validating map..."); + HashSet<Long> preloadedPointers = new HashSet<Long>(); + + // We only care about drawables that hold bitmaps + final Resources resources = context.getResources(); + final LongSparseArray<Drawable.ConstantState> drawables = resources.getPreloadedDrawables(); + + final int count = drawables.size(); + for (int i = 0; i < count; i++) { + final Bitmap bitmap = drawables.valueAt(i).getBitmap(); + if (bitmap != null && bitmap.getConfig() == Bitmap.Config.ARGB_8888) { + preloadedPointers.add(bitmap.mNativeBitmap); + } + } + + for (int i = 0; i < map.length; i += 4) { + if (!preloadedPointers.contains(map[i])) { + Log.w("Atlas", String.format("Pointer 0x%X, not in getPreloadedDrawables?", map[i])); + map[i] = 0; + } + } + } } static native void setupShadersDiskCache(String cacheFile); diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index 4cd1b25c56bd..dfd5cdf2ee0c 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -700,7 +700,7 @@ public final class ViewRootImpl implements ViewParent, } final boolean translucent = attrs.format != PixelFormat.OPAQUE; - mAttachInfo.mHardwareRenderer = HardwareRenderer.create(translucent); + mAttachInfo.mHardwareRenderer = HardwareRenderer.create(mContext, translucent); if (mAttachInfo.mHardwareRenderer != null) { mAttachInfo.mHardwareRenderer.setName(attrs.getTitle().toString()); mAttachInfo.mHardwareAccelerated = |