diff options
| author | 2024-04-10 19:41:50 +0000 | |
|---|---|---|
| committer | 2024-04-10 19:41:50 +0000 | |
| commit | b2ae995bccd4c52cbe5b40f2edd93f7ca77196fe (patch) | |
| tree | e271d882079a5a90360bb42776243b9359658d5a | |
| parent | 19ba208ffa3611c0240ce1af37eb925c342ca3c9 (diff) | |
| parent | 8db814a43c1d4f3e1fff45724799cb804c3b80e3 (diff) | |
Merge "Make resources get package updates for all users" into main
11 files changed, 348 insertions, 76 deletions
diff --git a/core/tests/overlaytests/device_non_system/Android.bp b/core/tests/overlaytests/device_non_system/Android.bp new file mode 100644 index 000000000000..dd7786a4e43f --- /dev/null +++ b/core/tests/overlaytests/device_non_system/Android.bp @@ -0,0 +1,39 @@ +// Copyright (C) 2024 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 { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "frameworks_base_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["frameworks_base_license"], +} + +android_test { + name: "OverlayDeviceTestsNonSystem", + team: "trendy_team_android_resources", + srcs: ["src/**/*.java"], + platform_apis: true, + certificate: "platform", + static_libs: [ + "androidx.test.rules", + "testng", + "compatibility-device-util-axt", + ], + test_suites: ["device-tests"], + data: [ + ":OverlayDeviceTestsNonSystem_AppOverlay", + ], +} diff --git a/core/tests/overlaytests/device_non_system/AndroidManifest.xml b/core/tests/overlaytests/device_non_system/AndroidManifest.xml new file mode 100644 index 000000000000..a37d1689e80e --- /dev/null +++ b/core/tests/overlaytests/device_non_system/AndroidManifest.xml @@ -0,0 +1,29 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2024 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. +--> + +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="com.android.overlaytest.non_system"> + + <uses-sdk android:minSdkVersion="34" /> + + <application> + <uses-library android:name="android.test.runner"/> + </application> + + <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner" + android:targetPackage="com.android.overlaytest.non_system" + android:label="Runtime resource overlay tests for non system app" /> +</manifest> diff --git a/core/tests/overlaytests/device_non_system/AndroidTest.xml b/core/tests/overlaytests/device_non_system/AndroidTest.xml new file mode 100644 index 000000000000..fc47e6a90880 --- /dev/null +++ b/core/tests/overlaytests/device_non_system/AndroidTest.xml @@ -0,0 +1,45 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2024 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. +--> + +<configuration description="Test module config for OverlayDeviceTestsNonSystem"> + <option name="test-tag" value="OverlayDeviceTestsNonSystem" /> + <option name="test-suite-tag" value="apct" /> + <option name="test-suite-tag" value="apct-instrumentation" /> + + <target_preparer class="com.android.tradefed.targetprep.TestAppInstallSetup"> + <option name="cleanup-apks" value="true" /> + <option name="test-file-name" value="OverlayDeviceTestsNonSystem_AppOverlay.apk" /> + </target_preparer> + + <target_preparer class="com.android.tradefed.targetprep.RunOnSecondaryUserTargetPreparer"> + <option name="test-package-name" value="com.android.overlaytest.non_system" /> + </target_preparer> + + <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer"> + <option name="test-user-token" value="%TEST_USER%"/> + <option name="run-command" + value="cmd overlay enable --user %TEST_USER% com.android.overlaytest.non_system.app_overlay" /> + </target_preparer> + + <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller"> + <option name="cleanup-apks" value="true" /> + <option name="test-file-name" value="OverlayDeviceTestsNonSystem.apk" /> + </target_preparer> + + <test class="com.android.tradefed.testtype.AndroidJUnitTest"> + <option name="package" value="com.android.overlaytest.non_system" /> + </test> +</configuration> diff --git a/core/tests/overlaytests/device_non_system/res/layout/layout.xml b/core/tests/overlaytests/device_non_system/res/layout/layout.xml new file mode 100644 index 000000000000..2cb201377d52 --- /dev/null +++ b/core/tests/overlaytests/device_non_system/res/layout/layout.xml @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ Copyright (C) 2024 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. + --> +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto" + android:orientation="vertical" + android:layout_width="match_parent" + android:layout_height="match_parent"> + + <TextView + android:id="@+id/text_view_id" + android:layout_height="wrap_content" + android:layout_width="wrap_content" + android:text="@string/test_string" /> +</LinearLayout>
\ No newline at end of file diff --git a/core/tests/overlaytests/device_non_system/res/values/overlayable.xml b/core/tests/overlaytests/device_non_system/res/values/overlayable.xml new file mode 100644 index 000000000000..f8017bc35d5d --- /dev/null +++ b/core/tests/overlaytests/device_non_system/res/values/overlayable.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ Copyright (C) 2024 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. + --> + +<resources> + <overlayable name="TestResources"> + <policy type="public"> + <item type="string" name="test_string" /> + </policy> + </overlayable> +</resources>
\ No newline at end of file diff --git a/core/tests/overlaytests/device_non_system/res/values/strings.xml b/core/tests/overlaytests/device_non_system/res/values/strings.xml new file mode 100644 index 000000000000..ff501a0639ff --- /dev/null +++ b/core/tests/overlaytests/device_non_system/res/values/strings.xml @@ -0,0 +1,3 @@ +<resources> + <string name="test_string">Original</string> +</resources>
\ No newline at end of file diff --git a/core/tests/overlaytests/device_non_system/src/com/android/overlaytest/OverlayTest.java b/core/tests/overlaytests/device_non_system/src/com/android/overlaytest/OverlayTest.java new file mode 100644 index 000000000000..2b0fe6cdc559 --- /dev/null +++ b/core/tests/overlaytests/device_non_system/src/com/android/overlaytest/OverlayTest.java @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2024 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 com.android.overlaytest; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +import android.view.LayoutInflater; +import android.view.View; +import android.widget.TextView; + +import androidx.test.InstrumentationRegistry; + +import com.android.overlaytest.non_system.R; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** + * This test class is to verify overlay behavior for non-system apps. + */ +@RunWith(JUnit4.class) +public class OverlayTest { + @Test + public void testStringOverlay() throws Throwable { + final LayoutInflater inflater = LayoutInflater.from(InstrumentationRegistry.getContext()); + final View layout = inflater.inflate(R.layout.layout, null); + TextView tv = layout.findViewById(R.id.text_view_id); + assertNotNull(tv); + assertEquals("Overlaid", tv.getText().toString()); + } +} diff --git a/core/tests/overlaytests/device_non_system/test-apps/AppOverlay/Android.bp b/core/tests/overlaytests/device_non_system/test-apps/AppOverlay/Android.bp new file mode 100644 index 000000000000..b5e6d9c692bd --- /dev/null +++ b/core/tests/overlaytests/device_non_system/test-apps/AppOverlay/Android.bp @@ -0,0 +1,30 @@ +// Copyright (C) 2024 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 { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "frameworks_base_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["frameworks_base_license"], +} + +android_test { + name: "OverlayDeviceTestsNonSystem_AppOverlay", + team: "trendy_team_android_resources", + sdk_version: "current", + certificate: "platform", + aaptflags: ["--no-resource-removal"], +} diff --git a/core/tests/overlaytests/device_non_system/test-apps/AppOverlay/AndroidManifest.xml b/core/tests/overlaytests/device_non_system/test-apps/AppOverlay/AndroidManifest.xml new file mode 100644 index 000000000000..4df80c085602 --- /dev/null +++ b/core/tests/overlaytests/device_non_system/test-apps/AppOverlay/AndroidManifest.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2024 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. +--> + +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="com.android.overlaytest.non_system.app_overlay" + android:versionCode="1" + android:versionName="1.0"> + <application android:hasCode="false" /> + <overlay android:targetPackage="com.android.overlaytest.non_system" + android:targetName="TestResources" + android:isStatic="true" + android:resourcesMap="@xml/overlays"/> +</manifest>
\ No newline at end of file diff --git a/core/tests/overlaytests/device_non_system/test-apps/AppOverlay/res/xml/overlays.xml b/core/tests/overlaytests/device_non_system/test-apps/AppOverlay/res/xml/overlays.xml new file mode 100644 index 000000000000..d0d4bfed94ed --- /dev/null +++ b/core/tests/overlaytests/device_non_system/test-apps/AppOverlay/res/xml/overlays.xml @@ -0,0 +1,19 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ Copyright (C) 2024 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. + --> +<overlay> + <item target="string/test_string" value="Overlaid"/> +</overlay>
\ No newline at end of file diff --git a/services/core/java/com/android/server/om/OverlayManagerService.java b/services/core/java/com/android/server/om/OverlayManagerService.java index 4b8e4852aee7..6c93fe787816 100644 --- a/services/core/java/com/android/server/om/OverlayManagerService.java +++ b/services/core/java/com/android/server/om/OverlayManagerService.java @@ -32,6 +32,7 @@ import static android.os.Process.INVALID_UID; import static android.os.Trace.TRACE_TAG_RRO; import static android.os.Trace.traceBegin; import static android.os.Trace.traceEnd; + import static com.android.server.om.OverlayManagerServiceImpl.OperationFailedException; import android.annotation.NonNull; @@ -279,7 +280,8 @@ public final class OverlayManagerService extends SystemService { HandlerThread packageMonitorThread = new HandlerThread(TAG); packageMonitorThread.start(); - mPackageMonitor.register(context, packageMonitorThread.getLooper(), true); + mPackageMonitor.register( + context, packageMonitorThread.getLooper(), UserHandle.ALL, true); final IntentFilter userFilter = new IntentFilter(); userFilter.addAction(ACTION_USER_ADDED); @@ -369,17 +371,17 @@ public final class OverlayManagerService extends SystemService { @Override public void onPackageAppearedWithExtras(String packageName, Bundle extras) { - handlePackageAdd(packageName, extras); + handlePackageAdd(packageName, extras, getChangingUserId()); } @Override public void onPackageChangedWithExtras(String packageName, Bundle extras) { - handlePackageChange(packageName, extras); + handlePackageChange(packageName, extras, getChangingUserId()); } @Override public void onPackageDisappearedWithExtras(String packageName, Bundle extras) { - handlePackageRemove(packageName, extras); + handlePackageRemove(packageName, extras, getChangingUserId()); } } @@ -393,54 +395,45 @@ public final class OverlayManagerService extends SystemService { return userIds; } - private void handlePackageAdd(String packageName, Bundle extras) { + private void handlePackageAdd(String packageName, Bundle extras, int userId) { final boolean replacing = extras.getBoolean(Intent.EXTRA_REPLACING, false); - final int uid = extras.getInt(Intent.EXTRA_UID, 0); - final int[] userIds = getUserIds(uid); if (replacing) { - onPackageReplaced(packageName, userIds); + onPackageReplaced(packageName, userId); } else { - onPackageAdded(packageName, userIds); + onPackageAdded(packageName, userId); } } - private void handlePackageChange(String packageName, Bundle extras) { - final int uid = extras.getInt(Intent.EXTRA_UID, 0); - final int[] userIds = getUserIds(uid); + private void handlePackageChange(String packageName, Bundle extras, int userId) { if (!ACTION_OVERLAY_CHANGED.equals(extras.getString(EXTRA_REASON))) { - onPackageChanged(packageName, userIds); + onPackageChanged(packageName, userId); } } - private void handlePackageRemove(String packageName, Bundle extras) { + private void handlePackageRemove(String packageName, Bundle extras, int userId) { final boolean replacing = extras.getBoolean(Intent.EXTRA_REPLACING, false); final boolean systemUpdateUninstall = extras.getBoolean(Intent.EXTRA_SYSTEM_UPDATE_UNINSTALL, false); - final int uid = extras.getInt(Intent.EXTRA_UID, 0); - final int[] userIds = getUserIds(uid); if (replacing) { - onPackageReplacing(packageName, systemUpdateUninstall, userIds); + onPackageReplacing(packageName, systemUpdateUninstall, userId); } else { - onPackageRemoved(packageName, userIds); + onPackageRemoved(packageName, userId); } } - private void onPackageAdded(@NonNull final String packageName, - @NonNull final int[] userIds) { + private void onPackageAdded(@NonNull final String packageName, final int userId) { try { traceBegin(TRACE_TAG_RRO, "OMS#onPackageAdded " + packageName); - for (final int userId : userIds) { - synchronized (mLock) { - var packageState = mPackageManager.onPackageAdded(packageName, userId); - if (packageState != null && !mPackageManager.isInstantApp(packageName, - userId)) { - try { - updateTargetPackagesLocked( - mImpl.onPackageAdded(packageName, userId)); - } catch (OperationFailedException e) { - Slog.e(TAG, "onPackageAdded internal error", e); - } + synchronized (mLock) { + var packageState = mPackageManager.onPackageAdded(packageName, userId); + if (packageState != null && !mPackageManager.isInstantApp(packageName, + userId)) { + try { + updateTargetPackagesLocked( + mImpl.onPackageAdded(packageName, userId)); + } catch (OperationFailedException e) { + Slog.e(TAG, "onPackageAdded internal error", e); } } } @@ -449,21 +442,18 @@ public final class OverlayManagerService extends SystemService { } } - private void onPackageChanged(@NonNull final String packageName, - @NonNull final int[] userIds) { + private void onPackageChanged(@NonNull final String packageName, final int userId) { try { traceBegin(TRACE_TAG_RRO, "OMS#onPackageChanged " + packageName); - for (int userId : userIds) { - synchronized (mLock) { - var packageState = mPackageManager.onPackageUpdated(packageName, userId); - if (packageState != null && !mPackageManager.isInstantApp(packageName, - userId)) { - try { - updateTargetPackagesLocked( - mImpl.onPackageChanged(packageName, userId)); - } catch (OperationFailedException e) { - Slog.e(TAG, "onPackageChanged internal error", e); - } + synchronized (mLock) { + var packageState = mPackageManager.onPackageUpdated(packageName, userId); + if (packageState != null && !mPackageManager.isInstantApp(packageName, + userId)) { + try { + updateTargetPackagesLocked( + mImpl.onPackageChanged(packageName, userId)); + } catch (OperationFailedException e) { + Slog.e(TAG, "onPackageChanged internal error", e); } } } @@ -473,20 +463,18 @@ public final class OverlayManagerService extends SystemService { } private void onPackageReplacing(@NonNull final String packageName, - boolean systemUpdateUninstall, @NonNull final int[] userIds) { + boolean systemUpdateUninstall, final int userId) { try { traceBegin(TRACE_TAG_RRO, "OMS#onPackageReplacing " + packageName); - for (int userId : userIds) { - synchronized (mLock) { - var packageState = mPackageManager.onPackageUpdated(packageName, userId); - if (packageState != null && !mPackageManager.isInstantApp(packageName, - userId)) { - try { - updateTargetPackagesLocked(mImpl.onPackageReplacing(packageName, - systemUpdateUninstall, userId)); - } catch (OperationFailedException e) { - Slog.e(TAG, "onPackageReplacing internal error", e); - } + synchronized (mLock) { + var packageState = mPackageManager.onPackageUpdated(packageName, userId); + if (packageState != null && !mPackageManager.isInstantApp(packageName, + userId)) { + try { + updateTargetPackagesLocked(mImpl.onPackageReplacing(packageName, + systemUpdateUninstall, userId)); + } catch (OperationFailedException e) { + Slog.e(TAG, "onPackageReplacing internal error", e); } } } @@ -495,21 +483,18 @@ public final class OverlayManagerService extends SystemService { } } - private void onPackageReplaced(@NonNull final String packageName, - @NonNull final int[] userIds) { + private void onPackageReplaced(@NonNull final String packageName, final int userId) { try { traceBegin(TRACE_TAG_RRO, "OMS#onPackageReplaced " + packageName); - for (int userId : userIds) { - synchronized (mLock) { - var packageState = mPackageManager.onPackageUpdated(packageName, userId); - if (packageState != null && !mPackageManager.isInstantApp(packageName, - userId)) { - try { - updateTargetPackagesLocked( - mImpl.onPackageReplaced(packageName, userId)); - } catch (OperationFailedException e) { - Slog.e(TAG, "onPackageReplaced internal error", e); - } + synchronized (mLock) { + var packageState = mPackageManager.onPackageUpdated(packageName, userId); + if (packageState != null && !mPackageManager.isInstantApp(packageName, + userId)) { + try { + updateTargetPackagesLocked( + mImpl.onPackageReplaced(packageName, userId)); + } catch (OperationFailedException e) { + Slog.e(TAG, "onPackageReplaced internal error", e); } } } @@ -518,15 +503,12 @@ public final class OverlayManagerService extends SystemService { } } - private void onPackageRemoved(@NonNull final String packageName, - @NonNull final int[] userIds) { + private void onPackageRemoved(@NonNull final String packageName, final int userId) { try { traceBegin(TRACE_TAG_RRO, "OMS#onPackageRemoved " + packageName); - for (int userId : userIds) { - synchronized (mLock) { - mPackageManager.onPackageRemoved(packageName, userId); - updateTargetPackagesLocked(mImpl.onPackageRemoved(packageName, userId)); - } + synchronized (mLock) { + mPackageManager.onPackageRemoved(packageName, userId); + updateTargetPackagesLocked(mImpl.onPackageRemoved(packageName, userId)); } } finally { traceEnd(TRACE_TAG_RRO); |