Merge "Update FontRenderingTests to handle 90x90 test area" into mnc-dev
diff --git a/CtsTestCaseList.mk b/CtsTestCaseList.mk
index 9021921..db777b5 100644
--- a/CtsTestCaseList.mk
+++ b/CtsTestCaseList.mk
@@ -172,6 +172,7 @@
CtsTextTestCases \
CtsTextureViewTestCases \
CtsThemeTestCases \
+ CtsTransitionTestCases \
CtsTvTestCases \
CtsUiAutomationTestCases \
CtsUiRenderingTestCases \
diff --git a/apps/CtsVerifier/AndroidManifest.xml b/apps/CtsVerifier/AndroidManifest.xml
index a914e7c..ac9466d 100644
--- a/apps/CtsVerifier/AndroidManifest.xml
+++ b/apps/CtsVerifier/AndroidManifest.xml
@@ -1449,6 +1449,17 @@
android:value="android.software.live_tv" />
</activity>
+ <activity android:name=".tv.TimeShiftTestActivity"
+ android:label="@string/tv_time_shift_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.live_tv" />
+ </activity>
+
<activity android:name=".screenpinning.ScreenPinningTestActivity"
android:label="@string/screen_pinning_test">
<intent-filter>
@@ -1460,12 +1471,6 @@
android:value="android.hardware.type.television:android.software.leanback:android.hardware.type.watch" />
</activity>
- <activity android:name=".tv.MockTvInputSettingsActivity">
- <intent-filter>
- <action android:name="android.intent.action.MAIN" />
- </intent-filter>
- </activity>
-
<activity android:name=".tv.MockTvInputSetupActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
diff --git a/apps/CtsVerifier/res/values/strings.xml b/apps/CtsVerifier/res/values/strings.xml
index 926a993..ad41891 100644
--- a/apps/CtsVerifier/res/values/strings.xml
+++ b/apps/CtsVerifier/res/values/strings.xml
@@ -1616,6 +1616,41 @@
The Spanish audio track should be selected.
</string>
+ <string name="tv_time_shift_test">TV app time shift test</string>
+ <string name="tv_time_shift_test_info">
+ This test verifies that the TV app invokes proper time shift APIs in the framwork.
+ </string>
+ <string name="tv_time_shift_test_pause_resume">
+ Press the \"Launch TV app\" button. Verify that the playback control is available.
+ Pause the playback and then resume it.
+ </string>
+ <string name="tv_time_shift_test_verify_resume_after_pause">
+ The playback should be resumed after pause.
+ </string>
+ <string name="tv_time_shift_test_verify_position_tracking">
+ The playback position tracking should be activated.
+ </string>
+ <string name="tv_time_shift_test_speed_rate">
+ Press the \"Launch TV app\" button. Verify that the playback control is available.
+ Rewind the playback and in a few seconds fast-forward it.
+ </string>
+ <string name="tv_time_shift_test_verify_rewind">
+ The playback should be rewinded.
+ </string>
+ <string name="tv_time_shift_test_verify_fast_forward">
+ The playback should be fast-forwarded.
+ </string>
+ <string name="tv_time_shift_test_seek">
+ Press the \"Launch TV app\" button. Verify that the playback control is available.
+ Seek to previous and then seek to next.
+ </string>
+ <string name="tv_time_shift_test_verify_seek_to_previous">
+ The playback position should be moved to the previous position.
+ </string>
+ <string name="tv_time_shift_test_verify_seek_to_next">
+ The playback position should be moved to the next position.
+ </string>
+
<string name="overlay_view_text">Overlay View Dummy Text</string>
<string name="fake_rating">Fake</string>
diff --git a/apps/CtsVerifier/res/xml/mock_tv_input_service.xml b/apps/CtsVerifier/res/xml/mock_tv_input_service.xml
index 1a2cf86..d9cb867 100644
--- a/apps/CtsVerifier/res/xml/mock_tv_input_service.xml
+++ b/apps/CtsVerifier/res/xml/mock_tv_input_service.xml
@@ -15,5 +15,4 @@
-->
<tv-input xmlns:android="http://schemas.android.com/apk/res/android"
- android:setupActivity="com.android.cts.verifier.tv.MockTvInputSetupActivity"
- android:settingsActivity="com.android.cts.verifier.tv.MockTvInputSettingsActivity" />
+ android:setupActivity="com.android.cts.verifier.tv.MockTvInputSetupActivity" />
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/camera/fov/DetermineFovActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/camera/fov/DetermineFovActivity.java
index 8b989e1..959e98f 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/camera/fov/DetermineFovActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/camera/fov/DetermineFovActivity.java
@@ -145,7 +145,7 @@
mTargetDistanceCm = getTargetDistance();
mReportedFovDegrees = PhotoCaptureActivity.getReportedFovDegrees();
- mFovDegrees = mReportedFovDegrees > 80 ? 60 : mReportedFovDegrees;
+ mFovDegrees = mReportedFovDegrees > 120 ? 60 : mReportedFovDegrees;
mFovMaxDegrees = mFovDegrees + FOV_ADJUSTMENT_RANGE / 2;
mFovMinDegrees = mFovDegrees - FOV_ADJUSTMENT_RANGE / 2;
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsSerializer.java b/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsSerializer.java
index 57d0c8f..9abfa9a 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsSerializer.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsSerializer.java
@@ -151,6 +151,19 @@
cfgArray.put(obj);
}
}
+ sizes = map.getHighResolutionOutputSizes(fmts[fi]);
+ if (sizes != null) {
+ for (int si = 0; si < Array.getLength(sizes); si++) {
+ JSONObject obj = new JSONObject();
+ obj.put("format", fmts[fi]);
+ obj.put("width",sizes[si].getWidth());
+ obj.put("height", sizes[si].getHeight());
+ obj.put("input", false);
+ obj.put("minFrameDuration",
+ map.getOutputMinFrameDuration(fmts[fi],sizes[si]));
+ cfgArray.put(obj);
+ }
+ }
}
}
mapObj.put("availableStreamConfigurations", cfgArray);
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsService.java b/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsService.java
index 85b8a18..5b034fe 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsService.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsService.java
@@ -1077,10 +1077,10 @@
"Zero stream configs available for requested format: %s",
sformat));
}
- width = sizes[0].getWidth();
+ width = ItsUtils.getMaxSize(sizes).getWidth();
}
if (height <= 0) {
- height = sizes[0].getHeight();
+ height = ItsUtils.getMaxSize(sizes).getHeight();
}
outputSizes[i] = new Size(width, height);
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsUtils.java b/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsUtils.java
index fddee4d..6fd050b 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsUtils.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsUtils.java
@@ -128,10 +128,24 @@
if (configMap == null) {
throw new ItsException("Failed to get stream config");
}
- return configMap.getOutputSizes(format);
+ Size[] normalSizes = configMap.getOutputSizes(format);
+ Size[] slowSizes = configMap.getHighResolutionOutputSizes(format);
+ Size[] allSizes = null;
+ if (normalSizes != null && slowSizes != null) {
+ allSizes = new Size[normalSizes.length + slowSizes.length];
+ System.arraycopy(normalSizes, 0, allSizes, 0,
+ normalSizes.length);
+ System.arraycopy(slowSizes, 0, allSizes, normalSizes.length,
+ slowSizes.length);
+ } else if (normalSizes != null) {
+ allSizes = normalSizes;
+ } else if (slowSizes != null) {
+ allSizes = slowSizes;
+ }
+ return allSizes;
}
- private static Size getMaxSize(Size[] sizes) {
+ public static Size getMaxSize(Size[] sizes) {
if (sizes == null || sizes.length == 0) {
throw new IllegalArgumentException("sizes was empty");
}
@@ -252,4 +266,3 @@
}
}
}
-
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/tv/MockTvInputService.java b/apps/CtsVerifier/src/com/android/cts/verifier/tv/MockTvInputService.java
index 9f4ac2d..f875684 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/tv/MockTvInputService.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/tv/MockTvInputService.java
@@ -16,8 +16,7 @@
package com.android.cts.verifier.tv;
-import com.android.cts.verifier.R;
-
+import android.annotation.SuppressLint;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
@@ -28,6 +27,7 @@
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Rect;
+import android.media.PlaybackParams;
import android.media.tv.TvContentRating;
import android.media.tv.TvContract;
import android.media.tv.TvInputManager;
@@ -35,14 +35,21 @@
import android.media.tv.TvTrackInfo;
import android.net.Uri;
import android.os.Bundle;
-import android.view.Surface;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.util.Log;
import android.view.LayoutInflater;
+import android.view.Surface;
import android.view.View;
import android.widget.TextView;
+import com.android.cts.verifier.R;
+
import java.util.ArrayList;
import java.util.List;
+@SuppressLint("NewApi")
public class MockTvInputService extends TvInputService {
private static final String TAG = "MockTvInputService";
@@ -50,6 +57,7 @@
private static final String SELECT_TRACK_TYPE = "type";
private static final String SELECT_TRACK_ID = "id";
private static final String CAPTION_ENABLED = "enabled";
+ private static final String PAUSE_CALLED = "pause_called";
private static Object sLock = new Object();
private static Callback sTuneCallback = null;
@@ -58,6 +66,14 @@
private static Callback sUnblockContentCallback = null;
private static Callback sSelectTrackCallback = null;
private static Callback sSetCaptionEnabledCallback = null;
+ // Callbacks for time shift.
+ private static Callback sResumeAfterPauseCallback = null;
+ private static Callback sPositionTrackingCallback = null;
+ private static Callback sRewindCallback = null;
+ private static Callback sFastForwardCallback = null;
+ private static Callback sSeekToPreviousCallback = null;
+ private static Callback sSeekToNextCallback = null;
+
private static TvContentRating sRating = null;
static final TvTrackInfo sEngAudioTrack =
@@ -144,6 +160,42 @@
}
}
+ static void expectResumeAfterPause(View postTarget, Runnable successCallback) {
+ synchronized (sLock) {
+ sResumeAfterPauseCallback = new Callback(postTarget, successCallback);
+ }
+ }
+
+ static void expectPositionTracking(View postTarget, Runnable successCallback) {
+ synchronized (sLock) {
+ sPositionTrackingCallback = new Callback(postTarget, successCallback);
+ }
+ }
+
+ static void expectRewind(View postTarget, Runnable successCallback) {
+ synchronized (sLock) {
+ sRewindCallback = new Callback(postTarget, successCallback);
+ }
+ }
+
+ static void expectFastForward(View postTarget, Runnable successCallback) {
+ synchronized (sLock) {
+ sFastForwardCallback = new Callback(postTarget, successCallback);
+ }
+ }
+
+ static void expectSeekToPrevious(View postTarget, Runnable successCallback) {
+ synchronized (sLock) {
+ sSeekToPreviousCallback = new Callback(postTarget, successCallback);
+ }
+ }
+
+ static void expectSeekToNext(View postTarget, Runnable successCallback) {
+ synchronized (sLock) {
+ sSeekToNextCallback = new Callback(postTarget, successCallback);
+ }
+ }
+
static String getInputId(Context context) {
return TvContract.buildInputId(new ComponentName(context,
MockTvInputService.class.getName()));
@@ -172,10 +224,45 @@
}
private static class MockSessionImpl extends Session {
+ private static final int MSG_SEEK = 1000;
+ private static final int SEEK_DELAY_MS = 300;
+
private final Context mContext;
private Surface mSurface = null;
private List<TvTrackInfo> mTracks = new ArrayList<>();
+ private long mRecordStartTimeMs;
+ private long mPausedTimeMs;
+ // The time in milliseconds when the current position is lastly updated.
+ private long mLastCurrentPositionUpdateTimeMs;
+ // The current playback position.
+ private long mCurrentPositionMs;
+ // The current playback speed rate.
+ private float mSpeed;
+
+ private final Handler mHandler = new Handler(Looper.getMainLooper()) {
+ @Override
+ public void handleMessage(Message msg) {
+ if (msg.what == MSG_SEEK) {
+ // Actually, this input doesn't play any videos, it just shows the image.
+ // So we should simulate the playback here by changing the current playback
+ // position periodically in order to test the time shift.
+ // If the playback is paused, the current playback position doesn't need to be
+ // changed.
+ if (mPausedTimeMs == 0) {
+ long currentTimeMs = System.currentTimeMillis();
+ mCurrentPositionMs += (long) ((currentTimeMs
+ - mLastCurrentPositionUpdateTimeMs) * mSpeed);
+ mCurrentPositionMs = Math.max(mRecordStartTimeMs,
+ Math.min(mCurrentPositionMs, currentTimeMs));
+ mLastCurrentPositionUpdateTimeMs = currentTimeMs;
+ }
+ sendEmptyMessageDelayed(MSG_SEEK, SEEK_DELAY_MS);
+ }
+ super.handleMessage(msg);
+ }
+ };
+
private MockSessionImpl(Context context) {
super(context);
mContext = context;
@@ -263,6 +350,12 @@
notifyTracksChanged(mTracks);
notifyTrackSelected(TvTrackInfo.TYPE_AUDIO, sEngAudioTrack.getId());
notifyTrackSelected(TvTrackInfo.TYPE_SUBTITLE, null);
+ notifyTimeShiftStatusChanged(TvInputManager.TIME_SHIFT_STATUS_AVAILABLE);
+ mRecordStartTimeMs = mCurrentPositionMs = mLastCurrentPositionUpdateTimeMs
+ = System.currentTimeMillis();
+ mPausedTimeMs = 0;
+ mHandler.sendEmptyMessageDelayed(MSG_SEEK, SEEK_DELAY_MS);
+ mSpeed = 1;
return true;
}
@@ -305,6 +398,88 @@
}
}
}
+
+ @Override
+ public long onTimeShiftGetCurrentPosition() {
+ synchronized (sLock) {
+ if (sPositionTrackingCallback != null) {
+ sPositionTrackingCallback.post();
+ sPositionTrackingCallback = null;
+ }
+ }
+ Log.d(TAG, "currentPositionMs=" + mCurrentPositionMs);
+ return mCurrentPositionMs;
+ }
+
+ @Override
+ public long onTimeShiftGetStartPosition() {
+ return mRecordStartTimeMs;
+ }
+
+ @Override
+ public void onTimeShiftPause() {
+ synchronized (sLock) {
+ if (sResumeAfterPauseCallback != null) {
+ sResumeAfterPauseCallback.mBundle.putBoolean(PAUSE_CALLED, true);
+ }
+ }
+ mCurrentPositionMs = mPausedTimeMs = mLastCurrentPositionUpdateTimeMs
+ = System.currentTimeMillis();
+ }
+
+ @Override
+ public void onTimeShiftResume() {
+ synchronized (sLock) {
+ if (sResumeAfterPauseCallback != null
+ && sResumeAfterPauseCallback.mBundle.getBoolean(PAUSE_CALLED)) {
+ sResumeAfterPauseCallback.post();
+ sResumeAfterPauseCallback = null;
+ }
+ }
+ mSpeed = 1;
+ mPausedTimeMs = 0;
+ mLastCurrentPositionUpdateTimeMs = System.currentTimeMillis();
+ }
+
+ @Override
+ public void onTimeShiftSeekTo(long timeMs) {
+ synchronized (sLock) {
+ if (mCurrentPositionMs > timeMs) {
+ if (sSeekToPreviousCallback != null) {
+ sSeekToPreviousCallback.post();
+ sSeekToPreviousCallback = null;
+ }
+ } else if (mCurrentPositionMs < timeMs) {
+ if (sSeekToNextCallback != null) {
+ sSeekToNextCallback.post();
+ sSeekToNextCallback = null;
+ }
+ }
+ }
+ mLastCurrentPositionUpdateTimeMs = System.currentTimeMillis();
+ mCurrentPositionMs = Math.max(mRecordStartTimeMs,
+ Math.min(timeMs, mLastCurrentPositionUpdateTimeMs));
+ }
+
+ @Override
+ public void onTimeShiftSetPlaybackParams(PlaybackParams params) {
+ synchronized(sLock) {
+ if (params != null) {
+ if (params.getSpeed() > 1) {
+ if (sFastForwardCallback != null) {
+ sFastForwardCallback.post();
+ sFastForwardCallback = null;
+ }
+ } else if (params.getSpeed() < 1) {
+ if (sRewindCallback != null) {
+ sRewindCallback.post();
+ sRewindCallback = null;
+ }
+ }
+ }
+ }
+ mSpeed = params.getSpeed();
+ }
}
private static class Callback {
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/tv/TimeShiftTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/tv/TimeShiftTestActivity.java
new file mode 100644
index 0000000..5e4036c
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/tv/TimeShiftTestActivity.java
@@ -0,0 +1,222 @@
+/*
+ * 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;
+
+import android.content.Intent;
+import android.database.Cursor;
+import android.media.tv.TvContract;
+import android.view.View;
+import android.widget.Toast;
+
+import com.android.cts.verifier.R;
+
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Tests for verifying TV app behavior on time shift.
+ */
+public class TimeShiftTestActivity extends TvAppVerifierActivity
+ implements View.OnClickListener {
+ private static final long TIMEOUT_MS = TimeUnit.MINUTES.toMillis(5);
+ private static final boolean NOT_PASSED = false;
+ private static final boolean PASSED = true;
+
+ private View mPauseResumeItem;
+ private View mVerifyResumeAfterPauseItem;
+ private View mVerifyPositionTrackingItem;
+
+ private View mSetPlaybackParamsItem;
+ private View mVerifyRewindItem;
+ private View mVerifyFastForwardItem;
+
+ private View mSeekToItem;
+ private View mVerifySeekToPreviousItem;
+ private View mVerifySeekToNextItem;
+
+ private Intent mTvAppIntent = null;
+
+ @Override
+ public void onClick(View v) {
+ final View postTarget = getPostTarget();
+
+ if (containsButton(mPauseResumeItem, v)) {
+ mVerifyResumeAfterPauseItem.setTag(NOT_PASSED);
+ mVerifyPositionTrackingItem.setTag(NOT_PASSED);
+
+ final Runnable failCallback = new Runnable() {
+ @Override
+ public void run() {
+ setPassState(mVerifyResumeAfterPauseItem, false);
+ setPassState(mVerifyPositionTrackingItem, false);
+ }
+ };
+ postTarget.postDelayed(failCallback, TIMEOUT_MS);
+ MockTvInputService.expectResumeAfterPause(postTarget, new Runnable() {
+ @Override
+ public void run() {
+ postTarget.removeCallbacks(failCallback);
+ setPassState(mPauseResumeItem, true);
+ setPassState(mVerifyResumeAfterPauseItem, true);
+ mVerifyResumeAfterPauseItem.setTag(PASSED);
+ if (isPassedState(mVerifyResumeAfterPauseItem)
+ && isPassedState(mVerifyPositionTrackingItem)) {
+ setButtonEnabled(mSetPlaybackParamsItem, true);
+ }
+ }
+ });
+ MockTvInputService.expectPositionTracking(postTarget, new Runnable() {
+ @Override
+ public void run() {
+ postTarget.removeCallbacks(failCallback);
+ setPassState(mPauseResumeItem, true);
+ setPassState(mVerifyPositionTrackingItem, true);
+ mVerifyPositionTrackingItem.setTag(PASSED);
+ if (isPassedState(mVerifyResumeAfterPauseItem)
+ && isPassedState(mVerifyPositionTrackingItem)) {
+ setButtonEnabled(mSetPlaybackParamsItem, true);
+ }
+ }
+ });
+ } else if (containsButton(mSetPlaybackParamsItem, v)) {
+ mVerifyRewindItem.setTag(NOT_PASSED);
+ mVerifyFastForwardItem.setTag(NOT_PASSED);
+
+ final Runnable failCallback = new Runnable() {
+ @Override
+ public void run() {
+ setPassState(mVerifyRewindItem, false);
+ setPassState(mVerifyFastForwardItem, false);
+ }
+ };
+ postTarget.postDelayed(failCallback, TIMEOUT_MS);
+ MockTvInputService.expectRewind(postTarget, new Runnable() {
+ @Override
+ public void run() {
+ postTarget.removeCallbacks(failCallback);
+ setPassState(mSetPlaybackParamsItem, true);
+ setPassState(mVerifyRewindItem, true);
+ mVerifyRewindItem.setTag(PASSED);
+ if (isPassedState(mVerifyRewindItem) && isPassedState(mVerifyFastForwardItem)) {
+ setButtonEnabled(mSeekToItem, true);
+ }
+ }
+ });
+ MockTvInputService.expectFastForward(postTarget, new Runnable() {
+ @Override
+ public void run() {
+ postTarget.removeCallbacks(failCallback);
+ setPassState(mSetPlaybackParamsItem, true);
+ setPassState(mVerifyFastForwardItem, true);
+ mVerifyFastForwardItem.setTag(PASSED);
+ if (isPassedState(mVerifyRewindItem) && isPassedState(mVerifyFastForwardItem)) {
+ setButtonEnabled(mSeekToItem, true);
+ }
+ }
+ });
+ } else if (containsButton(mSeekToItem, v)) {
+ mVerifySeekToPreviousItem.setTag(NOT_PASSED);
+ mVerifySeekToNextItem.setTag(NOT_PASSED);
+
+ final Runnable failCallback = new Runnable() {
+ @Override
+ public void run() {
+ setPassState(mVerifySeekToPreviousItem, false);
+ setPassState(mVerifySeekToNextItem, false);
+ }
+ };
+ postTarget.postDelayed(failCallback, TIMEOUT_MS);
+ MockTvInputService.expectSeekToPrevious(postTarget, new Runnable() {
+ @Override
+ public void run() {
+ postTarget.removeCallbacks(failCallback);
+ setPassState(mSeekToItem, true);
+ setPassState(mVerifySeekToPreviousItem, true);
+ mVerifySeekToPreviousItem.setTag(PASSED);
+ if (isPassedState(mVerifySeekToPreviousItem)
+ && isPassedState(mVerifySeekToNextItem)) {
+ getPassButton().setEnabled(true);
+ }
+ }
+ });
+ MockTvInputService.expectSeekToNext(postTarget, new Runnable() {
+ @Override
+ public void run() {
+ postTarget.removeCallbacks(failCallback);
+ setPassState(mSeekToItem, true);
+ setPassState(mVerifySeekToNextItem, true);
+ mVerifySeekToNextItem.setTag(PASSED);
+ if (isPassedState(mVerifySeekToPreviousItem)
+ && isPassedState(mVerifySeekToNextItem)) {
+ getPassButton().setEnabled(true);
+ }
+ }
+ });
+ }
+ if (mTvAppIntent == null) {
+ String[] projection = { TvContract.Channels._ID };
+ try (Cursor cursor = getContentResolver().query(
+ TvContract.buildChannelsUriForInput(MockTvInputService.getInputId(this)),
+ projection, null, null, null)) {
+ if (cursor != null && cursor.moveToNext()) {
+ mTvAppIntent = new Intent(Intent.ACTION_VIEW,
+ TvContract.buildChannelUri(cursor.getLong(0)));
+ }
+ }
+ if (mTvAppIntent == null) {
+ Toast.makeText(this, R.string.tv_channel_not_found, Toast.LENGTH_SHORT).show();
+ return;
+ }
+ }
+ startActivity(mTvAppIntent);
+ }
+
+ @Override
+ protected void createTestItems() {
+ mPauseResumeItem = createUserItem(
+ R.string.tv_time_shift_test_pause_resume,
+ R.string.tv_launch_tv_app, this);
+ setButtonEnabled(mPauseResumeItem, true);
+ mVerifyResumeAfterPauseItem = createAutoItem(
+ R.string.tv_time_shift_test_verify_resume_after_pause);
+ mVerifyPositionTrackingItem = createAutoItem(
+ R.string.tv_time_shift_test_verify_position_tracking);
+ mSetPlaybackParamsItem = createUserItem(
+ R.string.tv_time_shift_test_speed_rate,
+ R.string.tv_launch_tv_app, this);
+ mVerifyRewindItem = createAutoItem(
+ R.string.tv_time_shift_test_verify_rewind);
+ mVerifyFastForwardItem = createAutoItem(
+ R.string.tv_time_shift_test_verify_fast_forward);
+ mSeekToItem = createUserItem(
+ R.string.tv_time_shift_test_seek,
+ R.string.tv_launch_tv_app, this);
+ mVerifySeekToPreviousItem = createAutoItem(
+ R.string.tv_time_shift_test_verify_seek_to_previous);
+ mVerifySeekToNextItem = createAutoItem(
+ R.string.tv_time_shift_test_verify_seek_to_next);
+ }
+
+ @Override
+ protected void setInfoResources() {
+ setInfoResources(R.string.tv_time_shift_test,
+ R.string.tv_time_shift_test_info, -1);
+ }
+
+ private boolean isPassedState(View view) {
+ return ((Boolean) view.getTag()) == PASSED;
+ }
+}
diff --git a/hostsidetests/devicepolicy/app/LauncherTests/Android.mk b/hostsidetests/devicepolicy/app/LauncherTests/Android.mk
index 4517ea2..5f645b6 100644
--- a/hostsidetests/devicepolicy/app/LauncherTests/Android.mk
+++ b/hostsidetests/devicepolicy/app/LauncherTests/Android.mk
@@ -26,6 +26,8 @@
LOCAL_JAVA_LIBRARIES := android.test.runner cts-junit
+LOCAL_STATIC_JAVA_LIBRARIES = android-support-v4 ctstestrunner
+
LOCAL_SDK_VERSION := current
include $(BUILD_CTS_PACKAGE)
diff --git a/hostsidetests/devicepolicy/app/LauncherTests/AndroidManifest.xml b/hostsidetests/devicepolicy/app/LauncherTests/AndroidManifest.xml
index a21b8c2..5ded006 100644
--- a/hostsidetests/devicepolicy/app/LauncherTests/AndroidManifest.xml
+++ b/hostsidetests/devicepolicy/app/LauncherTests/AndroidManifest.xml
@@ -23,7 +23,7 @@
<uses-library android:name="android.test.runner" />
</application>
- <instrumentation android:name="android.test.InstrumentationTestRunner"
+ <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
android:targetPackage="com.android.cts.launchertests"
android:label="Launcher Apps CTS Tests"/>
</manifest>
diff --git a/hostsidetests/devicepolicy/app/LauncherTests/src/com/android/cts/launchertests/LauncherAppsTests.java b/hostsidetests/devicepolicy/app/LauncherTests/src/com/android/cts/launchertests/LauncherAppsTests.java
index 3d44ecd..3bd21d9 100644
--- a/hostsidetests/devicepolicy/app/LauncherTests/src/com/android/cts/launchertests/LauncherAppsTests.java
+++ b/hostsidetests/devicepolicy/app/LauncherTests/src/com/android/cts/launchertests/LauncherAppsTests.java
@@ -38,8 +38,8 @@
import android.os.ResultReceiver;
import android.os.UserHandle;
import android.os.UserManager;
-import android.test.InstrumentationTestCase;
-import android.test.InstrumentationTestRunner;
+import android.support.test.InstrumentationRegistry;
+import android.test.AndroidTestCase;
import android.util.Pair;
import java.util.concurrent.Semaphore;
@@ -49,7 +49,7 @@
/**
* Tests for LauncherApps service
*/
-public class LauncherAppsTests extends InstrumentationTestCase {
+public class LauncherAppsTests extends AndroidTestCase {
public static final String SIMPLE_APP_PACKAGE = "com.android.cts.launcherapps.simpleapp";
@@ -69,7 +69,7 @@
private LauncherApps mLauncherApps;
private UserHandle mUser;
- private InstrumentationTestRunner mInstrumentation;
+ private Instrumentation mInstrumentation;
private Messenger mService;
private Connection mConnection;
private Result mResult;
@@ -78,8 +78,8 @@
@Override
protected void setUp() throws Exception {
super.setUp();
- mInstrumentation = (InstrumentationTestRunner) getInstrumentation();
- Bundle arguments = mInstrumentation.getArguments();
+ mInstrumentation = InstrumentationRegistry.getInstrumentation();
+ Bundle arguments = InstrumentationRegistry.getArguments();
UserManager userManager = (UserManager) mInstrumentation.getContext().getSystemService(
Context.USER_SERVICE);
mUser = getUserHandleArgument(userManager, "testUser", arguments);
diff --git a/hostsidetests/devicepolicy/app/ManagedProfile/AndroidManifest.xml b/hostsidetests/devicepolicy/app/ManagedProfile/AndroidManifest.xml
index 82f6d6d..31e4ad4 100644
--- a/hostsidetests/devicepolicy/app/ManagedProfile/AndroidManifest.xml
+++ b/hostsidetests/devicepolicy/app/ManagedProfile/AndroidManifest.xml
@@ -22,6 +22,7 @@
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.WRITE_CONTACTS" />
+ <uses-permission android:name="android.permission.CAMERA" />
<application>
<uses-library android:name="android.test.runner" />
diff --git a/hostsidetests/devicepolicy/app/ManagedProfile/res/xml/device_admin.xml b/hostsidetests/devicepolicy/app/ManagedProfile/res/xml/device_admin.xml
index 8f39ed0..c3d5c98 100644
--- a/hostsidetests/devicepolicy/app/ManagedProfile/res/xml/device_admin.xml
+++ b/hostsidetests/devicepolicy/app/ManagedProfile/res/xml/device_admin.xml
@@ -15,5 +15,6 @@
<device-admin xmlns:android="http://schemas.android.com/apk/res/android" android:visible="false">
<uses-policies>
<wipe-data />
+ <disable-camera />
</uses-policies>
</device-admin>
diff --git a/hostsidetests/devicepolicy/app/ManagedProfile/res/xml/primary_device_admin.xml b/hostsidetests/devicepolicy/app/ManagedProfile/res/xml/primary_device_admin.xml
index a6aff49..0ec3d1e 100644
--- a/hostsidetests/devicepolicy/app/ManagedProfile/res/xml/primary_device_admin.xml
+++ b/hostsidetests/devicepolicy/app/ManagedProfile/res/xml/primary_device_admin.xml
@@ -16,5 +16,6 @@
<uses-policies>
<reset-password />
<limit-password />
+ <disable-camera />
</uses-policies>
</device-admin>
diff --git a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/CameraPolicyTest.java b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/CameraPolicyTest.java
new file mode 100644
index 0000000..25e0b94
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/CameraPolicyTest.java
@@ -0,0 +1,140 @@
+/*
+ * 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.managedprofile;
+
+import android.app.admin.DevicePolicyManager;
+import android.content.ComponentName;
+import android.content.Context;
+import android.hardware.camera2.CameraManager;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.test.AndroidTestCase;
+
+
+public class CameraPolicyTest extends AndroidTestCase {
+
+ protected static final String MANAGED_PROFILE_PKG = "com.android.cts.managedprofile";
+
+ private static final String PRIMARY_ADMIN_RECEIVER_TEST_CLASS =
+ MANAGED_PROFILE_PKG + ".PrimaryUserDeviceAdmin";
+
+ private static final String MANAGED_PROFILE_ADMIN_RECEIVER_TEST_CLASS =
+ MANAGED_PROFILE_PKG + ".BaseManagedProfileTest$BasicAdminReceiver";
+
+ private DevicePolicyManager mDevicePolicyManager;
+
+ private CameraManager mCameraManager;
+
+ private ComponentName mPrimaryAdminComponent;
+
+ private ComponentName mManagedProfileAdminComponent;
+
+ private HandlerThread mBackgroundThread;
+
+ /**
+ * A {@link Handler} for running tasks in the background.
+ */
+ private Handler mBackgroundHandler;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ mDevicePolicyManager = (DevicePolicyManager) getContext()
+ .getSystemService(Context.DEVICE_POLICY_SERVICE);
+ mCameraManager = (CameraManager) getContext().getSystemService(Context.CAMERA_SERVICE);
+ mPrimaryAdminComponent = new ComponentName(MANAGED_PROFILE_PKG,
+ PRIMARY_ADMIN_RECEIVER_TEST_CLASS);
+ mManagedProfileAdminComponent = new ComponentName(MANAGED_PROFILE_PKG,
+ MANAGED_PROFILE_ADMIN_RECEIVER_TEST_CLASS);
+ startBackgroundThread();
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ stopBackgroundThread();
+ super.tearDown();
+ }
+
+ public void testDisableCameraInManagedProfile() throws Exception {
+ mDevicePolicyManager.setCameraDisabled(mManagedProfileAdminComponent, true);
+ assertTrue(mDevicePolicyManager.getCameraDisabled(mManagedProfileAdminComponent));
+ assertTrue(mDevicePolicyManager.getCameraDisabled(null));
+ checkCanOpenCamera(false);
+ }
+
+ public void testEnableCameraInManagedProfile() throws Exception {
+ mDevicePolicyManager.setCameraDisabled(mManagedProfileAdminComponent, false);
+ assertFalse(mDevicePolicyManager.getCameraDisabled(mManagedProfileAdminComponent));
+ assertFalse(mDevicePolicyManager.getCameraDisabled(null));
+ checkCanOpenCamera(true);
+ }
+
+ public void testDisableCameraInPrimaryProfile() throws Exception {
+ mDevicePolicyManager.setCameraDisabled(mPrimaryAdminComponent, true);
+ assertTrue(mDevicePolicyManager.getCameraDisabled(mPrimaryAdminComponent));
+ assertTrue(mDevicePolicyManager.getCameraDisabled(null));
+ checkCanOpenCamera(false);
+ }
+
+ public void testEnableCameraInPrimaryProfile() throws Exception {
+ mDevicePolicyManager.setCameraDisabled(mPrimaryAdminComponent, false);
+ assertFalse(mDevicePolicyManager.getCameraDisabled(mPrimaryAdminComponent));
+ assertFalse(mDevicePolicyManager.getCameraDisabled(null));
+ checkCanOpenCamera(true);
+ }
+
+ public void testIsCameraEnabledInPrimaryProfile() throws Exception {
+ assertFalse(mDevicePolicyManager.getCameraDisabled(mPrimaryAdminComponent));
+ assertFalse(mDevicePolicyManager.getCameraDisabled(null));
+ checkCanOpenCamera(true);
+ }
+
+ public void testIsCameraEnabledInManagedProfile() throws Exception {
+ assertFalse(mDevicePolicyManager.getCameraDisabled(mManagedProfileAdminComponent));
+ assertFalse(mDevicePolicyManager.getCameraDisabled(null));
+ checkCanOpenCamera(true);
+ }
+
+ private void checkCanOpenCamera(boolean canOpen) {
+ boolean successToOpen = CameraUtils
+ .blockUntilOpenCamera(mCameraManager, mBackgroundHandler);
+ assertEquals(canOpen, successToOpen);
+ }
+
+ /**
+ * Starts a background thread and its {@link Handler}.
+ */
+ private void startBackgroundThread() {
+ mBackgroundThread = new HandlerThread("CameraBackground");
+ mBackgroundThread.start();
+ mBackgroundHandler = new Handler(mBackgroundThread.getLooper());
+ }
+
+ /**
+ * Stops the background thread and its {@link Handler}.
+ */
+ private void stopBackgroundThread() {
+ mBackgroundThread.quitSafely();
+ try {
+ mBackgroundThread.join();
+ mBackgroundThread = null;
+ mBackgroundHandler = null;
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+}
diff --git a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/CameraUtils.java b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/CameraUtils.java
new file mode 100644
index 0000000..516e244
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/CameraUtils.java
@@ -0,0 +1,93 @@
+/*
+ * 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.managedprofile;
+
+import android.hardware.camera2.CameraDevice;
+import android.hardware.camera2.CameraManager;
+import android.os.Handler;
+import android.util.Log;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+/**
+ * A util class to help open camera in a blocking way.
+ */
+class CameraUtils {
+
+ private static final String TAG = "CameraUtils";
+
+ /**
+ * @return true if success to open camera, false otherwise.
+ */
+ public static boolean blockUntilOpenCamera(CameraManager cameraManager, Handler handler) {
+ try {
+ String[] cameraIdList = cameraManager.getCameraIdList();
+ if (cameraIdList == null || cameraIdList.length == 0) {
+ return false;
+ }
+ String cameraId = cameraIdList[0];
+ CameraCallback callback = new CameraCallback();
+ cameraManager.openCamera(cameraId, callback, handler);
+ return callback.waitForResult();
+ } catch (Exception ex) {
+ // No matter what is going wrong, it means fail to open camera.
+ ex.printStackTrace();
+ return false;
+ }
+ }
+
+ /**
+ * {@link CameraDevice.StateCallback} is called when {@link CameraDevice} changes its state.
+ */
+ private static class CameraCallback extends CameraDevice.StateCallback {
+
+ private static final int OPEN_TIMEOUT_SECONDS = 5;
+
+ private final CountDownLatch mLatch = new CountDownLatch(1);
+
+ private AtomicBoolean mResult = new AtomicBoolean(false);
+
+ @Override
+ public void onOpened(CameraDevice cameraDevice) {
+ Log.d(TAG, "open camera successfully");
+ mResult.set(true);
+ if (cameraDevice != null) {
+ cameraDevice.close();
+ }
+ mLatch.countDown();
+ }
+
+ @Override
+ public void onDisconnected(CameraDevice cameraDevice) {
+ Log.d(TAG, "disconnect camera");
+ mLatch.countDown();
+ }
+
+ @Override
+ public void onError(CameraDevice cameraDevice, int error) {
+ Log.e(TAG, "Fail to open camera, error code = " + error);
+ mLatch.countDown();
+ }
+
+ public boolean waitForResult() throws InterruptedException {
+ mLatch.await(OPEN_TIMEOUT_SECONDS, TimeUnit.SECONDS);
+ return mResult.get();
+ }
+ }
+}
diff --git a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/PermissionsTest.java b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/PermissionsTest.java
index 2faf158..1cc2ee2 100644
--- a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/PermissionsTest.java
+++ b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/PermissionsTest.java
@@ -30,6 +30,8 @@
public class PermissionsTest extends BaseManagedProfileTest {
private static final String SIMPLE_APP_PACKAGE_NAME = "com.android.cts.launcherapps.simpleapp";
+ private static final String SIMPLE_PRE_M_APP_PACKAGE_NAME =
+ "com.android.cts.launcherapps.simplepremapp";
private static final String PERMISSION_NAME = "android.permission.READ_CONTACTS";
@Override
@@ -47,8 +49,8 @@
mDevicePolicyManager.setPermissionGrantState(ADMIN_RECEIVER_COMPONENT,
SIMPLE_APP_PACKAGE_NAME, PERMISSION_NAME,
DevicePolicyManager.PERMISSION_GRANT_STATE_DENIED);
- assertTrue(mDevicePolicyManager.getPermissionGrantState(ADMIN_RECEIVER_COMPONENT,
- SIMPLE_APP_PACKAGE_NAME, PERMISSION_NAME) ==
+ assertEquals(mDevicePolicyManager.getPermissionGrantState(ADMIN_RECEIVER_COMPONENT,
+ SIMPLE_APP_PACKAGE_NAME, PERMISSION_NAME),
DevicePolicyManager.PERMISSION_GRANT_STATE_DENIED);
assertEquals(pm.checkPermission(PERMISSION_NAME, SIMPLE_APP_PACKAGE_NAME),
PackageManager.PERMISSION_DENIED);
@@ -56,8 +58,8 @@
mDevicePolicyManager.setPermissionGrantState(ADMIN_RECEIVER_COMPONENT,
SIMPLE_APP_PACKAGE_NAME, PERMISSION_NAME,
DevicePolicyManager.PERMISSION_GRANT_STATE_DEFAULT);
- assertTrue(mDevicePolicyManager.getPermissionGrantState(ADMIN_RECEIVER_COMPONENT,
- SIMPLE_APP_PACKAGE_NAME, PERMISSION_NAME) ==
+ assertEquals(mDevicePolicyManager.getPermissionGrantState(ADMIN_RECEIVER_COMPONENT,
+ SIMPLE_APP_PACKAGE_NAME, PERMISSION_NAME),
DevicePolicyManager.PERMISSION_GRANT_STATE_DEFAULT);
// Should stay denied
assertEquals(pm.checkPermission(PERMISSION_NAME, SIMPLE_APP_PACKAGE_NAME),
@@ -66,8 +68,8 @@
mDevicePolicyManager.setPermissionGrantState(ADMIN_RECEIVER_COMPONENT,
SIMPLE_APP_PACKAGE_NAME, PERMISSION_NAME,
DevicePolicyManager.PERMISSION_GRANT_STATE_GRANTED);
- assertTrue(mDevicePolicyManager.getPermissionGrantState(ADMIN_RECEIVER_COMPONENT,
- SIMPLE_APP_PACKAGE_NAME, PERMISSION_NAME) ==
+ assertEquals(mDevicePolicyManager.getPermissionGrantState(ADMIN_RECEIVER_COMPONENT,
+ SIMPLE_APP_PACKAGE_NAME, PERMISSION_NAME),
DevicePolicyManager.PERMISSION_GRANT_STATE_GRANTED);
assertEquals(pm.checkPermission(PERMISSION_NAME, SIMPLE_APP_PACKAGE_NAME),
PackageManager.PERMISSION_GRANTED);
@@ -75,8 +77,8 @@
mDevicePolicyManager.setPermissionGrantState(ADMIN_RECEIVER_COMPONENT,
SIMPLE_APP_PACKAGE_NAME, PERMISSION_NAME,
DevicePolicyManager.PERMISSION_GRANT_STATE_DEFAULT);
- assertTrue(mDevicePolicyManager.getPermissionGrantState(ADMIN_RECEIVER_COMPONENT,
- SIMPLE_APP_PACKAGE_NAME, PERMISSION_NAME) ==
+ assertEquals(mDevicePolicyManager.getPermissionGrantState(ADMIN_RECEIVER_COMPONENT,
+ SIMPLE_APP_PACKAGE_NAME, PERMISSION_NAME),
DevicePolicyManager.PERMISSION_GRANT_STATE_DEFAULT);
// Should stay granted
assertEquals(pm.checkPermission(PERMISSION_NAME, SIMPLE_APP_PACKAGE_NAME),
@@ -97,4 +99,29 @@
assertEquals(mDevicePolicyManager.getPermissionPolicy(ADMIN_RECEIVER_COMPONENT),
DevicePolicyManager.PERMISSION_POLICY_PROMPT);
}
+
+ public void testPermissionGrantStatePreMApp() {
+ // These tests are to make sure that pre-M apps are not granted runtime permissions
+ // by a profile owner
+ PackageManager pm = mContext.getPackageManager();
+ assertFalse(mDevicePolicyManager.setPermissionGrantState(ADMIN_RECEIVER_COMPONENT,
+ SIMPLE_PRE_M_APP_PACKAGE_NAME, PERMISSION_NAME,
+ DevicePolicyManager.PERMISSION_GRANT_STATE_DENIED));
+ assertEquals(mDevicePolicyManager.getPermissionGrantState(ADMIN_RECEIVER_COMPONENT,
+ SIMPLE_PRE_M_APP_PACKAGE_NAME, PERMISSION_NAME),
+ DevicePolicyManager.PERMISSION_GRANT_STATE_DEFAULT);
+ // Install time permissions should always be granted
+ assertEquals(pm.checkPermission(PERMISSION_NAME, SIMPLE_PRE_M_APP_PACKAGE_NAME),
+ PackageManager.PERMISSION_GRANTED);
+
+ mDevicePolicyManager.setPermissionGrantState(ADMIN_RECEIVER_COMPONENT,
+ SIMPLE_PRE_M_APP_PACKAGE_NAME, PERMISSION_NAME,
+ DevicePolicyManager.PERMISSION_GRANT_STATE_GRANTED);
+ assertEquals(mDevicePolicyManager.getPermissionGrantState(ADMIN_RECEIVER_COMPONENT,
+ SIMPLE_PRE_M_APP_PACKAGE_NAME, PERMISSION_NAME),
+ DevicePolicyManager.PERMISSION_GRANT_STATE_DEFAULT);
+ // Install time permissions should always be granted
+ assertEquals(pm.checkPermission(PERMISSION_NAME, SIMPLE_PRE_M_APP_PACKAGE_NAME),
+ PackageManager.PERMISSION_GRANTED);
+ }
}
diff --git a/hostsidetests/devicepolicy/app/SimplePreMApp/Android.mk b/hostsidetests/devicepolicy/app/SimplePreMApp/Android.mk
new file mode 100644
index 0000000..7460552
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/SimplePreMApp/Android.mk
@@ -0,0 +1,33 @@
+# 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.
+
+# This app is meant for testing device policy permission APIs on legacy apps (pre-M)
+
+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_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_PACKAGE_NAME := CtsSimplePreMApp
+
+LOCAL_SDK_VERSION := 21
+
+include $(BUILD_CTS_PACKAGE)
diff --git a/hostsidetests/devicepolicy/app/SimplePreMApp/AndroidManifest.xml b/hostsidetests/devicepolicy/app/SimplePreMApp/AndroidManifest.xml
new file mode 100644
index 0000000..85962a1
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/SimplePreMApp/AndroidManifest.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * 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.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.cts.launcherapps.simplepremapp">
+
+ <uses-sdk android:targetSdkVersion="21"/>
+
+ <uses-permission android:name="android.permission.READ_CONTACTS"/>
+
+ <application>
+ <activity android:name=".SimpleActivity" >
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+ </application>
+
+</manifest>
+
diff --git a/hostsidetests/devicepolicy/app/SimplePreMApp/src/com/android/cts/launcherapps/simplepremapp/SimpleActivity.java b/hostsidetests/devicepolicy/app/SimplePreMApp/src/com/android/cts/launcherapps/simplepremapp/SimpleActivity.java
new file mode 100644
index 0000000..0dba719
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/SimplePreMApp/src/com/android/cts/launcherapps/simplepremapp/SimpleActivity.java
@@ -0,0 +1,39 @@
+/*
+ * 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.launcherapps.simplepremapp;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Bundle;
+import android.util.Log;
+
+import java.lang.Override;
+
+/**
+ * A simple activity to install for various users to test LauncherApps.
+ */
+public class SimpleActivity extends Activity {
+
+ private static final String TAG = "SimpleActivity";
+
+ @Override
+ public void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+ Log.i(TAG, "Created for user " + android.os.Process.myUserHandle());
+ }
+
+}
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ManagedProfileTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ManagedProfileTest.java
index 255c49e..3f0805c 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ManagedProfileTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ManagedProfileTest.java
@@ -31,6 +31,7 @@
private static final String MANAGED_PROFILE_APK = "CtsManagedProfileApp.apk";
private static final String SIMPLE_APP_APK = "CtsSimpleApp.apk";
+ private static final String SIMPLE_PRE_M_APP_APK = "CtsSimplePreMApp.apk";
private static final String INTENT_SENDER_PKG = "com.android.cts.intent.sender";
private static final String INTENT_SENDER_APK = "CtsIntentSenderApp.apk";
@@ -45,6 +46,7 @@
MANAGED_PROFILE_PKG + ".BaseManagedProfileTest$BasicAdminReceiver";
private static final String FEATURE_BLUETOOTH = "android.hardware.bluetooth";
+ private static final String FEATURE_CAMERA = "android.hardware.camera";
private int mUserId;
@Override
@@ -257,6 +259,52 @@
"testGetRemoteDevice", mUserId));
}
+ public void testCameraPolicy() throws Exception {
+ boolean hasCamera = hasDeviceFeature(FEATURE_CAMERA);
+ if (!mHasFeature || !hasCamera) {
+ return;
+ }
+ try {
+ setDeviceAdmin(MANAGED_PROFILE_PKG + "/.PrimaryUserDeviceAdmin");
+
+ // Disable managed profile camera.
+ assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".CameraPolicyTest",
+ "testDisableCameraInManagedProfile",
+ mUserId));
+ assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".CameraPolicyTest",
+ "testIsCameraEnabledInPrimaryProfile",
+ 0));
+
+ // Enable managed profile camera.
+ assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".CameraPolicyTest",
+ "testEnableCameraInManagedProfile",
+ mUserId));
+ assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".CameraPolicyTest",
+ "testIsCameraEnabledInPrimaryProfile",
+ 0));
+
+ // Disable primary profile camera.
+ assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".CameraPolicyTest",
+ "testDisableCameraInPrimaryProfile",
+ 0));
+ assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".CameraPolicyTest",
+ "testIsCameraEnabledInManagedProfile",
+ mUserId));
+
+ // Enable primary profile camera.
+ assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".CameraPolicyTest",
+ "testEnableCameraInPrimaryProfile",
+ 0));
+ assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".CameraPolicyTest",
+ "testIsCameraEnabledInManagedProfile",
+ mUserId));
+ } finally {
+ final String adminHelperClass = ".PrimaryUserAdminHelper";
+ assertTrue("Clear device admin failed", runDeviceTestsAsUser(MANAGED_PROFILE_PKG,
+ adminHelperClass, "testClearDeviceAdmin", 0 /* user 0 */));
+ }
+ }
+
public void testManagedContacts() throws Exception {
if (!mHasFeature) {
return;
@@ -417,11 +465,20 @@
if (!mHasFeature) {
return;
}
- installApp(SIMPLE_APP_APK);
+ installAppAsUser(SIMPLE_APP_APK, mUserId);
assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".PermissionsTest",
"testPermissionGrantState", mUserId));
}
+ public void testPermissionGrantPreMApp() throws Exception {
+ if (!mHasFeature) {
+ return;
+ }
+ installAppAsUser(SIMPLE_PRE_M_APP_APK, mUserId);
+ assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".PermissionsTest",
+ "testPermissionGrantStatePreMApp", mUserId));
+ }
+
private void disableActivityForUser(String activityName, int userId)
throws DeviceNotAvailableException {
String command = "am start -W --user " + userId
diff --git a/libs/testserver/src/android/webkit/cts/CtsTestServer.java b/libs/testserver/src/android/webkit/cts/CtsTestServer.java
index de8a30d..de88f3b 100644
--- a/libs/testserver/src/android/webkit/cts/CtsTestServer.java
+++ b/libs/testserver/src/android/webkit/cts/CtsTestServer.java
@@ -1032,7 +1032,7 @@
conn.receiveRequestEntity( (HttpEntityEnclosingRequest) request);
}
- mExecutorService.submit(new HandleResponseTask(conn, request));
+ mExecutorService.execute(new HandleResponseTask(conn, request));
} catch (IOException e) {
// normal during shutdown, ignore
Log.w(TAG, e);
@@ -1063,7 +1063,7 @@
return path.equals(SHUTDOWN_PREFIX);
}
- private class HandleResponseTask implements Callable<Void> {
+ private class HandleResponseTask implements Runnable {
private DefaultHttpServerConnection mConnection;
@@ -1076,12 +1076,15 @@
}
@Override
- public Void call() throws Exception {
- HttpResponse response = mServer.getResponse(mRequest);
- mConnection.sendResponseHeader(response);
- mConnection.sendResponseEntity(response);
- mConnection.close();
- return null;
+ public void run() {
+ try {
+ HttpResponse response = mServer.getResponse(mRequest);
+ mConnection.sendResponseHeader(response);
+ mConnection.sendResponseEntity(response);
+ mConnection.close();
+ } catch (Exception e) {
+ Log.e(TAG, "Error handling request:", e);
+ }
}
}
}
diff --git a/libs/vogar-expect/src/vogar/ExpectationStore.java b/libs/vogar-expect/src/vogar/ExpectationStore.java
index 1818889..090322d 100644
--- a/libs/vogar-expect/src/vogar/ExpectationStore.java
+++ b/libs/vogar-expect/src/vogar/ExpectationStore.java
@@ -152,7 +152,7 @@
private void readExpectation(JsonReader reader, ModeId mode) throws IOException {
boolean isFailure = false;
- Result result = Result.SUCCESS;
+ Result result = Result.EXEC_FAILED;
Pattern pattern = MATCH_ALL_PATTERN;
Set<String> names = new LinkedHashSet<String>();
Set<String> tags = new LinkedHashSet<String>();
@@ -170,6 +170,12 @@
} else if (name.equals("names")) {
readStrings(reader, names);
} else if (name.equals("failure")) {
+ // isFailure is somewhat arbitrarily keyed on the existence of a "failure"
+ // element instead of looking at the "result" field. There are only about 5
+ // expectations in our entire expectation store that have this tag.
+ //
+ // TODO: Get rid of it and the "failures" map and just use the outcomes
+ // map for everything. Both uses seem useless.
isFailure = true;
names.add(reader.nextString());
} else if (name.equals("pattern")) {
diff --git a/tests/expectations/knownfailures.txt b/tests/expectations/knownfailures.txt
index 88e5da2..86fe4af 100644
--- a/tests/expectations/knownfailures.txt
+++ b/tests/expectations/knownfailures.txt
@@ -172,5 +172,12 @@
"android.hardware.camera2.cts.ImageReaderTest#testAllOutputYUVResolutions"
],
bug: 18689511
+},
+{
+ description: "The new prepare performance test is not yet passing on all devices",
+ names: [
+ "android.hardware.camera2.cts.SurfaceViewPreviewTest#testPreparePerformance"
+ ],
+ bug: 17989532
}
]
diff --git a/tests/tests/accounts/src/android/accounts/cts/AccountManagerTest.java b/tests/tests/accounts/src/android/accounts/cts/AccountManagerTest.java
index 0e84fb9..4350191 100644
--- a/tests/tests/accounts/src/android/accounts/cts/AccountManagerTest.java
+++ b/tests/tests/accounts/src/android/accounts/cts/AccountManagerTest.java
@@ -1452,27 +1452,14 @@
}
/**
- * Tests the setting of lastAuthenticatedTime on accountAuthenticated being
- * successful.
- */
- public void testLastAuthenticatedTimeAfterAccountAuthenticated() throws IOException,
- AuthenticatorException, OperationCanceledException {
- long accountAddTime = addAccountAndReturnAccountAddedTime(ACCOUNT, ACCOUNT_PASSWORD);
- mockAuthenticator.callAccountAuthenticated();
- long accountAuthenticatedTime = getLastAuthenticatedTime(ACCOUNT);
- assertTrue(accountAuthenticatedTime > accountAddTime);
- }
-
- /**
- * Tests the setting of lastAuthenticatedTime on setPassword being
- * successful.
+ * LastAuthenticatedTime on setPassword should not be disturbed.
*/
public void testLastAuthenticatedTimeAfterSetPassword() throws IOException,
AuthenticatorException, OperationCanceledException {
long accountAddTime = addAccountAndReturnAccountAddedTime(ACCOUNT, ACCOUNT_PASSWORD);
mockAuthenticator.callSetPassword();
long setPasswordTime = getLastAuthenticatedTime(ACCOUNT);
- assertTrue(setPasswordTime > accountAddTime);
+ assertTrue(setPasswordTime == accountAddTime);
}
/**
@@ -1947,7 +1934,14 @@
private long addAccountAndReturnAccountAddedTime(Account account, String password)
throws OperationCanceledException, AuthenticatorException, IOException {
- addAccountExplicitly(account, password, null /* userData */);
+ addAccount(am,
+ ACCOUNT_TYPE,
+ AUTH_TOKEN_TYPE,
+ REQUIRED_FEATURES,
+ OPTIONS_BUNDLE,
+ mActivity,
+ null /* callback */,
+ null /* handler */);
return getLastAuthenticatedTime(account);
}
diff --git a/tests/tests/accounts/src/android/accounts/cts/MockAccountAuthenticator.java b/tests/tests/accounts/src/android/accounts/cts/MockAccountAuthenticator.java
index faebd53..c1b08de 100644
--- a/tests/tests/accounts/src/android/accounts/cts/MockAccountAuthenticator.java
+++ b/tests/tests/accounts/src/android/accounts/cts/MockAccountAuthenticator.java
@@ -151,6 +151,8 @@
this.mAuthTokenType = authTokenType;
this.mRequiredFeatures = requiredFeatures;
this.mOptionsAddAccount = options;
+ AccountManager am = AccountManager.get(mContext);
+ am.addAccountExplicitly(AccountManagerTest.ACCOUNT, "fakePassword", null);
return createResultBundle();
}
diff --git a/tests/tests/graphics/src/android/graphics/cts/PaintTest.java b/tests/tests/graphics/src/android/graphics/cts/PaintTest.java
index 8d96d91..80e0253 100644
--- a/tests/tests/graphics/src/android/graphics/cts/PaintTest.java
+++ b/tests/tests/graphics/src/android/graphics/cts/PaintTest.java
@@ -809,7 +809,6 @@
}
public void testReset() {
-
Paint p = new Paint();
ColorFilter c = new ColorFilter();
MaskFilter m = new MaskFilter();
@@ -845,7 +844,6 @@
assertEquals(null, p.getShader());
assertEquals(null, p.getTypeface());
assertEquals(null, p.getXfermode());
-
}
public void testSetLinearText() {
@@ -930,6 +928,20 @@
assertMeasureText(text, textChars, textSpan, 4, 7, widths[4] + widths[5] + widths[6]);
}
+ public void testMeasureTextContext() {
+ Paint p = new Paint();
+ // Arabic LAM, which is different width depending on context
+ String shortString = "\u0644";
+ String longString = "\u0644\u0644\u0644";
+ char[] longChars = longString.toCharArray();
+ SpannedString longSpanned = new SpannedString(longString);
+ float width = p.measureText(shortString);
+ // Verify that measurement of substring is consistent no matter what surrounds it.
+ assertMeasureText(longString, longChars, longSpanned, 0, 1, width);
+ assertMeasureText(longString, longChars, longSpanned, 1, 2, width);
+ assertMeasureText(longString, longChars, longSpanned, 2, 3, width);
+ }
+
public void testMeasureTextWithLongText() {
// This test is not compatible with 4.0.3
if ("4.0.3".equals(Build.VERSION.RELEASE)) {
@@ -1184,6 +1196,51 @@
}
}
+ public void testGetRunAdvance_nonzeroIndex() {
+ Paint p = new Paint();
+ final String text = "Android powers hundreds of millions of mobile " +
+ "devices in more than 190 countries around the world. It's" +
+ "the largest installed base of any mobile platform and" +
+ "growing fast—every day another million users power up their" +
+ "Android devices for the first time and start looking for" +
+ "apps, games, and other digital content.";
+ // Test offset index does not affect width.
+ final float widthAndroidFirst = p.getRunAdvance(
+ text, 0, 7, 0, text.length(), false, 7);
+ final float widthAndroidSecond = p.getRunAdvance(
+ text, 215, 222, 0, text.length(), false, 222);
+ assertTrue(Math.abs(widthAndroidFirst - widthAndroidSecond) < 1);
+ }
+
+ public void testGetRunAdvance_glyphDependingContext() {
+ Paint p = new Paint();
+ // Test the context change the character shape.
+ // First character should be isolated form because the context ends at index 1.
+ final float isolatedFormWidth = p.getRunAdvance("\u0644\u0644", 0, 1, 0, 1, true, 1);
+ // First character should be initial form because the context ends at index 2.
+ final float initialFormWidth = p.getRunAdvance("\u0644\u0644", 0, 1, 0, 2, true, 1);
+ assertTrue(isolatedFormWidth > initialFormWidth);
+ }
+
+ public void testGetRunAdvance_arabic() {
+ Paint p = new Paint();
+ // Test total width is equals to sum of each character's width.
+ // "What is Unicode?" in Arabic.
+ final String text =
+ "\u0645\u0627\u0020\u0647\u064A\u0020\u0627\u0644\u0634" +
+ "\u0641\u0631\u0629\u0020\u0627\u0644\u0645\u0648\u062D" +
+ "\u062F\u0629\u0020\u064A\u0648\u0646\u064A\u0643\u0648" +
+ "\u062F\u061F";
+ final float totalWidth = p.getRunAdvance(
+ text, 0, text.length(), 0, text.length(), true, text.length());
+ float sumOfCharactersWidth = 0;
+ for (int i = 0; i < text.length(); i++) {
+ sumOfCharactersWidth += p.getRunAdvance(
+ text, i, i + 1, 0, text.length(), true, i + 1);
+ }
+ assertTrue(Math.abs(totalWidth - sumOfCharactersWidth) < 1);
+ }
+
public void testGetOffsetForAdvance() {
Paint p = new Paint();
{
diff --git a/tests/tests/hardware/src/android/hardware/camera2/cts/Camera2SurfaceViewCtsActivity.java b/tests/tests/hardware/src/android/hardware/camera2/cts/Camera2SurfaceViewCtsActivity.java
index 936883e..1881774 100644
--- a/tests/tests/hardware/src/android/hardware/camera2/cts/Camera2SurfaceViewCtsActivity.java
+++ b/tests/tests/hardware/src/android/hardware/camera2/cts/Camera2SurfaceViewCtsActivity.java
@@ -19,6 +19,7 @@
import android.app.Activity;
import android.os.Bundle;
import android.os.ConditionVariable;
+import android.os.SystemClock;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
@@ -57,7 +58,7 @@
int waitTimeMs = timeOutMs;
boolean changeSucceeded = false;
while (!changeSucceeded && waitTimeMs > 0) {
- long startTimeMs = System.currentTimeMillis();
+ long startTimeMs = SystemClock.elapsedRealtime();
changeSucceeded = surfaceChangedDone.block(waitTimeMs);
if (!changeSucceeded) {
Log.e(TAG, "Wait for surface change timed out after " + timeOutMs + " ms");
@@ -72,7 +73,7 @@
// again.
changeSucceeded = false;
}
- waitTimeMs -= (System.currentTimeMillis() - startTimeMs);
+ waitTimeMs -= (SystemClock.elapsedRealtime() - startTimeMs);
}
// Couldn't get expected surface size change.
diff --git a/tests/tests/hardware/src/android/hardware/camera2/cts/CameraTestUtils.java b/tests/tests/hardware/src/android/hardware/camera2/cts/CameraTestUtils.java
index b744686..ed8f7b7 100644
--- a/tests/tests/hardware/src/android/hardware/camera2/cts/CameraTestUtils.java
+++ b/tests/tests/hardware/src/android/hardware/camera2/cts/CameraTestUtils.java
@@ -947,6 +947,44 @@
Size[] availableSizes = configMap.getOutputSizes(format);
assertArrayNotEmpty(availableSizes, "availableSizes should not be empty for format: "
+ format);
+ Size[] highResAvailableSizes = configMap.getHighResolutionOutputSizes(format);
+ if (highResAvailableSizes != null && highResAvailableSizes.length > 0) {
+ Size[] allSizes = new Size[availableSizes.length + highResAvailableSizes.length];
+ System.arraycopy(availableSizes, 0, allSizes, 0,
+ availableSizes.length);
+ System.arraycopy(highResAvailableSizes, 0, allSizes, availableSizes.length,
+ highResAvailableSizes.length);
+ availableSizes = allSizes;
+ }
+ if (VERBOSE) Log.v(TAG, "Supported sizes are: " + Arrays.deepToString(availableSizes));
+ return availableSizes;
+ }
+
+ /**
+ * Get the available output sizes for the given class.
+ *
+ */
+ public static Size[] getSupportedSizeForClass(Class klass, String cameraId,
+ CameraManager cameraManager) throws CameraAccessException {
+ CameraCharacteristics properties = cameraManager.getCameraCharacteristics(cameraId);
+ assertNotNull("Can't get camera characteristics!", properties);
+ if (VERBOSE) {
+ Log.v(TAG, "get camera characteristics for camera: " + cameraId);
+ }
+ StreamConfigurationMap configMap =
+ properties.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
+ Size[] availableSizes = configMap.getOutputSizes(klass);
+ assertArrayNotEmpty(availableSizes, "availableSizes should not be empty for class: "
+ + klass);
+ Size[] highResAvailableSizes = configMap.getHighResolutionOutputSizes(ImageFormat.PRIVATE);
+ if (highResAvailableSizes != null && highResAvailableSizes.length > 0) {
+ Size[] allSizes = new Size[availableSizes.length + highResAvailableSizes.length];
+ System.arraycopy(availableSizes, 0, allSizes, 0,
+ availableSizes.length);
+ System.arraycopy(highResAvailableSizes, 0, allSizes, availableSizes.length,
+ highResAvailableSizes.length);
+ availableSizes = allSizes;
+ }
if (VERBOSE) Log.v(TAG, "Supported sizes are: " + Arrays.deepToString(availableSizes));
return availableSizes;
}
@@ -970,10 +1008,9 @@
*/
static public List<Size> getSupportedPreviewSizes(String cameraId,
CameraManager cameraManager, Size bound) throws CameraAccessException {
- CameraCharacteristics props = cameraManager.getCameraCharacteristics(cameraId);
- StreamConfigurationMap config =
- props.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
- Size[] rawSizes = config.getOutputSizes(android.view.SurfaceHolder.class);
+
+ Size[] rawSizes = getSupportedSizeForClass(android.view.SurfaceHolder.class, cameraId,
+ cameraManager);
assertArrayNotEmpty(rawSizes,
"Available sizes for SurfaceHolder class should not be empty");
if (VERBOSE) {
@@ -1059,10 +1096,9 @@
*/
static public List<Size> getSupportedVideoSizes(String cameraId,
CameraManager cameraManager, Size bound) throws CameraAccessException {
- CameraCharacteristics props = cameraManager.getCameraCharacteristics(cameraId);
- StreamConfigurationMap config =
- props.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
- Size[] rawSizes = config.getOutputSizes(android.media.MediaRecorder.class);
+
+ Size[] rawSizes = getSupportedSizeForClass(android.media.MediaRecorder.class,
+ cameraId, cameraManager);
assertArrayNotEmpty(rawSizes,
"Available sizes for MediaRecorder class should not be empty");
if (VERBOSE) {
diff --git a/tests/tests/hardware/src/android/hardware/camera2/cts/DngCreatorTest.java b/tests/tests/hardware/src/android/hardware/camera2/cts/DngCreatorTest.java
index 8184226..0da0ce7 100644
--- a/tests/tests/hardware/src/android/hardware/camera2/cts/DngCreatorTest.java
+++ b/tests/tests/hardware/src/android/hardware/camera2/cts/DngCreatorTest.java
@@ -115,19 +115,7 @@
continue;
}
- Size[] targetCaptureSizes =
- mStaticInfo.getAvailableSizesForFormatChecked(ImageFormat.RAW_SENSOR,
- StaticMetadata.StreamDirection.Output);
-
- assertTrue("No capture sizes available for RAW format!",
- targetCaptureSizes.length != 0);
- Rect activeArray = mStaticInfo.getActiveArraySizeChecked();
- Size activeArraySize = new Size(activeArray.width(), activeArray.height());
- assertTrue("Missing ActiveArraySize", activeArray.width() > 0 &&
- activeArray.height() > 0);
- // TODO: Allow PixelArraySize also.
- assertArrayContains("Available sizes for RAW format must include ActiveArraySize",
- targetCaptureSizes, activeArraySize);
+ Size activeArraySize = mStaticInfo.getRawDimensChecked();
// Create capture image reader
CameraTestUtils.SimpleImageReaderListener captureListener
@@ -202,19 +190,7 @@
continue;
}
- Size[] targetCaptureSizes =
- mStaticInfo.getAvailableSizesForFormatChecked(ImageFormat.RAW_SENSOR,
- StaticMetadata.StreamDirection.Output);
-
- assertTrue("No capture sizes available for RAW format!",
- targetCaptureSizes.length != 0);
- Rect activeArray = mStaticInfo.getActiveArraySizeChecked();
- Size activeArraySize = new Size(activeArray.width(), activeArray.height());
- assertTrue("Missing ActiveArraySize", activeArray.width() > 0 &&
- activeArray.height() > 0);
- // TODO: Allow PixelArraySize also.
- assertArrayContains("Available sizes for RAW format must include ActiveArraySize",
- targetCaptureSizes, activeArraySize);
+ Size activeArraySize = mStaticInfo.getRawDimensChecked();
Size[] targetPreviewSizes =
mStaticInfo.getAvailableSizesForFormatChecked(ImageFormat.YUV_420_888,
@@ -322,19 +298,7 @@
continue;
}
- Size[] targetCaptureSizes =
- mStaticInfo.getAvailableSizesForFormatChecked(ImageFormat.RAW_SENSOR,
- StaticMetadata.StreamDirection.Output);
-
- assertTrue("No capture sizes available for RAW format!",
- targetCaptureSizes.length != 0);
- Rect activeArray = mStaticInfo.getActiveArraySizeChecked();
- Size activeArraySize = new Size(activeArray.width(), activeArray.height());
- assertTrue("Active array has invalid size!", activeArray.width() > 0 &&
- activeArray.height() > 0);
- // TODO: Allow PixelArraySize also.
- assertArrayContains("Available sizes for RAW format must include ActiveArraySize",
- targetCaptureSizes, activeArraySize);
+ Size activeArraySize = mStaticInfo.getRawDimensChecked();
// Get largest jpeg size
Size[] targetJpegSizes =
@@ -369,8 +333,8 @@
Bitmap.Config.ARGB_8888);
Size rawBitmapSize = new Size(rawBitmap.getWidth(), rawBitmap.getHeight());
- assertTrue("Raw bitmap size must be equal to active array size.",
- rawBitmapSize.equals(activeArraySize));
+ assertTrue("Raw bitmap size must be equal to either pre-correction active array" +
+ " size or pixel array size.", rawBitmapSize.equals(activeArraySize));
byte[] rawPlane = new byte[raw.getPlanes()[0].getRowStride() * raw.getHeight()];
diff --git a/tests/tests/hardware/src/android/hardware/camera2/cts/ExtendedCameraCharacteristicsTest.java b/tests/tests/hardware/src/android/hardware/camera2/cts/ExtendedCameraCharacteristicsTest.java
index 695df10..99f7091 100644
--- a/tests/tests/hardware/src/android/hardware/camera2/cts/ExtendedCameraCharacteristicsTest.java
+++ b/tests/tests/hardware/src/android/hardware/camera2/cts/ExtendedCameraCharacteristicsTest.java
@@ -373,7 +373,7 @@
/**
* Test values for static metadata used by the BURST capability.
*/
- public void testStaticBurstCharacteristics() {
+ public void testStaticBurstCharacteristics() throws Exception {
int counter = 0;
final float SIZE_ERROR_MARGIN = 0.03f;
for (CameraCharacteristics c : mCharacteristics) {
@@ -404,7 +404,9 @@
Size maxSlowYuvSize = CameraTestUtils.getMaxSize(slowYuvSizes);
maxYuvSize = CameraTestUtils.getMaxSize(new Size[]{maxYuvSize, maxSlowYuvSize});
}
- Size maxJpegSize = CameraTestUtils.getMaxSize(config.getOutputSizes(ImageFormat.JPEG));
+
+ Size maxJpegSize = CameraTestUtils.getMaxSize(CameraTestUtils.getSupportedSizeForFormat(
+ ImageFormat.JPEG, mIds[counter], mCameraManager));
boolean haveMaxYuv = maxYuvSize != null ?
(maxJpegSize.getWidth() <= maxYuvSize.getWidth() &&
@@ -599,7 +601,7 @@
/**
* Cross-check StreamConfigurationMap output
*/
- public void testStreamConfigurationMap() {
+ public void testStreamConfigurationMap() throws Exception {
int counter = 0;
for (CameraCharacteristics c : mCharacteristics) {
Log.i(TAG, "testStreamConfigurationMap: Testing camera ID " + mIds[counter]);
@@ -754,7 +756,8 @@
SurfaceTexture st = new SurfaceTexture(1);
Surface surf = new Surface(st);
- Size[] opaqueSizes = config.getOutputSizes(SurfaceTexture.class);
+ Size[] opaqueSizes = CameraTestUtils.getSupportedSizeForClass(SurfaceTexture.class,
+ mIds[counter], mCameraManager);
assertTrue("Opaque format has no sizes listed",
opaqueSizes.length > 0);
for (Size size : opaqueSizes) {
@@ -798,7 +801,8 @@
* Test high speed capability and cross-check the high speed sizes and fps ranges from
* the StreamConfigurationMap.
*/
- public void testConstrainedHighSpeedCapability() {
+ public void testConstrainedHighSpeedCapability() throws Exception {
+ int counter = 0;
for (CameraCharacteristics c : mCharacteristics) {
int[] capabilities = CameraTestUtils.getValueNotNull(
c, CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES);
@@ -809,7 +813,8 @@
c, CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
List<Size> highSpeedSizes = Arrays.asList(config.getHighSpeedVideoSizes());
assertTrue("High speed sizes shouldn't be empty", highSpeedSizes.size() > 0);
- Size[] allSizes = config.getOutputSizes(ImageFormat.PRIVATE);
+ Size[] allSizes = CameraTestUtils.getSupportedSizeForFormat(ImageFormat.PRIVATE,
+ mIds[counter], mCameraManager);
assertTrue("Normal size for PRIVATE format shouldn't be null or empty",
allSizes != null && allSizes.length > 0);
for (Size size: highSpeedSizes) {
@@ -869,6 +874,7 @@
}
}
}
+ counter++;
}
}
diff --git a/tests/tests/hardware/src/android/hardware/camera2/cts/StaticMetadataTest.java b/tests/tests/hardware/src/android/hardware/camera2/cts/StaticMetadataTest.java
index e876d1b..0bc74b3 100644
--- a/tests/tests/hardware/src/android/hardware/camera2/cts/StaticMetadataTest.java
+++ b/tests/tests/hardware/src/android/hardware/camera2/cts/StaticMetadataTest.java
@@ -86,10 +86,6 @@
mCollector.expectTrue("Full device must contain BURST_CAPTURE capability",
availableCaps.contains(REQUEST_AVAILABLE_CAPABILITIES_BURST_CAPTURE));
- // Max resolution fps must be >= 20.
- mCollector.expectTrue("Full device must support at least 20fps for max resolution",
- getFpsForMaxSize(id) >= MIN_FPS_FOR_FULL_DEVICE);
-
// Need support per frame control
mCollector.expectTrue("Full device must support per frame control",
mStaticInfo.isPerFrameControlSupported());
diff --git a/tests/tests/hardware/src/android/hardware/camera2/cts/StillCaptureTest.java b/tests/tests/hardware/src/android/hardware/camera2/cts/StillCaptureTest.java
index 73cfaf7..ee4ddd9 100644
--- a/tests/tests/hardware/src/android/hardware/camera2/cts/StillCaptureTest.java
+++ b/tests/tests/hardware/src/android/hardware/camera2/cts/StillCaptureTest.java
@@ -663,16 +663,7 @@
*/
private void rawCaptureTestByCamera() throws Exception {
Size maxPreviewSz = mOrderedPreviewSizes.get(0);
- Size[] rawSizes = mStaticInfo.getRawOutputSizesChecked();
-
- assertTrue("No capture sizes available for RAW format!",
- rawSizes.length != 0);
- Rect activeArray = mStaticInfo.getActiveArraySizeChecked();
- Size size = new Size(activeArray.width(), activeArray.height());
- assertTrue("Missing ActiveArraySize", activeArray.width() > 0 &&
- activeArray.height() > 0);
- assertArrayContains("Available sizes for RAW format must include ActiveArraySize",
- rawSizes, size);
+ Size size = mStaticInfo.getRawDimensChecked();
// Prepare raw capture and start preview.
CaptureRequest.Builder previewBuilder =
@@ -711,20 +702,12 @@
private void fullRawCaptureTestByCamera() throws Exception {
Size maxPreviewSz = mOrderedPreviewSizes.get(0);
Size maxStillSz = mOrderedStillSizes.get(0);
- Size[] rawSizes = mStaticInfo.getRawOutputSizesChecked();
SimpleCaptureCallback resultListener = new SimpleCaptureCallback();
SimpleImageReaderListener jpegListener = new SimpleImageReaderListener();
SimpleImageReaderListener rawListener = new SimpleImageReaderListener();
- assertTrue("No capture sizes available for RAW format!",
- rawSizes.length != 0);
- Rect activeArray = mStaticInfo.getActiveArraySizeChecked();
- Size size = new Size(activeArray.width(), activeArray.height());
- assertTrue("Missing ActiveArraySize", activeArray.width() > 0 &&
- activeArray.height() > 0);
- assertArrayContains("Available sizes for RAW format must include ActiveArraySize",
- rawSizes, size);
+ Size size = mStaticInfo.getRawDimensChecked();
if (VERBOSE) {
Log.v(TAG, "Testing multi capture with size " + size.toString()
diff --git a/tests/tests/hardware/src/android/hardware/camera2/cts/helpers/StaticMetadata.java b/tests/tests/hardware/src/android/hardware/camera2/cts/helpers/StaticMetadata.java
index 74b55e1..e26cf7a 100644
--- a/tests/tests/hardware/src/android/hardware/camera2/cts/helpers/StaticMetadata.java
+++ b/tests/tests/hardware/src/android/hardware/camera2/cts/helpers/StaticMetadata.java
@@ -41,6 +41,8 @@
import java.util.List;
import java.util.Set;
+import static android.hardware.camera2.cts.helpers.AssertHelpers.*;
+
/**
* Helpers to get common static info out of the camera.
*
@@ -743,6 +745,26 @@
}
/**
+ * Get and check pre-correction active array size.
+ */
+ public Rect getPreCorrectedActiveArraySizeChecked() {
+ Key<Rect> key = CameraCharacteristics.SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE;
+ Rect activeArray = getValueFromKeyNonNull(key);
+
+ if (activeArray == null) {
+ return new Rect(0, 0, 0, 0);
+ }
+
+ Size pixelArraySize = getPixelArraySizeChecked();
+ checkTrueForKey(key, "values left/top are invalid", activeArray.left >= 0 && activeArray.top >= 0);
+ checkTrueForKey(key, "values width/height are invalid",
+ activeArray.width() <= pixelArraySize.getWidth() &&
+ activeArray.height() <= pixelArraySize.getHeight());
+
+ return activeArray;
+ }
+
+ /**
* Get and check active array size.
*/
public Rect getActiveArraySizeChecked() {
@@ -763,6 +785,29 @@
}
/**
+ * Get the dimensions to use for RAW16 buffers.
+ */
+ public Size getRawDimensChecked() throws Exception {
+ Size[] targetCaptureSizes = getAvailableSizesForFormatChecked(ImageFormat.RAW_SENSOR,
+ StaticMetadata.StreamDirection.Output);
+ Assert.assertTrue("No capture sizes available for RAW format!",
+ targetCaptureSizes.length != 0);
+ Rect activeArray = getPreCorrectedActiveArraySizeChecked();
+ Size preCorrectionActiveArraySize =
+ new Size(activeArray.width(), activeArray.height());
+ Size pixelArraySize = getPixelArraySizeChecked();
+ Assert.assertTrue("Missing pre-correction active array size", activeArray.width() > 0 &&
+ activeArray.height() > 0);
+ Assert.assertTrue("Missing pixel array size", pixelArraySize.getWidth() > 0 &&
+ pixelArraySize.getHeight() > 0);
+ Size[] allowedArraySizes = new Size[] { preCorrectionActiveArraySize,
+ pixelArraySize };
+ return assertArrayContainsAnyOf("Available sizes for RAW format" +
+ " must include either the pre-corrected active array size, or the full " +
+ "pixel array size", targetCaptureSizes, allowedArraySizes);
+ }
+
+ /**
* Get the sensitivity value and clamp to the range if needed.
*
* @param sensitivity Input sensitivity value to check.
@@ -1401,7 +1446,8 @@
return minDurationMap;
}
- for (android.util.Size size : config.getOutputSizes(format)) {
+ for (android.util.Size size : getAvailableSizesForFormatChecked(format,
+ StreamDirection.Output)) {
long minFrameDuration = config.getOutputMinFrameDuration(format, size);
if (minFrameDuration != 0) {
diff --git a/tests/tests/hardware/src/android/hardware/cts/CameraTest.java b/tests/tests/hardware/src/android/hardware/cts/CameraTest.java
index 019bd21..ec9caaf 100644
--- a/tests/tests/hardware/src/android/hardware/cts/CameraTest.java
+++ b/tests/tests/hardware/src/android/hardware/cts/CameraTest.java
@@ -37,6 +37,7 @@
import android.os.ConditionVariable;
import android.os.Environment;
import android.os.Looper;
+import android.os.SystemClock;
import android.test.ActivityInstrumentationTestCase2;
import android.test.MoreAsserts;
import android.test.UiThreadTest;
@@ -1975,7 +1976,7 @@
// This method tests if the actual fps is between minimum and maximum.
// It also tests if the frame interval is too long.
public void onPreviewFrame(byte[] data, android.hardware.Camera camera) {
- long arrivalTime = System.currentTimeMillis();
+ long arrivalTime = SystemClock.elapsedRealtime();
camera.addCallbackBuffer(data);
if (firstFrameArrivalTime == 0) firstFrameArrivalTime = arrivalTime;
diff --git a/tests/tests/keystore/src/android/keystore/cts/ECDSASignatureTest.java b/tests/tests/keystore/src/android/keystore/cts/ECDSASignatureTest.java
new file mode 100644
index 0000000..2330209
--- /dev/null
+++ b/tests/tests/keystore/src/android/keystore/cts/ECDSASignatureTest.java
@@ -0,0 +1,119 @@
+/*
+ * 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 android.keystore.cts;
+
+import android.security.keystore.KeyGenParameterSpec;
+import android.security.keystore.KeyProperties;
+
+import junit.framework.TestCase;
+
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+import java.security.Security;
+import java.security.Signature;
+
+public class ECDSASignatureTest extends TestCase {
+
+ public void testNONEwithECDSATruncatesInputToFieldSize() throws Exception {
+ assertNONEwithECDSATruncatesInputToFieldSize(224);
+ assertNONEwithECDSATruncatesInputToFieldSize(256);
+ assertNONEwithECDSATruncatesInputToFieldSize(384);
+ assertNONEwithECDSATruncatesInputToFieldSize(521);
+ }
+
+ private void assertNONEwithECDSATruncatesInputToFieldSize(int keySizeBits) throws Exception {
+ byte[] message = new byte[(keySizeBits * 3) / 8];
+ for (int i = 0; i < message.length; i++) {
+ message[i] = (byte) (i + 1);
+ }
+ KeyPairGenerator generator = KeyPairGenerator.getInstance("EC", "AndroidKeyStore");
+ generator.initialize(new KeyGenParameterSpec.Builder(
+ "test1",
+ KeyProperties.PURPOSE_SIGN)
+ .setDigests(KeyProperties.DIGEST_NONE)
+ .setKeySize(keySizeBits)
+ .build());
+ KeyPair keyPair = generator.generateKeyPair();
+
+ Signature signature = Signature.getInstance("NONEwithECDSA");
+ signature.initSign(keyPair.getPrivate());
+ assertSame(Security.getProvider(SignatureTest.EXPECTED_PROVIDER_NAME),
+ signature.getProvider());
+ signature.update(message);
+ byte[] sigBytes = signature.sign();
+
+ signature = Signature.getInstance(signature.getAlgorithm(), signature.getProvider());
+ signature.initVerify(keyPair.getPublic());
+
+ // Verify the full-length message
+ signature.update(message);
+ assertTrue(signature.verify(sigBytes));
+
+ // Verify the message truncated to field size
+ signature.update(message, 0, (keySizeBits + 7) / 8);
+ assertTrue(signature.verify(sigBytes));
+
+ // Verify message truncated to one byte shorter than field size -- this should fail
+ signature.update(message, 0, (keySizeBits / 8) - 1);
+ assertFalse(signature.verify(sigBytes));
+ }
+
+ public void testNONEwithECDSASupportsMessagesShorterThanFieldSize() throws Exception {
+ assertNONEwithECDSASupportsMessagesShorterThanFieldSize(224);
+ assertNONEwithECDSASupportsMessagesShorterThanFieldSize(256);
+ assertNONEwithECDSASupportsMessagesShorterThanFieldSize(384);
+ assertNONEwithECDSASupportsMessagesShorterThanFieldSize(521);
+ }
+
+ private void assertNONEwithECDSASupportsMessagesShorterThanFieldSize(
+ int keySizeBits) throws Exception {
+ byte[] message = new byte[(keySizeBits * 3 / 4) / 8];
+ for (int i = 0; i < message.length; i++) {
+ message[i] = (byte) (i + 1);
+ }
+ KeyPairGenerator generator = KeyPairGenerator.getInstance("EC", "AndroidKeyStore");
+ generator.initialize(new KeyGenParameterSpec.Builder(
+ "test1",
+ KeyProperties.PURPOSE_SIGN)
+ .setDigests(KeyProperties.DIGEST_NONE)
+ .setKeySize(keySizeBits)
+ .build());
+ KeyPair keyPair = generator.generateKeyPair();
+
+ Signature signature = Signature.getInstance("NONEwithECDSA");
+ signature.initSign(keyPair.getPrivate());
+ assertSame(Security.getProvider(SignatureTest.EXPECTED_PROVIDER_NAME),
+ signature.getProvider());
+ signature.update(message);
+ byte[] sigBytes = signature.sign();
+
+ signature = Signature.getInstance(signature.getAlgorithm(), signature.getProvider());
+ signature.initVerify(keyPair.getPublic());
+
+ // Verify the message
+ signature.update(message);
+ assertTrue(signature.verify(sigBytes));
+
+ // Assert that the message is left-padded with zero bits
+ byte[] fullLengthMessage = new byte[keySizeBits / 8];
+ System.arraycopy(message, 0,
+ fullLengthMessage, fullLengthMessage.length - message.length,
+ message.length);
+ signature.update(fullLengthMessage);
+ assertTrue(signature.verify(sigBytes));
+ }
+}
diff --git a/tests/tests/keystore/src/android/keystore/cts/SignatureTest.java b/tests/tests/keystore/src/android/keystore/cts/SignatureTest.java
index 34d8b1b..9e8678b 100644
--- a/tests/tests/keystore/src/android/keystore/cts/SignatureTest.java
+++ b/tests/tests/keystore/src/android/keystore/cts/SignatureTest.java
@@ -43,7 +43,7 @@
import android.test.MoreAsserts;
public class SignatureTest extends AndroidTestCase {
- private static final String EXPECTED_PROVIDER_NAME = "AndroidKeyStoreBCWorkaround";
+ static final String EXPECTED_PROVIDER_NAME = "AndroidKeyStoreBCWorkaround";
private static final String[] EXPECTED_SIGNATURE_ALGORITHMS = {
"NONEwithRSA",
@@ -209,6 +209,9 @@
new TreeMap<String, byte[]>(String.CASE_INSENSITIVE_ORDER);
static {
// From RI
+ LONG_MSG_KAT_SIGNATURES.put("NONEwithECDSA", HexEncoding.decode(
+ "304502206e4039608a66ce118821eeca3e2af7f530f51d1ce8089685a13f49010e3cd58b02210083a5"
+ + "fe62a171f1b1d775fad712128a223d6b63336e0248783652474221cb3193"));
LONG_MSG_KAT_SIGNATURES.put("SHA1withECDSA", HexEncoding.decode(
"3044022075f09bb5c87d883c088ca2ad263bbe1754ab614f727465bc43695d3521eaccf80220460e4e"
+ "32421e6f4398cd9b7fbb31a1d1f2961f26b9783620f6413f0e6f7efb84"));
@@ -509,7 +512,7 @@
KeyPair keyPair = getKeyPairForSignatureAlgorithm(algorithm, keyPairs);
try {
- if (algorithm.toLowerCase(Locale.US).startsWith("nonewith")) {
+ if (algorithm.toLowerCase(Locale.US).startsWith("nonewithrsa")) {
// This algorithm cannot accept large messages
Signature signature = Signature.getInstance(algorithm);
signature.initSign(keyPair.getPrivate());
diff --git a/tests/tests/media/src/android/media/cts/MediaSyncTest.java b/tests/tests/media/src/android/media/cts/MediaSyncTest.java
index 6f9e2a2..41d8d89 100644
--- a/tests/tests/media/src/android/media/cts/MediaSyncTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaSyncTest.java
@@ -503,7 +503,7 @@
// sync.getTolerance() is MediaSync's tolerance of the playback rate, whereas
// PLAYBACK_RATE_TOLERANCE_PERCENT / 100 is our test's tolerance.
// We need to add both to get an upperbound for allowable error.
- mediaDurationUs * (sync.getTolerance() + PLAYBACK_RATE_TOLERANCE_PERCENT / 100)
+ mediaDurationUs * (sync.getTolerance() + PLAYBACK_RATE_TOLERANCE_PERCENT / 100.)
+ TIME_MEASUREMENT_TOLERANCE_US);
}
diff --git a/tests/tests/net/Android.mk b/tests/tests/net/Android.mk
index a35e145..6524871 100644
--- a/tests/tests/net/Android.mk
+++ b/tests/tests/net/Android.mk
@@ -26,7 +26,8 @@
LOCAL_JAVA_LIBRARIES := voip-common conscrypt org.apache.http.legacy
-LOCAL_JNI_SHARED_LIBRARIES := libcts_jni libnativedns_jni
+LOCAL_JNI_SHARED_LIBRARIES := libcts_jni libnativedns_jni \
+ libnativemultinetwork_jni
# include CtsTestServer as a temporary hack to free net.cts from cts.stub.
LOCAL_SRC_FILES := $(call all-java-files-under, src)
diff --git a/tests/tests/net/jni/Android.mk b/tests/tests/net/jni/Android.mk
index 75982de..ca82b30 100644
--- a/tests/tests/net/jni/Android.mk
+++ b/tests/tests/net/jni/Android.mk
@@ -28,3 +28,12 @@
LOCAL_SHARED_LIBRARIES := libnativehelper liblog
include $(BUILD_SHARED_LIBRARY)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := libnativemultinetwork_jni
+# Don't include this package in any configuration by default.
+LOCAL_MODULE_TAGS := optional
+LOCAL_SRC_FILES := NativeMultinetworkJni.c
+LOCAL_C_INCLUDES := $(JNI_H_INCLUDE)
+LOCAL_SHARED_LIBRARIES := libandroid libnativehelper liblog
+include $(BUILD_SHARED_LIBRARY)
diff --git a/tests/tests/net/jni/NativeMultinetworkJni.c b/tests/tests/net/jni/NativeMultinetworkJni.c
new file mode 100644
index 0000000..9a5ab9c
--- /dev/null
+++ b/tests/tests/net/jni/NativeMultinetworkJni.c
@@ -0,0 +1,216 @@
+/*
+ * Copyright (C) 2010 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 LOG_TAG "MultinetworkApiTest"
+#include <utils/Log.h>
+
+#include <arpa/inet.h>
+#include <errno.h>
+#include <inttypes.h>
+#include <jni.h>
+#include <netdb.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+#include <android/multinetwork.h>
+
+#define UNUSED(X) ((void) X)
+
+static const char kHostname[] = "connectivitycheck.android.com";
+
+
+JNIEXPORT jint Java_android_net_cts_MultinetworkApiTest_runGetaddrinfoCheck(
+ JNIEnv* env, jclass class, jlong nethandle) {
+ UNUSED(env);
+ UNUSED(class);
+ net_handle_t handle = (net_handle_t) nethandle;
+ struct addrinfo *res = NULL;
+
+ errno = 0;
+ int rval = android_getaddrinfofornetwork(handle, kHostname, NULL, NULL, &res);
+ const int saved_errno = errno;
+ freeaddrinfo(res);
+
+ ALOGD("android_getaddrinfofornetwork(%llu, %s) returned rval=%d errno=%d",
+ handle, kHostname, rval, saved_errno);
+ return rval == 0 ? 0 : -saved_errno;
+}
+
+JNIEXPORT jint Java_android_net_cts_MultinetworkApiTest_runSetprocnetwork(
+ JNIEnv* env, jclass class, jlong nethandle) {
+ UNUSED(env);
+ UNUSED(class);
+ net_handle_t handle = (net_handle_t) nethandle;
+
+ errno = 0;
+ int rval = android_setprocnetwork(handle);
+ const int saved_errno = errno;
+ ALOGD("android_setprocnetwork(%llu) returned rval=%d errno=%d",
+ handle, rval, saved_errno);
+ return rval == 0 ? 0 : -saved_errno;
+}
+
+JNIEXPORT jint Java_android_net_cts_MultinetworkApiTest_runSetsocknetwork(
+ JNIEnv* env, jclass class, jlong nethandle) {
+ UNUSED(env);
+ UNUSED(class);
+ net_handle_t handle = (net_handle_t) nethandle;
+
+ errno = 0;
+ int fd = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
+ if (fd < 0) {
+ ALOGD("socket() failed, errno=%d", errno);
+ return -errno;
+ }
+
+ errno = 0;
+ int rval = android_setsocknetwork(handle, fd);
+ const int saved_errno = errno;
+ ALOGD("android_setprocnetwork(%llu, %d) returned rval=%d errno=%d",
+ handle, fd, rval, saved_errno);
+ close(fd);
+ return rval == 0 ? 0 : -saved_errno;
+}
+
+static const int kSockaddrStrLen = INET6_ADDRSTRLEN + strlen("[]:65535");
+
+void sockaddr_ntop(const struct sockaddr *sa, socklen_t salen, char *dst, const size_t size) {
+ char addrstr[INET6_ADDRSTRLEN];
+ char portstr[sizeof("65535")];
+ char buf[sizeof(addrstr) + sizeof(portstr) + sizeof("[]:")];
+ int ret = getnameinfo(sa, salen,
+ addrstr, sizeof(addrstr),
+ portstr, sizeof(portstr),
+ NI_NUMERICHOST | NI_NUMERICSERV);
+ if (ret == 0) {
+ snprintf(buf, sizeof(buf),
+ (sa->sa_family == AF_INET6) ? "[%s]:%s" : "%s:%s",
+ addrstr, portstr);
+ } else {
+ sprintf(buf, "???");
+ }
+
+ strlcpy(dst, buf, (strlen(buf) < size - 1) ? strlen(buf) : size - 1);
+}
+
+JNIEXPORT jint Java_android_net_cts_MultinetworkApiTest_runDatagramCheck(
+ JNIEnv* env, jclass class, jlong nethandle) {
+ UNUSED(env);
+ UNUSED(class);
+ const struct addrinfo kHints = {
+ .ai_flags = AI_ADDRCONFIG,
+ .ai_family = AF_UNSPEC,
+ .ai_socktype = SOCK_DGRAM,
+ .ai_protocol = IPPROTO_UDP,
+ };
+ struct addrinfo *res = NULL;
+ net_handle_t handle = (net_handle_t) nethandle;
+
+ // Quoth Ian Swett:
+ // "QUIC always uses 80 and 443, but only 443 is used for secure(HTTPS) traffic."
+ int rval = android_getaddrinfofornetwork(handle, kHostname, "80", &kHints, &res);
+ if (rval != 0) {
+ ALOGD("android_getaddrinfofornetwork(%llu, %s) returned rval=%d errno=%d",
+ handle, kHostname, rval, errno);
+ freeaddrinfo(res);
+ return -errno;
+ }
+
+ // Rely upon getaddrinfo sorting the best destination to the front.
+ int fd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
+ if (fd < 0) {
+ ALOGD("socket(%d, %d, %d) failed, errno=%d",
+ res->ai_family, res->ai_socktype, res->ai_protocol, errno);
+ freeaddrinfo(res);
+ return -errno;
+ }
+
+ rval = android_setsocknetwork(handle, fd);
+ ALOGD("android_setprocnetwork(%llu, %d) returned rval=%d errno=%d",
+ handle, fd, rval, errno);
+ if (rval != 0) {
+ close(fd);
+ freeaddrinfo(res);
+ return -errno;
+ }
+
+ char addrstr[kSockaddrStrLen];
+ sockaddr_ntop(res->ai_addr, res->ai_addrlen, addrstr, sizeof(addrstr));
+ ALOGD("Attempting connect() to %s...", addrstr);
+
+ rval = connect(fd, res->ai_addr, res->ai_addrlen);
+ if (rval != 0) {
+ close(fd);
+ freeaddrinfo(res);
+ return -errno;
+ }
+ freeaddrinfo(res);
+
+ struct sockaddr_storage src_addr;
+ socklen_t src_addrlen = sizeof(src_addr);
+ if (getsockname(fd, (struct sockaddr *)&src_addr, &src_addrlen) != 0) {
+ close(fd);
+ return -errno;
+ }
+ sockaddr_ntop((const struct sockaddr *)&src_addr, sizeof(src_addr), addrstr, sizeof(addrstr));
+ ALOGD("... from %s", addrstr);
+
+ // Don't let reads or writes block indefinitely.
+ const struct timeval timeo = { 5, 0 }; // 5 seconds
+ setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &timeo, sizeof(timeo));
+ setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, &timeo, sizeof(timeo));
+
+ uint8_t quic_packet[] = {
+ 0x0c, // public flags: 64bit conn ID, 8bit sequence number
+ 0, 0, 0, 0, 0, 0, 0, 0, // 64bit connection ID
+ 0x01, // sequence number
+ 0x00, // private flags
+ 0x07, // type: regular frame type "PING"
+ };
+
+ arc4random_buf(quic_packet + 1, 8); // random connection ID
+
+ ssize_t sent = send(fd, quic_packet, sizeof(quic_packet), 0);
+ if (sent < (ssize_t)sizeof(quic_packet)) {
+ ALOGD("send(QUIC packet) returned sent=%zd, errno=%d", sent, errno);
+ close(fd);
+ return -errno;
+ }
+
+ uint8_t response[1500];
+ ssize_t rcvd = recv(fd, response, sizeof(response), 0);
+ if (rcvd < sent) {
+ ALOGD("recv() returned rcvd=%zd, errno=%d", rcvd, errno);
+ close(fd);
+ return -errno;
+ }
+
+ int conn_id_cmp = memcmp(quic_packet + 1, response + 1, 8);
+ if (conn_id_cmp != 0) {
+ ALOGD("sent and received connection IDs do not match");
+ close(fd);
+ return -EPROTO;
+ }
+
+ // TODO: log, and compare to the IP address encoded in the
+ // response, since this should be a public reset packet.
+
+ close(fd);
+ return 0;
+}
diff --git a/tests/tests/net/src/android/net/cts/MultinetworkApiTest.java b/tests/tests/net/src/android/net/cts/MultinetworkApiTest.java
new file mode 100644
index 0000000..51ee50e
--- /dev/null
+++ b/tests/tests/net/src/android/net/cts/MultinetworkApiTest.java
@@ -0,0 +1,155 @@
+/*
+ * 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 android.net.cts;
+
+import android.content.Context;
+import android.net.ConnectivityManager;
+import android.net.Network;
+import android.net.NetworkCapabilities;
+import android.net.NetworkUtils;
+import android.system.ErrnoException;
+import android.system.OsConstants;
+import android.test.AndroidTestCase;
+
+import java.util.ArrayList;
+
+
+public class MultinetworkApiTest extends AndroidTestCase {
+
+ static {
+ System.loadLibrary("nativemultinetwork_jni");
+ }
+
+ private static final String TAG = "MultinetworkNativeApiTest";
+
+ /**
+ * @return 0 on success
+ */
+ private static native int runGetaddrinfoCheck(long networkHandle);
+ private static native int runSetprocnetwork(long networkHandle);
+ private static native int runSetsocknetwork(long networkHandle);
+ private static native int runDatagramCheck(long networkHandle);
+
+ private ConnectivityManager mCM;
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ mCM = (ConnectivityManager) getContext().getSystemService(Context.CONNECTIVITY_SERVICE);
+ }
+
+ private Network[] getTestableNetworks() {
+ final ArrayList<Network> testableNetworks = new ArrayList<Network>();
+ for (Network network : mCM.getAllNetworks()) {
+ final NetworkCapabilities nc = mCM.getNetworkCapabilities(network);
+ if (nc != null
+ && nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)
+ && nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)) {
+ testableNetworks.add(network);
+ }
+ }
+
+ assertTrue(
+ "This test requires that at least one network be connected. " +
+ "Please ensure that the device is connected to a network.",
+ testableNetworks.size() >= 1);
+ return testableNetworks.toArray(new Network[0]);
+ }
+
+ public void testGetaddrinfo() throws ErrnoException {
+ for (Network network : getTestableNetworks()) {
+ int errno = runGetaddrinfoCheck(network.getNetworkHandle());
+ if (errno != 0) {
+ throw new ErrnoException(
+ "getaddrinfo on " + mCM.getNetworkInfo(network), -errno);
+ }
+ }
+ }
+
+ public void testSetprocnetwork() throws ErrnoException {
+ // Hopefully no prior test in this process space has set a default network.
+ assertNull(mCM.getProcessDefaultNetwork());
+ assertEquals(0, NetworkUtils.getBoundNetworkForProcess());
+
+ for (Network network : getTestableNetworks()) {
+ mCM.setProcessDefaultNetwork(null);
+ assertNull(mCM.getProcessDefaultNetwork());
+
+ int errno = runSetprocnetwork(network.getNetworkHandle());
+ if (errno != 0) {
+ throw new ErrnoException(
+ "setprocnetwork on " + mCM.getNetworkInfo(network), -errno);
+ }
+ Network processDefault = mCM.getProcessDefaultNetwork();
+ assertNotNull(processDefault);
+ assertEquals(network, processDefault);
+ // TODO: open DatagramSockets, connect them to 192.0.2.1 and 2001:db8::,
+ // and ensure that the source address is in fact on this network as
+ // determined by mCM.getLinkProperties(network).
+
+ mCM.setProcessDefaultNetwork(null);
+ }
+
+ for (Network network : getTestableNetworks()) {
+ NetworkUtils.bindProcessToNetwork(0);
+ assertNull(mCM.getBoundNetworkForProcess());
+
+ int errno = runSetprocnetwork(network.getNetworkHandle());
+ if (errno != 0) {
+ throw new ErrnoException(
+ "setprocnetwork on " + mCM.getNetworkInfo(network), -errno);
+ }
+ assertEquals(network, new Network(mCM.getBoundNetworkForProcess()));
+ // TODO: open DatagramSockets, connect them to 192.0.2.1 and 2001:db8::,
+ // and ensure that the source address is in fact on this network as
+ // determined by mCM.getLinkProperties(network).
+
+ NetworkUtils.bindProcessToNetwork(0);
+ }
+ }
+
+ public void testSetsocknetwork() throws ErrnoException {
+ for (Network network : getTestableNetworks()) {
+ int errno = runSetsocknetwork(network.getNetworkHandle());
+ if (errno != 0) {
+ throw new ErrnoException(
+ "setsocknetwork on " + mCM.getNetworkInfo(network), -errno);
+ }
+ }
+ }
+
+ public void testNativeDatagramTransmission() throws ErrnoException {
+ for (Network network : getTestableNetworks()) {
+ int errno = runDatagramCheck(network.getNetworkHandle());
+ if (errno != 0) {
+ throw new ErrnoException(
+ "DatagramCheck on " + mCM.getNetworkInfo(network), -errno);
+ }
+ }
+ }
+
+ public void testNoSuchNetwork() {
+ final Network eNoNet = new Network(54321);
+ assertNull(mCM.getNetworkInfo(eNoNet));
+
+ final long eNoNetHandle = eNoNet.getNetworkHandle();
+ assertEquals(-OsConstants.ENONET, runSetsocknetwork(eNoNetHandle));
+ assertEquals(-OsConstants.ENONET, runSetprocnetwork(eNoNetHandle));
+ // TODO: correct test permissions so this call is not silently re-mapped
+ // to query on the default network.
+ // assertEquals(-OsConstants.ENONET, runGetaddrinfoCheck(eNoNetHandle));
+ }
+}
diff --git a/tests/tests/net/src/android/net/cts/MultinetworkTest.java b/tests/tests/net/src/android/net/cts/MultinetworkSysctlTest.java
similarity index 96%
rename from tests/tests/net/src/android/net/cts/MultinetworkTest.java
rename to tests/tests/net/src/android/net/cts/MultinetworkSysctlTest.java
index 256c030..c091a13 100644
--- a/tests/tests/net/src/android/net/cts/MultinetworkTest.java
+++ b/tests/tests/net/src/android/net/cts/MultinetworkSysctlTest.java
@@ -27,9 +27,9 @@
import java.io.IOException;
/**
- * Tests for multinetwork functionality.
+ * Tests for multinetwork sysctl functionality.
*/
-public class MultinetworkTest extends AndroidTestCase {
+public class MultinetworkSysctlTest extends AndroidTestCase {
// Global sysctls. Must be present and set to 1.
private static final String[] GLOBAL_SYSCTLS = {
diff --git a/tests/tests/os/Android.mk b/tests/tests/os/Android.mk
index 9dfb86e..f4b140e 100644
--- a/tests/tests/os/Android.mk
+++ b/tests/tests/os/Android.mk
@@ -31,6 +31,7 @@
LOCAL_SRC_FILES := $(call all-java-files-under, src) \
src/android/os/cts/IParcelFileDescriptorPeer.aidl \
src/android/os/cts/IEmptyService.aidl \
+ src/android/os/cts/ISeccompIsolatedService.aidl \
src/android/os/cts/ISecondary.aidl
LOCAL_PACKAGE_NAME := CtsOsTestCases
diff --git a/tests/tests/os/AndroidManifest.xml b/tests/tests/os/AndroidManifest.xml
index f225903..deb7045 100644
--- a/tests/tests/os/AndroidManifest.xml
+++ b/tests/tests/os/AndroidManifest.xml
@@ -120,6 +120,10 @@
</intent-filter>
</service>
+ <service android:name="android.os.cts.SeccompTest$IsolatedService"
+ android:isolatedProcess="true">
+ </service>
+
<service android:name="android.os.cts.MessengerService"
android:process=":messengerService">
</service>
diff --git a/tests/tests/os/jni/Android.mk b/tests/tests/os/jni/Android.mk
index fab1ec2..24a0651 100644
--- a/tests/tests/os/jni/Android.mk
+++ b/tests/tests/os/jni/Android.mk
@@ -47,7 +47,9 @@
endif
ifeq ($(ARCH_SUPPORTS_SECCOMP),1)
- LOCAL_SRC_FILES += seccomp-tests/tests/seccomp_bpf_tests.c
+ LOCAL_SRC_FILES += seccomp-tests/tests/seccomp_bpf_tests.c \
+ seccomp_sample_program.cpp
+
# This define controls the behavior of OSFeatures.needsSeccompSupport().
LOCAL_CFLAGS += -DARCH_SUPPORTS_SECCOMP
endif
diff --git a/tests/tests/os/jni/android_os_cts_SeccompTest.cpp b/tests/tests/os/jni/android_os_cts_SeccompTest.cpp
index cd1543d..528696b 100644
--- a/tests/tests/os/jni/android_os_cts_SeccompTest.cpp
+++ b/tests/tests/os/jni/android_os_cts_SeccompTest.cpp
@@ -17,7 +17,15 @@
#include <android/log.h>
#include <jni.h>
#include <string.h>
+#include <time.h>
+#if defined(ARCH_SUPPORTS_SECCOMP)
+#include <linux/filter.h>
+#include <linux/seccomp.h>
+#include <sys/syscall.h>
+#endif
+
+#include "seccomp_sample_program.h"
#include "seccomp-tests/tests/test_harness.h"
// Forward declare from seccomp_bpf_tests.c.
@@ -46,9 +54,33 @@
return false;
}
+jboolean android_security_cts_SeccompBpfTest_installTestFilter(JNIEnv*, jclass) {
+#if !defined(ARCH_SUPPORTS_SECCOMP)
+ return false;
+#else
+ struct sock_fprog prog = GetTestSeccompFilterProgram();
+
+ if (prog.len == 0)
+ return false;
+
+ int rv = syscall(__NR_seccomp, SECCOMP_SET_MODE_FILTER, SECCOMP_FILTER_FLAG_TSYNC, &prog);
+ return rv == 0;
+#endif
+}
+
+jint android_security_cts_SeccompBpfTest_getClockBootTime(JNIEnv*, jclass) {
+ struct timespec ts;
+ int rv = clock_gettime(CLOCK_BOOTTIME, &ts);
+ return rv;
+}
+
static JNINativeMethod methods[] = {
{ "runKernelUnitTest", "(Ljava/lang/String;)Z",
(void*)android_security_cts_SeccompBpfTest_runKernelUnitTest },
+ { "installTestFilter", "()Z",
+ (void*)android_security_cts_SeccompBpfTest_installTestFilter },
+ { "getClockBootTime", "()I",
+ (void*)android_security_cts_SeccompBpfTest_getClockBootTime },
};
int register_android_os_cts_SeccompTest(JNIEnv* env) {
diff --git a/tests/tests/os/jni/seccomp_sample_program.cpp b/tests/tests/os/jni/seccomp_sample_program.cpp
new file mode 100644
index 0000000..e291e8a
--- /dev/null
+++ b/tests/tests/os/jni/seccomp_sample_program.cpp
@@ -0,0 +1,1458 @@
+/*
+ * 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.
+ */
+
+#include <linux/filter.h>
+
+// This file defines a sample seccomp-bpf policy. It is taken from the
+// Chromium renderer process policy applied to isolatedProcess services.
+//
+// In the future, this policy should be further restricted to just the set
+// of system calls that an isolatedProcess should be allowed to make.
+
+#if defined(__arm__)
+struct sock_filter kTestSeccompFilter[] = {
+ {0x20, 0, 0, 0x4},
+ {0x15, 1, 0, 0x40000028},
+ {0x6, 0, 0, 0x30006},
+ {0x20, 0, 0, 0x0},
+ {0x35, 0, 90, 0xab},
+ {0x35, 0, 43, 0x108},
+ {0x35, 0, 21, 0x14f},
+ {0x35, 0, 10, 0x168},
+ {0x35, 0, 5, 0x181},
+ {0x35, 0, 2, 0xf0006},
+ {0x35, 0, 58, 0xffff0},
+ {0x35, 57, 55, 0xffff1},
+ {0x35, 0, 43, 0x182},
+ {0x35, 53, 55, 0xf0001},
+ {0x35, 0, 2, 0x16f},
+ {0x35, 0, 53, 0x17e},
+ {0x35, 52, 39, 0x180},
+ {0x35, 38, 51, 0x16e},
+ {0x35, 0, 5, 0x15b},
+ {0x35, 0, 2, 0x160},
+ {0x35, 0, 35, 0x161},
+ {0x35, 45, 47, 0x165},
+ {0x35, 0, 46, 0x15c},
+ {0x35, 45, 32, 0x15d},
+ {0x35, 0, 2, 0x152},
+ {0x35, 0, 30, 0x153},
+ {0x35, 40, 42, 0x15a},
+ {0x35, 41, 39, 0x151},
+ {0x35, 0, 10, 0x121},
+ {0x35, 0, 5, 0x138},
+ {0x35, 0, 2, 0x143},
+ {0x35, 0, 24, 0x147},
+ {0x35, 23, 34, 0x148},
+ {0x35, 0, 22, 0x139},
+ {0x35, 32, 34, 0x142},
+ {0x35, 0, 2, 0x127},
+ {0x35, 0, 30, 0x12a},
+ {0x35, 31, 18, 0x135},
+ {0x35, 30, 28, 0x126},
+ {0x35, 0, 4, 0x10e},
+ {0x35, 0, 2, 0x119},
+ {0x35, 0, 14, 0x11e},
+ {0x35, 137, 26, 0x120},
+ {0x35, 23, 25, 0x118},
+ {0x35, 0, 3, 0x10b},
+ {0x35, 0, 23, 0x10c},
+ {0x35, 9, 0, 0x10d},
+ {0x5, 0, 0, 0x110},
+ {0x35, 7, 20, 0x10a},
+ {0x35, 0, 25, 0xce},
+ {0x35, 0, 12, 0xee},
+ {0x35, 0, 6, 0xf9},
+ {0x35, 0, 2, 0x100},
+ {0x35, 0, 13, 0x101},
+ {0x35, 129, 14, 0x107},
+ {0x35, 1, 0, 0xfa},
+ {0x5, 0, 0, 0x10d},
+ {0x35, 11, 9, 0xfd},
+ {0x35, 0, 2, 0xf0},
+ {0x35, 0, 148, 0xf1},
+ {0x35, 6, 8, 0xf8},
+ {0x35, 7, 0, 0xef},
+ {0x5, 0, 0, 0x106},
+ {0x35, 0, 7, 0xda},
+ {0x35, 0, 3, 0xde},
+ {0x35, 0, 3, 0xe0},
+ {0x35, 2, 0, 0xe1},
+ {0x5, 0, 0, 0x103},
+ {0x35, 1, 0, 0xdc},
+ {0x5, 0, 0, 0x102},
+ {0x35, 209, 172, 0xdd},
+ {0x35, 0, 2, 0xd2},
+ {0x35, 0, 253, 0xd3},
+ {0x35, 252, 253, 0xd4},
+ {0x35, 252, 251, 0xd1},
+ {0x35, 0, 10, 0xb9},
+ {0x35, 0, 5, 0xc1},
+ {0x35, 0, 2, 0xc7},
+ {0x35, 0, 248, 0xcb},
+ {0x35, 247, 246, 0xcd},
+ {0x35, 0, 245, 0xc5},
+ {0x35, 244, 245, 0xc6},
+ {0x35, 0, 2, 0xbb},
+ {0x35, 0, 244, 0xbf},
+ {0x35, 162, 242, 0xc0},
+ {0x35, 241, 240, 0xba},
+ {0x35, 0, 4, 0xb2},
+ {0x35, 0, 2, 0xb5},
+ {0x35, 0, 239, 0xb6},
+ {0x35, 237, 236, 0xb8},
+ {0x35, 236, 237, 0xb4},
+ {0x35, 0, 2, 0xad},
+ {0x35, 0, 234, 0xb0},
+ {0x35, 233, 234, 0xb1},
+ {0x35, 156, 232, 0xac},
+ {0x35, 0, 42, 0x52},
+ {0x35, 0, 21, 0x7e},
+ {0x35, 0, 10, 0x96},
+ {0x35, 0, 5, 0xa4},
+ {0x35, 0, 2, 0xa8},
+ {0x35, 0, 226, 0xa9},
+ {0x35, 224, 226, 0xaa},
+ {0x35, 0, 223, 0xa5},
+ {0x35, 224, 223, 0xa6},
+ {0x35, 0, 2, 0x9e},
+ {0x35, 0, 221, 0x9f},
+ {0x35, 220, 221, 0xa2},
+ {0x35, 220, 219, 0x98},
+ {0x35, 0, 5, 0x8c},
+ {0x35, 0, 2, 0x90},
+ {0x35, 0, 217, 0x91},
+ {0x35, 216, 215, 0x94},
+ {0x35, 0, 214, 0x8d},
+ {0x35, 213, 212, 0x8e},
+ {0x35, 0, 2, 0x85},
+ {0x35, 0, 210, 0x86},
+ {0x35, 209, 211, 0x8a},
+ {0x35, 210, 209, 0x7f},
+ {0x35, 0, 10, 0x64},
+ {0x35, 0, 5, 0x73},
+ {0x35, 0, 2, 0x7a},
+ {0x35, 0, 205, 0x7b},
+ {0x35, 153, 205, 0x7d},
+ {0x35, 0, 204, 0x77},
+ {0x35, 203, 202, 0x79},
+ {0x35, 0, 2, 0x6c},
+ {0x35, 0, 200, 0x6d},
+ {0x35, 199, 200, 0x72},
+ {0x35, 197, 199, 0x6a},
+ {0x35, 0, 4, 0x5b},
+ {0x35, 0, 2, 0x60},
+ {0x35, 0, 195, 0x62},
+ {0x35, 193, 195, 0x63},
+ {0x35, 192, 193, 0x5c},
+ {0x35, 0, 2, 0x54},
+ {0x35, 0, 192, 0x55},
+ {0x35, 191, 189, 0x57},
+ {0x35, 188, 190, 0x53},
+ {0x35, 0, 21, 0x2d},
+ {0x35, 0, 10, 0x3e},
+ {0x35, 0, 5, 0x46},
+ {0x35, 0, 2, 0x4f},
+ {0x35, 0, 185, 0x50},
+ {0x35, 182, 183, 0x51},
+ {0x35, 0, 181, 0x48},
+ {0x35, 181, 182, 0x4e},
+ {0x35, 0, 2, 0x41},
+ {0x35, 0, 180, 0x43},
+ {0x35, 179, 178, 0x44},
+ {0x35, 177, 176, 0x3f},
+ {0x35, 0, 5, 0x33},
+ {0x35, 0, 2, 0x38},
+ {0x35, 0, 175, 0x3c},
+ {0x35, 174, 172, 0x3d},
+ {0x35, 0, 173, 0x36},
+ {0x35, 124, 171, 0x37},
+ {0x35, 0, 2, 0x2f},
+ {0x35, 0, 169, 0x30},
+ {0x35, 168, 169, 0x31},
+ {0x35, 166, 167, 0x2e},
+ {0x35, 0, 10, 0x17},
+ {0x35, 0, 5, 0x21},
+ {0x35, 0, 2, 0x26},
+ {0x35, 0, 162, 0x29},
+ {0x35, 163, 162, 0x2b},
+ {0x35, 0, 160, 0x22},
+ {0x35, 153, 161, 0x25},
+ {0x35, 0, 2, 0x19},
+ {0x35, 0, 159, 0x1d},
+ {0x35, 158, 157, 0x1e},
+ {0x35, 156, 155, 0x18},
+ {0x35, 0, 4, 0xd},
+ {0x35, 0, 2, 0x11},
+ {0x35, 0, 154, 0x13},
+ {0x35, 153, 152, 0x15},
+ {0x35, 150, 152, 0xe},
+ {0x35, 0, 2, 0x3},
+ {0x35, 0, 149, 0x7},
+ {0x35, 147, 149, 0x8},
+ {0x35, 146, 147, 0x2},
+ {0x20, 0, 0, 0x14},
+ {0x15, 0, 140, 0x0},
+ {0x20, 0, 0, 0x10},
+ {0x15, 143, 144, 0x1},
+ {0x20, 0, 0, 0x14},
+ {0x15, 0, 136, 0x0},
+ {0x20, 0, 0, 0x10},
+ {0x15, 139, 0, 0x1},
+ {0x20, 0, 0, 0x14},
+ {0x15, 0, 132, 0x0},
+ {0x20, 0, 0, 0x10},
+ {0x15, 135, 0, 0x6},
+ {0x20, 0, 0, 0x14},
+ {0x15, 0, 128, 0x0},
+ {0x20, 0, 0, 0x10},
+ {0x15, 131, 0, 0x2},
+ {0x20, 0, 0, 0x14},
+ {0x15, 0, 124, 0x0},
+ {0x20, 0, 0, 0x10},
+ {0x15, 127, 0, 0x0},
+ {0x20, 0, 0, 0x14},
+ {0x15, 0, 120, 0x0},
+ {0x20, 0, 0, 0x10},
+ {0x15, 123, 0, 0x5},
+ {0x20, 0, 0, 0x14},
+ {0x15, 0, 116, 0x0},
+ {0x20, 0, 0, 0x10},
+ {0x15, 119, 120, 0x3},
+ {0x20, 0, 0, 0x1c},
+ {0x15, 0, 112, 0x0},
+ {0x20, 0, 0, 0x18},
+ {0x45, 0, 115, 0xfffffe7f},
+ {0x20, 0, 0, 0x1c},
+ {0x15, 0, 108, 0x0},
+ {0x20, 0, 0, 0x18},
+ {0x54, 0, 0, 0xfffffe7f},
+ {0x15, 110, 0, 0x1},
+ {0x20, 0, 0, 0x1c},
+ {0x15, 0, 103, 0x0},
+ {0x20, 0, 0, 0x18},
+ {0x54, 0, 0, 0xfffffe7f},
+ {0x15, 105, 0, 0x3},
+ {0x20, 0, 0, 0x1c},
+ {0x15, 0, 98, 0x0},
+ {0x20, 0, 0, 0x18},
+ {0x54, 0, 0, 0xfffffe7f},
+ {0x15, 100, 0, 0x4},
+ {0x20, 0, 0, 0x1c},
+ {0x15, 0, 93, 0x0},
+ {0x20, 0, 0, 0x18},
+ {0x54, 0, 0, 0xfffffe7f},
+ {0x15, 95, 0, 0x5},
+ {0x20, 0, 0, 0x1c},
+ {0x15, 0, 88, 0x0},
+ {0x20, 0, 0, 0x18},
+ {0x54, 0, 0, 0xfffffe7f},
+ {0x15, 90, 0, 0x9},
+ {0x20, 0, 0, 0x1c},
+ {0x15, 0, 83, 0x0},
+ {0x20, 0, 0, 0x18},
+ {0x54, 0, 0, 0xfffffe7f},
+ {0x15, 85, 0, 0xa},
+ {0x6, 0, 0, 0x30005},
+ {0x20, 0, 0, 0x24},
+ {0x15, 0, 77, 0x0},
+ {0x20, 0, 0, 0x20},
+ {0x15, 80, 79, 0x4},
+ {0x20, 0, 0, 0x2c},
+ {0x15, 0, 73, 0x0},
+ {0x20, 0, 0, 0x28},
+ {0x45, 77, 76, 0xfffdb7cc},
+ {0x20, 0, 0, 0x14},
+ {0x15, 0, 69, 0x0},
+ {0x20, 0, 0, 0x10},
+ {0x15, 72, 0, 0x10},
+ {0x20, 0, 0, 0x14},
+ {0x15, 0, 65, 0x0},
+ {0x20, 0, 0, 0x10},
+ {0x15, 68, 0, 0xf},
+ {0x20, 0, 0, 0x14},
+ {0x15, 0, 61, 0x0},
+ {0x20, 0, 0, 0x10},
+ {0x15, 64, 0, 0x3},
+ {0x20, 0, 0, 0x14},
+ {0x15, 0, 57, 0x0},
+ {0x20, 0, 0, 0x10},
+ {0x15, 60, 0, 0x4},
+ {0x20, 0, 0, 0x14},
+ {0x15, 0, 53, 0x0},
+ {0x20, 0, 0, 0x10},
+ {0x15, 56, 0, 0x53564d41},
+ {0x20, 0, 0, 0x14},
+ {0x15, 0, 49, 0x0},
+ {0x20, 0, 0, 0x10},
+ {0x15, 52, 0, 0x29},
+ {0x6, 0, 0, 0x30004},
+ {0x20, 0, 0, 0x24},
+ {0x15, 0, 44, 0x0},
+ {0x20, 0, 0, 0x20},
+ {0x45, 48, 47, 0xfffffff8},
+ {0x20, 0, 0, 0x1c},
+ {0x15, 0, 40, 0x0},
+ {0x20, 0, 0, 0x18},
+ {0x15, 43, 0, 0x3},
+ {0x20, 0, 0, 0x1c},
+ {0x15, 0, 36, 0x0},
+ {0x20, 0, 0, 0x18},
+ {0x15, 39, 0, 0x1},
+ {0x20, 0, 0, 0x1c},
+ {0x15, 0, 32, 0x0},
+ {0x20, 0, 0, 0x18},
+ {0x15, 35, 0, 0x2},
+ {0x20, 0, 0, 0x1c},
+ {0x15, 0, 28, 0x0},
+ {0x20, 0, 0, 0x18},
+ {0x15, 31, 0, 0x6},
+ {0x20, 0, 0, 0x1c},
+ {0x15, 0, 24, 0x0},
+ {0x20, 0, 0, 0x18},
+ {0x15, 27, 0, 0x7},
+ {0x20, 0, 0, 0x1c},
+ {0x15, 0, 20, 0x0},
+ {0x20, 0, 0, 0x18},
+ {0x15, 23, 0, 0x5},
+ {0x20, 0, 0, 0x1c},
+ {0x15, 0, 16, 0x0},
+ {0x20, 0, 0, 0x18},
+ {0x15, 19, 0, 0x0},
+ {0x20, 0, 0, 0x1c},
+ {0x15, 0, 12, 0x0},
+ {0x20, 0, 0, 0x18},
+ {0x15, 15, 0, 0x406},
+ {0x20, 0, 0, 0x1c},
+ {0x15, 0, 8, 0x0},
+ {0x20, 0, 0, 0x18},
+ {0x15, 0, 12, 0x4},
+ {0x20, 0, 0, 0x24},
+ {0x15, 0, 4, 0x0},
+ {0x20, 0, 0, 0x20},
+ {0x45, 8, 7, 0xfff1e3fc},
+ {0x20, 0, 0, 0x14},
+ {0x15, 1, 0, 0x0},
+ {0x6, 0, 0, 0x30003},
+ {0x20, 0, 0, 0x10},
+ {0x15, 2, 0, 0x2da4},
+ {0x6, 0, 0, 0x30002},
+ {0x6, 0, 0, 0x50001},
+ {0x6, 0, 0, 0x7fff0000},
+ {0x6, 0, 0, 0x30001},
+};
+#elif defined(__aarch64__)
+// Note: aarch64 is not required to support seccomp-bpf yet, but some Nexus
+// devices do support it. For completeness, this test BPF program is provided.
+struct sock_filter kTestSeccompFilter[] = {
+ {0x20, 0, 0, 0x4},
+ {0x15, 1, 0, 0xc00000b7},
+ {0x6, 0, 0, 0x30006},
+ {0x20, 0, 0, 0x0},
+ {0x35, 0, 51, 0x88},
+ {0x35, 0, 25, 0xba},
+ {0x35, 0, 12, 0xdf},
+ {0x35, 0, 6, 0xea},
+ {0x35, 0, 3, 0x104},
+ {0x35, 0, 1, 0x114},
+ {0x35, 86, 85, 0x116},
+ {0x35, 85, 81, 0x105},
+ {0x35, 0, 84, 0xf2},
+ {0x35, 83, 82, 0xf3},
+ {0x35, 0, 2, 0xe4},
+ {0x35, 0, 77, 0xe6},
+ {0x35, 92, 80, 0xe9},
+ {0x35, 0, 79, 0xe2},
+ {0x35, 78, 97, 0xe3},
+ {0x35, 0, 6, 0xd1},
+ {0x35, 0, 3, 0xd9},
+ {0x35, 0, 1, 0xdd},
+ {0x35, 100, 73, 0xde},
+ {0x35, 69, 73, 0xdc},
+ {0x35, 0, 68, 0xd5},
+ {0x35, 67, 71, 0xd6},
+ {0x35, 0, 2, 0xcc},
+ {0x35, 0, 69, 0xce},
+ {0x35, 68, 64, 0xd0},
+ {0x35, 0, 66, 0xc7},
+ {0x35, 65, 99, 0xc8},
+ {0x35, 0, 12, 0x9e},
+ {0x35, 0, 6, 0xa6},
+ {0x35, 0, 3, 0xa9},
+ {0x35, 0, 1, 0xac},
+ {0x35, 61, 57, 0xb3},
+ {0x35, 60, 56, 0xaa},
+ {0x35, 0, 58, 0xa7},
+ {0x35, 58, 98, 0xa8},
+ {0x35, 0, 2, 0xa1},
+ {0x35, 0, 56, 0xa3},
+ {0x35, 55, 51, 0xa4},
+ {0x35, 0, 50, 0x9f},
+ {0x35, 49, 52, 0xa0},
+ {0x35, 0, 6, 0x94},
+ {0x35, 0, 3, 0x97},
+ {0x35, 0, 1, 0x9c},
+ {0x35, 49, 45, 0x9d},
+ {0x35, 48, 47, 0x99},
+ {0x35, 0, 43, 0x95},
+ {0x35, 42, 45, 0x96},
+ {0x35, 0, 2, 0x8b},
+ {0x35, 0, 40, 0x8e},
+ {0x35, 42, 43, 0x8f},
+ {0x35, 0, 42, 0x89},
+ {0x35, 41, 37, 0x8a},
+ {0x35, 0, 25, 0x4e},
+ {0x35, 0, 12, 0x65},
+ {0x35, 0, 6, 0x80},
+ {0x35, 0, 3, 0x83},
+ {0x35, 0, 1, 0x85},
+ {0x35, 31, 35, 0x86},
+ {0x35, 30, 117, 0x84},
+ {0x35, 0, 29, 0x81},
+ {0x35, 122, 115, 0x82},
+ {0x35, 0, 2, 0x72},
+ {0x35, 0, 30, 0x7c},
+ {0x35, 29, 25, 0x7d},
+ {0x35, 0, 24, 0x66},
+ {0x35, 118, 27, 0x71},
+ {0x35, 0, 6, 0x5b},
+ {0x35, 0, 3, 0x61},
+ {0x35, 0, 1, 0x63},
+ {0x35, 23, 22, 0x64},
+ {0x35, 155, 22, 0x62},
+ {0x35, 0, 20, 0x5c},
+ {0x35, 16, 20, 0x5d},
+ {0x35, 0, 2, 0x58},
+ {0x35, 0, 17, 0x59},
+ {0x35, 13, 17, 0x5a},
+ {0x35, 0, 15, 0x4f},
+ {0x35, 15, 11, 0x51},
+ {0x35, 0, 15, 0x2c},
+ {0x35, 0, 6, 0x3b},
+ {0x35, 0, 3, 0x3e},
+ {0x35, 0, 1, 0x48},
+ {0x35, 10, 6, 0x4a},
+ {0x35, 9, 5, 0x44},
+ {0x35, 0, 4, 0x3c},
+ {0x35, 6, 7, 0x3d},
+ {0x35, 0, 3, 0x34},
+ {0x35, 0, 4, 0x38},
+ {0x35, 4, 0, 0x3a},
+ {0x5, 0, 0, 0x104},
+ {0x35, 0, 2, 0x2d},
+ {0x35, 1, 0, 0x33},
+ {0x5, 0, 0, 0x102},
+ {0x5, 0, 0, 0x102},
+ {0x35, 0, 5, 0x1d},
+ {0x35, 0, 2, 0x21},
+ {0x35, 0, 254, 0x27},
+ {0x35, 253, 254, 0x2b},
+ {0x35, 0, 251, 0x1e},
+ {0x35, 250, 252, 0x20},
+ {0x35, 0, 2, 0x14},
+ {0x35, 0, 248, 0x19},
+ {0x35, 249, 179, 0x1a},
+ {0x35, 0, 248, 0x11},
+ {0x35, 247, 246, 0x13},
+ {0x20, 0, 0, 0x24},
+ {0x15, 3, 0, 0x0},
+ {0x15, 0, 235, 0xffffffff},
+ {0x20, 0, 0, 0x20},
+ {0x45, 0, 233, 0x80000000},
+ {0x20, 0, 0, 0x20},
+ {0x15, 238, 239, 0x4},
+ {0x20, 0, 0, 0x24},
+ {0x15, 3, 0, 0x0},
+ {0x15, 0, 228, 0xffffffff},
+ {0x20, 0, 0, 0x20},
+ {0x45, 0, 226, 0x80000000},
+ {0x20, 0, 0, 0x20},
+ {0x45, 233, 231, 0xfffffff8},
+ {0x20, 0, 0, 0x2c},
+ {0x15, 3, 0, 0x0},
+ {0x15, 0, 221, 0xffffffff},
+ {0x20, 0, 0, 0x28},
+ {0x45, 0, 219, 0x80000000},
+ {0x20, 0, 0, 0x28},
+ {0x45, 226, 224, 0xfffdb7cc},
+ {0x20, 0, 0, 0x14},
+ {0x15, 3, 0, 0x0},
+ {0x15, 0, 214, 0xffffffff},
+ {0x20, 0, 0, 0x10},
+ {0x45, 0, 212, 0x80000000},
+ {0x20, 0, 0, 0x10},
+ {0x15, 217, 219, 0x1},
+ {0x20, 0, 0, 0x14},
+ {0x15, 3, 0, 0x0},
+ {0x15, 0, 207, 0xffffffff},
+ {0x20, 0, 0, 0x10},
+ {0x45, 0, 205, 0x80000000},
+ {0x20, 0, 0, 0x10},
+ {0x15, 210, 0, 0x10},
+ {0x20, 0, 0, 0x14},
+ {0x15, 3, 0, 0x0},
+ {0x15, 0, 200, 0xffffffff},
+ {0x20, 0, 0, 0x10},
+ {0x45, 0, 198, 0x80000000},
+ {0x20, 0, 0, 0x10},
+ {0x15, 203, 0, 0xf},
+ {0x20, 0, 0, 0x14},
+ {0x15, 3, 0, 0x0},
+ {0x15, 0, 193, 0xffffffff},
+ {0x20, 0, 0, 0x10},
+ {0x45, 0, 191, 0x80000000},
+ {0x20, 0, 0, 0x10},
+ {0x15, 196, 0, 0x3},
+ {0x20, 0, 0, 0x14},
+ {0x15, 3, 0, 0x0},
+ {0x15, 0, 186, 0xffffffff},
+ {0x20, 0, 0, 0x10},
+ {0x45, 0, 184, 0x80000000},
+ {0x20, 0, 0, 0x10},
+ {0x15, 189, 0, 0x4},
+ {0x20, 0, 0, 0x14},
+ {0x15, 3, 0, 0x0},
+ {0x15, 0, 179, 0xffffffff},
+ {0x20, 0, 0, 0x10},
+ {0x45, 0, 177, 0x80000000},
+ {0x20, 0, 0, 0x10},
+ {0x15, 182, 0, 0x53564d41},
+ {0x20, 0, 0, 0x14},
+ {0x15, 3, 0, 0x0},
+ {0x15, 0, 172, 0xffffffff},
+ {0x20, 0, 0, 0x10},
+ {0x45, 0, 170, 0x80000000},
+ {0x20, 0, 0, 0x10},
+ {0x15, 175, 0, 0x29},
+ {0x6, 0, 0, 0x30005},
+ {0x20, 0, 0, 0x14},
+ {0x15, 3, 0, 0x0},
+ {0x15, 0, 164, 0xffffffff},
+ {0x20, 0, 0, 0x10},
+ {0x45, 0, 162, 0x80000000},
+ {0x20, 0, 0, 0x10},
+ {0x15, 167, 0, 0x1393},
+ {0x6, 0, 0, 0x30004},
+ {0x20, 0, 0, 0x14},
+ {0x15, 3, 0, 0x0},
+ {0x15, 0, 156, 0xffffffff},
+ {0x20, 0, 0, 0x10},
+ {0x45, 0, 154, 0x80000000},
+ {0x20, 0, 0, 0x10},
+ {0x15, 159, 0, 0x1},
+ {0x20, 0, 0, 0x14},
+ {0x15, 3, 0, 0x0},
+ {0x15, 0, 149, 0xffffffff},
+ {0x20, 0, 0, 0x10},
+ {0x45, 0, 147, 0x80000000},
+ {0x20, 0, 0, 0x10},
+ {0x15, 152, 0, 0x6},
+ {0x20, 0, 0, 0x14},
+ {0x15, 3, 0, 0x0},
+ {0x15, 0, 142, 0xffffffff},
+ {0x20, 0, 0, 0x10},
+ {0x45, 0, 140, 0x80000000},
+ {0x20, 0, 0, 0x10},
+ {0x15, 145, 0, 0x2},
+ {0x20, 0, 0, 0x14},
+ {0x15, 3, 0, 0x0},
+ {0x15, 0, 135, 0xffffffff},
+ {0x20, 0, 0, 0x10},
+ {0x45, 0, 133, 0x80000000},
+ {0x20, 0, 0, 0x10},
+ {0x15, 138, 0, 0x0},
+ {0x20, 0, 0, 0x14},
+ {0x15, 3, 0, 0x0},
+ {0x15, 0, 128, 0xffffffff},
+ {0x20, 0, 0, 0x10},
+ {0x45, 0, 126, 0x80000000},
+ {0x20, 0, 0, 0x10},
+ {0x15, 131, 0, 0x5},
+ {0x20, 0, 0, 0x14},
+ {0x15, 3, 0, 0x0},
+ {0x15, 0, 121, 0xffffffff},
+ {0x20, 0, 0, 0x10},
+ {0x45, 0, 119, 0x80000000},
+ {0x20, 0, 0, 0x10},
+ {0x15, 124, 126, 0x3},
+ {0x20, 0, 0, 0x1c},
+ {0x15, 3, 0, 0x0},
+ {0x15, 0, 114, 0xffffffff},
+ {0x20, 0, 0, 0x18},
+ {0x45, 0, 112, 0x80000000},
+ {0x20, 0, 0, 0x18},
+ {0x45, 0, 117, 0xfffffe7f},
+ {0x20, 0, 0, 0x1c},
+ {0x15, 3, 0, 0x0},
+ {0x15, 0, 107, 0xffffffff},
+ {0x20, 0, 0, 0x18},
+ {0x45, 0, 105, 0x80000000},
+ {0x20, 0, 0, 0x18},
+ {0x54, 0, 0, 0xfffffe7f},
+ {0x15, 109, 0, 0x1},
+ {0x20, 0, 0, 0x1c},
+ {0x15, 3, 0, 0x0},
+ {0x15, 0, 99, 0xffffffff},
+ {0x20, 0, 0, 0x18},
+ {0x45, 0, 97, 0x80000000},
+ {0x20, 0, 0, 0x18},
+ {0x54, 0, 0, 0xfffffe7f},
+ {0x15, 101, 0, 0x3},
+ {0x20, 0, 0, 0x1c},
+ {0x15, 3, 0, 0x0},
+ {0x15, 0, 91, 0xffffffff},
+ {0x20, 0, 0, 0x18},
+ {0x45, 0, 89, 0x80000000},
+ {0x20, 0, 0, 0x18},
+ {0x54, 0, 0, 0xfffffe7f},
+ {0x15, 93, 0, 0x4},
+ {0x20, 0, 0, 0x1c},
+ {0x15, 3, 0, 0x0},
+ {0x15, 0, 83, 0xffffffff},
+ {0x20, 0, 0, 0x18},
+ {0x45, 0, 81, 0x80000000},
+ {0x20, 0, 0, 0x18},
+ {0x54, 0, 0, 0xfffffe7f},
+ {0x15, 85, 0, 0x5},
+ {0x20, 0, 0, 0x1c},
+ {0x15, 3, 0, 0x0},
+ {0x15, 0, 75, 0xffffffff},
+ {0x20, 0, 0, 0x18},
+ {0x45, 0, 73, 0x80000000},
+ {0x20, 0, 0, 0x18},
+ {0x54, 0, 0, 0xfffffe7f},
+ {0x15, 77, 0, 0x9},
+ {0x20, 0, 0, 0x1c},
+ {0x15, 3, 0, 0x0},
+ {0x15, 0, 67, 0xffffffff},
+ {0x20, 0, 0, 0x18},
+ {0x45, 0, 65, 0x80000000},
+ {0x20, 0, 0, 0x18},
+ {0x54, 0, 0, 0xfffffe7f},
+ {0x15, 69, 0, 0xa},
+ {0x6, 0, 0, 0x30003},
+ {0x20, 0, 0, 0x1c},
+ {0x15, 3, 0, 0x0},
+ {0x15, 0, 58, 0xffffffff},
+ {0x20, 0, 0, 0x18},
+ {0x45, 0, 56, 0x80000000},
+ {0x20, 0, 0, 0x18},
+ {0x15, 61, 0, 0x3},
+ {0x20, 0, 0, 0x1c},
+ {0x15, 3, 0, 0x0},
+ {0x15, 0, 51, 0xffffffff},
+ {0x20, 0, 0, 0x18},
+ {0x45, 0, 49, 0x80000000},
+ {0x20, 0, 0, 0x18},
+ {0x15, 54, 0, 0x1},
+ {0x20, 0, 0, 0x1c},
+ {0x15, 3, 0, 0x0},
+ {0x15, 0, 44, 0xffffffff},
+ {0x20, 0, 0, 0x18},
+ {0x45, 0, 42, 0x80000000},
+ {0x20, 0, 0, 0x18},
+ {0x15, 47, 0, 0x2},
+ {0x20, 0, 0, 0x1c},
+ {0x15, 3, 0, 0x0},
+ {0x15, 0, 37, 0xffffffff},
+ {0x20, 0, 0, 0x18},
+ {0x45, 0, 35, 0x80000000},
+ {0x20, 0, 0, 0x18},
+ {0x15, 40, 0, 0x6},
+ {0x20, 0, 0, 0x1c},
+ {0x15, 3, 0, 0x0},
+ {0x15, 0, 30, 0xffffffff},
+ {0x20, 0, 0, 0x18},
+ {0x45, 0, 28, 0x80000000},
+ {0x20, 0, 0, 0x18},
+ {0x15, 33, 0, 0x7},
+ {0x20, 0, 0, 0x1c},
+ {0x15, 3, 0, 0x0},
+ {0x15, 0, 23, 0xffffffff},
+ {0x20, 0, 0, 0x18},
+ {0x45, 0, 21, 0x80000000},
+ {0x20, 0, 0, 0x18},
+ {0x15, 26, 0, 0x5},
+ {0x20, 0, 0, 0x1c},
+ {0x15, 3, 0, 0x0},
+ {0x15, 0, 16, 0xffffffff},
+ {0x20, 0, 0, 0x18},
+ {0x45, 0, 14, 0x80000000},
+ {0x20, 0, 0, 0x18},
+ {0x15, 19, 0, 0x0},
+ {0x20, 0, 0, 0x1c},
+ {0x15, 3, 0, 0x0},
+ {0x15, 0, 9, 0xffffffff},
+ {0x20, 0, 0, 0x18},
+ {0x45, 0, 7, 0x80000000},
+ {0x20, 0, 0, 0x18},
+ {0x15, 12, 0, 0x406},
+ {0x20, 0, 0, 0x1c},
+ {0x15, 4, 0, 0x0},
+ {0x15, 0, 2, 0xffffffff},
+ {0x20, 0, 0, 0x18},
+ {0x45, 1, 0, 0x80000000},
+ {0x6, 0, 0, 0x30002},
+ {0x20, 0, 0, 0x18},
+ {0x15, 0, 6, 0x4},
+ {0x20, 0, 0, 0x24},
+ {0x15, 0, 4, 0x0},
+ {0x20, 0, 0, 0x20},
+ {0x45, 2, 0, 0xffe1e3fc},
+ {0x6, 0, 0, 0x7fff0000},
+ {0x6, 0, 0, 0x50001},
+ {0x6, 0, 0, 0x30001},
+};
+#elif defined(__i386__)
+struct sock_filter kTestSeccompFilter[] = {
+ {0x20, 0, 0, 0x4},
+ {0x15, 1, 0, 0x40000003},
+ {0x6, 0, 0, 0x30007},
+ {0x20, 0, 0, 0x0},
+ {0x45, 0, 1, 0x40000000},
+ {0x6, 0, 0, 0x30006},
+ {0x35, 0, 87, 0x94},
+ {0x35, 0, 43, 0xdd},
+ {0x35, 0, 20, 0x11c},
+ {0x35, 0, 10, 0x13f},
+ {0x35, 0, 5, 0x149},
+ {0x35, 0, 2, 0x163},
+ {0x35, 0, 79, 0x164},
+ {0x35, 78, 73, 0x165},
+ {0x35, 0, 78, 0x14c},
+ {0x35, 71, 76, 0x161},
+ {0x35, 0, 2, 0x141},
+ {0x35, 0, 74, 0x144},
+ {0x35, 73, 68, 0x145},
+ {0x35, 67, 73, 0x140},
+ {0x35, 0, 4, 0x12d},
+ {0x35, 0, 2, 0x136},
+ {0x35, 0, 69, 0x137},
+ {0x35, 68, 63, 0x138},
+ {0x35, 68, 62, 0x134},
+ {0x35, 0, 2, 0x127},
+ {0x35, 0, 66, 0x128},
+ {0x35, 65, 59, 0x12c},
+ {0x35, 63, 64, 0x11d},
+ {0x35, 0, 11, 0xfe},
+ {0x35, 0, 6, 0x10a},
+ {0x35, 0, 3, 0x10e},
+ {0x35, 1, 0, 0x10f},
+ {0x5, 0, 0, 0x135},
+ {0x35, 57, 52, 0x110},
+ {0x35, 0, 56, 0x10c},
+ {0x35, 55, 50, 0x10d},
+ {0x35, 0, 2, 0x102},
+ {0x35, 0, 54, 0x103},
+ {0x35, 135, 52, 0x109},
+ {0x35, 51, 52, 0x101},
+ {0x35, 0, 4, 0xef},
+ {0x35, 0, 2, 0xf1},
+ {0x35, 0, 48, 0xfc},
+ {0x35, 42, 48, 0xfd},
+ {0x35, 153, 46, 0xf0},
+ {0x35, 0, 3, 0xe0},
+ {0x35, 0, 45, 0xe1},
+ {0x35, 0, 43, 0xee},
+ {0x5, 0, 0, 0x12a},
+ {0x35, 41, 252, 0xde},
+ {0x35, 0, 20, 0xb6},
+ {0x35, 0, 10, 0xc7},
+ {0x35, 0, 5, 0xd2},
+ {0x35, 0, 2, 0xd9},
+ {0x35, 0, 36, 0xdb},
+ {0x35, 30, 177, 0xdc},
+ {0x35, 0, 29, 0xd3},
+ {0x35, 28, 34, 0xd4},
+ {0x35, 0, 2, 0xcd},
+ {0x35, 0, 32, 0xce},
+ {0x35, 31, 25, 0xd1},
+ {0x35, 24, 30, 0xcb},
+ {0x35, 0, 4, 0xbf},
+ {0x35, 0, 2, 0xc1},
+ {0x35, 0, 21, 0xc5},
+ {0x35, 20, 26, 0xc6},
+ {0x35, 231, 25, 0xc0},
+ {0x35, 0, 2, 0xb9},
+ {0x35, 0, 17, 0xba},
+ {0x35, 21, 22, 0xbb},
+ {0x35, 21, 15, 0xb8},
+ {0x35, 0, 9, 0xa9},
+ {0x35, 0, 4, 0xb0},
+ {0x35, 0, 2, 0xb2},
+ {0x35, 0, 16, 0xb4},
+ {0x35, 15, 16, 0xb5},
+ {0x35, 15, 14, 0xb1},
+ {0x35, 0, 2, 0xab},
+ {0x35, 0, 13, 0xac},
+ {0x35, 12, 157, 0xad},
+ {0x35, 5, 10, 0xaa},
+ {0x35, 0, 5, 0xa2},
+ {0x35, 0, 2, 0xa5},
+ {0x35, 0, 8, 0xa6},
+ {0x35, 7, 6, 0xa8},
+ {0x35, 0, 6, 0xa4},
+ {0x5, 0, 0, 0x105},
+ {0x35, 0, 2, 0x98},
+ {0x35, 0, 2, 0x9e},
+ {0x35, 1, 2, 0x9f},
+ {0x35, 1, 0, 0x96},
+ {0x5, 0, 0, 0x102},
+ {0x5, 0, 0, 0x100},
+ {0x35, 0, 40, 0x4f},
+ {0x35, 0, 20, 0x6e},
+ {0x35, 0, 10, 0x7d},
+ {0x35, 0, 5, 0x8a},
+ {0x35, 0, 2, 0x8e},
+ {0x35, 0, 250, 0x90},
+ {0x35, 249, 250, 0x91},
+ {0x35, 0, 247, 0x8c},
+ {0x35, 246, 247, 0x8d},
+ {0x35, 0, 2, 0x7f},
+ {0x35, 0, 246, 0x85},
+ {0x35, 245, 243, 0x86},
+ {0x35, 243, 156, 0x7e},
+ {0x35, 0, 4, 0x76},
+ {0x35, 0, 2, 0x79},
+ {0x35, 0, 241, 0x7a},
+ {0x35, 240, 239, 0x7b},
+ {0x35, 238, 239, 0x77},
+ {0x35, 0, 2, 0x72},
+ {0x35, 0, 236, 0x73},
+ {0x35, 234, 236, 0x75},
+ {0x35, 235, 233, 0x6f},
+ {0x35, 0, 9, 0x60},
+ {0x35, 0, 4, 0x66},
+ {0x35, 0, 2, 0x6a},
+ {0x35, 0, 229, 0x6c},
+ {0x35, 230, 229, 0x6d},
+ {0x35, 229, 145, 0x67},
+ {0x35, 0, 2, 0x63},
+ {0x35, 0, 225, 0x64},
+ {0x35, 224, 226, 0x65},
+ {0x35, 225, 224, 0x62},
+ {0x35, 0, 4, 0x57},
+ {0x35, 0, 2, 0x5a},
+ {0x35, 0, 170, 0x5b},
+ {0x35, 219, 220, 0x5c},
+ {0x35, 218, 220, 0x59},
+ {0x35, 0, 2, 0x51},
+ {0x35, 0, 216, 0x52},
+ {0x35, 215, 216, 0x53},
+ {0x35, 215, 216, 0x50},
+ {0x35, 0, 20, 0x29},
+ {0x35, 0, 10, 0x38},
+ {0x35, 0, 5, 0x41},
+ {0x35, 0, 2, 0x46},
+ {0x35, 0, 209, 0x48},
+ {0x35, 209, 210, 0x4e},
+ {0x35, 0, 209, 0x43},
+ {0x35, 208, 207, 0x44},
+ {0x35, 0, 2, 0x3d},
+ {0x35, 0, 206, 0x3e},
+ {0x35, 204, 203, 0x3f},
+ {0x35, 202, 204, 0x3c},
+ {0x35, 0, 4, 0x30},
+ {0x35, 0, 2, 0x33},
+ {0x35, 0, 201, 0x36},
+ {0x35, 152, 199, 0x37},
+ {0x35, 198, 199, 0x31},
+ {0x35, 0, 2, 0x2d},
+ {0x35, 0, 196, 0x2e},
+ {0x35, 195, 194, 0x2f},
+ {0x35, 195, 194, 0x2b},
+ {0x35, 0, 9, 0x17},
+ {0x35, 0, 4, 0x1f},
+ {0x35, 0, 2, 0x22},
+ {0x35, 0, 191, 0x25},
+ {0x35, 188, 182, 0x26},
+ {0x35, 187, 189, 0x21},
+ {0x35, 0, 2, 0x19},
+ {0x35, 0, 187, 0x1d},
+ {0x35, 184, 185, 0x1e},
+ {0x35, 184, 183, 0x18},
+ {0x35, 0, 4, 0xe},
+ {0x35, 0, 2, 0x12},
+ {0x35, 0, 180, 0x13},
+ {0x35, 181, 180, 0x15},
+ {0x35, 180, 178, 0x11},
+ {0x35, 0, 2, 0x3},
+ {0x35, 0, 177, 0x8},
+ {0x35, 176, 175, 0xd},
+ {0x35, 174, 175, 0x2},
+ {0x20, 0, 0, 0x14},
+ {0x15, 0, 168, 0x0},
+ {0x20, 0, 0, 0x10},
+ {0x15, 171, 0, 0x1},
+ {0x20, 0, 0, 0x14},
+ {0x15, 0, 164, 0x0},
+ {0x20, 0, 0, 0x10},
+ {0x15, 167, 0, 0x6},
+ {0x20, 0, 0, 0x14},
+ {0x15, 0, 160, 0x0},
+ {0x20, 0, 0, 0x10},
+ {0x15, 163, 0, 0x2},
+ {0x20, 0, 0, 0x14},
+ {0x15, 0, 156, 0x0},
+ {0x20, 0, 0, 0x10},
+ {0x15, 159, 0, 0x0},
+ {0x20, 0, 0, 0x14},
+ {0x15, 0, 152, 0x0},
+ {0x20, 0, 0, 0x10},
+ {0x15, 155, 0, 0x5},
+ {0x20, 0, 0, 0x14},
+ {0x15, 0, 148, 0x0},
+ {0x20, 0, 0, 0x10},
+ {0x15, 151, 152, 0x3},
+ {0x20, 0, 0, 0x1c},
+ {0x15, 0, 144, 0x0},
+ {0x20, 0, 0, 0x18},
+ {0x45, 0, 147, 0xfffffe7f},
+ {0x20, 0, 0, 0x1c},
+ {0x15, 0, 140, 0x0},
+ {0x20, 0, 0, 0x18},
+ {0x54, 0, 0, 0xfffffe7f},
+ {0x15, 142, 0, 0x1},
+ {0x20, 0, 0, 0x1c},
+ {0x15, 0, 135, 0x0},
+ {0x20, 0, 0, 0x18},
+ {0x54, 0, 0, 0xfffffe7f},
+ {0x15, 137, 0, 0x3},
+ {0x20, 0, 0, 0x1c},
+ {0x15, 0, 130, 0x0},
+ {0x20, 0, 0, 0x18},
+ {0x54, 0, 0, 0xfffffe7f},
+ {0x15, 132, 0, 0x4},
+ {0x20, 0, 0, 0x1c},
+ {0x15, 0, 125, 0x0},
+ {0x20, 0, 0, 0x18},
+ {0x54, 0, 0, 0xfffffe7f},
+ {0x15, 127, 0, 0x5},
+ {0x20, 0, 0, 0x1c},
+ {0x15, 0, 120, 0x0},
+ {0x20, 0, 0, 0x18},
+ {0x54, 0, 0, 0xfffffe7f},
+ {0x15, 122, 0, 0x9},
+ {0x20, 0, 0, 0x1c},
+ {0x15, 0, 115, 0x0},
+ {0x20, 0, 0, 0x18},
+ {0x54, 0, 0, 0xfffffe7f},
+ {0x15, 117, 0, 0xa},
+ {0x6, 0, 0, 0x30005},
+ {0x20, 0, 0, 0x24},
+ {0x15, 0, 109, 0x0},
+ {0x20, 0, 0, 0x20},
+ {0x15, 112, 111, 0x4},
+ {0x20, 0, 0, 0x14},
+ {0x15, 0, 105, 0x0},
+ {0x20, 0, 0, 0x10},
+ {0x15, 108, 0, 0x10},
+ {0x20, 0, 0, 0x14},
+ {0x15, 0, 101, 0x0},
+ {0x20, 0, 0, 0x10},
+ {0x15, 104, 0, 0xf},
+ {0x20, 0, 0, 0x14},
+ {0x15, 0, 97, 0x0},
+ {0x20, 0, 0, 0x10},
+ {0x15, 100, 0, 0x3},
+ {0x20, 0, 0, 0x14},
+ {0x15, 0, 93, 0x0},
+ {0x20, 0, 0, 0x10},
+ {0x15, 96, 0, 0x4},
+ {0x20, 0, 0, 0x14},
+ {0x15, 0, 89, 0x0},
+ {0x20, 0, 0, 0x10},
+ {0x15, 92, 0, 0x53564d41},
+ {0x20, 0, 0, 0x14},
+ {0x15, 0, 85, 0x0},
+ {0x20, 0, 0, 0x10},
+ {0x15, 88, 0, 0x29},
+ {0x6, 0, 0, 0x30004},
+ {0x20, 0, 0, 0x24},
+ {0x15, 0, 80, 0x0},
+ {0x20, 0, 0, 0x20},
+ {0x45, 84, 83, 0xfffffff8},
+ {0x20, 0, 0, 0x14},
+ {0x15, 0, 76, 0x0},
+ {0x20, 0, 0, 0x10},
+ {0x15, 79, 0, 0x8},
+ {0x20, 0, 0, 0x14},
+ {0x15, 0, 72, 0x0},
+ {0x20, 0, 0, 0x10},
+ {0x15, 75, 0, 0xd},
+ {0x20, 0, 0, 0x14},
+ {0x15, 0, 68, 0x0},
+ {0x20, 0, 0, 0x10},
+ {0x15, 71, 0, 0xa},
+ {0x20, 0, 0, 0x14},
+ {0x15, 0, 64, 0x0},
+ {0x20, 0, 0, 0x10},
+ {0x15, 67, 0, 0x9},
+ {0x20, 0, 0, 0x14},
+ {0x15, 0, 60, 0x0},
+ {0x20, 0, 0, 0x10},
+ {0x15, 63, 0, 0xc},
+ {0x20, 0, 0, 0x14},
+ {0x15, 0, 56, 0x0},
+ {0x20, 0, 0, 0x10},
+ {0x15, 59, 0, 0xb},
+ {0x20, 0, 0, 0x14},
+ {0x15, 0, 52, 0x0},
+ {0x20, 0, 0, 0x10},
+ {0x15, 55, 0, 0x11},
+ {0x20, 0, 0, 0x14},
+ {0x15, 0, 48, 0x0},
+ {0x20, 0, 0, 0x10},
+ {0x15, 51, 50, 0x10},
+ {0x20, 0, 0, 0x2c},
+ {0x15, 0, 44, 0x0},
+ {0x20, 0, 0, 0x28},
+ {0x45, 48, 47, 0xfffdb7cc},
+ {0x20, 0, 0, 0x1c},
+ {0x15, 0, 40, 0x0},
+ {0x20, 0, 0, 0x18},
+ {0x15, 43, 0, 0x3},
+ {0x20, 0, 0, 0x1c},
+ {0x15, 0, 36, 0x0},
+ {0x20, 0, 0, 0x18},
+ {0x15, 39, 0, 0x1},
+ {0x20, 0, 0, 0x1c},
+ {0x15, 0, 32, 0x0},
+ {0x20, 0, 0, 0x18},
+ {0x15, 35, 0, 0x2},
+ {0x20, 0, 0, 0x1c},
+ {0x15, 0, 28, 0x0},
+ {0x20, 0, 0, 0x18},
+ {0x15, 31, 0, 0x6},
+ {0x20, 0, 0, 0x1c},
+ {0x15, 0, 24, 0x0},
+ {0x20, 0, 0, 0x18},
+ {0x15, 27, 0, 0x7},
+ {0x20, 0, 0, 0x1c},
+ {0x15, 0, 20, 0x0},
+ {0x20, 0, 0, 0x18},
+ {0x15, 23, 0, 0x5},
+ {0x20, 0, 0, 0x1c},
+ {0x15, 0, 16, 0x0},
+ {0x20, 0, 0, 0x18},
+ {0x15, 19, 0, 0x0},
+ {0x20, 0, 0, 0x1c},
+ {0x15, 0, 12, 0x0},
+ {0x20, 0, 0, 0x18},
+ {0x15, 15, 0, 0x406},
+ {0x20, 0, 0, 0x1c},
+ {0x15, 0, 8, 0x0},
+ {0x20, 0, 0, 0x18},
+ {0x15, 0, 12, 0x4},
+ {0x20, 0, 0, 0x24},
+ {0x15, 0, 4, 0x0},
+ {0x20, 0, 0, 0x20},
+ {0x45, 8, 7, 0xfff363fc},
+ {0x20, 0, 0, 0x14},
+ {0x15, 1, 0, 0x0},
+ {0x6, 0, 0, 0x30003},
+ {0x20, 0, 0, 0x10},
+ {0x15, 2, 0, 0x9d0},
+ {0x6, 0, 0, 0x30002},
+ {0x6, 0, 0, 0x50001},
+ {0x6, 0, 0, 0x7fff0000},
+ {0x6, 0, 0, 0x30001},
+};
+#elif defined(__x86_64__)
+struct sock_filter kTestSeccompFilter[] = {
+ {0x20, 0, 0, 0x4},
+ {0x15, 1, 0, 0xc000003e},
+ {0x6, 0, 0, 0x30007},
+ {0x20, 0, 0, 0x0},
+ {0x45, 0, 1, 0x40000000},
+ {0x6, 0, 0, 0x30006},
+ {0x35, 0, 59, 0x7f},
+ {0x35, 0, 29, 0xe4},
+ {0x35, 0, 14, 0x111},
+ {0x35, 0, 7, 0x120},
+ {0x35, 0, 3, 0x13c},
+ {0x35, 0, 1, 0x13f},
+ {0x35, 102, 95, 0x140},
+ {0x35, 101, 94, 0x13e},
+ {0x35, 0, 1, 0x123},
+ {0x35, 99, 94, 0x126},
+ {0x35, 98, 91, 0x121},
+ {0x35, 0, 3, 0x119},
+ {0x35, 0, 1, 0x11d},
+ {0x35, 95, 88, 0x11e},
+ {0x35, 94, 89, 0x11a},
+ {0x35, 0, 86, 0x112},
+ {0x35, 85, 92, 0x118},
+ {0x35, 0, 6, 0xf8},
+ {0x35, 0, 3, 0x106},
+ {0x35, 0, 1, 0x10e},
+ {0x35, 88, 83, 0x110},
+ {0x35, 80, 82, 0x107},
+ {0x35, 0, 86, 0x101},
+ {0x35, 78, 80, 0x102},
+ {0x35, 0, 4, 0xea},
+ {0x35, 0, 1, 0xec},
+ {0x35, 77, 82, 0xf7},
+ {0x35, 74, 0, 0xeb},
+ {0x5, 0, 0, 0x12a},
+ {0x35, 0, 89, 0xe5},
+ {0x35, 73, 78, 0xe7},
+ {0x35, 0, 15, 0xac},
+ {0x35, 0, 7, 0xcb},
+ {0x35, 0, 3, 0xd9},
+ {0x35, 0, 1, 0xdc},
+ {0x35, 73, 66, 0xdd},
+ {0x35, 67, 65, 0xda},
+ {0x35, 0, 1, 0xd5},
+ {0x35, 70, 65, 0xd6},
+ {0x35, 62, 69, 0xd4},
+ {0x35, 0, 4, 0xbb},
+ {0x35, 0, 1, 0xc9},
+ {0x35, 118, 61, 0xca},
+ {0x35, 0, 65, 0xc8},
+ {0x5, 0, 0, 0x121},
+ {0x35, 0, 56, 0xae},
+ {0x35, 57, 62, 0xba},
+ {0x35, 0, 6, 0x8a},
+ {0x35, 0, 3, 0x95},
+ {0x35, 0, 1, 0x9d},
+ {0x35, 58, 166, 0x9e},
+ {0x35, 57, 52, 0x97},
+ {0x35, 0, 56, 0x8c},
+ {0x35, 55, 50, 0x8e},
+ {0x35, 0, 3, 0x83},
+ {0x35, 0, 1, 0x87},
+ {0x35, 45, 52, 0x88},
+ {0x35, 44, 46, 0x84},
+ {0x35, 0, 50, 0x80},
+ {0x35, 49, 44, 0x81},
+ {0x35, 0, 28, 0x3b},
+ {0x35, 0, 14, 0x69},
+ {0x35, 0, 7, 0x74},
+ {0x35, 0, 3, 0x79},
+ {0x35, 0, 1, 0x7c},
+ {0x35, 36, 38, 0x7e},
+ {0x35, 35, 42, 0x7a},
+ {0x35, 0, 1, 0x77},
+ {0x35, 35, 33, 0x78},
+ {0x35, 34, 32, 0x76},
+ {0x35, 0, 3, 0x6e},
+ {0x35, 0, 1, 0x71},
+ {0x35, 31, 29, 0x73},
+ {0x35, 35, 30, 0x6f},
+ {0x35, 0, 27, 0x6b},
+ {0x35, 33, 28, 0x6d},
+ {0x35, 0, 6, 0x4a},
+ {0x35, 0, 3, 0x62},
+ {0x35, 0, 1, 0x67},
+ {0x35, 24, 29, 0x68},
+ {0x35, 23, 28, 0x66},
+ {0x35, 0, 27, 0x4c},
+ {0x35, 21, 19, 0x60},
+ {0x35, 0, 3, 0x3f},
+ {0x35, 0, 1, 0x48},
+ {0x35, 18, 174, 0x49},
+ {0x35, 15, 17, 0x40},
+ {0x35, 0, 14, 0x3c},
+ {0x35, 238, 15, 0x3e},
+ {0x35, 0, 15, 0x1d},
+ {0x35, 0, 6, 0x31},
+ {0x35, 0, 3, 0x36},
+ {0x35, 0, 1, 0x39},
+ {0x35, 15, 8, 0x3a},
+ {0x35, 9, 14, 0x37},
+ {0x35, 0, 6, 0x33},
+ {0x35, 238, 12, 0x35},
+ {0x35, 0, 3, 0x27},
+ {0x35, 0, 1, 0x29},
+ {0x35, 4, 2, 0x2c},
+ {0x35, 8, 3, 0x28},
+ {0x35, 1, 0, 0x20},
+ {0x5, 0, 0, 0x105},
+ {0x35, 5, 0, 0x24},
+ {0x5, 0, 0, 0x104},
+ {0x35, 0, 7, 0xb},
+ {0x35, 0, 4, 0x15},
+ {0x35, 0, 2, 0x1a},
+ {0x35, 233, 0, 0x1c},
+ {0x5, 0, 0, 0x100},
+ {0x35, 254, 253, 0x16},
+ {0x35, 0, 253, 0x12},
+ {0x35, 252, 253, 0x13},
+ {0x35, 0, 3, 0x6},
+ {0x35, 0, 1, 0x9},
+ {0x35, 233, 240, 0xa},
+ {0x35, 248, 247, 0x7},
+ {0x35, 0, 247, 0x4},
+ {0x35, 246, 245, 0x5},
+ {0x20, 0, 0, 0x14},
+ {0x15, 3, 0, 0x0},
+ {0x15, 0, 239, 0xffffffff},
+ {0x20, 0, 0, 0x10},
+ {0x45, 0, 237, 0x80000000},
+ {0x20, 0, 0, 0x10},
+ {0x15, 239, 0, 0x1},
+ {0x20, 0, 0, 0x14},
+ {0x15, 3, 0, 0x0},
+ {0x15, 0, 232, 0xffffffff},
+ {0x20, 0, 0, 0x10},
+ {0x45, 0, 230, 0x80000000},
+ {0x20, 0, 0, 0x10},
+ {0x15, 232, 0, 0x6},
+ {0x20, 0, 0, 0x14},
+ {0x15, 3, 0, 0x0},
+ {0x15, 0, 225, 0xffffffff},
+ {0x20, 0, 0, 0x10},
+ {0x45, 0, 223, 0x80000000},
+ {0x20, 0, 0, 0x10},
+ {0x15, 225, 0, 0x2},
+ {0x20, 0, 0, 0x14},
+ {0x15, 3, 0, 0x0},
+ {0x15, 0, 218, 0xffffffff},
+ {0x20, 0, 0, 0x10},
+ {0x45, 0, 216, 0x80000000},
+ {0x20, 0, 0, 0x10},
+ {0x15, 218, 0, 0x0},
+ {0x20, 0, 0, 0x14},
+ {0x15, 3, 0, 0x0},
+ {0x15, 0, 211, 0xffffffff},
+ {0x20, 0, 0, 0x10},
+ {0x45, 0, 209, 0x80000000},
+ {0x20, 0, 0, 0x10},
+ {0x15, 211, 0, 0x5},
+ {0x20, 0, 0, 0x14},
+ {0x15, 3, 0, 0x0},
+ {0x15, 0, 204, 0xffffffff},
+ {0x20, 0, 0, 0x10},
+ {0x45, 0, 202, 0x80000000},
+ {0x20, 0, 0, 0x10},
+ {0x15, 204, 205, 0x3},
+ {0x20, 0, 0, 0x1c},
+ {0x15, 3, 0, 0x0},
+ {0x15, 0, 197, 0xffffffff},
+ {0x20, 0, 0, 0x18},
+ {0x45, 0, 195, 0x80000000},
+ {0x20, 0, 0, 0x18},
+ {0x45, 0, 197, 0xfffffe7f},
+ {0x20, 0, 0, 0x1c},
+ {0x15, 3, 0, 0x0},
+ {0x15, 0, 190, 0xffffffff},
+ {0x20, 0, 0, 0x18},
+ {0x45, 0, 188, 0x80000000},
+ {0x20, 0, 0, 0x18},
+ {0x54, 0, 0, 0xfffffe7f},
+ {0x15, 189, 0, 0x1},
+ {0x20, 0, 0, 0x1c},
+ {0x15, 3, 0, 0x0},
+ {0x15, 0, 182, 0xffffffff},
+ {0x20, 0, 0, 0x18},
+ {0x45, 0, 180, 0x80000000},
+ {0x20, 0, 0, 0x18},
+ {0x54, 0, 0, 0xfffffe7f},
+ {0x15, 181, 0, 0x3},
+ {0x20, 0, 0, 0x1c},
+ {0x15, 3, 0, 0x0},
+ {0x15, 0, 174, 0xffffffff},
+ {0x20, 0, 0, 0x18},
+ {0x45, 0, 172, 0x80000000},
+ {0x20, 0, 0, 0x18},
+ {0x54, 0, 0, 0xfffffe7f},
+ {0x15, 173, 0, 0x4},
+ {0x20, 0, 0, 0x1c},
+ {0x15, 3, 0, 0x0},
+ {0x15, 0, 166, 0xffffffff},
+ {0x20, 0, 0, 0x18},
+ {0x45, 0, 164, 0x80000000},
+ {0x20, 0, 0, 0x18},
+ {0x54, 0, 0, 0xfffffe7f},
+ {0x15, 165, 0, 0x5},
+ {0x20, 0, 0, 0x1c},
+ {0x15, 3, 0, 0x0},
+ {0x15, 0, 158, 0xffffffff},
+ {0x20, 0, 0, 0x18},
+ {0x45, 0, 156, 0x80000000},
+ {0x20, 0, 0, 0x18},
+ {0x54, 0, 0, 0xfffffe7f},
+ {0x15, 157, 0, 0x9},
+ {0x20, 0, 0, 0x1c},
+ {0x15, 3, 0, 0x0},
+ {0x15, 0, 150, 0xffffffff},
+ {0x20, 0, 0, 0x18},
+ {0x45, 0, 148, 0x80000000},
+ {0x20, 0, 0, 0x18},
+ {0x54, 0, 0, 0xfffffe7f},
+ {0x15, 149, 0, 0xa},
+ {0x6, 0, 0, 0x30005},
+ {0x20, 0, 0, 0x14},
+ {0x15, 3, 0, 0x0},
+ {0x15, 0, 141, 0xffffffff},
+ {0x20, 0, 0, 0x10},
+ {0x45, 0, 139, 0x80000000},
+ {0x20, 0, 0, 0x10},
+ {0x15, 141, 0, 0x10},
+ {0x20, 0, 0, 0x14},
+ {0x15, 3, 0, 0x0},
+ {0x15, 0, 134, 0xffffffff},
+ {0x20, 0, 0, 0x10},
+ {0x45, 0, 132, 0x80000000},
+ {0x20, 0, 0, 0x10},
+ {0x15, 134, 0, 0xf},
+ {0x20, 0, 0, 0x14},
+ {0x15, 3, 0, 0x0},
+ {0x15, 0, 127, 0xffffffff},
+ {0x20, 0, 0, 0x10},
+ {0x45, 0, 125, 0x80000000},
+ {0x20, 0, 0, 0x10},
+ {0x15, 127, 0, 0x3},
+ {0x20, 0, 0, 0x14},
+ {0x15, 3, 0, 0x0},
+ {0x15, 0, 120, 0xffffffff},
+ {0x20, 0, 0, 0x10},
+ {0x45, 0, 118, 0x80000000},
+ {0x20, 0, 0, 0x10},
+ {0x15, 120, 0, 0x4},
+ {0x20, 0, 0, 0x14},
+ {0x15, 3, 0, 0x0},
+ {0x15, 0, 113, 0xffffffff},
+ {0x20, 0, 0, 0x10},
+ {0x45, 0, 111, 0x80000000},
+ {0x20, 0, 0, 0x10},
+ {0x15, 113, 0, 0x53564d41},
+ {0x20, 0, 0, 0x14},
+ {0x15, 3, 0, 0x0},
+ {0x15, 0, 106, 0xffffffff},
+ {0x20, 0, 0, 0x10},
+ {0x45, 0, 104, 0x80000000},
+ {0x20, 0, 0, 0x10},
+ {0x15, 106, 0, 0x29},
+ {0x6, 0, 0, 0x30004},
+ {0x20, 0, 0, 0x1c},
+ {0x15, 3, 0, 0x0},
+ {0x15, 0, 98, 0xffffffff},
+ {0x20, 0, 0, 0x18},
+ {0x45, 0, 96, 0x80000000},
+ {0x20, 0, 0, 0x18},
+ {0x15, 98, 0, 0x3},
+ {0x20, 0, 0, 0x1c},
+ {0x15, 3, 0, 0x0},
+ {0x15, 0, 91, 0xffffffff},
+ {0x20, 0, 0, 0x18},
+ {0x45, 0, 89, 0x80000000},
+ {0x20, 0, 0, 0x18},
+ {0x15, 91, 0, 0x1},
+ {0x20, 0, 0, 0x1c},
+ {0x15, 3, 0, 0x0},
+ {0x15, 0, 84, 0xffffffff},
+ {0x20, 0, 0, 0x18},
+ {0x45, 0, 82, 0x80000000},
+ {0x20, 0, 0, 0x18},
+ {0x15, 84, 0, 0x2},
+ {0x20, 0, 0, 0x1c},
+ {0x15, 3, 0, 0x0},
+ {0x15, 0, 77, 0xffffffff},
+ {0x20, 0, 0, 0x18},
+ {0x45, 0, 75, 0x80000000},
+ {0x20, 0, 0, 0x18},
+ {0x15, 77, 0, 0x6},
+ {0x20, 0, 0, 0x1c},
+ {0x15, 3, 0, 0x0},
+ {0x15, 0, 70, 0xffffffff},
+ {0x20, 0, 0, 0x18},
+ {0x45, 0, 68, 0x80000000},
+ {0x20, 0, 0, 0x18},
+ {0x15, 70, 0, 0x7},
+ {0x20, 0, 0, 0x1c},
+ {0x15, 3, 0, 0x0},
+ {0x15, 0, 63, 0xffffffff},
+ {0x20, 0, 0, 0x18},
+ {0x45, 0, 61, 0x80000000},
+ {0x20, 0, 0, 0x18},
+ {0x15, 63, 0, 0x5},
+ {0x20, 0, 0, 0x1c},
+ {0x15, 3, 0, 0x0},
+ {0x15, 0, 56, 0xffffffff},
+ {0x20, 0, 0, 0x18},
+ {0x45, 0, 54, 0x80000000},
+ {0x20, 0, 0, 0x18},
+ {0x15, 56, 0, 0x0},
+ {0x20, 0, 0, 0x1c},
+ {0x15, 3, 0, 0x0},
+ {0x15, 0, 49, 0xffffffff},
+ {0x20, 0, 0, 0x18},
+ {0x45, 0, 47, 0x80000000},
+ {0x20, 0, 0, 0x18},
+ {0x15, 49, 0, 0x406},
+ {0x20, 0, 0, 0x1c},
+ {0x15, 3, 0, 0x0},
+ {0x15, 0, 42, 0xffffffff},
+ {0x20, 0, 0, 0x18},
+ {0x45, 0, 40, 0x80000000},
+ {0x20, 0, 0, 0x18},
+ {0x15, 0, 43, 0x4},
+ {0x20, 0, 0, 0x24},
+ {0x15, 0, 41, 0x0},
+ {0x20, 0, 0, 0x20},
+ {0x45, 39, 38, 0xffe363fc},
+ {0x20, 0, 0, 0x14},
+ {0x15, 3, 0, 0x0},
+ {0x15, 0, 31, 0xffffffff},
+ {0x20, 0, 0, 0x10},
+ {0x45, 0, 29, 0x80000000},
+ {0x20, 0, 0, 0x10},
+ {0x15, 31, 0, 0xa57},
+ {0x6, 0, 0, 0x30003},
+ {0x20, 0, 0, 0x14},
+ {0x15, 3, 0, 0x0},
+ {0x15, 0, 23, 0xffffffff},
+ {0x20, 0, 0, 0x10},
+ {0x45, 0, 21, 0x80000000},
+ {0x20, 0, 0, 0x10},
+ {0x15, 23, 24, 0x1},
+ {0x20, 0, 0, 0x24},
+ {0x15, 3, 0, 0x0},
+ {0x15, 0, 16, 0xffffffff},
+ {0x20, 0, 0, 0x20},
+ {0x45, 0, 14, 0x80000000},
+ {0x20, 0, 0, 0x20},
+ {0x15, 16, 15, 0x4},
+ {0x20, 0, 0, 0x24},
+ {0x15, 3, 0, 0x0},
+ {0x15, 0, 9, 0xffffffff},
+ {0x20, 0, 0, 0x20},
+ {0x45, 0, 7, 0x80000000},
+ {0x20, 0, 0, 0x20},
+ {0x45, 10, 9, 0xfffffff8},
+ {0x20, 0, 0, 0x2c},
+ {0x15, 4, 0, 0x0},
+ {0x15, 0, 2, 0xffffffff},
+ {0x20, 0, 0, 0x28},
+ {0x45, 1, 0, 0x80000000},
+ {0x6, 0, 0, 0x30002},
+ {0x20, 0, 0, 0x28},
+ {0x45, 2, 1, 0xfffdb7cc},
+ {0x6, 0, 0, 0x50001},
+ {0x6, 0, 0, 0x7fff0000},
+ {0x6, 0, 0, 0x30001},
+};
+#endif
+
+struct sock_fprog GetTestSeccompFilterProgram() {
+ struct sock_fprog prog = {
+ .len = sizeof(kTestSeccompFilter) / sizeof(struct sock_filter),
+ .filter = kTestSeccompFilter
+ };
+ return prog;
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/tv/MockTvInputSettingsActivity.java b/tests/tests/os/jni/seccomp_sample_program.h
similarity index 72%
rename from apps/CtsVerifier/src/com/android/cts/verifier/tv/MockTvInputSettingsActivity.java
rename to tests/tests/os/jni/seccomp_sample_program.h
index 4231db7..1293572 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/tv/MockTvInputSettingsActivity.java
+++ b/tests/tests/os/jni/seccomp_sample_program.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2014 The Android Open Source Project
+ * 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.
@@ -14,10 +14,6 @@
* limitations under the License.
*/
-package com.android.cts.verifier.tv;
+#include <linux/filter.h>
-import android.preference.PreferenceActivity;
-
-public class MockTvInputSettingsActivity extends PreferenceActivity {
-
-}
+struct sock_fprog GetTestSeccompFilterProgram();
diff --git a/tests/tests/os/src/android/os/cts/ISeccompIsolatedService.aidl b/tests/tests/os/src/android/os/cts/ISeccompIsolatedService.aidl
new file mode 100644
index 0000000..5234eff
--- /dev/null
+++ b/tests/tests/os/src/android/os/cts/ISeccompIsolatedService.aidl
@@ -0,0 +1,36 @@
+/*
+ * 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 android.os.cts;
+
+import android.os.IBinder;
+import android.os.ParcelFileDescriptor;
+
+interface ISeccompIsolatedService {
+ boolean installFilter();
+
+ boolean createThread();
+
+ boolean getSystemInfo();
+
+ boolean writeToFile(in ParcelFileDescriptor fd);
+
+ boolean openAshmem();
+
+ boolean openDevFile();
+
+ void violatePolicy();
+}
diff --git a/tests/tests/os/src/android/os/cts/SeccompTest.java b/tests/tests/os/src/android/os/cts/SeccompTest.java
index e8de783..4c2f78f 100644
--- a/tests/tests/os/src/android/os/cts/SeccompTest.java
+++ b/tests/tests/os/src/android/os/cts/SeccompTest.java
@@ -16,9 +16,36 @@
package android.os.cts;
-import junit.framework.TestCase;
+import android.app.Service;
+import android.content.Context;
+import android.content.ComponentName;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.os.Environment;
+import android.os.IBinder;
+import android.os.ParcelFileDescriptor;
+import android.os.RemoteException;
+import android.os.MemoryFile;
+import android.os.SystemClock;
+import android.os.Build;
+import android.util.Log;
+import android.test.AndroidTestCase;
-public class SeccompTest extends TestCase {
+import com.google.common.util.concurrent.AbstractFuture;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+import java.util.Date;
+
+public class SeccompTest extends AndroidTestCase {
+ final static String TAG = "SeccompTest";
+
static {
System.loadLibrary("ctsos_jni");
}
@@ -142,7 +169,218 @@
}
/**
+ * Integration test for seccomp-bpf policy applied to an isolatedProcess=true
+ * service. This will perform various operations in an isolated process under a
+ * fairly restrictive seccomp policy.
+ */
+ public void testIsolatedServicePolicy() throws InterruptedException, ExecutionException,
+ RemoteException {
+ if (!OSFeatures.needsSeccompSupport())
+ return;
+
+ final IsolatedServiceConnection peer = new IsolatedServiceConnection();
+ final Intent intent = new Intent(getContext(), IsolatedService.class);
+ assertTrue(getContext().bindService(intent, peer, Context.BIND_AUTO_CREATE));
+
+ final ISeccompIsolatedService service = peer.get();
+
+ // installFilter() must be called first, to set the seccomp policy.
+ assertTrue(service.installFilter());
+ assertTrue(service.createThread());
+ assertTrue(service.getSystemInfo());
+ doFileWriteTest(service);
+ assertTrue(service.openAshmem());
+ assertTrue(service.openDevFile());
+
+ getContext().unbindService(peer);
+ }
+
+ /**
+ * Integration test for seccomp-bpf policy with isolatedProcess, where the
+ * process then violates the policy and gets killed by the kernel.
+ */
+ public void testViolateIsolatedServicePolicy() throws InterruptedException,
+ ExecutionException, RemoteException {
+ if (!OSFeatures.needsSeccompSupport())
+ return;
+
+ final IsolatedServiceConnection peer = new IsolatedServiceConnection();
+ final Intent intent = new Intent(getContext(), IsolatedService.class);
+ assertTrue(getContext().bindService(intent, peer, Context.BIND_AUTO_CREATE));
+
+ final ISeccompIsolatedService service = peer.get();
+
+ assertTrue(service.installFilter());
+ boolean gotRemoteException = false;
+ try {
+ service.violatePolicy();
+ } catch (RemoteException e) {
+ gotRemoteException = true;
+ }
+ assertTrue(gotRemoteException);
+
+ getContext().unbindService(peer);
+ }
+
+ private void doFileWriteTest(ISeccompIsolatedService service) throws RemoteException {
+ final String fileName = "seccomp_test";
+ ParcelFileDescriptor fd = null;
+ try {
+ FileOutputStream fOut = getContext().openFileOutput(fileName, 0);
+ fd = ParcelFileDescriptor.dup(fOut.getFD());
+ fOut.close();
+ } catch (FileNotFoundException e) {
+ fail(e.getMessage());
+ return;
+ } catch (IOException e) {
+ fail(e.getMessage());
+ return;
+ }
+
+ assertTrue(service.writeToFile(fd));
+
+ try {
+ FileInputStream fIn = getContext().openFileInput(fileName);
+ assertEquals('!', fIn.read());
+ fIn.close();
+ } catch (FileNotFoundException e) {
+ fail(e.getMessage());
+ } catch (IOException e) {
+ fail(e.getMessage());
+ }
+ }
+
+ class IsolatedServiceConnection extends AbstractFuture<ISeccompIsolatedService>
+ implements ServiceConnection {
+ @Override
+ public void onServiceConnected(ComponentName name, IBinder service) {
+ set(ISeccompIsolatedService.Stub.asInterface(service));
+ }
+
+ @Override
+ public void onServiceDisconnected(ComponentName name) {
+ }
+
+ @Override
+ public ISeccompIsolatedService get() throws InterruptedException, ExecutionException {
+ try {
+ return get(10, TimeUnit.SECONDS);
+ } catch (TimeoutException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+
+ public static class IsolatedService extends Service {
+ private final ISeccompIsolatedService.Stub mService = new ISeccompIsolatedService.Stub() {
+ public boolean installFilter() {
+ return installTestFilter();
+ }
+
+ public boolean createThread() {
+ Thread thread = new Thread(new Runnable() {
+ @Override
+ public void run() {
+ try {
+ Thread.currentThread().setPriority(Thread.MIN_PRIORITY);
+ Thread.sleep(100);
+ } catch (InterruptedException e) {
+ }
+ }
+ });
+ thread.run();
+ try {
+ thread.join();
+ } catch (InterruptedException e) {
+ return false;
+ }
+ return true;
+ }
+
+ public boolean getSystemInfo() {
+ long uptimeMillis = SystemClock.uptimeMillis();
+ if (uptimeMillis < 1) {
+ Log.d(TAG, "SystemClock failed");
+ return false;
+ }
+
+ String version = Build.VERSION.CODENAME;
+ if (version.length() == 0) {
+ Log.d(TAG, "Build.VERSION failed");
+ return false;
+ }
+
+ long time = (new Date()).getTime();
+ if (time < 100) {
+ Log.d(TAG, "getTime failed");
+ return false;
+ }
+
+ return true;
+ }
+
+ public boolean writeToFile(ParcelFileDescriptor fd) {
+ FileOutputStream fOut = new FileOutputStream(fd.getFileDescriptor());
+ try {
+ fOut.write('!');
+ fOut.close();
+ } catch (IOException e) {
+ return false;
+ }
+ return true;
+ }
+
+ public boolean openAshmem() {
+ byte[] buffer = {'h', 'e', 'l', 'l', 'o'};
+ try {
+ MemoryFile file = new MemoryFile("seccomp_isolated_test", 32);
+ file.writeBytes(buffer, 0, 0, buffer.length);
+ file.close();
+ return true;
+ } catch (IOException e) {
+ return false;
+ }
+ }
+
+ public boolean openDevFile() {
+ try {
+ FileInputStream fIn = new FileInputStream("/dev/zero");
+ boolean succeed = fIn.read() == 0;
+ succeed &= fIn.read() == 0;
+ succeed &= fIn.read() == 0;
+ fIn.close();
+ return succeed;
+ } catch (FileNotFoundException e) {
+ return false;
+ } catch (IOException e) {
+ return false;
+ }
+ }
+
+ public void violatePolicy() {
+ getClockBootTime();
+ }
+ };
+
+ @Override
+ public IBinder onBind(Intent intent) {
+ return mService;
+ }
+ }
+
+ /**
* Runs the seccomp_bpf_unittest of the given name.
*/
private native boolean runKernelUnitTest(final String name);
+
+ /**
+ * Installs a test seccomp-bpf filter program that.
+ */
+ private native static boolean installTestFilter();
+
+ /**
+ * Attempts to get the CLOCK_BOOTTIME, which is a violation of the
+ * policy specified by installTestFilter().
+ */
+ private native static int getClockBootTime();
}
diff --git a/tests/tests/telecom/src/android/telecom/cts/BaseTelecomTestWithMockServices.java b/tests/tests/telecom/src/android/telecom/cts/BaseTelecomTestWithMockServices.java
index fb62f26..c862cc3 100644
--- a/tests/tests/telecom/src/android/telecom/cts/BaseTelecomTestWithMockServices.java
+++ b/tests/tests/telecom/src/android/telecom/cts/BaseTelecomTestWithMockServices.java
@@ -282,7 +282,7 @@
extras.putInt(TelecomManager.EXTRA_START_CALL_WITH_VIDEO_STATE, videoState);
}
- mTelecomManager.placeCall(getTestNumber(), extras);
+ mTelecomManager.placeCall(createTestNumber(), extras);
}
/**
@@ -290,8 +290,12 @@
* calls if multiple calls to the same number are placed within a short period of time which
* can cause certain tests to fail.
*/
- Uri getTestNumber() {
- return Uri.fromParts("tel", String.valueOf(sCounter++), null);
+ Uri createTestNumber() {
+ return Uri.fromParts("tel", String.valueOf(++sCounter), null);
+ }
+
+ public static Uri getTestNumber() {
+ return Uri.fromParts("tel", String.valueOf(sCounter), null);
}
void assertNumCalls(final MockInCallService inCallService, final int numCalls) {
diff --git a/tests/tests/telecom/src/android/telecom/cts/CallDetailsTest.java b/tests/tests/telecom/src/android/telecom/cts/CallDetailsTest.java
new file mode 100644
index 0000000..a23af17
--- /dev/null
+++ b/tests/tests/telecom/src/android/telecom/cts/CallDetailsTest.java
@@ -0,0 +1,195 @@
+/*
+ * 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 android.telecom.cts;
+
+import static android.telecom.cts.TestUtils.*;
+
+import android.os.Bundle;
+import android.net.Uri;
+import android.telecom.Call;
+import android.telecom.Connection;
+import android.telecom.ConnectionRequest;
+import android.telecom.DisconnectCause;
+import android.telecom.GatewayInfo;
+import android.telecom.InCallService;
+import android.telecom.PhoneAccount;
+import android.telecom.PhoneAccountHandle;
+import android.telecom.StatusHints;
+import android.telecom.TelecomManager;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertThat;
+
+/**
+ * Suites of tests that verifies the various Call details.
+ */
+public class CallDetailsTest extends BaseTelecomTestWithMockServices {
+
+ private MockInCallService mInCallService;
+ private Call mCall;
+ public static final int CONNECTION_CAPABILITIES =
+ Connection.CAPABILITY_HOLD | Connection.CAPABILITY_MUTE |
+ /**
+ * CAPABILITY_HIGH_DEF_AUDIO & CAPABILITY_WIFI are hidden, so
+ * hardcoding the values for now.
+ */
+ 0x00008000 | 0x00010000;
+ public static final int CALL_CAPABILITIES =
+ Call.Details.CAPABILITY_HOLD | Call.Details.CAPABILITY_MUTE;
+ public static final int CALL_PROPERTIES =
+ Call.Details.PROPERTY_HIGH_DEF_AUDIO | Call.Details.PROPERTY_WIFI;
+ public static final String CALLER_DISPLAY_NAME = "CTS test";
+ public static final int CALLER_DISPLAY_NAME_PRESENTATION = TelecomManager.PRESENTATION_ALLOWED;
+
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ if (TestUtils.shouldTestTelecom(mContext)) {
+ PhoneAccount account = setupConnectionService(
+ new MockConnectionService() {
+ @Override
+ public Connection onCreateOutgoingConnection(
+ PhoneAccountHandle connectionManagerPhoneAccount,
+ ConnectionRequest request) {
+ Connection connection = super.onCreateOutgoingConnection(
+ connectionManagerPhoneAccount,
+ request);
+ // Modify the connection object created with local values.
+ connection.setConnectionCapabilities(CONNECTION_CAPABILITIES);
+ connection.setCallerDisplayName(
+ CALLER_DISPLAY_NAME,
+ CALLER_DISPLAY_NAME_PRESENTATION);
+ Bundle extras = new Bundle();
+ extras.putString(
+ TelecomManager.GATEWAY_PROVIDER_PACKAGE,
+ PACKAGE);
+ connection.setExtras(extras);
+ lock.release();
+ return connection;
+ }
+ }, FLAG_REGISTER | FLAG_ENABLE);
+
+ }
+ /** Place a call as a part of the setup before we test the various
+ * Call details.
+ */
+ placeAndVerifyCall();
+
+ mInCallService = mInCallCallbacks.getService();
+ mCall = mInCallService.getLastCall();
+ }
+
+ /**
+ * Tests whether the getAccountHandle() getter returns the correct object.
+ */
+ public void testAccountHandle() {
+ assertThat(mCall.getDetails().getAccountHandle(), is(PhoneAccountHandle.class));
+ assertEquals(TEST_PHONE_ACCOUNT_HANDLE, mCall.getDetails().getAccountHandle());
+ }
+
+ /**
+ * Tests whether the getCallCapabilities() getter returns the correct object.
+ */
+ public void testCallCapabilities() {
+ assertThat(mCall.getDetails().getCallCapabilities(), is(Integer.class));
+ assertEquals(CALL_CAPABILITIES, mCall.getDetails().getCallCapabilities());
+ }
+
+ /**
+ * Tests whether the getCallerDisplayName() getter returns the correct object.
+ */
+ public void testCallerDisplayName() {
+ assertThat(mCall.getDetails().getCallerDisplayName(), is(String.class));
+ assertEquals(CALLER_DISPLAY_NAME, mCall.getDetails().getCallerDisplayName());
+ }
+
+ /**
+ * Tests whether the getCallerDisplayNamePresentation() getter returns the correct object.
+ */
+ public void testCallerDisplayNamePresentation() {
+ assertThat(mCall.getDetails().getCallerDisplayNamePresentation(), is(Integer.class));
+ assertEquals(CALLER_DISPLAY_NAME_PRESENTATION, mCall.getDetails().getCallerDisplayNamePresentation());
+ }
+
+ /**
+ * Tests whether the getCallProperties() getter returns the correct object.
+ */
+ public void testCallProperties() {
+ assertThat(mCall.getDetails().getCallProperties(), is(Integer.class));
+ assertEquals(CALL_PROPERTIES, mCall.getDetails().getCallProperties());
+ }
+
+ /**
+ * Tests whether the getConnectTimeMillis() getter returns the correct object.
+ */
+ public void testConnectTimeMillis() {
+ assertThat(mCall.getDetails().getConnectTimeMillis(), is(Long.class));
+ }
+
+ /**
+ * Tests whether the getDisconnectCause() getter returns the correct object.
+ */
+ public void testDisconnectCause() {
+ assertThat(mCall.getDetails().getDisconnectCause(), is(DisconnectCause.class));
+ }
+
+ /**
+ * Tests whether the getExtras() getter returns the correct object.
+ */
+ public void testExtras() {
+ assertThat(mCall.getDetails().getExtras(), is(Bundle.class));
+ assertEquals(PACKAGE, mCall.getDetails().getExtras().getString(TelecomManager.GATEWAY_PROVIDER_PACKAGE));
+ }
+
+ /**
+ * Tests whether the getGatewayInfo() getter returns the correct object.
+ */
+ public void testGatewayInfo() {
+ assertThat(mCall.getDetails().getGatewayInfo(), is(GatewayInfo.class));
+ }
+
+ /**
+ * Tests whether the getHandle() getter returns the correct object.
+ */
+ public void testHandle() {
+ assertThat(mCall.getDetails().getHandle(), is(Uri.class));
+ assertEquals(getTestNumber(), mCall.getDetails().getHandle());
+ }
+
+ /**
+ * Tests whether the getHandlePresentation() getter returns the correct object.
+ */
+ public void testHandlePresentation() {
+ assertThat(mCall.getDetails().getHandlePresentation(), is(Integer.class));
+ assertEquals(MockConnectionService.CONNECTION_PRESENTATION, mCall.getDetails().getHandlePresentation());
+ }
+
+ /**
+ * Tests whether the getStatusHints() getter returns the correct object.
+ */
+ public void testStatusHints() {
+ assertThat(mCall.getDetails().getStatusHints(), is(StatusHints.class));
+ }
+
+ /**
+ * Tests whether the getVideoProfile() getter returns the correct object.
+ */
+ public void testVideoProfile() {
+ assertThat(mCall.getDetails().getVideoState(), is(Integer.class));
+ }
+}
diff --git a/tests/tests/telecom/src/android/telecom/cts/MockConnectionService.java b/tests/tests/telecom/src/android/telecom/cts/MockConnectionService.java
index acd93f7..250f197 100644
--- a/tests/tests/telecom/src/android/telecom/cts/MockConnectionService.java
+++ b/tests/tests/telecom/src/android/telecom/cts/MockConnectionService.java
@@ -29,6 +29,8 @@
* received.
*/
public class MockConnectionService extends CtsConnectionService {
+ public static final int CONNECTION_PRESENTATION = TelecomManager.PRESENTATION_ALLOWED;
+
/**
* Used to control whether the {@link MockVideoProvider} will be created when connections are
* created. Used by {@link VideoCallTest#testVideoCallDelayProvider()} to test scenario where
@@ -44,7 +46,7 @@
public Connection onCreateOutgoingConnection(PhoneAccountHandle connectionManagerPhoneAccount,
ConnectionRequest request) {
final MockConnection connection = new MockConnection();
- connection.setAddress(request.getAddress(), TelecomManager.PRESENTATION_ALLOWED);
+ connection.setAddress(request.getAddress(), CONNECTION_PRESENTATION);
if (mCreateVideoProvider) {
connection.createMockVideoProvider();
} else {
@@ -61,7 +63,7 @@
public Connection onCreateIncomingConnection(PhoneAccountHandle connectionManagerPhoneAccount,
ConnectionRequest request) {
final MockConnection connection = new MockConnection();
- connection.setAddress(request.getAddress(), TelecomManager.PRESENTATION_ALLOWED);
+ connection.setAddress(request.getAddress(), CONNECTION_PRESENTATION);
connection.createMockVideoProvider();
connection.setVideoState(request.getVideoState());
diff --git a/tests/tests/telecom/src/android/telecom/cts/MockInCallService.java b/tests/tests/telecom/src/android/telecom/cts/MockInCallService.java
index c3890a0..e725466 100644
--- a/tests/tests/telecom/src/android/telecom/cts/MockInCallService.java
+++ b/tests/tests/telecom/src/android/telecom/cts/MockInCallService.java
@@ -21,6 +21,7 @@
import android.util.ArrayMap;
import java.util.ArrayList;
+import java.util.List;
import java.util.Map;
import java.util.concurrent.Semaphore;
@@ -49,9 +50,14 @@
}
}
+ /**
+ * Note that the super implementations of the callback methods are all no-ops, but we call
+ * them anyway to make sure that the CTS coverage tool detects that we are testing them.
+ */
private Call.Callback mCallCallback = new Call.Callback() {
@Override
public void onStateChanged(Call call, int state) {
+ super.onStateChanged(call, state);
if (getCallbacks() != null) {
getCallbacks().onCallStateChanged(call, state);
}
@@ -59,6 +65,7 @@
@Override
public void onVideoCallChanged(Call call, InCallService.VideoCall videoCall) {
+ super.onVideoCallChanged(call, videoCall);
saveVideoCall(call, videoCall);
}
};
@@ -85,6 +92,7 @@
@Override
public void onCallAdded(Call call) {
+ super.onCallAdded(call);
if (!mCalls.contains(call)) {
mCalls.add(call);
call.registerCallback(mCallCallback);
@@ -101,6 +109,7 @@
@Override
public void onCallRemoved(Call call) {
+ super.onCallRemoved(call);
mCalls.remove(call);
if (getCallbacks() != null) {
getCallbacks().onCallRemoved(call, mCalls.size());
diff --git a/tests/tests/transition/Android.mk b/tests/tests/transition/Android.mk
new file mode 100644
index 0000000..3b48e25
--- /dev/null
+++ b/tests/tests/transition/Android.mk
@@ -0,0 +1,33 @@
+# 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.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_PACKAGE_NAME := CtsTransitionTestCases
+
+# 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
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_CTS_PACKAGE)
diff --git a/tests/tests/transition/AndroidManifest.xml b/tests/tests/transition/AndroidManifest.xml
new file mode 100644
index 0000000..0ce1791
--- /dev/null
+++ b/tests/tests/transition/AndroidManifest.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.cts.transition">
+ <uses-sdk android:minSdkVersion="11" />
+ <uses-permission android:name="android.permission.INJECT_EVENTS" />
+ <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
+ <application>
+ <activity android:name="android.transition.cts.TransitionActivity"
+ android:label="TransitionActivity"/>
+ <uses-library android:name="android.test.runner" />
+ </application>
+
+ <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
+ android:targetPackage="com.android.cts.transition"
+ android:label="CTS tests for android.transition package">
+ <meta-data android:name="listener"
+ android:value="com.android.cts.runner.CtsTestRunListener" />
+ </instrumentation>
+</manifest>
+
diff --git a/tests/tests/transition/res/layout/scene1.xml b/tests/tests/transition/res/layout/scene1.xml
new file mode 100644
index 0000000..4ed5b03
--- /dev/null
+++ b/tests/tests/transition/res/layout/scene1.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+ <View android:layout_width="10dp"
+ android:layout_height="10dp"
+ android:background="#F00"
+ android:id="@+id/redSquare" />
+ <View android:layout_width="10dp"
+ android:layout_height="10dp"
+ android:background="#0F0"
+ android:id="@+id/greenSquare"
+ android:layout_below="@+id/redSquare" />
+</RelativeLayout>
diff --git a/tests/tests/transition/res/layout/scene2.xml b/tests/tests/transition/res/layout/scene2.xml
new file mode 100644
index 0000000..2033c95
--- /dev/null
+++ b/tests/tests/transition/res/layout/scene2.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+ <View android:layout_width="10dp"
+ android:layout_height="10dp"
+ android:background="#0F0"
+ android:id="@+id/greenSquare" />
+ <View android:layout_width="10dp"
+ android:layout_height="10dp"
+ android:background="#F00"
+ android:id="@+id/redSquare"
+ android:layout_below="@+id/greenSquare" />
+</RelativeLayout>
diff --git a/tests/tests/transition/res/layout/scene3.xml b/tests/tests/transition/res/layout/scene3.xml
new file mode 100644
index 0000000..b0625aa
--- /dev/null
+++ b/tests/tests/transition/res/layout/scene3.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+ <View android:layout_width="10dp"
+ android:layout_height="10dp"
+ android:background="#0F0"
+ android:id="@+id/greenSquare" />
+ <View android:layout_width="10dp"
+ android:layout_height="10dp"
+ android:background="#F00"
+ android:id="@+id/redSquare"
+ android:layout_toRightOf="@+id/greenSquare" />
+</RelativeLayout>
diff --git a/tests/tests/transition/res/layout/transition_main.xml b/tests/tests/transition/res/layout/transition_main.xml
new file mode 100644
index 0000000..64de7dd
--- /dev/null
+++ b/tests/tests/transition/res/layout/transition_main.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:id="@+id/container"/>
diff --git a/tests/tests/transition/res/values/strings.xml b/tests/tests/transition/res/values/strings.xml
new file mode 100644
index 0000000..579da74
--- /dev/null
+++ b/tests/tests/transition/res/values/strings.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+<resources>
+ <string name="add_button">Add Button</string>
+</resources>
diff --git a/tests/tests/transition/src/android/transition/cts/BaseTransitionTest.java b/tests/tests/transition/src/android/transition/cts/BaseTransitionTest.java
new file mode 100644
index 0000000..4bbfc2c
--- /dev/null
+++ b/tests/tests/transition/src/android/transition/cts/BaseTransitionTest.java
@@ -0,0 +1,132 @@
+/*
+ * 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 android.transition.cts;
+
+import android.animation.Animator;
+import android.animation.ObjectAnimator;
+import android.test.ActivityInstrumentationTestCase2;
+import android.transition.Scene;
+import android.transition.TransitionManager;
+import android.transition.TransitionValues;
+import android.transition.Visibility;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.FrameLayout;
+
+import java.util.ArrayList;
+import com.android.cts.transition.R;
+
+public class BaseTransitionTest extends ActivityInstrumentationTestCase2<TransitionActivity> {
+ protected TransitionActivity mActivity;
+ protected FrameLayout mSceneRoot;
+ public float mAnimatedValue;
+ protected ArrayList<View> mTargets = new ArrayList<>();
+ protected TestTransition mTransition;
+
+ public BaseTransitionTest() {
+ super(TransitionActivity.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ setActivityInitialTouchMode(false);
+ mActivity = getActivity();
+ mSceneRoot = (FrameLayout) mActivity.findViewById(R.id.container);
+ mTargets.clear();
+ mTransition = new TestTransition();
+ }
+
+ protected void waitForStart() throws InterruptedException {
+ waitForStart(mTransition.listener);
+ }
+
+ protected static void waitForStart(SimpleTransitionListener listener) throws InterruptedException {
+ long endTime = System.currentTimeMillis() + 50;
+ synchronized (listener) {
+ while (!listener.started) {
+ long now = System.currentTimeMillis();
+ long waitTime = endTime - now;
+ if (waitTime <= 0) {
+ throw new InterruptedException();
+ }
+ listener.wait(waitTime);
+ }
+ }
+ }
+
+ protected void waitForEnd(long waitMillis) throws InterruptedException {
+ waitForEnd(mTransition.listener, waitMillis);
+ }
+
+ protected static void waitForEnd(SimpleTransitionListener listener, long waitMillis)
+ throws InterruptedException {
+ long endTime = System.currentTimeMillis() + waitMillis;
+ synchronized (listener) {
+ while (!listener.ended) {
+ long now = System.currentTimeMillis();
+ long waitTime = endTime - now;
+ if (waitTime <= 0) {
+ throw new InterruptedException();
+ }
+ listener.wait(waitTime);
+ }
+ }
+ }
+
+ protected void startTransition(final int layoutId) throws Throwable {
+ runTestOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ Scene scene = Scene.getSceneForLayout(mSceneRoot, layoutId, mActivity);
+ TransitionManager.go(scene, mTransition);
+ }
+ });
+ waitForStart();
+ }
+
+ protected void endTransition() throws Throwable {
+ runTestOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ TransitionManager.endTransitions(mSceneRoot);
+ }
+ });
+ }
+
+ public class TestTransition extends Visibility {
+ public final SimpleTransitionListener listener = new SimpleTransitionListener();
+
+ public TestTransition() {
+ addListener(listener);
+ setDuration(100);
+ }
+
+ @Override
+ public Animator onAppear(ViewGroup sceneRoot, View view, TransitionValues startValues,
+ TransitionValues endValues) {
+ mTargets.add(view);
+ return ObjectAnimator.ofFloat(BaseTransitionTest.this, "mAnimatedValue", 0, 1);
+ }
+
+ @Override
+ public Animator onDisappear(ViewGroup sceneRoot, View view, TransitionValues startValues,
+ TransitionValues endValues) {
+ mTargets.add(view);
+ return ObjectAnimator.ofFloat(BaseTransitionTest.this, "mAnimatedValue", 1, 0);
+ }
+ }
+}
diff --git a/tests/tests/transition/src/android/transition/cts/SimpleTransitionListener.java b/tests/tests/transition/src/android/transition/cts/SimpleTransitionListener.java
new file mode 100644
index 0000000..4d18bbfb
--- /dev/null
+++ b/tests/tests/transition/src/android/transition/cts/SimpleTransitionListener.java
@@ -0,0 +1,65 @@
+/*
+ * 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 android.transition.cts;
+
+import android.transition.Transition;
+import android.transition.Transition.TransitionListener;
+
+/**
+ * Listener captures whether each of the methods is called.
+ */
+class SimpleTransitionListener implements TransitionListener {
+
+ public boolean started;
+
+ public boolean ended;
+
+ public boolean canceled;
+
+ public boolean paused;
+
+ public boolean resumed;
+
+ @Override
+ public synchronized void onTransitionStart(Transition transition) {
+ started = true;
+ notifyAll();
+ }
+
+ @Override
+ public synchronized void onTransitionEnd(Transition transition) {
+ ended = true;
+ notifyAll();
+ }
+
+ @Override
+ public synchronized void onTransitionCancel(Transition transition) {
+ canceled = true;
+ notifyAll();
+ }
+
+ @Override
+ public synchronized void onTransitionPause(Transition transition) {
+ paused = true;
+ notifyAll();
+ }
+
+ @Override
+ public synchronized void onTransitionResume(Transition transition) {
+ resumed = true;
+ notifyAll();
+ }
+}
diff --git a/tests/tests/transition/src/android/transition/cts/TransitionActivity.java b/tests/tests/transition/src/android/transition/cts/TransitionActivity.java
new file mode 100644
index 0000000..8236bd5
--- /dev/null
+++ b/tests/tests/transition/src/android/transition/cts/TransitionActivity.java
@@ -0,0 +1,43 @@
+/*
+ * 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 android.transition.cts;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.Intent;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.graphics.RadialGradient;
+import android.graphics.Shader;
+import android.graphics.drawable.ShapeDrawable;
+import android.graphics.drawable.shapes.OvalShape;
+import android.os.Bundle;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewGroup;
+import java.util.ArrayList;
+
+import com.android.cts.transition.R;
+
+public class TransitionActivity extends Activity {
+ @Override
+ public void onCreate(Bundle bundle){
+ super.onCreate(bundle);
+ setContentView(R.layout.transition_main);
+ }
+}
+
diff --git a/tests/tests/transition/src/android/transition/cts/TransitionManagerTest.java b/tests/tests/transition/src/android/transition/cts/TransitionManagerTest.java
new file mode 100644
index 0000000..5d16b19
--- /dev/null
+++ b/tests/tests/transition/src/android/transition/cts/TransitionManagerTest.java
@@ -0,0 +1,174 @@
+/*
+ * 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 android.transition.cts;
+
+import com.android.cts.transition.R;
+
+import android.transition.Scene;
+import android.transition.TransitionManager;
+import android.view.View;
+import android.widget.FrameLayout;
+
+public class TransitionManagerTest extends BaseTransitionTest {
+
+ public TransitionManagerTest() {
+ }
+
+ public void testBeginDelayedTransition() throws Throwable {
+ runTestOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ TransitionManager.beginDelayedTransition(mSceneRoot, mTransition);
+ View view = mActivity.getLayoutInflater().inflate(R.layout.scene1, mSceneRoot,
+ false);
+ mSceneRoot.addView(view);
+ }
+ });
+
+ waitForStart();
+ waitForEnd(150);
+ assertFalse(mTransition.listener.resumed);
+ assertFalse(mTransition.listener.paused);
+ assertFalse(mTransition.listener.canceled);
+ runTestOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ assertNotNull(mActivity.findViewById(R.id.redSquare));
+ assertNotNull(mActivity.findViewById(R.id.greenSquare));
+ }
+ });
+ }
+
+ public void testGo() throws Throwable {
+ startTransition(R.layout.scene1);
+ waitForStart();
+ waitForEnd(150);
+
+ assertFalse(mTransition.listener.resumed);
+ assertFalse(mTransition.listener.paused);
+ assertFalse(mTransition.listener.canceled);
+ runTestOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ assertNotNull(mActivity.findViewById(R.id.redSquare));
+ assertNotNull(mActivity.findViewById(R.id.greenSquare));
+ }
+ });
+ }
+
+ public void testSetTransition1() throws Throwable {
+ final TransitionManager transitionManager = new TransitionManager();
+
+ runTestOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ Scene scene = Scene.getSceneForLayout(mSceneRoot, R.layout.scene1, mActivity);
+ transitionManager.setTransition(scene, mTransition);
+ transitionManager.transitionTo(scene);
+ }
+ });
+
+ waitForStart();
+ waitForEnd(150);
+ assertFalse(mTransition.listener.resumed);
+ assertFalse(mTransition.listener.paused);
+ assertFalse(mTransition.listener.canceled);
+
+ runTestOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ assertNotNull(mActivity.findViewById(R.id.redSquare));
+ assertNotNull(mActivity.findViewById(R.id.greenSquare));
+ mTransition.listener.started = false;
+ mTransition.listener.ended = false;
+ Scene scene = Scene.getSceneForLayout(mSceneRoot, R.layout.scene2, mActivity);
+ transitionManager.transitionTo(scene);
+ }
+ });
+ Thread.sleep(50);
+ assertFalse(mTransition.listener.started);
+ endTransition();
+ }
+
+ public void testSetTransition2() throws Throwable {
+ final TransitionManager transitionManager = new TransitionManager();
+ final Scene[] scenes = new Scene[3];
+
+ runTestOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ scenes[0] = Scene.getSceneForLayout(mSceneRoot, R.layout.scene1, mActivity);
+ scenes[1] = Scene.getSceneForLayout(mSceneRoot, R.layout.scene2, mActivity);
+ scenes[2] = Scene.getSceneForLayout(mSceneRoot, R.layout.scene3, mActivity);
+ transitionManager.setTransition(scenes[0], scenes[1], mTransition);
+ transitionManager.transitionTo(scenes[0]);
+ }
+ });
+ Thread.sleep(50);
+ assertFalse(mTransition.listener.started);
+
+ runTestOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ transitionManager.transitionTo(scenes[1]);
+ }
+ });
+
+ waitForStart();
+ waitForEnd(150);
+ assertFalse(mTransition.listener.resumed);
+ assertFalse(mTransition.listener.paused);
+ assertFalse(mTransition.listener.canceled);
+
+ runTestOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ mTransition.listener.started = false;
+ mTransition.listener.ended = false;
+ transitionManager.transitionTo(scenes[2]);
+ }
+ });
+ Thread.sleep(50);
+ assertFalse(mTransition.listener.started);
+ endTransition();
+ }
+
+ public void testEndTransitions() throws Throwable {
+ mTransition.setDuration(400);
+
+ startTransition(R.layout.scene1);
+ waitForStart();
+ endTransition();
+ waitForEnd(50);
+ }
+
+ public void testEndTransitionsBeforeStarted() throws Throwable {
+ mTransition.setDuration(400);
+
+ runTestOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ Scene scene = Scene.getSceneForLayout(mSceneRoot, R.layout.scene1, mActivity);
+ TransitionManager.go(scene, mTransition);
+ TransitionManager.endTransitions(mSceneRoot);
+ }
+ });
+ Thread.sleep(50);
+ assertFalse(mTransition.listener.started);
+ assertFalse(mTransition.listener.ended);
+ }
+}
+
diff --git a/tests/tests/transition/src/android/transition/cts/TransitionTest.java b/tests/tests/transition/src/android/transition/cts/TransitionTest.java
new file mode 100644
index 0000000..6ecf8a4
--- /dev/null
+++ b/tests/tests/transition/src/android/transition/cts/TransitionTest.java
@@ -0,0 +1,79 @@
+/*
+ * 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 android.transition.cts;
+
+import com.android.cts.transition.R;
+
+import android.transition.AutoTransition;
+import android.transition.Scene;
+import android.transition.TransitionManager;
+
+public class TransitionTest extends BaseTransitionTest {
+
+ public TransitionTest() {
+ }
+
+ public void testAddListener() throws Throwable {
+ startTransition(R.layout.scene1);
+
+ waitForStart();
+
+ final SimpleTransitionListener listener2 = new SimpleTransitionListener();
+ mTransition.addListener(listener2);
+
+ runTestOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ AutoTransition autoTransition = new AutoTransition();
+ autoTransition.setDuration(100);
+ autoTransition.addListener(listener2);
+ Scene scene = Scene.getSceneForLayout(mSceneRoot, R.layout.scene2, mActivity);
+ TransitionManager.go(scene, autoTransition);
+ }
+ });
+
+ waitForStart(listener2);
+
+ assertTrue(mTransition.listener.paused);
+ assertTrue(mTransition.listener.resumed);
+ assertFalse(mTransition.listener.canceled);
+ assertTrue(mTransition.listener.ended);
+ assertTrue(mTransition.listener.started);
+
+ assertTrue(listener2.paused);
+ assertTrue(listener2.resumed);
+ assertFalse(listener2.canceled);
+ assertTrue(listener2.ended);
+ assertTrue(listener2.started);
+ endTransition();
+ }
+
+ public void testRemoveListener() throws Throwable {
+ startTransition(R.layout.scene1);
+ waitForStart();
+
+ runTestOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ mTransition.removeListener(mTransition.listener);
+ }
+ });
+
+ Thread.sleep(150);
+ assertFalse(mTransition.listener.ended);
+ }
+}
+
diff --git a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/CanvasStateTests.java b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/CanvasStateTests.java
new file mode 100644
index 0000000..becc2f7
--- /dev/null
+++ b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/CanvasStateTests.java
@@ -0,0 +1,126 @@
+/*
+ * 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 android.uirendering.cts.testclasses;
+
+import android.graphics.Canvas;
+import android.graphics.Path;
+import android.graphics.RectF;
+import android.graphics.Region;
+import android.test.suitebuilder.annotation.SmallTest;
+import android.uirendering.cts.testinfrastructure.ActivityTestBase;
+import android.uirendering.cts.testinfrastructure.CanvasClient;
+
+/**
+ * Tests of state query-able from canvas at draw time.
+ *
+ * Although these tests don't verify drawing content, they still make use of ActivityTestBase's
+ * capability to test the hardware accelerated Canvas in the way that it is used by Views.
+ */
+public class CanvasStateTests extends ActivityTestBase {
+
+ @SmallTest
+ public void testClipRectReturnValues() {
+ createTest()
+ .addCanvasClient(new CanvasClient() {
+ @Override
+ public void draw(Canvas canvas, int width, int height) {
+ canvas.save();
+ boolean isNonEmpty = canvas.clipRect(0, 0, 20, 20);
+ assertTrue("clip state should be non empty", isNonEmpty);
+
+ isNonEmpty = canvas.clipRect(0, 40, 20, 60);
+ assertFalse("clip state should be empty", isNonEmpty);
+ canvas.restore();
+ }
+ })
+ .runWithoutVerification();
+ }
+
+ @SmallTest
+ public void testClipRegionReturnValues() {
+ createTest()
+ .addCanvasClient(new CanvasClient() {
+ @Override
+ public void draw(Canvas canvas, int width, int height) {
+ canvas.save();
+ RectF clipRectF = new RectF(0, 0, 20, 20);
+
+ assertFalse(canvas.quickReject(0, 0, 20, 20, Canvas.EdgeType.BW));
+ if (!canvas.isHardwareAccelerated()) {
+ // SW canvas may not be in View space, so we offset the clipping region
+ // so it will operate within the canvas client's window.
+ // (Currently, this isn't necessary, since SW layer size == draw area)
+ canvas.getMatrix().mapRect(clipRectF);
+ }
+
+ Region rectRegion = new Region();
+ rectRegion.set((int) clipRectF.left, (int) clipRectF.top,
+ (int) clipRectF.right, (int) clipRectF.bottom);
+
+ boolean isNonEmpty = canvas.clipRegion(rectRegion);
+ assertTrue("clip state should be non empty", isNonEmpty);
+
+ // Note: we don't test that non-intersecting clip regions empty the clip,
+ // For region clipping, the impl is allowed to return true conservatively
+ // in many cases.
+ canvas.restore();
+ }
+ })
+ .runWithoutVerification();
+ }
+
+ @SmallTest
+ public void testClipPathReturnValues() {
+ createTest()
+ .addCanvasClient(new CanvasClient() {
+ @Override
+ public void draw(Canvas canvas, int width, int height) {
+ canvas.save();
+ Path rectPath = new Path();
+ rectPath.addRect(0, 0, 20, 20, Path.Direction.CW);
+
+ boolean isNonEmpty = canvas.clipPath(rectPath);
+ assertTrue("clip state should be non empty", isNonEmpty);
+
+ rectPath.offset(0, 40);
+ isNonEmpty = canvas.clipPath(rectPath);
+ assertFalse("clip state should be empty", isNonEmpty);
+ canvas.restore();
+ }
+ })
+ .runWithoutVerification();
+ }
+ @SmallTest
+ public void testQuickReject() {
+ createTest()
+ .addCanvasClient(new CanvasClient() {
+ @Override
+ public void draw(Canvas canvas, int width, int height) {
+ canvas.save();
+ canvas.clipRect(0, 0, 20, 20);
+
+ // not rejected!
+ assertFalse(canvas.quickReject(0, 0, 20, 20, Canvas.EdgeType.BW));
+
+ // rejected!
+ assertTrue(canvas.quickReject(0, 40, 20, 60, Canvas.EdgeType.BW));
+ canvas.restore();
+ }
+ })
+ .runWithoutVerification();
+ }
+}
diff --git a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/PathClippingTests.java b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/PathClippingTests.java
index 12ae2a3..2726dac 100644
--- a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/PathClippingTests.java
+++ b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/PathClippingTests.java
@@ -1,3 +1,19 @@
+/*
+ * 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 android.uirendering.cts.testclasses;
import android.graphics.Canvas;
diff --git a/tests/tests/uirendering/src/android/uirendering/cts/testinfrastructure/ActivityTestBase.java b/tests/tests/uirendering/src/android/uirendering/cts/testinfrastructure/ActivityTestBase.java
index 8c5f245..526f4f9 100644
--- a/tests/tests/uirendering/src/android/uirendering/cts/testinfrastructure/ActivityTestBase.java
+++ b/tests/tests/uirendering/src/android/uirendering/cts/testinfrastructure/ActivityTestBase.java
@@ -263,6 +263,20 @@
}
}
+ /**
+ * Runs a test where each testcase is run without verification. Should only be used
+ * where custom CanvasClients, Views, or ViewInitializers do their own internal
+ * test assertions.
+ */
+ public void runWithoutVerification() {
+ runWithVerifier(new BitmapVerifier() {
+ @Override
+ public boolean verify(int[] bitmap, int offset, int stride, int width, int height) {
+ return true;
+ }
+ });
+ }
+
public TestCaseBuilder addWebView(String webViewUrl,
@Nullable ViewInitializer viewInitializer) {
return addWebView(webViewUrl, viewInitializer, false)
diff --git a/tests/tests/widget/src/android/widget/cts/TextViewTest.java b/tests/tests/widget/src/android/widget/cts/TextViewTest.java
index 0f30ca6..ec098f8 100644
--- a/tests/tests/widget/src/android/widget/cts/TextViewTest.java
+++ b/tests/tests/widget/src/android/widget/cts/TextViewTest.java
@@ -78,12 +78,16 @@
import android.util.TypedValue;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
+import android.view.ActionMode;
import android.view.Gravity;
import android.view.KeyEvent;
+import android.view.Menu;
+import android.view.MenuItem;
import android.view.View;
import android.view.View.OnCreateContextMenuListener;
import android.view.View.OnLongClickListener;
import android.view.ViewGroup;
+import android.view.accessibility.AccessibilityNodeInfo;
import android.view.inputmethod.BaseInputConnection;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.ExtractedText;
@@ -4423,6 +4427,135 @@
assertEquals(Layout.HYPHENATION_FREQUENCY_FULL, tv.getHyphenationFrequency());
}
+ public void testSetAndGetCustomSelectionActionModeCallback() {
+ final String text = "abcde";
+ mActivity.runOnUiThread(new Runnable() {
+ public void run() {
+ mTextView = new EditText(mActivity);
+ mActivity.setContentView(mTextView);
+ mTextView.setText(text, BufferType.SPANNABLE);
+ mTextView.setTextIsSelectable(true);
+ mTextView.requestFocus();
+ mTextView.setSelected(true);
+ }
+ });
+ mInstrumentation.waitForIdleSync();
+
+ // Check default value.
+ assertNull(mTextView.getCustomSelectionActionModeCallback());
+
+ MockActionModeCallback callbackBlockActionMode = new MockActionModeCallback(false);
+ mTextView.setCustomSelectionActionModeCallback(callbackBlockActionMode);
+ assertEquals(callbackBlockActionMode,
+ mTextView.getCustomSelectionActionModeCallback());
+
+ mActivity.runOnUiThread(new Runnable() {
+ public void run() {
+ // Set selection and try to start action mode.
+ final Bundle args = new Bundle();
+ args.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_SELECTION_START_INT, 0);
+ args.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_SELECTION_END_INT, text.length());
+ mTextView.performAccessibilityActionInternal(
+ AccessibilityNodeInfo.ACTION_SET_SELECTION, args);
+ }
+ });
+ mInstrumentation.waitForIdleSync();
+
+ assertEquals(1, callbackBlockActionMode.getCreateCount());
+
+ mActivity.runOnUiThread(new Runnable() {
+ public void run() {
+ // Remove selection and stop action mode.
+ mTextView.onTextContextMenuItem(android.R.id.copy);
+ }
+ });
+ mInstrumentation.waitForIdleSync();
+
+ // Action mode was blocked.
+ assertEquals(0, callbackBlockActionMode.getDestroyCount());
+
+ // Overwrite callback.
+ MockActionModeCallback callbackStartActionMode = new MockActionModeCallback(true);
+ mTextView.setCustomSelectionActionModeCallback(callbackStartActionMode);
+ assertEquals(callbackStartActionMode, mTextView.getCustomSelectionActionModeCallback());
+
+ mActivity.runOnUiThread(new Runnable() {
+ public void run() {
+ // Set selection and try to start action mode.
+ final Bundle args = new Bundle();
+ args.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_SELECTION_START_INT, 0);
+ args.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_SELECTION_END_INT, text.length());
+ mTextView.performAccessibilityActionInternal(
+ AccessibilityNodeInfo.ACTION_SET_SELECTION, args);
+
+ }
+ });
+ mInstrumentation.waitForIdleSync();
+
+ assertEquals(1, callbackStartActionMode.getCreateCount());
+
+ mActivity.runOnUiThread(new Runnable() {
+ public void run() {
+ // Remove selection and stop action mode.
+ mTextView.onTextContextMenuItem(android.R.id.copy);
+ }
+ });
+ mInstrumentation.waitForIdleSync();
+
+ // Action mode was started
+ assertEquals(1, callbackStartActionMode.getDestroyCount());
+ }
+
+ public void testSetAndGetCustomInseltionActionMode() {
+ initTextViewForTyping();
+ // Check default value.
+ assertNull(mTextView.getCustomInsertionActionModeCallback());
+
+ MockActionModeCallback callback = new MockActionModeCallback(false);
+ mTextView.setCustomInsertionActionModeCallback(callback);
+ assertEquals(callback, mTextView.getCustomInsertionActionModeCallback());
+ // TODO(Bug: 22033189): Tests the set callback is actually used.
+ }
+
+ private static class MockActionModeCallback implements ActionMode.Callback {
+ private int mCreateCount = 0;
+ private int mDestroyCount = 0;
+ private final boolean mAllowToStartActionMode;
+
+ public MockActionModeCallback(boolean allowToStartActionMode) {
+ mAllowToStartActionMode = allowToStartActionMode;
+ }
+
+ public int getCreateCount() {
+ return mCreateCount;
+ }
+
+ public int getDestroyCount() {
+ return mDestroyCount;
+ }
+
+ @Override
+ public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
+ return false;
+ }
+
+ @Override
+ public void onDestroyActionMode(ActionMode mode) {
+ mDestroyCount++;
+ }
+
+ @Override
+ public boolean onCreateActionMode(ActionMode mode, Menu menu) {
+ mCreateCount++;
+ return mAllowToStartActionMode;
+ }
+
+ @Override
+ public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
+ return false;
+ }
+ };
+
private static class MockOnEditorActionListener implements OnEditorActionListener {
private boolean isOnEditorActionCalled;