diff options
author | android-build-team Robot <android-build-team-robot@google.com> | 2018-03-21 21:22:00 +0000 |
---|---|---|
committer | android-build-team Robot <android-build-team-robot@google.com> | 2018-03-21 21:22:00 +0000 |
commit | fb268151905f0978b5836a7dcdc17dcfc4802b33 (patch) | |
tree | e4f2bbe52d675df854324e540f2faf776f4ab030 | |
parent | 138557dc38e9efc01d6d6b7aa374215abcbe61a6 (diff) | |
parent | 9c24395f6940a5d5c0b5c2256a42f862e4e9f6fb (diff) | |
download | cts-oreo-m4-s3-release.tar.gz |
Snap for 4657601 from 9c24395f6940a5d5c0b5c2256a42f862e4e9f6fb to oc-m4-releaseandroid-8.1.0_r67android-8.1.0_r65android-8.1.0_r64android-8.1.0_r63android-8.1.0_r62android-8.1.0_r61android-8.1.0_r60android-8.1.0_r53android-8.1.0_r51android-8.1.0_r48android-8.1.0_r45android-8.1.0_r42android-8.1.0_r40android-8.1.0_r39android-8.1.0_r38android-8.1.0_r37android-8.1.0_r32android-8.1.0_r31android-8.1.0_r29android-8.1.0_r28android-8.1.0_r27oreo-m8-releaseoreo-m4-s9-releaseoreo-m4-s8-releaseoreo-m4-s7-releaseoreo-m4-s6-releaseoreo-m4-s5-releaseoreo-m4-s4-releaseoreo-m4-s3-releaseoreo-m4-s2-releaseoreo-m4-s12-releaseoreo-m4-s11-releaseoreo-m4-s10-release
Change-Id: Id6583aa3f2ec8689e920aad5829b2eb2b8d8b107
8 files changed, 223 insertions, 1 deletions
diff --git a/hostsidetests/appsecurity/src/android/appsecurity/cts/OverlayHostTest.java b/hostsidetests/appsecurity/src/android/appsecurity/cts/OverlayHostTest.java new file mode 100644 index 00000000000..b543fbd6ae3 --- /dev/null +++ b/hostsidetests/appsecurity/src/android/appsecurity/cts/OverlayHostTest.java @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2017 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 android.appsecurity.cts; + +import com.android.compatibility.common.tradefed.build.CompatibilityBuildHelper; +import com.android.tradefed.build.IBuildInfo; +import com.android.tradefed.device.CollectingOutputReceiver; +import com.android.tradefed.testtype.DeviceTestCase; +import com.android.tradefed.testtype.IBuildReceiver; + +public class OverlayHostTest extends DeviceTestCase implements IBuildReceiver { + private static final String PKG = "com.android.cts.overlayapp"; + private static final String APK = "CtsOverlayApp.apk"; + private CompatibilityBuildHelper mBuildHelper; + + @Override + protected void setUp() throws Exception { + super.setUp(); + getDevice().uninstallPackage(PKG); + } + + @Override + protected void tearDown() throws Exception { + getDevice().uninstallPackage(PKG); + super.tearDown(); + } + + @Override + public void setBuild(IBuildInfo buildInfo) { + mBuildHelper = new CompatibilityBuildHelper(buildInfo); + } + + public void testInstallingOverlayHasNoEffect() throws Exception { + assertNull(getDevice().installPackage(mBuildHelper.getTestFile(APK), false, false)); + CollectingOutputReceiver receiver = new CollectingOutputReceiver(); + getDevice().getIDevice().executeShellCommand("cmd overlay list", receiver); + + // The package of the installed overlay should not appear in the overlay manager list. + final String output = receiver.getOutput(); + assertFalse(output.contains(PKG)); + } + +} diff --git a/hostsidetests/appsecurity/test-apps/OverlayApp/Android.mk b/hostsidetests/appsecurity/test-apps/OverlayApp/Android.mk new file mode 100644 index 00000000000..21366a5e01c --- /dev/null +++ b/hostsidetests/appsecurity/test-apps/OverlayApp/Android.mk @@ -0,0 +1,28 @@ +# +# Copyright (C) 2017 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. +# + +LOCAL_PATH := $(call my-dir) + +include $(CLEAR_VARS) + +LOCAL_MODULE_TAGS := tests +LOCAL_SDK_VERSION := current +LOCAL_COMPATIBILITY_SUITE := cts vts general-tests +LOCAL_PACKAGE_NAME := CtsOverlayApp + +# Tag this module as a cts test artifact +include $(BUILD_CTS_SUPPORT_PACKAGE) + diff --git a/hostsidetests/appsecurity/test-apps/OverlayApp/AndroidManifest.xml b/hostsidetests/appsecurity/test-apps/OverlayApp/AndroidManifest.xml new file mode 100644 index 00000000000..83036b23069 --- /dev/null +++ b/hostsidetests/appsecurity/test-apps/OverlayApp/AndroidManifest.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2017 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.cts.overlayapp"> + <overlay android:targetPackage="android" /> + + <application android:hasCode="false" /> +</manifest> diff --git a/hostsidetests/appsecurity/test-apps/OverlayApp/res/values/values.xml b/hostsidetests/appsecurity/test-apps/OverlayApp/res/values/values.xml new file mode 100644 index 00000000000..495a43e8630 --- /dev/null +++ b/hostsidetests/appsecurity/test-apps/OverlayApp/res/values/values.xml @@ -0,0 +1,19 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2017 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> + <string name="cancel">Forget about it!</string> +</resources> diff --git a/tests/autofillservice/src/android/autofillservice/cts/Helper.java b/tests/autofillservice/src/android/autofillservice/cts/Helper.java index c1a70f09f53..f1d02dd12d1 100644 --- a/tests/autofillservice/src/android/autofillservice/cts/Helper.java +++ b/tests/autofillservice/src/android/autofillservice/cts/Helper.java @@ -45,6 +45,7 @@ import android.webkit.WebView; import com.android.compatibility.common.util.SystemUtil; +import java.lang.reflect.Field; import java.util.List; import java.util.function.Function; @@ -855,6 +856,50 @@ final class Helper { return InstrumentationRegistry.getInstrumentation().getContext(); } + private static Field getField(Class<?> clazz, String fieldName) { + final Field[] fields = clazz.getDeclaredFields(); + final StringBuilder fieldNames = new StringBuilder(); + for (Field field : fields) { + fieldNames.append(field.getName()).append(" "); + field.setAccessible(true); + if (field.getName().equals(fieldName)) { + return field; + } + } + throw new IllegalArgumentException( + "no field " + fieldName + " on " + clazz.getName() + ": " + fieldNames); + } + + /** + * Uses reflection to get a field from an object. + */ + static <T> T getField(Object object, String fieldName) { + try { + final Class<?> clazz = object.getClass(); + final Field field = getField(clazz, fieldName); + @SuppressWarnings("unchecked") + final T value = (T) field.get(object); + return value; + } catch (Exception e) { + throw new IllegalArgumentException( + "error getting field " + fieldName + " from object" + object, e); + } + } + + /** + * Uses reflection to set a field in an object. + */ + static void setField(Object object, String fieldName, Object value) { + try { + final Class<?> clazz = object.getClass(); + final Field field = getField(clazz, fieldName); + field.set(object, value); + } catch (Exception e) { + throw new IllegalArgumentException("error setting field " + fieldName + " on object " + + object, e); + } + } + /** * Cleans up the autofill state; should be called before pretty much any test. */ diff --git a/tests/autofillservice/src/android/autofillservice/cts/InstrumentedAutoFillService.java b/tests/autofillservice/src/android/autofillservice/cts/InstrumentedAutoFillService.java index 2c234cdef5d..6694e5a145a 100644 --- a/tests/autofillservice/src/android/autofillservice/cts/InstrumentedAutoFillService.java +++ b/tests/autofillservice/src/android/autofillservice/cts/InstrumentedAutoFillService.java @@ -125,7 +125,8 @@ public class InstrumentedAutoFillService extends AutofillService { final ComponentName component = contexts.get(contexts.size() - 1).getStructure() .getActivityComponent(); final String actualPackage = component.getPackageName(); - if (!actualPackage.equals(getPackageName())) { + if (!actualPackage.equals(getPackageName()) + && !actualPackage.equals(sReplier.mAcceptedPackageName)) { Log.w(TAG, "Got request from package " + actualPackage); return false; } @@ -246,16 +247,22 @@ public class InstrumentedAutoFillService extends AutofillService { private final BlockingQueue<SaveRequest> mSaveRequests = new LinkedBlockingQueue<>(); private List<Exception> mExceptions; + private String mAcceptedPackageName; private Replier() { } + private IdMode mIdMode = IdMode.RESOURCE_ID; public void setIdMode(IdMode mode) { this.mIdMode = mode; } + public void acceptRequestsFromPackage(String packageName) { + mAcceptedPackageName = packageName; + } + /** * Gets the exceptions thrown asynchronously, if any. */ @@ -356,6 +363,7 @@ public class InstrumentedAutoFillService extends AutofillService { mFillRequests.clear(); mSaveRequests.clear(); mExceptions = null; + mAcceptedPackageName = null; } private void onFillRequest(List<FillContext> contexts, Bundle data, diff --git a/tests/autofillservice/src/android/autofillservice/cts/VirtualContainerActivityTest.java b/tests/autofillservice/src/android/autofillservice/cts/VirtualContainerActivityTest.java index 8adbdd7fe2d..31eae24ba6c 100644 --- a/tests/autofillservice/src/android/autofillservice/cts/VirtualContainerActivityTest.java +++ b/tests/autofillservice/src/android/autofillservice/cts/VirtualContainerActivityTest.java @@ -35,6 +35,7 @@ import android.app.assist.AssistStructure.ViewNode; import android.autofillservice.cts.CannedFillResponse.CannedDataset; import android.autofillservice.cts.InstrumentedAutoFillService.FillRequest; import android.autofillservice.cts.VirtualContainerView.Line; +import android.content.ComponentName; import android.graphics.Rect; import android.os.SystemClock; import android.service.autofill.SaveInfo; @@ -411,6 +412,30 @@ public class VirtualContainerActivityTest extends AutoFillServiceTestCase { sUiBot.assertSaveShowing(SAVE_DATA_TYPE_PASSWORD); } + @Test + public void testAppCannotFakePackageName() throws Exception { + // Set service. + enableService(); + + // Set expectations. + sReplier.acceptRequestsFromPackage("MALICIOUS"); + mActivity.mCustomView.fakePackageName(new ComponentName("MALICIOUS", "AM.I")); + sReplier.addResponse(new CannedDataset.Builder() + .setField(ID_USERNAME, "dude") + .setField(ID_PASSWORD, "sweet") + .setPresentation(createPresentation("The Dude")) + .build()); + + // Trigger auto-fill. + mActivity.mUsername.changeFocus(true); + assertDatasetShown(mActivity.mUsername, "The Dude"); + + // Make sure package name was sanitized. + final FillRequest request = sReplier.getNextFillRequest(); + assertThat(request.structure.getActivityComponent().getPackageName()) + .isEqualTo(mPackageName); + } + /** * Asserts the dataset picker is properly displayed in a give line. */ diff --git a/tests/autofillservice/src/android/autofillservice/cts/VirtualContainerView.java b/tests/autofillservice/src/android/autofillservice/cts/VirtualContainerView.java index 205fcaef4a3..8eecc294796 100644 --- a/tests/autofillservice/src/android/autofillservice/cts/VirtualContainerView.java +++ b/tests/autofillservice/src/android/autofillservice/cts/VirtualContainerView.java @@ -20,7 +20,9 @@ import static android.autofillservice.cts.Helper.FILL_TIMEOUT_MS; import static com.google.common.truth.Truth.assertWithMessage; +import android.app.assist.AssistStructure; import android.app.assist.AssistStructure.ViewNode; +import android.content.ComponentName; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; @@ -72,6 +74,7 @@ class VirtualContainerView extends View { private int mUnfocusedColor; private boolean mSync = true; private boolean mOverrideDispatchProvideAutofillStructure = false; + private ComponentName mFakedComponentName; public VirtualContainerView(Context context, AttributeSet attrs) { super(context, attrs); @@ -192,6 +195,18 @@ class VirtualContainerView extends View { Log.d(TAG, "onProvideAutofillVirtualStructure(): flags = " + flags); super.onProvideAutofillVirtualStructure(structure, flags); + if (mFakedComponentName != null) { + Log.d(TAG, "Faking package name to " + mFakedComponentName); + try { + final AssistStructure assistStructure = Helper.getField(structure, "mAssist"); + if (assistStructure != null) { + Helper.setField(assistStructure, "mActivityComponent", mFakedComponentName); + } + } catch (Exception e) { + Log.e(TAG, "Could not fake package name to " + mFakedComponentName, e); + } + } + final String packageName = getContext().getPackageName(); structure.setClassName(getClass().getName()); final int childrenSize = mItems.size(); @@ -254,6 +269,10 @@ class VirtualContainerView extends View { mSync = sync; } + void fakePackageName(ComponentName name) { + mFakedComponentName = name; + } + void setOverrideDispatchProvideAutofillStructure(boolean flag) { mOverrideDispatchProvideAutofillStructure = flag; } |