diff --git a/core/api/test-current.txt b/core/api/test-current.txt index 521793b0ec436..18723527ce19a 100644 --- a/core/api/test-current.txt +++ b/core/api/test-current.txt @@ -2412,6 +2412,16 @@ package android.service.dreams { method public final boolean shouldShowComplications(); } + public class DreamService extends android.app.Service implements android.view.Window.Callback { + method @Nullable public static android.service.dreams.DreamService.DreamMetadata getDreamMetadata(@NonNull android.content.Context, @Nullable android.content.pm.ServiceInfo); + } + + public static final class DreamService.DreamMetadata { + field @Nullable public final android.graphics.drawable.Drawable previewImage; + field @Nullable public final android.content.ComponentName settingsActivity; + field @NonNull public final boolean showComplications; + } + } package android.service.notification { diff --git a/core/java/android/service/dreams/DreamService.java b/core/java/android/service/dreams/DreamService.java index 2d461c6cf92e7..75155383855bd 100644 --- a/core/java/android/service/dreams/DreamService.java +++ b/core/java/android/service/dreams/DreamService.java @@ -22,6 +22,7 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SdkConstant; import android.annotation.SdkConstant.SdkConstantType; +import android.annotation.TestApi; import android.app.Activity; import android.app.ActivityTaskManager; import android.app.AlarmManager; @@ -1124,7 +1125,8 @@ public class DreamService extends Service implements Window.Callback { * @hide */ @Nullable - public static DreamMetadata getDreamMetadata(Context context, + @TestApi + public static DreamMetadata getDreamMetadata(@NonNull Context context, @Nullable ServiceInfo serviceInfo) { if (serviceInfo == null) return null; @@ -1183,7 +1185,8 @@ public class DreamService extends Service implements Window.Callback { } } - private static ComponentName convertToComponentName(String flattenedString, + @Nullable + private static ComponentName convertToComponentName(@Nullable String flattenedString, ServiceInfo serviceInfo) { if (flattenedString == null) { return null; @@ -1193,7 +1196,17 @@ public class DreamService extends Service implements Window.Callback { return new ComponentName(serviceInfo.packageName, flattenedString); } - return ComponentName.unflattenFromString(flattenedString); + // Ensure that the component is from the same package as the dream service. If not, + // treat the component as invalid and return null instead. + final ComponentName cn = ComponentName.unflattenFromString(flattenedString); + if (cn == null) return null; + if (!cn.getPackageName().equals(serviceInfo.packageName)) { + Log.w(TAG, + "Inconsistent package name in component: " + cn.getPackageName() + + ", should be: " + serviceInfo.packageName); + return null; + } + return cn; } /** @@ -1489,6 +1502,7 @@ public class DreamService extends Service implements Window.Callback { * * @hide */ + @TestApi public static final class DreamMetadata { @Nullable public final ComponentName settingsActivity; diff --git a/services/tests/servicestests/AndroidManifest.xml b/services/tests/servicestests/AndroidManifest.xml index 0483a60ca378a..7ae70eb6886b5 100644 --- a/services/tests/servicestests/AndroidManifest.xml +++ b/services/tests/servicestests/AndroidManifest.xml @@ -147,6 +147,19 @@ android:resource="@xml/test_dream_metadata" /> + + + + + + + + diff --git a/services/tests/servicestests/res/xml/test_dream_metadata.xml b/services/tests/servicestests/res/xml/test_dream_metadata.xml index aa054f1e9fa4f..9905c69474ad9 100644 --- a/services/tests/servicestests/res/xml/test_dream_metadata.xml +++ b/services/tests/servicestests/res/xml/test_dream_metadata.xml @@ -15,5 +15,5 @@ --> diff --git a/services/tests/servicestests/res/xml/test_dream_metadata_invalid.xml b/services/tests/servicestests/res/xml/test_dream_metadata_invalid.xml new file mode 100644 index 0000000000000..47864d9cf62d1 --- /dev/null +++ b/services/tests/servicestests/res/xml/test_dream_metadata_invalid.xml @@ -0,0 +1,20 @@ + + + + diff --git a/services/tests/servicestests/src/com/android/server/dreams/DreamServiceTest.java b/services/tests/servicestests/src/com/android/server/dreams/DreamServiceTest.java index 74d2e0f231bbf..0efd296fd8b6b 100644 --- a/services/tests/servicestests/src/com/android/server/dreams/DreamServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/dreams/DreamServiceTest.java @@ -16,7 +16,8 @@ package com.android.server.dreams; -import static org.junit.Assert.assertEquals; +import static com.google.common.truth.Truth.assertThat; + import static org.junit.Assert.assertFalse; import android.content.ComponentName; @@ -35,21 +36,36 @@ import org.junit.runner.RunWith; @SmallTest @RunWith(AndroidJUnit4.class) public class DreamServiceTest { + private static final String TEST_PACKAGE_NAME = "com.android.frameworks.servicestests"; + @Test public void testMetadataParsing() throws PackageManager.NameNotFoundException { - final String testPackageName = "com.android.frameworks.servicestests"; final String testDreamClassName = "com.android.server.dreams.TestDreamService"; - final String testSettingsActivity = "com.android.server.dreams/.TestDreamSettingsActivity"; + final String testSettingsActivity = + "com.android.frameworks.servicestests/.TestDreamSettingsActivity"; + final DreamService.DreamMetadata metadata = getDreamMetadata(testDreamClassName); - final Context context = InstrumentationRegistry.getInstrumentation().getTargetContext(); - - final ServiceInfo si = context.getPackageManager().getServiceInfo( - new ComponentName(testPackageName, testDreamClassName), - PackageManager.ComponentInfoFlags.of(PackageManager.GET_META_DATA)); - final DreamService.DreamMetadata metadata = DreamService.getDreamMetadata(context, si); - - assertEquals(0, metadata.settingsActivity.compareTo( - ComponentName.unflattenFromString(testSettingsActivity))); + assertThat(metadata.settingsActivity).isEqualTo( + ComponentName.unflattenFromString(testSettingsActivity)); assertFalse(metadata.showComplications); } + + @Test + public void testMetadataParsing_invalidSettingsActivity() + throws PackageManager.NameNotFoundException { + final String testDreamClassName = + "com.android.server.dreams.TestDreamServiceWithInvalidSettings"; + final DreamService.DreamMetadata metadata = getDreamMetadata(testDreamClassName); + + assertThat(metadata.settingsActivity).isNull(); + } + + private DreamService.DreamMetadata getDreamMetadata(String dreamClassName) + throws PackageManager.NameNotFoundException { + final Context context = InstrumentationRegistry.getInstrumentation().getTargetContext(); + final ServiceInfo si = context.getPackageManager().getServiceInfo( + new ComponentName(TEST_PACKAGE_NAME, dreamClassName), + PackageManager.ComponentInfoFlags.of(PackageManager.GET_META_DATA)); + return DreamService.getDreamMetadata(context, si); + } } diff --git a/services/tests/servicestests/src/com/android/server/dreams/TestDreamServiceWithInvalidSettings.java b/services/tests/servicestests/src/com/android/server/dreams/TestDreamServiceWithInvalidSettings.java new file mode 100644 index 0000000000000..5c7d02fb755c3 --- /dev/null +++ b/services/tests/servicestests/src/com/android/server/dreams/TestDreamServiceWithInvalidSettings.java @@ -0,0 +1,25 @@ +/* + * 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 com.android.server.dreams; + +import android.service.dreams.DreamService; + +/** + * Dream service implementation for unit testing, where the settings activity is invalid. + */ +public class TestDreamServiceWithInvalidSettings extends DreamService { +}