Merge "Menu callbacks for ToolbarActionBars, part 2" into lmp-dev
diff --git a/api/current.txt b/api/current.txt
index f3fc017..dca7481 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -3455,7 +3455,7 @@
     method public boolean navigateUpToFromChild(android.app.Activity, android.content.Intent);
     method public void onActionModeFinished(android.view.ActionMode);
     method public void onActionModeStarted(android.view.ActionMode);
-    method protected void onActivityReenter(int, android.content.Intent);
+    method public void onActivityReenter(int, android.content.Intent);
     method protected void onActivityResult(int, int, android.content.Intent);
     method public void onAttachFragment(android.app.Fragment);
     method public void onAttachedToWindow();
@@ -3466,7 +3466,7 @@
     method public boolean onContextItemSelected(android.view.MenuItem);
     method public void onContextMenuClosed(android.view.Menu);
     method protected void onCreate(android.os.Bundle);
-    method protected void onCreate(android.os.Bundle, android.os.PersistableBundle);
+    method public void onCreate(android.os.Bundle, android.os.PersistableBundle);
     method public void onCreateContextMenu(android.view.ContextMenu, android.view.View, android.view.ContextMenu.ContextMenuInfo);
     method public java.lang.CharSequence onCreateDescription();
     method protected deprecated android.app.Dialog onCreateDialog(int);
@@ -3498,7 +3498,7 @@
     method public void onPanelClosed(int, android.view.Menu);
     method protected void onPause();
     method protected void onPostCreate(android.os.Bundle);
-    method protected void onPostCreate(android.os.Bundle, android.os.PersistableBundle);
+    method public void onPostCreate(android.os.Bundle, android.os.PersistableBundle);
     method protected void onPostResume();
     method protected deprecated void onPrepareDialog(int, android.app.Dialog);
     method protected deprecated void onPrepareDialog(int, android.app.Dialog, android.os.Bundle);
@@ -3508,11 +3508,11 @@
     method public void onProvideAssistData(android.os.Bundle);
     method protected void onRestart();
     method protected void onRestoreInstanceState(android.os.Bundle);
-    method protected void onRestoreInstanceState(android.os.Bundle, android.os.PersistableBundle);
+    method public void onRestoreInstanceState(android.os.Bundle, android.os.PersistableBundle);
     method protected void onResume();
     method public deprecated java.lang.Object onRetainNonConfigurationInstance();
     method protected void onSaveInstanceState(android.os.Bundle);
-    method protected void onSaveInstanceState(android.os.Bundle, android.os.PersistableBundle);
+    method public void onSaveInstanceState(android.os.Bundle, android.os.PersistableBundle);
     method public boolean onSearchRequested();
     method protected void onStart();
     method protected void onStop();
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 29ef484..8f0266c 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -955,7 +955,7 @@
      * @see #onRestoreInstanceState
      * @see #onPostCreate
      */
-    protected void onCreate(@Nullable Bundle savedInstanceState,
+    public void onCreate(@Nullable Bundle savedInstanceState,
             @Nullable PersistableBundle persistentState) {
         onCreate(savedInstanceState);
     }
@@ -1040,7 +1040,7 @@
      * @see #onResume
      * @see #onSaveInstanceState
      */
-    protected void onRestoreInstanceState(Bundle savedInstanceState,
+    public void onRestoreInstanceState(Bundle savedInstanceState,
             PersistableBundle persistentState) {
         if (savedInstanceState != null) {
             onRestoreInstanceState(savedInstanceState);
@@ -1130,7 +1130,7 @@
      *
      * @see #onCreate
      */
-    protected void onPostCreate(@Nullable Bundle savedInstanceState,
+    public void onPostCreate(@Nullable Bundle savedInstanceState,
             @Nullable PersistableBundle persistentState) {
         onPostCreate(savedInstanceState);
     }
@@ -1380,7 +1380,7 @@
      * @see #onRestoreInstanceState(Bundle, PersistableBundle)
      * @see #onPause
      */
-    protected void onSaveInstanceState(Bundle outState, PersistableBundle outPersistentState) {
+    public void onSaveInstanceState(Bundle outState, PersistableBundle outPersistentState) {
         onSaveInstanceState(outState);
     }
 
@@ -4769,7 +4769,7 @@
      * @param data An Intent, which can return result data to the caller
      *               (various data can be attached to Intent "extras").
      */
-    protected void onActivityReenter(int resultCode, Intent data) {
+    public void onActivityReenter(int resultCode, Intent data) {
     }
 
     /**
diff --git a/libs/hwui/Layer.cpp b/libs/hwui/Layer.cpp
index e6bc4db..25caae3 100644
--- a/libs/hwui/Layer.cpp
+++ b/libs/hwui/Layer.cpp
@@ -54,6 +54,7 @@
     convexMask = NULL;
     caches.resourceCache.incrementRefcount(this);
     rendererLightPosDirty = true;
+    wasBuildLayered = false;
     renderState.registerLayer(this);
 }
 
diff --git a/libs/hwui/Layer.h b/libs/hwui/Layer.h
index 38c29c7..911b99880 100644
--- a/libs/hwui/Layer.h
+++ b/libs/hwui/Layer.h
@@ -306,6 +306,7 @@
     Rect dirtyRect;
     bool debugDrawUpdate;
     bool hasDrawnSinceUpdate;
+    bool wasBuildLayered;
 
 private:
     void requireRenderer();
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index 0f36c06..dbd273d 100755
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -605,6 +605,12 @@
     AutoFence fence;
 }
 
+void OpenGLRenderer::markLayersAsBuildLayers() {
+    for (size_t i = 0; i < mLayerUpdates.size(); i++) {
+        mLayerUpdates[i]->wasBuildLayered = true;
+    }
+}
+
 ///////////////////////////////////////////////////////////////////////////////
 // State management
 ///////////////////////////////////////////////////////////////////////////////
diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h
index e9ca5d9..e295b1a 100755
--- a/libs/hwui/OpenGLRenderer.h
+++ b/libs/hwui/OpenGLRenderer.h
@@ -150,6 +150,7 @@
     void cancelLayerUpdate(Layer* layer);
     void clearLayerUpdates();
     void flushLayerUpdates();
+    void markLayersAsBuildLayers();
 
     virtual int saveLayer(float left, float top, float right, float bottom,
             const SkPaint* paint, int flags) {
diff --git a/libs/hwui/RenderNode.cpp b/libs/hwui/RenderNode.cpp
index 8fb1f64..a10e70f 100644
--- a/libs/hwui/RenderNode.cpp
+++ b/libs/hwui/RenderNode.cpp
@@ -58,6 +58,19 @@
     fflush(file);
 }
 
+void RenderNode::debugDumpLayers(const char* prefix) {
+    if (mLayer) {
+        ALOGD("%sNode %p (%s) has layer %p (fbo = %u, wasBuildLayered = %s)",
+                prefix, this, getName(), mLayer, mLayer->getFbo(),
+                mLayer->wasBuildLayered ? "true" : "false");
+    }
+    if (mDisplayListData) {
+        for (size_t i = 0; i < mDisplayListData->children().size(); i++) {
+            mDisplayListData->children()[i]->mRenderNode->debugDumpLayers(prefix);
+        }
+    }
+}
+
 RenderNode::RenderNode()
         : mDirtyPropertyFields(0)
         , mNeedsDisplayListDataSync(false)
diff --git a/libs/hwui/RenderNode.h b/libs/hwui/RenderNode.h
index d897997..f329283 100644
--- a/libs/hwui/RenderNode.h
+++ b/libs/hwui/RenderNode.h
@@ -102,6 +102,7 @@
     };
 
     ANDROID_API static void outputLogBuffer(int fd);
+    void debugDumpLayers(const char* prefix);
 
     ANDROID_API void setStagingDisplayList(DisplayListData* newData);
 
diff --git a/libs/hwui/RenderState.cpp b/libs/hwui/RenderState.cpp
index 9948b44..a7c5e85 100644
--- a/libs/hwui/RenderState.cpp
+++ b/libs/hwui/RenderState.cpp
@@ -15,6 +15,8 @@
  */
 #include "RenderState.h"
 
+#include "renderthread/CanvasContext.h"
+
 namespace android {
 namespace uirenderer {
 
@@ -38,6 +40,17 @@
 void RenderState::onGLContextDestroyed() {
     if (CC_UNLIKELY(!mActiveLayers.empty())) {
         mCaches->dumpMemoryUsage();
+        for (std::set<renderthread::CanvasContext*>::iterator cit = mRegisteredContexts.begin();
+                cit != mRegisteredContexts.end(); cit++) {
+            renderthread::CanvasContext* context = *cit;
+            ALOGD("Context: %p (root = %p)", context, context->mRootRenderNode.get());
+            ALOGD("  Prefeteched layers: %zu", context->mPrefetechedLayers.size());
+            for (std::set<RenderNode*>::iterator pit = context->mPrefetechedLayers.begin();
+                    pit != context->mPrefetechedLayers.end(); pit++) {
+                (*pit)->debugDumpLayers("    ");
+            }
+            context->mRootRenderNode->debugDumpLayers("  ");
+        }
         LOG_ALWAYS_FATAL("layers have survived gl context destruction");
     }
 }
diff --git a/libs/hwui/RenderState.h b/libs/hwui/RenderState.h
index 3915fb5..c7ab197 100644
--- a/libs/hwui/RenderState.h
+++ b/libs/hwui/RenderState.h
@@ -29,6 +29,7 @@
 namespace uirenderer {
 
 namespace renderthread {
+class CanvasContext;
 class RenderThread;
 }
 
@@ -57,6 +58,14 @@
         mActiveLayers.erase(layer);
     }
 
+    void registerCanvasContext(renderthread::CanvasContext* context) {
+        mRegisteredContexts.insert(context);
+    }
+
+    void unregisterCanvasContext(renderthread::CanvasContext* context) {
+        mRegisteredContexts.erase(context);
+    }
+
 private:
     friend class renderthread::RenderThread;
     friend class Caches;
@@ -69,6 +78,7 @@
 
     Caches* mCaches;
     std::set<const Layer*> mActiveLayers;
+    std::set<renderthread::CanvasContext*> mRegisteredContexts;
 
     GLsizei mViewportWidth;
     GLsizei mViewportHeight;
diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp
index 428e426..4129a89 100644
--- a/libs/hwui/renderthread/CanvasContext.cpp
+++ b/libs/hwui/renderthread/CanvasContext.cpp
@@ -48,11 +48,13 @@
         , mHaveNewSurface(false)
         , mRootRenderNode(rootRenderNode) {
     mAnimationContext = contextFactory->createAnimationContext(mRenderThread.timeLord());
+    mRenderThread.renderState().registerCanvasContext(this);
 }
 
 CanvasContext::~CanvasContext() {
     destroy();
     delete mAnimationContext;
+    mRenderThread.renderState().unregisterCanvasContext(this);
 }
 
 void CanvasContext::destroy() {
@@ -299,6 +301,7 @@
     // purposes when the frame is actually drawn
     node->setPropertyFieldsDirty(RenderNode::GENERIC);
 
+    mCanvas->markLayersAsBuildLayers();
     mCanvas->flushLayerUpdates();
 
     node->incStrong(0);
diff --git a/libs/hwui/renderthread/CanvasContext.h b/libs/hwui/renderthread/CanvasContext.h
index 5984fd0..2460f6b 100644
--- a/libs/hwui/renderthread/CanvasContext.h
+++ b/libs/hwui/renderthread/CanvasContext.h
@@ -42,6 +42,7 @@
 class OpenGLRenderer;
 class Rect;
 class Layer;
+class RenderState;
 
 namespace renderthread {
 
@@ -95,6 +96,9 @@
 
 private:
     friend class RegisterFrameCallbackTask;
+    // TODO: Replace with something better for layer & other GL object
+    // lifecycle tracking
+    friend class android::uirenderer::RenderState;
 
     void setSurface(ANativeWindow* window);
     void swapBuffers();
diff --git a/libs/hwui/renderthread/RenderThread.h b/libs/hwui/renderthread/RenderThread.h
index 0b91e9d..c461f3a 100644
--- a/libs/hwui/renderthread/RenderThread.h
+++ b/libs/hwui/renderthread/RenderThread.h
@@ -40,6 +40,7 @@
 
 namespace renderthread {
 
+class CanvasContext;
 class DispatchFrameCallbacks;
 class EglManager;
 class RenderProxy;
diff --git a/services/print/java/com/android/server/print/PrintManagerService.java b/services/print/java/com/android/server/print/PrintManagerService.java
index 64242ba..6785cb8 100644
--- a/services/print/java/com/android/server/print/PrintManagerService.java
+++ b/services/print/java/com/android/server/print/PrintManagerService.java
@@ -627,26 +627,40 @@
             return userState;
         }
 
-        private void handleUserStarted(int userId) {
-            UserState userState;
-            synchronized (mLock) {
-                userState = getOrCreateUserStateLocked(userId);
-                userState.updateIfNeededLocked();
-            }
-            // This is the first time we switch to this user after boot, so
-            // now is the time to remove obsolete print jobs since they
-            // are from the last boot and no application would query them.
-            userState.removeObsoletePrintJobs();
+        private void handleUserStarted(final int userId) {
+            // This code will touch the remote print spooler which
+            // must be called off the main thread, so post the work.
+            BackgroundThread.getHandler().post(new Runnable() {
+                @Override
+                public void run() {
+                    UserState userState;
+                    synchronized (mLock) {
+                        userState = getOrCreateUserStateLocked(userId);
+                        userState.updateIfNeededLocked();
+                    }
+                    // This is the first time we switch to this user after boot, so
+                    // now is the time to remove obsolete print jobs since they
+                    // are from the last boot and no application would query them.
+                    userState.removeObsoletePrintJobs();
+                }
+            });
         }
 
-        private void handleUserStopped(int userId) {
-            synchronized (mLock) {
-                UserState userState = mUserStates.get(userId);
-                if (userState != null) {
-                    userState.destroyLocked();
-                    mUserStates.remove(userId);
+        private void handleUserStopped(final int userId) {
+            // This code will touch the remote print spooler which
+            // must be called off the main thread, so post the work.
+            BackgroundThread.getHandler().post(new Runnable() {
+                @Override
+                public void run() {
+                    synchronized (mLock) {
+                        UserState userState = mUserStates.get(userId);
+                        if (userState != null) {
+                            userState.destroyLocked();
+                            mUserStates.remove(userId);
+                        }
+                    }
                 }
-            }
+            });
         }
 
         private int resolveCallingProfileParentLocked(int userId) {