Loading core/java/android/service/dreams/DreamService.java +114 −2 Original line number Diff line number Diff line Loading @@ -31,6 +31,12 @@ import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.ServiceConnection; import android.content.pm.PackageManager; import android.content.pm.ServiceInfo; import android.content.res.Resources; import android.content.res.TypedArray; import android.content.res.XmlResourceParser; import android.graphics.drawable.Drawable; import android.os.Build; import android.os.Handler; import android.os.IBinder; Loading @@ -39,9 +45,11 @@ import android.os.Looper; import android.os.PowerManager; import android.os.RemoteException; import android.os.ServiceManager; import android.util.AttributeSet; import android.util.Log; import android.util.MathUtils; import android.util.Slog; import android.util.Xml; import android.view.ActionMode; import android.view.Display; import android.view.KeyEvent; Loading @@ -59,7 +67,11 @@ import android.view.accessibility.AccessibilityEvent; import com.android.internal.util.DumpUtils; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import java.io.FileDescriptor; import java.io.IOException; import java.io.PrintWriter; import java.util.ArrayDeque; import java.util.function.Consumer; Loading Loading @@ -159,8 +171,9 @@ import java.util.function.Consumer; * </pre> */ public class DreamService extends Service implements Window.Callback { private final String mTag = DreamService.class.getSimpleName() + "[" + getClass().getSimpleName() + "]"; private static final String TAG = DreamService.class.getSimpleName(); private final String mTag = TAG + "[" + getClass().getSimpleName() + "]"; private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); /** * The name of the dream manager service. Loading Loading @@ -190,6 +203,11 @@ public class DreamService extends Service implements Window.Callback { */ public static final String DREAM_META_DATA = "android.service.dream"; /** * Name of the root tag under which a Dream defines its metadata in an XML file. */ private static final String DREAM_META_DATA_ROOT_TAG = "dream"; /** * Extra containing a boolean for whether to show complications on the overlay. * @hide Loading Loading @@ -1080,6 +1098,82 @@ public class DreamService extends Service implements Window.Callback { // end public api /** * Parses and returns metadata of the dream service indicated by the service info. Returns null * if metadata cannot be found. * * Note that {@link ServiceInfo} must be fetched with {@link PackageManager#GET_META_DATA} flag. * * @hide */ @Nullable public static DreamMetadata getDreamMetadata(Context context, ServiceInfo serviceInfo) { final PackageManager pm = context.getPackageManager(); final TypedArray rawMetadata = readMetadata(pm, serviceInfo); if (rawMetadata == null) return null; final DreamMetadata metadata = new DreamMetadata( convertToComponentName(rawMetadata.getString( com.android.internal.R.styleable.Dream_settingsActivity), serviceInfo), rawMetadata.getDrawable( com.android.internal.R.styleable.Dream_previewImage)); rawMetadata.recycle(); return metadata; } /** * Returns the raw XML metadata fetched from the ${@link ServiceInfo}. * * Returns <code>null</code> if the ${@link ServiceInfo} doesn't contain valid dream metadata. */ @Nullable private static TypedArray readMetadata(PackageManager pm, ServiceInfo serviceInfo) { if (serviceInfo == null || serviceInfo.metaData == null) { return null; } try (XmlResourceParser parser = serviceInfo.loadXmlMetaData(pm, DreamService.DREAM_META_DATA)) { if (parser == null) { if (DEBUG) Log.w(TAG, "No " + DreamService.DREAM_META_DATA + " metadata"); return null; } final Resources res = pm.getResourcesForApplication(serviceInfo.applicationInfo); final AttributeSet attrs = Xml.asAttributeSet(parser); while (true) { final int type = parser.next(); if (type == XmlPullParser.END_DOCUMENT || type == XmlPullParser.START_TAG) { break; } } if (!parser.getName().equals(DREAM_META_DATA_ROOT_TAG)) { if (DEBUG) { Log.w(TAG, "Metadata does not start with " + DREAM_META_DATA_ROOT_TAG + " tag"); } return null; } return res.obtainAttributes(attrs, com.android.internal.R.styleable.Dream); } catch (PackageManager.NameNotFoundException | IOException | XmlPullParserException e) { if (DEBUG) Log.e(TAG, "Error parsing: " + serviceInfo.packageName, e); return null; } } private static ComponentName convertToComponentName(String flattenedString, ServiceInfo serviceInfo) { if (flattenedString == null) return null; if (!flattenedString.contains("/")) { return new ComponentName(serviceInfo.packageName, flattenedString); } return ComponentName.unflattenFromString(flattenedString); } /** * Called by DreamController.stopDream() when the Dream is about to be unbound and destroyed. * Loading Loading @@ -1302,4 +1396,22 @@ public class DreamService extends Service implements Window.Callback { onWindowCreated(a.getWindow()); } } /** * Represents metadata defined in {@link android.R.styleable#Dream <dream>}. * * @hide */ public static final class DreamMetadata { @Nullable public final ComponentName settingsActivity; @Nullable public final Drawable previewImage; DreamMetadata(ComponentName settingsActivity, Drawable previewImage) { this.settingsActivity = settingsActivity; this.previewImage = previewImage; } } } packages/SettingsLib/src/com/android/settingslib/dream/DreamBackend.java +8 −75 Original line number Diff line number Diff line Loading @@ -26,8 +26,6 @@ import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.content.pm.ServiceInfo; import android.content.res.Resources; import android.content.res.TypedArray; import android.content.res.XmlResourceParser; import android.graphics.drawable.Drawable; import android.os.RemoteException; import android.os.ServiceManager; Loading @@ -35,21 +33,14 @@ import android.provider.Settings; import android.service.dreams.DreamService; import android.service.dreams.IDreamManager; import android.text.TextUtils; import android.util.AttributeSet; import android.util.Log; import android.util.Xml; import com.android.settingslib.R; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import java.io.IOException; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.Comparator; import java.util.HashSet; import java.util.List; Loading Loading @@ -170,7 +161,7 @@ public class DreamBackend { PackageManager pm = mContext.getPackageManager(); Intent dreamIntent = new Intent(DreamService.SERVICE_INTERFACE); List<ResolveInfo> resolveInfos = pm.queryIntentServices(dreamIntent, PackageManager.GET_META_DATA); PackageManager.ResolveInfoFlags.of(PackageManager.GET_META_DATA)); List<DreamInfo> dreamInfos = new ArrayList<>(resolveInfos.size()); for (ResolveInfo resolveInfo : resolveInfos) { final ComponentName componentName = getDreamComponentName(resolveInfo); Loading @@ -185,15 +176,18 @@ public class DreamBackend { dreamInfo.componentName = componentName; dreamInfo.isActive = dreamInfo.componentName.equals(activeDream); final DreamMetadata dreamMetadata = getDreamMetadata(pm, resolveInfo); dreamInfo.settingsComponentName = dreamMetadata.mSettingsActivity; dreamInfo.previewImage = dreamMetadata.mPreviewImage; final DreamService.DreamMetadata dreamMetadata = DreamService.getDreamMetadata(mContext, resolveInfo.serviceInfo); if (dreamMetadata != null) { dreamInfo.settingsComponentName = dreamMetadata.settingsActivity; dreamInfo.previewImage = dreamMetadata.previewImage; } if (dreamInfo.previewImage == null) { dreamInfo.previewImage = mDreamPreviewDefault; } dreamInfos.add(dreamInfo); } Collections.sort(dreamInfos, mComparator); dreamInfos.sort(mComparator); return dreamInfos; } Loading Loading @@ -483,67 +477,6 @@ public class DreamBackend { return new ComponentName(resolveInfo.serviceInfo.packageName, resolveInfo.serviceInfo.name); } private static final class DreamMetadata { @Nullable Drawable mPreviewImage; @Nullable ComponentName mSettingsActivity; } @Nullable private static TypedArray readMetadata(PackageManager pm, ServiceInfo serviceInfo) { if (serviceInfo == null || serviceInfo.metaData == null) { return null; } try (XmlResourceParser parser = serviceInfo.loadXmlMetaData(pm, DreamService.DREAM_META_DATA)) { if (parser == null) { Log.w(TAG, "No " + DreamService.DREAM_META_DATA + " meta-data"); return null; } Resources res = pm.getResourcesForApplication(serviceInfo.applicationInfo); AttributeSet attrs = Xml.asAttributeSet(parser); while (true) { final int type = parser.next(); if (type == XmlPullParser.END_DOCUMENT || type == XmlPullParser.START_TAG) { break; } } String nodeName = parser.getName(); if (!"dream".equals(nodeName)) { Log.w(TAG, "Meta-data does not start with dream tag"); return null; } return res.obtainAttributes(attrs, com.android.internal.R.styleable.Dream); } catch (PackageManager.NameNotFoundException | IOException | XmlPullParserException e) { Log.w(TAG, "Error parsing : " + serviceInfo.packageName, e); return null; } } private static ComponentName convertToComponentName(String flattenedString, ServiceInfo serviceInfo) { if (flattenedString == null) return null; if (flattenedString.indexOf('/') < 0) { flattenedString = serviceInfo.packageName + "/" + flattenedString; } return ComponentName.unflattenFromString(flattenedString); } private static DreamMetadata getDreamMetadata(PackageManager pm, ResolveInfo resolveInfo) { DreamMetadata result = new DreamMetadata(); if (resolveInfo == null) return result; TypedArray rawMetadata = readMetadata(pm, resolveInfo.serviceInfo); if (rawMetadata == null) return result; result.mSettingsActivity = convertToComponentName(rawMetadata.getString( com.android.internal.R.styleable.Dream_settingsActivity), resolveInfo.serviceInfo); result.mPreviewImage = rawMetadata.getDrawable( com.android.internal.R.styleable.Dream_previewImage); rawMetadata.recycle(); return result; } private static void logd(String msg, Object... args) { if (DEBUG) { Log.d(TAG, args == null || args.length == 0 ? msg : String.format(msg, args)); Loading services/tests/servicestests/AndroidManifest.xml +13 −0 Original line number Diff line number Diff line Loading @@ -130,6 +130,19 @@ android:resource="@xml/test_account_type2_authenticator"/> </service> <service android:name="com.android.server.dreams.TestDreamService" 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" /> </service> <receiver android:name="com.android.server.devicepolicy.ApplicationRestrictionsTest$AdminReceiver" android:permission="android.permission.BIND_DEVICE_ADMIN" android:exported="true"> Loading services/tests/servicestests/res/xml/test_dream_metadata.xml 0 → 100644 +18 −0 Original line number Diff line number Diff line <!-- ~ 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. --> <dream xmlns:android="http://schemas.android.com/apk/res/android" android:settingsActivity="com.android.server.dreams/.TestDreamSettingsActivity" /> services/tests/servicestests/src/com/android/server/dreams/DreamServiceTest.java 0 → 100644 +56 −0 Original line number Diff line number Diff line /* * 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 static org.junit.Assert.assertEquals; import android.content.ComponentName; import android.content.Context; import android.content.pm.PackageManager; import android.content.pm.ServiceInfo; import android.service.dreams.DreamService; import androidx.test.filters.SmallTest; import androidx.test.platform.app.InstrumentationRegistry; import androidx.test.runner.AndroidJUnit4; import org.junit.Test; import org.junit.runner.RunWith; @SmallTest @RunWith(AndroidJUnit4.class) public class DreamServiceTest { @Test public void testMetadataParsing() { final String testDreamServiceComponent = "com.android.server.dreams/.TestDreamService"; final String testSettingsActivity = "com.android.server.dreams/.TestDreamSettingsActivity"; final Context context = InstrumentationRegistry.getInstrumentation().getTargetContext(); try { final ServiceInfo si = context.getPackageManager().getServiceInfo( ComponentName.unflattenFromString(testDreamServiceComponent), PackageManager.ComponentInfoFlags.of(PackageManager.GET_META_DATA)); final DreamService.DreamMetadata metadata = DreamService.getDreamMetadata(context, si); assertEquals(0, metadata.settingsActivity.compareTo( ComponentName.unflattenFromString(testSettingsActivity))); } catch (PackageManager.NameNotFoundException e) { e.printStackTrace(); } } } Loading
core/java/android/service/dreams/DreamService.java +114 −2 Original line number Diff line number Diff line Loading @@ -31,6 +31,12 @@ import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.ServiceConnection; import android.content.pm.PackageManager; import android.content.pm.ServiceInfo; import android.content.res.Resources; import android.content.res.TypedArray; import android.content.res.XmlResourceParser; import android.graphics.drawable.Drawable; import android.os.Build; import android.os.Handler; import android.os.IBinder; Loading @@ -39,9 +45,11 @@ import android.os.Looper; import android.os.PowerManager; import android.os.RemoteException; import android.os.ServiceManager; import android.util.AttributeSet; import android.util.Log; import android.util.MathUtils; import android.util.Slog; import android.util.Xml; import android.view.ActionMode; import android.view.Display; import android.view.KeyEvent; Loading @@ -59,7 +67,11 @@ import android.view.accessibility.AccessibilityEvent; import com.android.internal.util.DumpUtils; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import java.io.FileDescriptor; import java.io.IOException; import java.io.PrintWriter; import java.util.ArrayDeque; import java.util.function.Consumer; Loading Loading @@ -159,8 +171,9 @@ import java.util.function.Consumer; * </pre> */ public class DreamService extends Service implements Window.Callback { private final String mTag = DreamService.class.getSimpleName() + "[" + getClass().getSimpleName() + "]"; private static final String TAG = DreamService.class.getSimpleName(); private final String mTag = TAG + "[" + getClass().getSimpleName() + "]"; private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); /** * The name of the dream manager service. Loading Loading @@ -190,6 +203,11 @@ public class DreamService extends Service implements Window.Callback { */ public static final String DREAM_META_DATA = "android.service.dream"; /** * Name of the root tag under which a Dream defines its metadata in an XML file. */ private static final String DREAM_META_DATA_ROOT_TAG = "dream"; /** * Extra containing a boolean for whether to show complications on the overlay. * @hide Loading Loading @@ -1080,6 +1098,82 @@ public class DreamService extends Service implements Window.Callback { // end public api /** * Parses and returns metadata of the dream service indicated by the service info. Returns null * if metadata cannot be found. * * Note that {@link ServiceInfo} must be fetched with {@link PackageManager#GET_META_DATA} flag. * * @hide */ @Nullable public static DreamMetadata getDreamMetadata(Context context, ServiceInfo serviceInfo) { final PackageManager pm = context.getPackageManager(); final TypedArray rawMetadata = readMetadata(pm, serviceInfo); if (rawMetadata == null) return null; final DreamMetadata metadata = new DreamMetadata( convertToComponentName(rawMetadata.getString( com.android.internal.R.styleable.Dream_settingsActivity), serviceInfo), rawMetadata.getDrawable( com.android.internal.R.styleable.Dream_previewImage)); rawMetadata.recycle(); return metadata; } /** * Returns the raw XML metadata fetched from the ${@link ServiceInfo}. * * Returns <code>null</code> if the ${@link ServiceInfo} doesn't contain valid dream metadata. */ @Nullable private static TypedArray readMetadata(PackageManager pm, ServiceInfo serviceInfo) { if (serviceInfo == null || serviceInfo.metaData == null) { return null; } try (XmlResourceParser parser = serviceInfo.loadXmlMetaData(pm, DreamService.DREAM_META_DATA)) { if (parser == null) { if (DEBUG) Log.w(TAG, "No " + DreamService.DREAM_META_DATA + " metadata"); return null; } final Resources res = pm.getResourcesForApplication(serviceInfo.applicationInfo); final AttributeSet attrs = Xml.asAttributeSet(parser); while (true) { final int type = parser.next(); if (type == XmlPullParser.END_DOCUMENT || type == XmlPullParser.START_TAG) { break; } } if (!parser.getName().equals(DREAM_META_DATA_ROOT_TAG)) { if (DEBUG) { Log.w(TAG, "Metadata does not start with " + DREAM_META_DATA_ROOT_TAG + " tag"); } return null; } return res.obtainAttributes(attrs, com.android.internal.R.styleable.Dream); } catch (PackageManager.NameNotFoundException | IOException | XmlPullParserException e) { if (DEBUG) Log.e(TAG, "Error parsing: " + serviceInfo.packageName, e); return null; } } private static ComponentName convertToComponentName(String flattenedString, ServiceInfo serviceInfo) { if (flattenedString == null) return null; if (!flattenedString.contains("/")) { return new ComponentName(serviceInfo.packageName, flattenedString); } return ComponentName.unflattenFromString(flattenedString); } /** * Called by DreamController.stopDream() when the Dream is about to be unbound and destroyed. * Loading Loading @@ -1302,4 +1396,22 @@ public class DreamService extends Service implements Window.Callback { onWindowCreated(a.getWindow()); } } /** * Represents metadata defined in {@link android.R.styleable#Dream <dream>}. * * @hide */ public static final class DreamMetadata { @Nullable public final ComponentName settingsActivity; @Nullable public final Drawable previewImage; DreamMetadata(ComponentName settingsActivity, Drawable previewImage) { this.settingsActivity = settingsActivity; this.previewImage = previewImage; } } }
packages/SettingsLib/src/com/android/settingslib/dream/DreamBackend.java +8 −75 Original line number Diff line number Diff line Loading @@ -26,8 +26,6 @@ import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.content.pm.ServiceInfo; import android.content.res.Resources; import android.content.res.TypedArray; import android.content.res.XmlResourceParser; import android.graphics.drawable.Drawable; import android.os.RemoteException; import android.os.ServiceManager; Loading @@ -35,21 +33,14 @@ import android.provider.Settings; import android.service.dreams.DreamService; import android.service.dreams.IDreamManager; import android.text.TextUtils; import android.util.AttributeSet; import android.util.Log; import android.util.Xml; import com.android.settingslib.R; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import java.io.IOException; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.Comparator; import java.util.HashSet; import java.util.List; Loading Loading @@ -170,7 +161,7 @@ public class DreamBackend { PackageManager pm = mContext.getPackageManager(); Intent dreamIntent = new Intent(DreamService.SERVICE_INTERFACE); List<ResolveInfo> resolveInfos = pm.queryIntentServices(dreamIntent, PackageManager.GET_META_DATA); PackageManager.ResolveInfoFlags.of(PackageManager.GET_META_DATA)); List<DreamInfo> dreamInfos = new ArrayList<>(resolveInfos.size()); for (ResolveInfo resolveInfo : resolveInfos) { final ComponentName componentName = getDreamComponentName(resolveInfo); Loading @@ -185,15 +176,18 @@ public class DreamBackend { dreamInfo.componentName = componentName; dreamInfo.isActive = dreamInfo.componentName.equals(activeDream); final DreamMetadata dreamMetadata = getDreamMetadata(pm, resolveInfo); dreamInfo.settingsComponentName = dreamMetadata.mSettingsActivity; dreamInfo.previewImage = dreamMetadata.mPreviewImage; final DreamService.DreamMetadata dreamMetadata = DreamService.getDreamMetadata(mContext, resolveInfo.serviceInfo); if (dreamMetadata != null) { dreamInfo.settingsComponentName = dreamMetadata.settingsActivity; dreamInfo.previewImage = dreamMetadata.previewImage; } if (dreamInfo.previewImage == null) { dreamInfo.previewImage = mDreamPreviewDefault; } dreamInfos.add(dreamInfo); } Collections.sort(dreamInfos, mComparator); dreamInfos.sort(mComparator); return dreamInfos; } Loading Loading @@ -483,67 +477,6 @@ public class DreamBackend { return new ComponentName(resolveInfo.serviceInfo.packageName, resolveInfo.serviceInfo.name); } private static final class DreamMetadata { @Nullable Drawable mPreviewImage; @Nullable ComponentName mSettingsActivity; } @Nullable private static TypedArray readMetadata(PackageManager pm, ServiceInfo serviceInfo) { if (serviceInfo == null || serviceInfo.metaData == null) { return null; } try (XmlResourceParser parser = serviceInfo.loadXmlMetaData(pm, DreamService.DREAM_META_DATA)) { if (parser == null) { Log.w(TAG, "No " + DreamService.DREAM_META_DATA + " meta-data"); return null; } Resources res = pm.getResourcesForApplication(serviceInfo.applicationInfo); AttributeSet attrs = Xml.asAttributeSet(parser); while (true) { final int type = parser.next(); if (type == XmlPullParser.END_DOCUMENT || type == XmlPullParser.START_TAG) { break; } } String nodeName = parser.getName(); if (!"dream".equals(nodeName)) { Log.w(TAG, "Meta-data does not start with dream tag"); return null; } return res.obtainAttributes(attrs, com.android.internal.R.styleable.Dream); } catch (PackageManager.NameNotFoundException | IOException | XmlPullParserException e) { Log.w(TAG, "Error parsing : " + serviceInfo.packageName, e); return null; } } private static ComponentName convertToComponentName(String flattenedString, ServiceInfo serviceInfo) { if (flattenedString == null) return null; if (flattenedString.indexOf('/') < 0) { flattenedString = serviceInfo.packageName + "/" + flattenedString; } return ComponentName.unflattenFromString(flattenedString); } private static DreamMetadata getDreamMetadata(PackageManager pm, ResolveInfo resolveInfo) { DreamMetadata result = new DreamMetadata(); if (resolveInfo == null) return result; TypedArray rawMetadata = readMetadata(pm, resolveInfo.serviceInfo); if (rawMetadata == null) return result; result.mSettingsActivity = convertToComponentName(rawMetadata.getString( com.android.internal.R.styleable.Dream_settingsActivity), resolveInfo.serviceInfo); result.mPreviewImage = rawMetadata.getDrawable( com.android.internal.R.styleable.Dream_previewImage); rawMetadata.recycle(); return result; } private static void logd(String msg, Object... args) { if (DEBUG) { Log.d(TAG, args == null || args.length == 0 ? msg : String.format(msg, args)); Loading
services/tests/servicestests/AndroidManifest.xml +13 −0 Original line number Diff line number Diff line Loading @@ -130,6 +130,19 @@ android:resource="@xml/test_account_type2_authenticator"/> </service> <service android:name="com.android.server.dreams.TestDreamService" 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" /> </service> <receiver android:name="com.android.server.devicepolicy.ApplicationRestrictionsTest$AdminReceiver" android:permission="android.permission.BIND_DEVICE_ADMIN" android:exported="true"> Loading
services/tests/servicestests/res/xml/test_dream_metadata.xml 0 → 100644 +18 −0 Original line number Diff line number Diff line <!-- ~ 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. --> <dream xmlns:android="http://schemas.android.com/apk/res/android" android:settingsActivity="com.android.server.dreams/.TestDreamSettingsActivity" />
services/tests/servicestests/src/com/android/server/dreams/DreamServiceTest.java 0 → 100644 +56 −0 Original line number Diff line number Diff line /* * 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 static org.junit.Assert.assertEquals; import android.content.ComponentName; import android.content.Context; import android.content.pm.PackageManager; import android.content.pm.ServiceInfo; import android.service.dreams.DreamService; import androidx.test.filters.SmallTest; import androidx.test.platform.app.InstrumentationRegistry; import androidx.test.runner.AndroidJUnit4; import org.junit.Test; import org.junit.runner.RunWith; @SmallTest @RunWith(AndroidJUnit4.class) public class DreamServiceTest { @Test public void testMetadataParsing() { final String testDreamServiceComponent = "com.android.server.dreams/.TestDreamService"; final String testSettingsActivity = "com.android.server.dreams/.TestDreamSettingsActivity"; final Context context = InstrumentationRegistry.getInstrumentation().getTargetContext(); try { final ServiceInfo si = context.getPackageManager().getServiceInfo( ComponentName.unflattenFromString(testDreamServiceComponent), PackageManager.ComponentInfoFlags.of(PackageManager.GET_META_DATA)); final DreamService.DreamMetadata metadata = DreamService.getDreamMetadata(context, si); assertEquals(0, metadata.settingsActivity.compareTo( ComponentName.unflattenFromString(testSettingsActivity))); } catch (PackageManager.NameNotFoundException e) { e.printStackTrace(); } } }