Merge "dumpstate: set backlog to zero" am: e0268511a0
am: 8b65dbc738

Change-Id: Id0e290a9ae13f15291829d9de1ae326ceeafb59c
diff --git a/cmds/installd/migrate_legacy_obb_data.sh b/cmds/installd/migrate_legacy_obb_data.sh
index 4f8a1ec..1075688 100644
--- a/cmds/installd/migrate_legacy_obb_data.sh
+++ b/cmds/installd/migrate_legacy_obb_data.sh
@@ -15,6 +15,19 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+rm -rf /sdcard/Android/obb/test_probe
+mkdir -p /sdcard/Android/obb/
+touch /sdcard/Android/obb/test_probe
+if ! test -f /data/media/0/Android/obb/test_probe ; then
+  log -p i -t migrate_legacy_obb_data "No support for 'unshared_obb'. Not migrating"
+  rm -rf /sdcard/Android/obb/test_probe
+  exit 0
+fi
+
+# Delete the test file, and remove the obb folder if it is empty
+rm -rf /sdcard/Android/obb/test_probe
+rmdir /data/media/obb
+
 if ! test -d /data/media/obb ; then
   log -p i -t migrate_legacy_obb_data "No legacy obb data to migrate."
   exit 0
diff --git a/cmds/service/service.cpp b/cmds/service/service.cpp
index d5dc6b7..543357c 100644
--- a/cmds/service/service.cpp
+++ b/cmds/service/service.cpp
@@ -70,7 +70,7 @@
 {
     bool wantsUsage = false;
     int result = 0;
-    
+
     while (1) {
         int ic = getopt(argc, argv, "h?");
         if (ic < 0)
@@ -97,7 +97,7 @@
         aerr << "service: Unable to get default service manager!" << endl;
         return 20;
     }
-    
+
     if (optind >= argc) {
         wantsUsage = true;
     } else if (!wantsUsage) {
@@ -119,8 +119,8 @@
             for (unsigned i = 0; i < services.size(); i++) {
                 String16 name = services[i];
                 sp<IBinder> service = sm->checkService(name);
-                aout << i 
-                     << "\t" << good_old_string(name) 
+                aout << i
+                     << "\t" << good_old_string(name)
                      << ": [" << good_old_string(get_interface_name(service)) << "]"
                      << endl;
             }
@@ -188,68 +188,68 @@
                             optind++;
                             data.writeStrongBinder(nullptr);
                         } else if (strcmp(argv[optind], "intent") == 0) {
-                        	
-                        	char* action = nullptr;
-                        	char* dataArg = nullptr;
-                        	char* type = nullptr;
-                        	int launchFlags = 0;
-                        	char* component = nullptr;
-                        	int categoryCount = 0;
-                        	char* categories[16];
-                        	
-                        	char* context1 = nullptr;
-                        	
+
+                            char* action = nullptr;
+                            char* dataArg = nullptr;
+                            char* type = nullptr;
+                            int launchFlags = 0;
+                            char* component = nullptr;
+                            int categoryCount = 0;
+                            char* categories[16];
+
+                            char* context1 = nullptr;
+
                             optind++;
-                            
-                        	while (optind < argc)
-                        	{
-                        		char* key = strtok_r(argv[optind], "=", &context1);
-                        		char* value = strtok_r(nullptr, "=", &context1);
-                                
+
+                            while (optind < argc)
+                            {
+                                char* key = strtok_r(argv[optind], "=", &context1);
+                                char* value = strtok_r(nullptr, "=", &context1);
+
                                 // we have reached the end of the XXX=XXX args.
                                 if (key == nullptr) break;
-                        		
-                        		if (strcmp(key, "action") == 0)
-                        		{
-                        			action = value;
-                        		}
-                        		else if (strcmp(key, "data") == 0)
-                        		{
-                        			dataArg = value;
-                        		}
-                        		else if (strcmp(key, "type") == 0)
-                        		{
-                        			type = value;
-                        		}
-                        		else if (strcmp(key, "launchFlags") == 0)
-                        		{
-                        			launchFlags = atoi(value);
-                        		}
-                        		else if (strcmp(key, "component") == 0)
-                        		{
-                        			component = value;
-                        		}
-                        		else if (strcmp(key, "categories") == 0)
-                        		{
-                        			char* context2 = nullptr;
-                        			categories[categoryCount] = strtok_r(value, ",", &context2);
-                        			
-                        			while (categories[categoryCount] != nullptr)
-                        			{
-                        				categoryCount++;
-                        				categories[categoryCount] = strtok_r(nullptr, ",", &context2);
-                        			}
-                        		}
-                                
+
+                                if (strcmp(key, "action") == 0)
+                                {
+                                    action = value;
+                                }
+                                else if (strcmp(key, "data") == 0)
+                                {
+                                    dataArg = value;
+                                }
+                                else if (strcmp(key, "type") == 0)
+                                {
+                                    type = value;
+                                }
+                                else if (strcmp(key, "launchFlags") == 0)
+                                {
+                                    launchFlags = atoi(value);
+                                }
+                                else if (strcmp(key, "component") == 0)
+                                {
+                                    component = value;
+                                }
+                                else if (strcmp(key, "categories") == 0)
+                                {
+                                    char* context2 = nullptr;
+                                    categories[categoryCount] = strtok_r(value, ",", &context2);
+
+                                    while (categories[categoryCount] != nullptr)
+                                    {
+                                        categoryCount++;
+                                        categories[categoryCount] = strtok_r(nullptr, ",", &context2);
+                                    }
+                                }
+
                                 optind++;
-                        	} 
-                        	
+                            }
+
                             writeString16(data, action);
                             writeString16(data, dataArg);
                             writeString16(data, type);
-                       		data.writeInt32(launchFlags);
+                            data.writeInt32(launchFlags);
                             writeString16(data, component);
-                        	
+
                             if (categoryCount > 0)
                             {
                                 data.writeInt32(categoryCount);
@@ -261,10 +261,10 @@
                             else
                             {
                                 data.writeInt32(0);
-                            }                            
-  
+                            }
+
                             // for now just set the extra field to be null.
-                       		data.writeInt32(-1);
+                            data.writeInt32(-1);
                         } else {
                             aerr << "service: unknown option " << argv[optind] << endl;
                             wantsUsage = true;
@@ -272,7 +272,7 @@
                             break;
                         }
                     }
-                    
+
                     service->transact(code, data, &reply);
                     aout << "Result: " << reply << endl;
                 } else {
@@ -295,7 +295,7 @@
             result = 10;
         }
     }
-    
+
     if (wantsUsage) {
         aout << "Usage: service [-h|-?]\n"
                 "       service list\n"
@@ -311,7 +311,7 @@
 //                "       action=STR data=STR type=STR launchFlags=INT component=STR categories=STR[,STR,...]\n";
         return result;
     }
-    
+
     return result;
 }
 
diff --git a/libs/sensor/SensorManager.cpp b/libs/sensor/SensorManager.cpp
index 5840d51..96d5eb9 100644
--- a/libs/sensor/SensorManager.cpp
+++ b/libs/sensor/SensorManager.cpp
@@ -94,7 +94,7 @@
 
 SensorManager::SensorManager(const String16& opPackageName)
     : mSensorList(nullptr), mOpPackageName(opPackageName), mDirectConnectionHandle(1) {
-    // okay we're not locked here, but it's not needed during construction
+    Mutex::Autolock _l(mLock);
     assertStateLocked();
 }
 
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index bda7e43..1318bc0 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -1231,6 +1231,14 @@
     if (parent != nullptr && parent->isHiddenByPolicy()) {
         return true;
     }
+    if (usingRelativeZ(LayerVector::StateSet::Drawing)) {
+        auto zOrderRelativeOf = mDrawingState.zOrderRelativeOf.promote();
+        if (zOrderRelativeOf != nullptr) {
+            if (zOrderRelativeOf->isHiddenByPolicy()) {
+                return true;
+            }
+        }
+    }
     return s.flags & layer_state_t::eLayerHidden;
 }
 
@@ -1612,7 +1620,7 @@
     return mDrawingState.z;
 }
 
-bool Layer::usingRelativeZ(LayerVector::StateSet stateSet) {
+bool Layer::usingRelativeZ(LayerVector::StateSet stateSet) const {
     const bool useDrawing = stateSet == LayerVector::StateSet::Drawing;
     const State& state = useDrawing ? mDrawingState : mCurrentState;
     return state.zOrderRelativeOf != nullptr;
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index 5c55111..8a80e15 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -824,7 +824,7 @@
 
 protected:
     // -----------------------------------------------------------------------
-    bool usingRelativeZ(LayerVector::StateSet stateSet);
+    bool usingRelativeZ(LayerVector::StateSet stateSet) const;
 
     bool mPremultipliedAlpha{true};
     String8 mName;
diff --git a/services/surfaceflinger/TransactionCompletedThread.cpp b/services/surfaceflinger/TransactionCompletedThread.cpp
index 5cf8eb1..fd466de 100644
--- a/services/surfaceflinger/TransactionCompletedThread.cpp
+++ b/services/surfaceflinger/TransactionCompletedThread.cpp
@@ -197,8 +197,14 @@
     }
 
     transactionStats->latchTime = handle->latchTime;
-    transactionStats->surfaceStats.emplace_back(handle->surfaceControl, handle->acquireTime,
-                                                handle->previousReleaseFence);
+    // If the layer has already been destroyed, don't add the SurfaceControl to the callback.
+    // The client side keeps a sp<> to the SurfaceControl so if the SurfaceControl has been
+    // destroyed the client side is dead and there won't be anyone to send the callback to.
+    sp<IBinder> surfaceControl = handle->surfaceControl.promote();
+    if (surfaceControl) {
+        transactionStats->surfaceStats.emplace_back(surfaceControl, handle->acquireTime,
+                                                    handle->previousReleaseFence);
+    }
     return NO_ERROR;
 }
 
diff --git a/services/surfaceflinger/TransactionCompletedThread.h b/services/surfaceflinger/TransactionCompletedThread.h
index 21e2678..e849f71 100644
--- a/services/surfaceflinger/TransactionCompletedThread.h
+++ b/services/surfaceflinger/TransactionCompletedThread.h
@@ -49,7 +49,7 @@
 
     sp<ITransactionCompletedListener> listener;
     std::vector<CallbackId> callbackIds;
-    sp<IBinder> surfaceControl;
+    wp<IBinder> surfaceControl;
 
     bool releasePreviousBuffer = false;
     sp<Fence> previousReleaseFence;
diff --git a/services/surfaceflinger/tests/Transaction_test.cpp b/services/surfaceflinger/tests/Transaction_test.cpp
index f83b3ea..d5f6534 100644
--- a/services/surfaceflinger/tests/Transaction_test.cpp
+++ b/services/surfaceflinger/tests/Transaction_test.cpp
@@ -1115,6 +1115,56 @@
     }
 }
 
+TEST_P(LayerTypeTransactionTest, HideRelativeParentHidesLayer) {
+    sp<SurfaceControl> parent =
+            LayerTransactionTest::createLayer("Parent", 0 /* buffer width */, 0 /* buffer height */,
+                                              ISurfaceComposerClient::eFXSurfaceColor);
+    sp<SurfaceControl> relativeParent =
+            LayerTransactionTest::createLayer("RelativeParent", 0 /* buffer width */,
+                    0 /* buffer height */, ISurfaceComposerClient::eFXSurfaceColor);
+
+    sp<SurfaceControl> childLayer;
+    ASSERT_NO_FATAL_FAILURE(
+            childLayer = LayerTransactionTest::createLayer("childLayer", 0 /* buffer width */,
+                                                           0 /* buffer height */,
+                                                           ISurfaceComposerClient::eFXSurfaceColor,
+                                                           parent.get()));
+    Transaction()
+            .setColor(childLayer, half3{1.0f, 0.0f, 0.0f})
+            .setColor(parent, half3{0.0f, 0.0f, 0.0f})
+            .setColor(relativeParent, half3{0.0f, 1.0f, 0.0f})
+            .show(childLayer)
+            .show(parent)
+            .show(relativeParent)
+            .setLayer(parent, mLayerZBase - 1)
+            .setLayer(relativeParent, mLayerZBase)
+            .apply();
+
+    Transaction()
+            .setRelativeLayer(childLayer, relativeParent->getHandle(), 1)
+            .apply();
+
+    {
+        SCOPED_TRACE("setLayer above");
+        // Set layer should get applied and place the child above.
+        std::unique_ptr<ScreenCapture> screenshot;
+        ScreenCapture::captureScreen(&screenshot);
+        screenshot->expectColor(Rect(0, 0, 20, 30), Color::RED);
+    }
+
+    Transaction()
+        .hide(relativeParent)
+        .apply();
+
+    {
+        SCOPED_TRACE("hide relative parent");
+        // The relative should no longer be visible.
+        std::unique_ptr<ScreenCapture> screenshot;
+        ScreenCapture::captureScreen(&screenshot);
+        screenshot->expectColor(Rect(0, 0, 20, 30), Color::BLACK);
+    }
+}
+
 void LayerRenderTypeTransactionTest::setRelativeZGroupHelper(uint32_t layerType) {
     sp<SurfaceControl> layerR;
     sp<SurfaceControl> layerG;