Merge "Allow enabling component-alias via device config, on userdebug or eng devices"
This commit is contained in:
@@ -123,6 +123,7 @@ final class ActivityManagerConstants extends ContentObserver {
|
||||
static final String KEY_KILL_BG_RESTRICTED_CACHED_IDLE = "kill_bg_restricted_cached_idle";
|
||||
static final String KEY_KILL_BG_RESTRICTED_CACHED_IDLE_SETTLE_TIME =
|
||||
"kill_bg_restricted_cached_idle_settle_time";
|
||||
static final String KEY_ENABLE_COMPONENT_ALIAS = "enable_experimental_component_alias";
|
||||
static final String KEY_COMPONENT_ALIAS_OVERRIDES = "component_alias_overrides";
|
||||
|
||||
private static final int DEFAULT_MAX_CACHED_PROCESSES = 32;
|
||||
@@ -199,6 +200,7 @@ final class ActivityManagerConstants extends ContentObserver {
|
||||
* Whether or not to enable the extra delays to service restarts on memory pressure.
|
||||
*/
|
||||
private static final boolean DEFAULT_ENABLE_EXTRA_SERVICE_RESTART_DELAY_ON_MEM_PRESSURE = true;
|
||||
private static final boolean DEFAULT_ENABLE_COMPONENT_ALIAS = false;
|
||||
private static final String DEFAULT_COMPONENT_ALIAS_OVERRIDES = "";
|
||||
|
||||
// Flag stored in the DeviceConfig API.
|
||||
@@ -594,6 +596,12 @@ final class ActivityManagerConstants extends ContentObserver {
|
||||
boolean mEnableExtraServiceRestartDelayOnMemPressure =
|
||||
DEFAULT_ENABLE_EXTRA_SERVICE_RESTART_DELAY_ON_MEM_PRESSURE;
|
||||
|
||||
/**
|
||||
* Whether to enable "component alias" experimental feature. This can only be enabled
|
||||
* on userdebug or eng builds.
|
||||
*/
|
||||
volatile boolean mEnableComponentAlias = DEFAULT_ENABLE_COMPONENT_ALIAS;
|
||||
|
||||
/**
|
||||
* Defines component aliases. Format
|
||||
* ComponentName ":" ComponentName ( "," ComponentName ":" ComponentName )*
|
||||
@@ -831,6 +839,7 @@ final class ActivityManagerConstants extends ContentObserver {
|
||||
case KEY_ENABLE_EXTRA_SERVICE_RESTART_DELAY_ON_MEM_PRESSURE:
|
||||
updateEnableExtraServiceRestartDelayOnMemPressure();
|
||||
break;
|
||||
case KEY_ENABLE_COMPONENT_ALIAS:
|
||||
case KEY_COMPONENT_ALIAS_OVERRIDES:
|
||||
updateComponentAliases();
|
||||
break;
|
||||
@@ -1269,11 +1278,15 @@ final class ActivityManagerConstants extends ContentObserver {
|
||||
}
|
||||
|
||||
private void updateComponentAliases() {
|
||||
mEnableComponentAlias = DeviceConfig.getBoolean(
|
||||
DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
|
||||
KEY_ENABLE_COMPONENT_ALIAS,
|
||||
DEFAULT_ENABLE_COMPONENT_ALIAS);
|
||||
mComponentAliasOverrides = DeviceConfig.getString(
|
||||
DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
|
||||
KEY_COMPONENT_ALIAS_OVERRIDES,
|
||||
DEFAULT_COMPONENT_ALIAS_OVERRIDES);
|
||||
mService.mComponentAliasResolver.update(mComponentAliasOverrides);
|
||||
mService.mComponentAliasResolver.update(mEnableComponentAlias, mComponentAliasOverrides);
|
||||
}
|
||||
|
||||
private void updateProcessKillTimeout() {
|
||||
@@ -1512,6 +1525,8 @@ final class ActivityManagerConstants extends ContentObserver {
|
||||
pw.print("="); pw.println(mPushMessagingOverQuotaBehavior);
|
||||
pw.print(" "); pw.print(KEY_FGS_ALLOW_OPT_OUT);
|
||||
pw.print("="); pw.println(mFgsAllowOptOut);
|
||||
pw.print(" "); pw.print(KEY_ENABLE_COMPONENT_ALIAS);
|
||||
pw.print("="); pw.println(mEnableComponentAlias);
|
||||
pw.print(" "); pw.print(KEY_COMPONENT_ALIAS_OVERRIDES);
|
||||
pw.print("="); pw.println(mComponentAliasOverrides);
|
||||
|
||||
|
||||
@@ -8066,7 +8066,8 @@ public class ActivityManagerService extends IActivityManager.Stub
|
||||
|
||||
// Load the component aliases.
|
||||
t.traceBegin("componentAlias");
|
||||
mComponentAliasResolver.onSystemReady(mConstants.mComponentAliasOverrides);
|
||||
mComponentAliasResolver.onSystemReady(mConstants.mEnableComponentAlias,
|
||||
mConstants.mComponentAliasOverrides);
|
||||
t.traceEnd(); // componentAlias
|
||||
|
||||
t.traceEnd(); // PhaseActivityManagerReady
|
||||
|
||||
@@ -30,6 +30,7 @@ import android.content.pm.PackageManagerInternal;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import android.content.pm.ServiceInfo;
|
||||
import android.os.Binder;
|
||||
import android.os.Build;
|
||||
import android.os.ServiceManager;
|
||||
import android.os.UserHandle;
|
||||
import android.text.TextUtils;
|
||||
@@ -56,6 +57,8 @@ import java.util.function.Supplier;
|
||||
* "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.
|
||||
*
|
||||
* 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.
|
||||
@@ -77,6 +80,9 @@ public class ComponentAliasResolver {
|
||||
private final ActivityManagerService mAm;
|
||||
private final Context mContext;
|
||||
|
||||
@GuardedBy("mLock")
|
||||
private boolean mEnabledByDeviceConfig;
|
||||
|
||||
@GuardedBy("mLock")
|
||||
private boolean mEnabled;
|
||||
|
||||
@@ -141,7 +147,7 @@ public class ComponentAliasResolver {
|
||||
/**
|
||||
* Call this on systemRead().
|
||||
*/
|
||||
public void onSystemReady(String overrides) {
|
||||
public void onSystemReady(boolean enabledByDeviceConfig, String overrides) {
|
||||
synchronized (mLock) {
|
||||
mPlatformCompat = (PlatformCompat) ServiceManager.getService(
|
||||
Context.PLATFORM_COMPAT_SERVICE);
|
||||
@@ -149,19 +155,21 @@ public class ComponentAliasResolver {
|
||||
mCompatChangeListener);
|
||||
}
|
||||
if (DEBUG) Slog.d(TAG, "Compat listener set.");
|
||||
update(overrides);
|
||||
update(enabledByDeviceConfig, overrides);
|
||||
}
|
||||
|
||||
/**
|
||||
* (Re-)loads aliases from <meta-data> and the device config override.
|
||||
*/
|
||||
public void update(String overrides) {
|
||||
public void update(boolean enabledByDeviceConfig, String overrides) {
|
||||
synchronized (mLock) {
|
||||
if (mPlatformCompat == null) {
|
||||
return; // System not ready.
|
||||
}
|
||||
final boolean enabled = mPlatformCompat.isChangeEnabledByPackageName(
|
||||
USE_EXPERIMENTAL_COMPONENT_ALIAS, "android", UserHandle.USER_SYSTEM);
|
||||
final boolean enabled = Build.isDebuggable()
|
||||
&& (enabledByDeviceConfig
|
||||
|| mPlatformCompat.isChangeEnabledByPackageName(
|
||||
USE_EXPERIMENTAL_COMPONENT_ALIAS, "android", UserHandle.USER_SYSTEM));
|
||||
if (enabled != mEnabled) {
|
||||
Slog.i(TAG, (enabled ? "Enabling" : "Disabling") + " component aliases...");
|
||||
if (enabled) {
|
||||
@@ -172,6 +180,7 @@ public class ComponentAliasResolver {
|
||||
}
|
||||
}
|
||||
mEnabled = enabled;
|
||||
mEnabledByDeviceConfig = enabledByDeviceConfig;
|
||||
mOverrideString = overrides;
|
||||
|
||||
if (mEnabled) {
|
||||
@@ -184,7 +193,7 @@ public class ComponentAliasResolver {
|
||||
|
||||
private void refresh() {
|
||||
synchronized (mLock) {
|
||||
update(mOverrideString);
|
||||
update(mEnabledByDeviceConfig, mOverrideString);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -21,8 +21,6 @@
|
||||
<option name="test-file-name" value="ComponentAliasTests2.apk" />
|
||||
</target_preparer>
|
||||
<target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
|
||||
<option name="run-command" value="am compat enable --no-kill USE_EXPERIMENTAL_COMPONENT_ALIAS android" />
|
||||
|
||||
<!-- Exempt the helper APKs from the BG restriction, so they can start BG services. -->
|
||||
<option name="run-command" value="cmd deviceidle whitelist +android.content.componentalias.tests" />
|
||||
<option name="run-command" value="cmd deviceidle whitelist +android.content.componentalias.tests.sub1" />
|
||||
|
||||
@@ -17,6 +17,7 @@ package android.content.componentalias.tests;
|
||||
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.os.Build;
|
||||
import android.provider.DeviceConfig;
|
||||
import android.util.Log;
|
||||
|
||||
@@ -27,6 +28,7 @@ import com.android.compatibility.common.util.ShellUtils;
|
||||
import com.android.compatibility.common.util.TestUtils;
|
||||
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Assume;
|
||||
import org.junit.Before;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
@@ -37,7 +39,11 @@ public class BaseComponentAliasTest {
|
||||
protected static final DeviceConfigStateHelper sDeviceConfig = new DeviceConfigStateHelper(
|
||||
DeviceConfig.NAMESPACE_ACTIVITY_MANAGER);
|
||||
@Before
|
||||
public void enableComponentAlias() throws Exception {
|
||||
public void enableComponentAliasWithCompatFlag() throws Exception {
|
||||
Assume.assumeTrue(Build.isDebuggable());
|
||||
ShellUtils.runShellCommand(
|
||||
"am compat enable --no-kill USE_EXPERIMENTAL_COMPONENT_ALIAS android");
|
||||
sDeviceConfig.set("enable_experimental_component_alias", "");
|
||||
sDeviceConfig.set("component_alias_overrides", "");
|
||||
|
||||
// Make sure the feature is actually enabled.
|
||||
@@ -49,6 +55,8 @@ public class BaseComponentAliasTest {
|
||||
|
||||
@AfterClass
|
||||
public static void restoreDeviceConfig() throws Exception {
|
||||
ShellUtils.runShellCommand(
|
||||
"am compat disable --no-kill USE_EXPERIMENTAL_COMPONENT_ALIAS android");
|
||||
sDeviceConfig.close();
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright (C) 2022 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package android.content.componentalias.tests;
|
||||
|
||||
import android.os.Build;
|
||||
import android.provider.DeviceConfig;
|
||||
|
||||
import com.android.compatibility.common.util.DeviceConfigStateHelper;
|
||||
import com.android.compatibility.common.util.ShellUtils;
|
||||
import com.android.compatibility.common.util.TestUtils;
|
||||
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Assume;
|
||||
import org.junit.Test;
|
||||
|
||||
public class ComponentAliasEnableWithDeviceConfigTest {
|
||||
protected static final DeviceConfigStateHelper sDeviceConfig = new DeviceConfigStateHelper(
|
||||
DeviceConfig.NAMESPACE_ACTIVITY_MANAGER);
|
||||
|
||||
@AfterClass
|
||||
public static void restoreDeviceConfig() throws Exception {
|
||||
sDeviceConfig.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void enableComponentAliasWithCompatFlag() throws Exception {
|
||||
Assume.assumeTrue(Build.isDebuggable());
|
||||
|
||||
sDeviceConfig.set("component_alias_overrides", "");
|
||||
|
||||
// First, disable with both compat-id and device config.
|
||||
ShellUtils.runShellCommand(
|
||||
"am compat disable --no-kill USE_EXPERIMENTAL_COMPONENT_ALIAS android");
|
||||
sDeviceConfig.set("enable_experimental_component_alias", "");
|
||||
|
||||
TestUtils.waitUntil("Wait until component alias is actually enabled", () -> {
|
||||
return ShellUtils.runShellCommand("dumpsys activity component-alias")
|
||||
.indexOf("Enabled: false") > 0;
|
||||
});
|
||||
|
||||
// Then, enable by device config.
|
||||
sDeviceConfig.set("enable_experimental_component_alias", "true");
|
||||
|
||||
// Make sure the feature is actually enabled.
|
||||
TestUtils.waitUntil("Wait until component alias is actually enabled", () -> {
|
||||
return ShellUtils.runShellCommand("dumpsys activity component-alias")
|
||||
.indexOf("Enabled: true") > 0;
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright (C) 2022 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package android.content.componentalias.tests;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import android.os.Build;
|
||||
import android.provider.DeviceConfig;
|
||||
|
||||
import com.android.compatibility.common.util.DeviceConfigStateHelper;
|
||||
import com.android.compatibility.common.util.ShellUtils;
|
||||
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Assume;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* Test to make sure component-alias can't be enabled on user builds.
|
||||
*/
|
||||
public class ComponentAliasNotSupportedOnUserBuildTest {
|
||||
protected static final DeviceConfigStateHelper sDeviceConfig = new DeviceConfigStateHelper(
|
||||
DeviceConfig.NAMESPACE_ACTIVITY_MANAGER);
|
||||
|
||||
@AfterClass
|
||||
public static void restoreDeviceConfig() throws Exception {
|
||||
sDeviceConfig.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void enableComponentAliasWithCompatFlag() throws Exception {
|
||||
Assume.assumeFalse(Build.isDebuggable());
|
||||
|
||||
// Try to enable it by both the device config and compat-id.
|
||||
sDeviceConfig.set("enable_experimental_component_alias", "true");
|
||||
ShellUtils.runShellCommand(
|
||||
"am compat enable --no-kill USE_EXPERIMENTAL_COMPONENT_ALIAS android");
|
||||
|
||||
// Sleep for an arbitrary amount of time, so the config would sink in, if there was
|
||||
// no "not on user builds" check.
|
||||
|
||||
Thread.sleep(5000);
|
||||
|
||||
// Make sure the feature is still disabled.
|
||||
assertThat(ShellUtils.runShellCommand("dumpsys activity component-alias")
|
||||
.indexOf("Enabled: false") > 0).isTrue();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user