Merge "Fix deadlock in ComponentAliasResolver" into tm-dev am: 4e97fd8938
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/17663452 Change-Id: I4853a9a7d677facdb46ecf38f934280870b88985 Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
@@ -41,6 +41,7 @@ import android.util.Slog;
|
|||||||
import com.android.internal.annotations.GuardedBy;
|
import com.android.internal.annotations.GuardedBy;
|
||||||
import com.android.internal.content.PackageMonitor;
|
import com.android.internal.content.PackageMonitor;
|
||||||
import com.android.internal.os.BackgroundThread;
|
import com.android.internal.os.BackgroundThread;
|
||||||
|
import com.android.server.FgThread;
|
||||||
import com.android.server.LocalServices;
|
import com.android.server.LocalServices;
|
||||||
import com.android.server.compat.CompatChange;
|
import com.android.server.compat.CompatChange;
|
||||||
import com.android.server.compat.PlatformCompat;
|
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.
|
* 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
|
* "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.
|
* 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
|
* Also, for now, aliases can be defined across packages with different certificates, but
|
||||||
* be restrictions:
|
* in a final version this will most likely be tightened.
|
||||||
* - 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.
|
|
||||||
*/
|
*/
|
||||||
public class ComponentAliasResolver {
|
public class ComponentAliasResolver {
|
||||||
private static final String TAG = "ComponentAliasResolver";
|
private static final String TAG = "ComponentAliasResolver";
|
||||||
@@ -172,12 +179,17 @@ public class ComponentAliasResolver {
|
|||||||
USE_EXPERIMENTAL_COMPONENT_ALIAS, "android", UserHandle.USER_SYSTEM));
|
USE_EXPERIMENTAL_COMPONENT_ALIAS, "android", UserHandle.USER_SYSTEM));
|
||||||
if (enabled != mEnabled) {
|
if (enabled != mEnabled) {
|
||||||
Slog.i(TAG, (enabled ? "Enabling" : "Disabling") + " component aliases...");
|
Slog.i(TAG, (enabled ? "Enabling" : "Disabling") + " component aliases...");
|
||||||
|
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) {
|
if (enabled) {
|
||||||
mPackageMonitor.register(mAm.mContext, UserHandle.ALL,
|
mPackageMonitor.register(mAm.mContext, UserHandle.ALL,
|
||||||
/* externalStorage= */ false, BackgroundThread.getHandler());
|
/* externalStorage= */ false, BackgroundThread.getHandler());
|
||||||
} else {
|
} else {
|
||||||
mPackageMonitor.unregister();
|
mPackageMonitor.unregister();
|
||||||
}
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
mEnabled = enabled;
|
mEnabled = enabled;
|
||||||
mEnabledByDeviceConfig = enabledByDeviceConfig;
|
mEnabledByDeviceConfig = enabledByDeviceConfig;
|
||||||
|
|||||||
@@ -46,11 +46,15 @@ public class BaseComponentAliasTest {
|
|||||||
sDeviceConfig.set("enable_experimental_component_alias", "");
|
sDeviceConfig.set("enable_experimental_component_alias", "");
|
||||||
sDeviceConfig.set("component_alias_overrides", "");
|
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", () -> {
|
TestUtils.waitUntil("Wait until component alias is actually enabled", () -> {
|
||||||
return ShellUtils.runShellCommand("dumpsys activity component-alias")
|
String out = ShellUtils.runShellCommand("dumpsys activity component-alias");
|
||||||
.indexOf("Enabled: true") > 0;
|
|
||||||
|
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
|
@AfterClass
|
||||||
|
|||||||
Reference in New Issue
Block a user