Merge "Destroy the hardware renderer when ViewRootImpl's die is post-poned Bug #6109035"
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 0860890..ab4e73d 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -404,6 +404,7 @@
                     try {
                         fd.close();
                     } catch (IOException e) {
+                        // Ignore
                     }
                 }
                 return;
@@ -412,6 +413,7 @@
                 try {
                     profileFd.close();
                 } catch (IOException e) {
+                    // Ignore
                 }
             }
             profileFile = file;
@@ -843,14 +845,13 @@
             FileOutputStream fout = new FileOutputStream(fd);
             PrintWriter pw = new PrintWriter(fout);
             try {
-                return dumpMemInfo(pw, checkin, all, args);
+                return dumpMemInfo(pw, checkin, all);
             } finally {
                 pw.flush();
             }
         }
 
-        private Debug.MemoryInfo dumpMemInfo(PrintWriter pw, boolean checkin, boolean all,
-                String[] args) {
+        private Debug.MemoryInfo dumpMemInfo(PrintWriter pw, boolean checkin, boolean all) {
             long nativeMax = Debug.getNativeHeapSize() / 1024;
             long nativeAllocated = Debug.getNativeHeapAllocatedSize() / 1024;
             long nativeFree = Debug.getNativeHeapFreeSize() / 1024;
@@ -1458,17 +1459,6 @@
         return dm;
     }
 
-    static Configuration applyConfigCompat(Configuration config, CompatibilityInfo compat) {
-        if (config == null) {
-            return null;
-        }
-        if (compat != null && !compat.supportsScreen()) {
-            config = new Configuration(config);
-            compat.applyToConfiguration(config);
-        }
-        return config;
-    }
-
     private Configuration mMainThreadConfig = new Configuration();
     Configuration applyConfigCompatMainThread(Configuration config, CompatibilityInfo compat) {
         if (config == null) {
@@ -2509,7 +2499,7 @@
         return r;
     }
 
-    final void cleanUpPendingRemoveWindows(ActivityClientRecord r) {
+    static final void cleanUpPendingRemoveWindows(ActivityClientRecord r) {
         if (r.mPendingRemoveWindow != null) {
             r.mPendingRemoveWindowManager.removeViewImmediate(r.mPendingRemoveWindow);
             IBinder wtoken = r.mPendingRemoveWindow.getWindowToken();
@@ -3437,15 +3427,12 @@
                 = new ArrayList<ComponentCallbacks2>();
 
         if (mActivities.size() > 0) {
-            Iterator<ActivityClientRecord> it = mActivities.values().iterator();
-            while (it.hasNext()) {
-                ActivityClientRecord ar = it.next();
+            for (ActivityClientRecord ar : mActivities.values()) {
                 Activity a = ar.activity;
                 if (a != null) {
                     Configuration thisConfig = applyConfigCompatMainThread(newConfig,
                             ar.packageInfo.mCompatibilityInfo.getIfNeeded());
-                    if (!ar.activity.mFinished && (allActivities ||
-                            (a != null && !ar.paused))) {
+                    if (!ar.activity.mFinished && (allActivities || !ar.paused)) {
                         // If the activity is currently resumed, its configuration
                         // needs to change right now.
                         callbacks.add(a);
@@ -3455,24 +3442,24 @@
                         // the activity manager may, before then, decide the
                         // activity needs to be destroyed to handle its new
                         // configuration.
-                        if (DEBUG_CONFIGURATION) Slog.v(TAG, "Setting activity "
-                                + ar.activityInfo.name + " newConfig=" + thisConfig);
+                        if (DEBUG_CONFIGURATION) {
+                            Slog.v(TAG, "Setting activity "
+                                    + ar.activityInfo.name + " newConfig=" + thisConfig);
+                        }
                         ar.newConfig = thisConfig;
                     }
                 }
             }
         }
         if (mServices.size() > 0) {
-            Iterator<Service> it = mServices.values().iterator();
-            while (it.hasNext()) {
-                callbacks.add(it.next());
+            for (Service service : mServices.values()) {
+                callbacks.add(service);
             }
         }
         synchronized (mProviderMap) {
             if (mLocalProviders.size() > 0) {
-                Iterator<ProviderClientRecord> it = mLocalProviders.values().iterator();
-                while (it.hasNext()) {
-                    callbacks.add(it.next().mLocalProvider);
+                for (ProviderClientRecord providerClientRecord : mLocalProviders.values()) {
+                    callbacks.add(providerClientRecord.mLocalProvider);
                 }
             }
         }
@@ -3484,8 +3471,7 @@
         return callbacks;
     }
 
-    private final void performConfigurationChanged(
-            ComponentCallbacks2 cb, Configuration config) {
+    private static void performConfigurationChanged(ComponentCallbacks2 cb, Configuration config) {
         // Only for Activity objects, check that they actually call up to their
         // superclass implementation.  ComponentCallbacks2 is an interface, so
         // we check the runtime type and act accordingly.
@@ -3692,7 +3678,7 @@
         }
     }
 
-    final void handleDumpHeap(boolean managed, DumpHeapData dhd) {
+    static final void handleDumpHeap(boolean managed, DumpHeapData dhd) {
         if (managed) {
             try {
                 Debug.dumpHprofData(dhd.path, dhd.fd.getFileDescriptor());
@@ -3769,7 +3755,7 @@
         }
 
         final int N = callbacks.size();
-        for (int i=0; i<N; i++) {
+        for (int i = 0; i < N; i++) {
             callbacks.get(i).onTrimMemory(level);
         }
         WindowManagerImpl.getDefault().terminateEgl();
@@ -4057,9 +4043,7 @@
         final ArrayList<IActivityManager.ContentProviderHolder> results =
             new ArrayList<IActivityManager.ContentProviderHolder>();
 
-        Iterator<ProviderInfo> i = providers.iterator();
-        while (i.hasNext()) {
-            ProviderInfo cpi = i.next();
+        for (ProviderInfo cpi : providers) {
             StringBuilder buf = new StringBuilder(128);
             buf.append("Pub ");
             buf.append(cpi.authority);
diff --git a/core/java/android/view/HardwareRenderer.java b/core/java/android/view/HardwareRenderer.java
index 1f140e95..f98cfc0 100644
--- a/core/java/android/view/HardwareRenderer.java
+++ b/core/java/android/view/HardwareRenderer.java
@@ -1121,6 +1121,7 @@
                         GLES20Canvas.terminateCaches();
 
                         sEgl.eglDestroyContext(sEglDisplay, eglContext);
+                        sEglContextStorage.set(null);
                         sEglContextStorage.remove();
 
                         sEgl.eglDestroySurface(sEglDisplay, sPbuffer);
@@ -1134,7 +1135,6 @@
                         sEglDisplay = null;
                         sEglConfig = null;
                         sPbuffer = null;
-                        sEglContextStorage.set(null);
                     }
                 }
             }
@@ -1238,7 +1238,7 @@
         }
 
         private static void destroyHardwareLayer(View view) {
-            view.destroyLayer();
+            view.destroyLayer(true);
 
             if (view instanceof ViewGroup) {
                 ViewGroup group = (ViewGroup) view;
diff --git a/core/java/android/view/TextureView.java b/core/java/android/view/TextureView.java
index fc02cc1..83999a1 100644
--- a/core/java/android/view/TextureView.java
+++ b/core/java/android/view/TextureView.java
@@ -299,7 +299,7 @@
     }
 
     @Override
-    boolean destroyLayer() {
+    boolean destroyLayer(boolean valid) {
         return false;
     }
 
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 770d899..3afc20e 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -10045,7 +10045,7 @@
 
         destroyDrawingCache();
 
-        destroyLayer();
+        destroyLayer(false);
 
         if (mAttachInfo != null) {
             if (mDisplayList != null) {
@@ -10421,7 +10421,7 @@
         // Destroy any previous software drawing cache if needed
         switch (mLayerType) {
             case LAYER_TYPE_HARDWARE:
-                destroyLayer();
+                destroyLayer(false);
                 // fall through - non-accelerated views may use software layer mechanism instead
             case LAYER_TYPE_SOFTWARE:
                 destroyDrawingCache();
@@ -10559,11 +10559,12 @@
      * @see #setLayerType(int, android.graphics.Paint) 
      * @see #LAYER_TYPE_HARDWARE
      */
-    boolean destroyLayer() {
+    boolean destroyLayer(boolean valid) {
         if (mHardwareLayer != null) {
             AttachInfo info = mAttachInfo;
             if (info != null && info.mHardwareRenderer != null &&
-                    info.mHardwareRenderer.isEnabled() && info.mHardwareRenderer.validate()) {
+                    info.mHardwareRenderer.isEnabled() &&
+                    (valid || info.mHardwareRenderer.validate())) {
                 mHardwareLayer.destroy();
                 mHardwareLayer = null;
 
@@ -10587,7 +10588,7 @@
      * @hide
      */
     protected void destroyHardwareResources() {
-        destroyLayer();
+        destroyLayer(true);
     }
 
     /**
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index b8fbf17..6ccac78 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -1820,7 +1820,7 @@
      * Resets the cancel next up flag.
      * Returns true if the flag was previously set.
      */
-    private boolean resetCancelNextUpFlag(View view) {
+    private static boolean resetCancelNextUpFlag(View view) {
         if ((view.mPrivateFlags & CANCEL_NEXT_UP_EVENT) != 0) {
             view.mPrivateFlags &= ~CANCEL_NEXT_UP_EVENT;
             return true;
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 14b8084..befc1c6 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -1809,7 +1809,7 @@
      *
      * @return The measure spec to use to measure the root view.
      */
-    private int getRootMeasureSpec(int windowSize, int rootDimension) {
+    private static int getRootMeasureSpec(int windowSize, int rootDimension) {
         int measureSpec;
         switch (rootDimension) {
 
@@ -2432,12 +2432,12 @@
                 mAccessibilityInteractionConnectionManager);
         removeSendWindowContentChangedCallback();
 
+        destroyHardwareRenderer();
+
         mView = null;
         mAttachInfo.mRootView = null;
         mAttachInfo.mSurface = null;
 
-        destroyHardwareRenderer();
-
         mSurface.release();
 
         if (mInputQueueCallback != null && mInputQueue != null) {
@@ -2893,7 +2893,7 @@
      * @param focused The currently focused view.
      * @return An appropriate view, or null if no such view exists.
      */
-    private ViewGroup findAncestorToTakeFocusInTouchMode(View focused) {
+    private static ViewGroup findAncestorToTakeFocusInTouchMode(View focused) {
         ViewParent parent = focused.getParent();
         while (parent instanceof ViewGroup) {
             final ViewGroup vgParent = (ViewGroup) parent;
@@ -3763,7 +3763,7 @@
         }
     }
 
-    private void getGfxInfo(View view, int[] info) {
+    private static void getGfxInfo(View view, int[] info) {
         DisplayList displayList = view.mDisplayList;
         info[0]++;
         if (displayList != null) {
@@ -3784,6 +3784,7 @@
         if (immediate) {
             doDie();
         } else {
+            destroyHardwareRenderer();
             mHandler.sendEmptyMessage(MSG_DIE);
         }
     }
@@ -3826,10 +3827,18 @@
     }
 
     private void destroyHardwareRenderer() {
-        if (mAttachInfo.mHardwareRenderer != null) {
-            mAttachInfo.mHardwareRenderer.destroy(true);
-            mAttachInfo.mHardwareRenderer = null;
-            mAttachInfo.mHardwareAccelerated = false;
+        AttachInfo attachInfo = mAttachInfo;
+        HardwareRenderer hardwareRenderer = attachInfo.mHardwareRenderer;
+
+        if (hardwareRenderer != null) {
+            if (mView != null) {
+                hardwareRenderer.destroyHardwareResources(mView);
+            }
+            hardwareRenderer.destroy(true);
+            hardwareRenderer.setRequested(false);
+
+            attachInfo.mHardwareRenderer = null;
+            attachInfo.mHardwareAccelerated = false;
         }
     }
 
diff --git a/core/java/android/view/WindowManagerImpl.java b/core/java/android/view/WindowManagerImpl.java
index 0e4a30f..f2ee9f9 100644
--- a/core/java/android/view/WindowManagerImpl.java
+++ b/core/java/android/view/WindowManagerImpl.java
@@ -354,7 +354,7 @@
     View removeViewLocked(int index) {
         ViewRootImpl root = mRoots[index];
         View view = root.getView();
-        
+
         // Don't really remove until we have matched all calls to add().
         root.mAddNesting--;
         if (root.mAddNesting > 0) {