diff options
7 files changed, 156 insertions, 7 deletions
diff --git a/core/java/android/service/dreams/DreamService.java b/core/java/android/service/dreams/DreamService.java index 3f9c819cd62f..6efca0c6dc10 100644 --- a/core/java/android/service/dreams/DreamService.java +++ b/core/java/android/service/dreams/DreamService.java @@ -1389,7 +1389,8 @@ public class DreamService extends Service implements Window.Callback { convertToComponentName( rawMetadata.getString( com.android.internal.R.styleable.Dream_settingsActivity), - serviceInfo), + serviceInfo, + packageManager), rawMetadata.getDrawable( com.android.internal.R.styleable.Dream_previewImage), rawMetadata.getBoolean(R.styleable.Dream_showClockAndComplications, @@ -1404,26 +1405,38 @@ public class DreamService extends Service implements Window.Callback { } @Nullable - private static ComponentName convertToComponentName(@Nullable String flattenedString, - ServiceInfo serviceInfo) { + private static ComponentName convertToComponentName( + @Nullable String flattenedString, + ServiceInfo serviceInfo, + PackageManager packageManager) { if (flattenedString == null) { return null; } - if (!flattenedString.contains("/")) { - return new ComponentName(serviceInfo.packageName, flattenedString); + final ComponentName cn = + flattenedString.contains("/") + ? ComponentName.unflattenFromString(flattenedString) + : new ComponentName(serviceInfo.packageName, flattenedString); + + if (cn == null) { + return null; } // 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; } + + // Ensure that the activity exists. If not, treat the component as invalid and return null. + if (new Intent().setComponent(cn).resolveActivityInfo(packageManager, 0) == null) { + Log.w(TAG, "Dream settings activity not found: " + cn); + return null; + } + return cn; } diff --git a/services/tests/dreamservicetests/AndroidManifest.xml b/services/tests/dreamservicetests/AndroidManifest.xml index 6092ef6f9427..449521b05135 100644 --- a/services/tests/dreamservicetests/AndroidManifest.xml +++ b/services/tests/dreamservicetests/AndroidManifest.xml @@ -53,6 +53,35 @@ android:name="android.service.dream" android:resource="@xml/test_dream_metadata_invalid" /> </service> + + <service + android:name="com.android.server.dreams.TestDreamServiceWithNonexistentSettings" + android:exported="false" + android:label="Test Dream" > + <intent-filter> + <action android:name="android.service.dreams.DreamService" /> + <category android:name="android.intent.category.DEFAULT" /> + </intent-filter> + <meta-data + android:name="android.service.dream" + android:resource="@xml/test_dream_metadata_nonexistent_settings" /> + </service> + + <service + android:name="com.android.server.dreams.TestDreamServiceNoPackageNonexistentSettings" + android:exported="false" + android:label="Test Dream" > + <intent-filter> + <action android:name="android.service.dreams.DreamService" /> + <category android:name="android.intent.category.DEFAULT" /> + </intent-filter> + <meta-data + android:name="android.service.dream" + android:resource="@xml/test_dream_metadata_nopackage_nonexistent_settings" /> + </service> + + <activity android:name=".TestDreamSettingsActivity"> + </activity> </application> <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner" diff --git a/services/tests/dreamservicetests/res/xml/test_dream_metadata_nonexistent_settings.xml b/services/tests/dreamservicetests/res/xml/test_dream_metadata_nonexistent_settings.xml new file mode 100644 index 000000000000..a19ef0cd3e7e --- /dev/null +++ b/services/tests/dreamservicetests/res/xml/test_dream_metadata_nonexistent_settings.xml @@ -0,0 +1,20 @@ +<!-- + ~ 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. + --> + +<!-- The settings activity does not exist, which is invalid. --> +<dream xmlns:android="http://schemas.android.com/apk/res/android" + android:settingsActivity="com.android.frameworks.dreamservicetests/.TestDreamSettingsActivity2" + android:showClockAndComplications="false"/> diff --git a/services/tests/dreamservicetests/res/xml/test_dream_metadata_nopackage_nonexistent_settings.xml b/services/tests/dreamservicetests/res/xml/test_dream_metadata_nopackage_nonexistent_settings.xml new file mode 100644 index 000000000000..0453e92eed92 --- /dev/null +++ b/services/tests/dreamservicetests/res/xml/test_dream_metadata_nopackage_nonexistent_settings.xml @@ -0,0 +1,20 @@ +<!-- + ~ 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. + --> + +<!-- The settings activity does not exist, which is invalid. --> +<dream xmlns:android="http://schemas.android.com/apk/res/android" + android:settingsActivity="com.android.frameworks.dreamservicetests.TestDreamSettingsActivity2" + android:showClockAndComplications="false"/> diff --git a/services/tests/dreamservicetests/src/com/android/server/dreams/DreamServiceTest.java b/services/tests/dreamservicetests/src/com/android/server/dreams/DreamServiceTest.java index b98af6bc7dd0..b4e1abff3bf7 100644 --- a/services/tests/dreamservicetests/src/com/android/server/dreams/DreamServiceTest.java +++ b/services/tests/dreamservicetests/src/com/android/server/dreams/DreamServiceTest.java @@ -91,6 +91,28 @@ public class DreamServiceTest { } @Test + public void testMetadataParsing_nonexistentSettingsActivity() + throws PackageManager.NameNotFoundException { + final String testDreamClassName = + "com.android.server.dreams.TestDreamServiceWithNonexistentSettings"; + final DreamService.DreamMetadata metadata = getDreamMetadata(testDreamClassName); + + assertThat(metadata.settingsActivity).isNull(); + assertThat(metadata.dreamCategory).isEqualTo(DreamService.DREAM_CATEGORY_DEFAULT); + } + + @Test + public void testMetadataParsing_noPackage_nonexistentSettingsActivity() + throws PackageManager.NameNotFoundException { + final String testDreamClassName = + "com.android.server.dreams.TestDreamServiceNoPackageNonexistentSettings"; + final DreamService.DreamMetadata metadata = getDreamMetadata(testDreamClassName); + + assertThat(metadata.settingsActivity).isNull(); + assertThat(metadata.dreamCategory).isEqualTo(DreamService.DREAM_CATEGORY_DEFAULT); + } + + @Test public void testMetadataParsing_exceptionReading() { final PackageManager packageManager = Mockito.mock(PackageManager.class); final ServiceInfo serviceInfo = Mockito.mock(ServiceInfo.class); diff --git a/services/tests/dreamservicetests/src/com/android/server/dreams/TestDreamServiceWithNonexistentSettings.java b/services/tests/dreamservicetests/src/com/android/server/dreams/TestDreamServiceWithNonexistentSettings.java new file mode 100644 index 000000000000..de001754c353 --- /dev/null +++ b/services/tests/dreamservicetests/src/com/android/server/dreams/TestDreamServiceWithNonexistentSettings.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 doesn't exist. + */ +public class TestDreamServiceWithNonexistentSettings extends DreamService { +} diff --git a/services/tests/dreamservicetests/src/com/android/server/dreams/TestDreamSettingsActivity.java b/services/tests/dreamservicetests/src/com/android/server/dreams/TestDreamSettingsActivity.java new file mode 100644 index 000000000000..bb8db8a9b655 --- /dev/null +++ b/services/tests/dreamservicetests/src/com/android/server/dreams/TestDreamSettingsActivity.java @@ -0,0 +1,20 @@ +/* + * 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.server.dreams; + +public class TestDreamSettingsActivity { +} |