Merge "Fix vulnerability that allowed attackers to start arbitary activities" into tm-qpr-dev am: de117f20ff
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/19775871 Change-Id: Iad0b84f489fa749e146769650dc87cd7008e137a Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
@@ -2403,6 +2403,16 @@ package android.service.dreams {
|
|||||||
method public final boolean shouldShowComplications();
|
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 {
|
package android.service.notification {
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ import android.annotation.NonNull;
|
|||||||
import android.annotation.Nullable;
|
import android.annotation.Nullable;
|
||||||
import android.annotation.SdkConstant;
|
import android.annotation.SdkConstant;
|
||||||
import android.annotation.SdkConstant.SdkConstantType;
|
import android.annotation.SdkConstant.SdkConstantType;
|
||||||
|
import android.annotation.TestApi;
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.app.ActivityTaskManager;
|
import android.app.ActivityTaskManager;
|
||||||
import android.app.AlarmManager;
|
import android.app.AlarmManager;
|
||||||
@@ -1124,7 +1125,8 @@ public class DreamService extends Service implements Window.Callback {
|
|||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
@Nullable
|
@Nullable
|
||||||
public static DreamMetadata getDreamMetadata(Context context,
|
@TestApi
|
||||||
|
public static DreamMetadata getDreamMetadata(@NonNull Context context,
|
||||||
@Nullable ServiceInfo serviceInfo) {
|
@Nullable ServiceInfo serviceInfo) {
|
||||||
if (serviceInfo == null) return null;
|
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) {
|
ServiceInfo serviceInfo) {
|
||||||
if (flattenedString == null) {
|
if (flattenedString == null) {
|
||||||
return null;
|
return null;
|
||||||
@@ -1193,7 +1196,17 @@ public class DreamService extends Service implements Window.Callback {
|
|||||||
return new ComponentName(serviceInfo.packageName, flattenedString);
|
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
|
* @hide
|
||||||
*/
|
*/
|
||||||
|
@TestApi
|
||||||
public static final class DreamMetadata {
|
public static final class DreamMetadata {
|
||||||
@Nullable
|
@Nullable
|
||||||
public final ComponentName settingsActivity;
|
public final ComponentName settingsActivity;
|
||||||
|
|||||||
@@ -147,6 +147,19 @@
|
|||||||
android:resource="@xml/test_dream_metadata" />
|
android:resource="@xml/test_dream_metadata" />
|
||||||
</service>
|
</service>
|
||||||
|
|
||||||
|
<service
|
||||||
|
android:name="com.android.server.dreams.TestDreamServiceWithInvalidSettings"
|
||||||
|
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_invalid" />
|
||||||
|
</service>
|
||||||
|
|
||||||
<receiver android:name="com.android.server.devicepolicy.ApplicationRestrictionsTest$AdminReceiver"
|
<receiver android:name="com.android.server.devicepolicy.ApplicationRestrictionsTest$AdminReceiver"
|
||||||
android:permission="android.permission.BIND_DEVICE_ADMIN"
|
android:permission="android.permission.BIND_DEVICE_ADMIN"
|
||||||
android:exported="true">
|
android:exported="true">
|
||||||
|
|||||||
@@ -15,5 +15,5 @@
|
|||||||
-->
|
-->
|
||||||
|
|
||||||
<dream xmlns:android="http://schemas.android.com/apk/res/android"
|
<dream xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:settingsActivity="com.android.server.dreams/.TestDreamSettingsActivity"
|
android:settingsActivity="com.android.frameworks.servicestests/.TestDreamSettingsActivity"
|
||||||
android:showClockAndComplications="false" />
|
android:showClockAndComplications="false" />
|
||||||
|
|||||||
@@ -0,0 +1,20 @@
|
|||||||
|
<!--
|
||||||
|
~ 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.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<!-- The settings activity is in a different package, which is invalid -->
|
||||||
|
<dream xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:settingsActivity="com.android.server.dreams/.TestDreamSettingsActivity"
|
||||||
|
android:showClockAndComplications="false"/>
|
||||||
@@ -16,7 +16,8 @@
|
|||||||
|
|
||||||
package com.android.server.dreams;
|
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 static org.junit.Assert.assertFalse;
|
||||||
|
|
||||||
import android.content.ComponentName;
|
import android.content.ComponentName;
|
||||||
@@ -35,21 +36,36 @@ import org.junit.runner.RunWith;
|
|||||||
@SmallTest
|
@SmallTest
|
||||||
@RunWith(AndroidJUnit4.class)
|
@RunWith(AndroidJUnit4.class)
|
||||||
public class DreamServiceTest {
|
public class DreamServiceTest {
|
||||||
|
private static final String TEST_PACKAGE_NAME = "com.android.frameworks.servicestests";
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testMetadataParsing() throws PackageManager.NameNotFoundException {
|
public void testMetadataParsing() throws PackageManager.NameNotFoundException {
|
||||||
final String testPackageName = "com.android.frameworks.servicestests";
|
|
||||||
final String testDreamClassName = "com.android.server.dreams.TestDreamService";
|
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();
|
assertThat(metadata.settingsActivity).isEqualTo(
|
||||||
|
ComponentName.unflattenFromString(testSettingsActivity));
|
||||||
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)));
|
|
||||||
assertFalse(metadata.showComplications);
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user