frameworks/base: Add fix for ShortcutService deadlock

This commit is contained in:
Peter Cai 2022-06-12 20:51:24 -04:00
parent ec7870219a
commit f63374e53c
5 changed files with 120 additions and 4 deletions

View File

@ -1,7 +1,7 @@
From a26d483d257bdb33553f43719cdad0b392fc6ea4 Mon Sep 17 00:00:00 2001
From: Peter Cai <peter@typeblog.net>
Date: Tue, 12 Oct 2021 21:37:22 -0400
Subject: [PATCH 1/4] PackageParser: support glob matching for properties
Subject: [PATCH 1/5] PackageParser: support glob matching for properties
Needed to make phh's vendor overlays work
---

View File

@ -1,7 +1,7 @@
From 4182ca99bed1bed96178c382a75d4f747f206b1e Mon Sep 17 00:00:00 2001
From: Danny Lin <danny@kdrag0n.dev>
Date: Sat, 7 Nov 2020 23:47:30 -0800
Subject: [PATCH 2/4] core: Use real security patch level property
Subject: [PATCH 2/5] core: Use real security patch level property
The standard platform security patch level property may not reflect the
real patch level due to SafetyNet hacks, so we need to check the custom

View File

@ -1,7 +1,7 @@
From b2c3942e6eb0f899039f6be96f87b7b0727b41d3 Mon Sep 17 00:00:00 2001
From: Peter Cai <peter@typeblog.net>
Date: Wed, 1 Jun 2022 16:56:20 -0400
Subject: [PATCH 3/4] Implement a persistent property to override the default
Subject: [PATCH 3/5] Implement a persistent property to override the default
primary camera (0)
Change-Id: I49b45d00bf71d7932591b3516d49a680e1b6568b

View File

@ -1,7 +1,7 @@
From 6da03d0eadcabe836e71d2d88d7d2d057ba9efa4 Mon Sep 17 00:00:00 2001
From: dhacker29 <dhackerdvm@gmail.com>
Date: Tue, 24 Nov 2015 01:53:47 -0500
Subject: [PATCH 4/4] fw/b: Use ro.build.version.incremental to signal OTA
Subject: [PATCH 4/5] fw/b: Use ro.build.version.incremental to signal OTA
upgrades
Squash of:

View File

@ -0,0 +1,116 @@
From 9ae7ba267da4f6bf098bc3dd1ea0edc6aea59894 Mon Sep 17 00:00:00 2001
From: Peter Cai <peter@typeblog.net>
Date: Sun, 12 Jun 2022 13:17:38 -0400
Subject: [PATCH 5/5] ShortcutPackage: Acquire the service's lock before
reporting usage
When `ShortcutPackage.pushDynamicShortcut()` is called from
`ShortcutService.pushDynamicShortcut()`, the lock
`ShortcutService.mLock` is acquired. However, the final
`injectPostToHandler()` call drops this lock before calling
`awaitInAppSearch()`.
The `awaitInAppSearch()` method assumes that it is called while being
guarded by the `ShortcutService` lock. When called without acquiring the
lock, it will end up acquiring `ShortcutPackage.mLock` first, then
acquiring `ShortcutService.mLock` anyway due to various calls into
`ShortcutService` methods. This creates an opportunity for a dead lock
to happen, since two threads can wait on each other for releasing the
other lock they are currently trying to acquire. On one of my
development devices, this happens quite regularly:
> "android.bg" prio=5 tid=22 Blocked
> | group="main" sCount=1 ucsCount=0 flags=1 obj=0x16040c48 self=0xb40000709b1a3c00
> | sysTid=1515 nice=10 cgrp=default sched=0/0 handle=0x70904ebcb0
> | state=S schedstat=( 14737747935 45952650258 46431 ) utm=610 stm=862 core=0 HZ=100
> | stack=0x70903e8000-0x70903ea000 stackSize=1039KB
> | held mutexes=
> at com.android.server.pm.ShortcutService.scheduleSaveInner(ShortcutService.java:1176)
> - waiting to lock <0x0a5766e4> (a java.lang.Object) held by thread 122
> at com.android.server.pm.ShortcutService.scheduleSaveUser(ShortcutService.java:1166)
> at com.android.server.pm.ShortcutService.packageShortcutsChanged(ShortcutService.java:1769)
> at com.android.server.pm.ShortcutPackage.rescanPackage(ShortcutPackage.java:1224)
> at com.android.server.pm.ShortcutPackage.awaitInAppSearch(ShortcutPackage.java:2627)
> - locked <0x00e8774d> (a java.lang.Object)
> at com.android.server.pm.ShortcutPackage.awaitInAppSearch(ShortcutPackage.java:2593)
> at com.android.server.pm.ShortcutPackage.lambda$pushDynamicShortcut$3$ShortcutPackage(ShortcutPackage.java:452)
> at com.android.server.pm.ShortcutPackage$$ExternalSyntheticLambda3.run(unavailable:-1)
> at android.os.Handler.handleCallback(Handler.java:938)
> at android.os.Handler.dispatchMessage(Handler.java:99)
> at android.os.Looper.loopOnce(Looper.java:201)
> at android.os.Looper.loop(Looper.java:288)
> at android.os.HandlerThread.run(HandlerThread.java:67)
Meanwhile, in thread 122:
> "Binder:1489_6" prio=5 tid=122 Blocked
> | group="main" sCount=1 ucsCount=0 flags=1 obj=0x16047388 self=0xb400007074947c00
> | sysTid=2070 nice=0 cgrp=default sched=0/0 handle=0x70218e4cb0
> | state=S schedstat=( 10396689438 3745391103 31237 ) utm=808 stm=231 core=1 HZ=100
> | stack=0x70217ed000-0x70217ef000 stackSize=991KB
> | held mutexes=
> at com.android.server.pm.ShortcutPackage.awaitInAppSearch(ShortcutPackage.java:2605)
> - waiting to lock <0x00e8774d> (a java.lang.Object) held by thread 22
> at com.android.server.pm.ShortcutPackage.awaitInAppSearch(ShortcutPackage.java:2593)
> at com.android.server.pm.ShortcutPackage.forEachShortcutStopWhen(ShortcutPackage.java:2542)
> at com.android.server.pm.ShortcutPackage.forEachShortcutStopWhen(ShortcutPackage.java:2524)
> at com.android.server.pm.ShortcutPackage.areAllActivitiesStillEnabled(ShortcutPackage.java:1039)
> at com.android.server.pm.ShortcutPackage.rescanPackageIfNeeded(ShortcutPackage.java:1096)
> at com.android.server.pm.ShortcutUser.rescanPackageIfNeeded(ShortcutUser.java:338)
> at com.android.server.pm.ShortcutUser.onCalledByPublisher(ShortcutUser.java:294)
> at com.android.server.pm.ShortcutService.getPackageShortcutsForPublisherLocked(ShortcutService.java:1355)
> at com.android.server.pm.ShortcutService.lambda$pushDynamicShortcut$9$ShortcutService(ShortcutService.java:2210)
> - locked <0x0a5766e4> (a java.lang.Object)
> at com.android.server.pm.ShortcutService$$ExternalSyntheticLambda14.run(unavailable:-1)
> at com.android.server.pm.ShortcutService.injectPostToHandlerIfAppSearch(ShortcutService.java:1740)
> at com.android.server.pm.ShortcutService.pushDynamicShortcut(ShortcutService.java:2200)
> at android.content.pm.IShortcutService$Stub.onTransact(IShortcutService.java:715)
> at android.os.Binder.execTransactInternal(Binder.java:1201)
> at android.os.Binder.execTransact(Binder.java:1164)
The straightforward fix here seems to be just taking the
`ShortcutService` lock before calling `awaitInAppSearch()`. This commit
also added a method in `ShortcutService` to facilitate this interaction.
Test: manual
Change-Id: I0f997a02820b1598ca2a4ec25415c03f8f87fc87
---
.../core/java/com/android/server/pm/ShortcutPackage.java | 2 +-
.../core/java/com/android/server/pm/ShortcutService.java | 8 ++++++++
2 files changed, 9 insertions(+), 1 deletion(-)
diff --git a/services/core/java/com/android/server/pm/ShortcutPackage.java b/services/core/java/com/android/server/pm/ShortcutPackage.java
index b4bd086af272..d4f5a237f250 100644
--- a/services/core/java/com/android/server/pm/ShortcutPackage.java
+++ b/services/core/java/com/android/server/pm/ShortcutPackage.java
@@ -449,7 +449,7 @@ class ShortcutPackage extends ShortcutPackageItem {
forceReplaceShortcutInner(newShortcut);
if (isAppSearchEnabled()) {
- mShortcutUser.mService.injectPostToHandler(() -> awaitInAppSearch("reportUsage",
+ mShortcutUser.mService.injectPostToHandlerWithLock(() -> awaitInAppSearch("reportUsage",
session -> {
final AndroidFuture<Boolean> future = new AndroidFuture<>();
session.reportUsage(
diff --git a/services/core/java/com/android/server/pm/ShortcutService.java b/services/core/java/com/android/server/pm/ShortcutService.java
index 4e9e7a026a90..c688943d2838 100644
--- a/services/core/java/com/android/server/pm/ShortcutService.java
+++ b/services/core/java/com/android/server/pm/ShortcutService.java
@@ -1731,6 +1731,14 @@ public class ShortcutService extends IShortcutService.Stub {
mHandler.post(r);
}
+ void injectPostToHandlerWithLock(Runnable r) {
+ injectPostToHandler(() -> {
+ synchronized (mLock) {
+ r.run();
+ }
+ });
+ }
+
void injectRunOnNewThread(Runnable r) {
new Thread(r).start();
}
--
2.36.1