Fix deadlock in ComponentAliasResolver
Test: atest ComponentAliasTests ComponentAliasTests1 ComponentAliasTests2 (except for existing flakiness: b/228613740) Bug: 228273242 Change-Id: Iea7679702ce9c883e6df196de0ae47d7bdd5d876
This commit is contained in:
@@ -41,6 +41,7 @@ import android.util.Slog;
|
||||
import com.android.internal.annotations.GuardedBy;
|
||||
import com.android.internal.content.PackageMonitor;
|
||||
import com.android.internal.os.BackgroundThread;
|
||||
import com.android.server.FgThread;
|
||||
import com.android.server.LocalServices;
|
||||
import com.android.server.compat.CompatChange;
|
||||
import com.android.server.compat.PlatformCompat;
|
||||
@@ -53,17 +54,23 @@ import java.util.function.Supplier;
|
||||
/**
|
||||
* Manages and handles component aliases, which is an experimental feature.
|
||||
*
|
||||
* For now, this is an experimental feature to evaluate feasibility, so the implementation is
|
||||
* NOTE: THIS CLASS IS PURELY EXPERIMENTAL AND WILL BE REMOVED IN FUTURE ANDROID VERSIONS.
|
||||
* DO NOT USE IT.
|
||||
*
|
||||
* "Component alias" allows an android manifest component (for now only broadcasts and services)
|
||||
* to be defined in one android package while having the implementation in a different package.
|
||||
*
|
||||
* When/if this becomes a real feature, it will be most likely implemented very differently,
|
||||
* which is why this shouldn't be used.
|
||||
*
|
||||
* For now, because this is an experimental feature to evaluate feasibility, the implementation is
|
||||
* "quick & dirty". For example, to define aliases, we use a regular intent filter and meta-data
|
||||
* in the manifest, instead of adding proper tags/attributes to AndroidManifest.xml.
|
||||
*
|
||||
* Because it's an experimental feature, it can't be enabled on a user build.
|
||||
* This feature is disabled by default.
|
||||
*
|
||||
* Also, for now, aliases can be defined across any packages, but in the final version, there'll
|
||||
* be restrictions:
|
||||
* - We probably should only allow either privileged or preinstalled apps.
|
||||
* - Aliases can only be defined across packages that are atomically installed, and signed with the
|
||||
* same key.
|
||||
* Also, for now, aliases can be defined across packages with different certificates, but
|
||||
* in a final version this will most likely be tightened.
|
||||
*/
|
||||
public class ComponentAliasResolver {
|
||||
private static final String TAG = "ComponentAliasResolver";
|
||||
@@ -172,12 +179,17 @@ public class ComponentAliasResolver {
|
||||
USE_EXPERIMENTAL_COMPONENT_ALIAS, "android", UserHandle.USER_SYSTEM));
|
||||
if (enabled != mEnabled) {
|
||||
Slog.i(TAG, (enabled ? "Enabling" : "Disabling") + " component aliases...");
|
||||
if (enabled) {
|
||||
mPackageMonitor.register(mAm.mContext, UserHandle.ALL,
|
||||
/* externalStorage= */ false, BackgroundThread.getHandler());
|
||||
} else {
|
||||
mPackageMonitor.unregister();
|
||||
}
|
||||
FgThread.getHandler().post(() -> {
|
||||
// Registering/unregistering a receiver internally takes the AM lock, but AM
|
||||
// calls into this class while holding the AM lock. So do it on a handler to
|
||||
// avoid deadlocks.
|
||||
if (enabled) {
|
||||
mPackageMonitor.register(mAm.mContext, UserHandle.ALL,
|
||||
/* externalStorage= */ false, BackgroundThread.getHandler());
|
||||
} else {
|
||||
mPackageMonitor.unregister();
|
||||
}
|
||||
});
|
||||
}
|
||||
mEnabled = enabled;
|
||||
mEnabledByDeviceConfig = enabledByDeviceConfig;
|
||||
|
||||
@@ -46,11 +46,15 @@ public class BaseComponentAliasTest {
|
||||
sDeviceConfig.set("enable_experimental_component_alias", "");
|
||||
sDeviceConfig.set("component_alias_overrides", "");
|
||||
|
||||
// Make sure the feature is actually enabled.
|
||||
// Make sure the feature is actually enabled, and the aliases are loaded.
|
||||
TestUtils.waitUntil("Wait until component alias is actually enabled", () -> {
|
||||
return ShellUtils.runShellCommand("dumpsys activity component-alias")
|
||||
.indexOf("Enabled: true") > 0;
|
||||
String out = ShellUtils.runShellCommand("dumpsys activity component-alias");
|
||||
|
||||
return out.contains("Enabled: true")
|
||||
&& out.contains("android.content.componentalias.tests/.b.Alias04")
|
||||
&& out.contains("android.content.componentalias.tests/.s.Alias04");
|
||||
});
|
||||
ShellUtils.runShellCommand("am wait-for-broadcast-idle");
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
|
||||
Reference in New Issue
Block a user