Merge "Enforce support for TEL URIs with self-managed CS."
diff --git a/apps/CtsVerifier/res/layout/voicemail_hide_in_call_settings.xml b/apps/CtsVerifier/res/layout/voicemail_hide_in_call_settings.xml
index eb8b81a..4d7803b 100644
--- a/apps/CtsVerifier/res/layout/voicemail_hide_in_call_settings.xml
+++ b/apps/CtsVerifier/res/layout/voicemail_hide_in_call_settings.xml
@@ -46,6 +46,12 @@
</LinearLayout>
<Button
+ android:id="@+id/call_settings_check_not_applicable"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/visual_voicemail_service_remove_sim_not_applicable"/>
+
+ <Button
android:id="@+id/set_default_dialer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
diff --git a/apps/CtsVerifier/res/layout/voicemail_hide_ringtone_settings.xml b/apps/CtsVerifier/res/layout/voicemail_hide_ringtone_settings.xml
index ea11314..9ccd909 100644
--- a/apps/CtsVerifier/res/layout/voicemail_hide_ringtone_settings.xml
+++ b/apps/CtsVerifier/res/layout/voicemail_hide_ringtone_settings.xml
@@ -32,11 +32,18 @@
android:layout_height="wrap_content"
android:text="@string/open_voicemail_settings_explanation"
android:textSize="16dp"/>
+
<Button
- android:id="@+id/open_voicemail_settings"
+ android:id="@+id/voicemail_hide_ringtone_settings_not_applicable"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:text="@string/open_voicemail_settings"/>
+ android:text="@string/visual_voicemail_service_remove_sim_not_applicable"/>
+
+ <Button
+ android:id="@+id/open_voicemail_settings"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/open_voicemail_settings"/>
<LinearLayout
android:layout_width="wrap_content"
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/notifications/AttentionManagementVerifierActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/notifications/AttentionManagementVerifierActivity.java
old mode 100644
new mode 100755
index 199a86f..ddfa283
--- a/apps/CtsVerifier/src/com/android/cts/verifier/notifications/AttentionManagementVerifierActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/notifications/AttentionManagementVerifierActivity.java
@@ -388,7 +388,7 @@
Log.e(TAG, "failed to unpack data from mocklistener", e);
}
}
- pass &= found.size() == 3;
+ pass &= found.size() >= 3;
status = pass ? PASS : FAIL;
}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/notifications/NotificationListenerVerifierActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/notifications/NotificationListenerVerifierActivity.java
old mode 100644
new mode 100755
index 0983580..269f4fd
--- a/apps/CtsVerifier/src/com/android/cts/verifier/notifications/NotificationListenerVerifierActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/notifications/NotificationListenerVerifierActivity.java
@@ -271,9 +271,6 @@
"data integrity test: notification ID (%d, %d)");
pass &= checkEquals(mWhen3, payload.getLong(JSON_WHEN),
"data integrity test: notification when (%d, %d)");
- } else {
- pass = false;
- logFail("unexpected notification tag: " + tag);
}
} catch (JSONException e) {
pass = false;
@@ -281,7 +278,7 @@
}
}
- pass &= found.size() == 3;
+ pass &= found.size() >= 3;
status = pass ? PASS : FAIL;
}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/voicemail/CallSettingsCheckActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/voicemail/CallSettingsCheckActivity.java
index ac0f060..e2e4d30 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/voicemail/CallSettingsCheckActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/voicemail/CallSettingsCheckActivity.java
@@ -21,6 +21,8 @@
import android.telecom.TelecomManager;
import android.view.View;
import android.view.View.OnClickListener;
+import android.widget.Button;
+import android.widget.ImageView;
import com.android.cts.verifier.PassFailButtons;
import com.android.cts.verifier.R;
@@ -32,6 +34,10 @@
private DefaultDialerChanger mDefaultDialerChanger;
+ private Button mSetDefaultDialerButton;
+ private Button mNotApplicableButton;
+ private ImageView mRestoreDefaultDialerImage;
+
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@@ -44,6 +50,22 @@
mDefaultDialerChanger = new DefaultDialerChanger(this);
+ mSetDefaultDialerButton = findViewById(R.id.set_default_dialer);
+ mNotApplicableButton = findViewById(R.id.call_settings_check_not_applicable);
+ mRestoreDefaultDialerImage = findViewById(R.id.restore_default_dialer_image);
+
+ mNotApplicableButton.setOnClickListener(
+ new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ getPassButton().setEnabled(true);
+ mSetDefaultDialerButton.setEnabled(false);
+
+ mRestoreDefaultDialerImage.setImageDrawable(getDrawable(R.drawable.fs_warning));
+ }
+ }
+ );
+
findViewById(R.id.open_call_settings).setOnClickListener(
new OnClickListener() {
@Override
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/voicemail/VoicemailSettingsCheckActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/voicemail/VoicemailSettingsCheckActivity.java
index d4ac0db..f2a7345 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/voicemail/VoicemailSettingsCheckActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/voicemail/VoicemailSettingsCheckActivity.java
@@ -21,6 +21,8 @@
import android.telephony.TelephonyManager;
import android.view.View;
import android.view.View.OnClickListener;
+import android.widget.Button;
+import android.widget.ImageView;
import com.android.cts.verifier.PassFailButtons;
import com.android.cts.verifier.R;
@@ -30,6 +32,13 @@
*/
public class VoicemailSettingsCheckActivity extends PassFailButtons.Activity {
+ private Button mNotApplicableButton;
+ private Button mOpenVoiceMailSettingsButton;
+ private Button mRingtoneSettingsDoesNotExistButton;
+ private Button mRingtoneSettingsExistsButton;
+
+ private ImageView mRestoreDefaultDialerImage;
+
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@@ -40,7 +49,30 @@
setPassFailButtonClickListeners();
getPassButton().setEnabled(false);
- findViewById(R.id.open_voicemail_settings).setOnClickListener(
+
+ mNotApplicableButton = findViewById(R.id.voicemail_hide_ringtone_settings_not_applicable);
+ mOpenVoiceMailSettingsButton = findViewById(R.id.open_voicemail_settings);
+ mRingtoneSettingsDoesNotExistButton = findViewById(R.id.settings_hidden);
+ mRingtoneSettingsExistsButton = findViewById(R.id.settings_not_hidden);
+
+ mRestoreDefaultDialerImage = findViewById(R.id.restore_default_dialer_image);
+
+ mNotApplicableButton.setOnClickListener(
+ new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ getPassButton().setEnabled(true);
+
+ mOpenVoiceMailSettingsButton.setEnabled(false);
+ mRingtoneSettingsDoesNotExistButton.setEnabled(false);
+ mRingtoneSettingsExistsButton.setEnabled(false);
+
+ mRestoreDefaultDialerImage.setImageDrawable(getDrawable(R.drawable.fs_warning));
+ }
+ }
+ );
+
+ mOpenVoiceMailSettingsButton.setOnClickListener(
new OnClickListener() {
@Override
public void onClick(View v) {
@@ -50,7 +82,7 @@
}
);
- findViewById(R.id.settings_hidden).setOnClickListener(
+ mRingtoneSettingsDoesNotExistButton.setOnClickListener(
new OnClickListener() {
@Override
public void onClick(View v) {
@@ -60,7 +92,7 @@
}
);
- findViewById(R.id.settings_not_hidden).setOnClickListener(
+ mRingtoneSettingsExistsButton.setOnClickListener(
new OnClickListener() {
@Override
public void onClick(View v) {
@@ -68,6 +100,5 @@
}
}
);
-
}
}
diff --git a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/MediaPreparer.java b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/MediaPreparer.java
index a9369fa..f011f5e 100644
--- a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/MediaPreparer.java
+++ b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/MediaPreparer.java
@@ -19,12 +19,14 @@
import com.android.compatibility.common.tradefed.targetprep.PreconditionPreparer;
import com.android.compatibility.common.tradefed.util.DynamicConfigFileReader;
import com.android.ddmlib.IDevice;
+import com.android.ddmlib.Log;
import com.android.ddmlib.testrunner.TestIdentifier;
import com.android.tradefed.build.IBuildInfo;
import com.android.tradefed.config.Option;
import com.android.tradefed.config.OptionClass;
import com.android.tradefed.device.DeviceNotAvailableException;
import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.log.LogUtil;
import com.android.tradefed.result.ITestInvocationListener;
import com.android.tradefed.targetprep.BuildError;
import com.android.tradefed.targetprep.TargetSetupError;
@@ -110,6 +112,8 @@
/* Key to retrieve resolution string in metrics upon MediaPreparerListener.testEnded() */
private static final String RESOLUTION_STRING_KEY = "resolution";
+ private static final String LOG_TAG = "MediaPreparer";
+
/*
* In the case of MediaPreparer error, the default maximum resolution to push to the device.
* Pushing higher resolutions may lead to insufficient storage for installing test APKs.
@@ -204,12 +208,22 @@
}
/*
- * Copies the media files to the host from a predefined URL
- * Updates mLocalMediaPath to be the pathname of the directory containing bbb_short and
- * bbb_full media directories.
+ * Copies the media files to the host from a predefined URL.
+ *
+ * Synchronize this static method so that multiple shards won't download/extract
+ * this file to the same location on the host. Only an issue in Android O and above,
+ * where MediaPreparer is used for multiple, shardable modules.
*/
- private void downloadMediaToHost(ITestDevice device, IBuildInfo buildInfo, File mediaFolder)
+ private static synchronized File downloadMediaToHost(ITestDevice device, IBuildInfo buildInfo)
throws TargetSetupError {
+ // Retrieve default directory for storing media files
+ File mediaFolder = getDefaultMediaDir();
+ if (mediaFolder.exists() && mediaFolder.list().length > 0) {
+ // Folder has already been created and populated by previous MediaPreparer runs,
+ // assume all necessary media files exist inside.
+ return mediaFolder;
+ }
+ mediaFolder.mkdirs();
URL url;
try {
// Get download URL from dynamic configuration service
@@ -222,12 +236,13 @@
}
File mediaFolderZip = new File(mediaFolder.getAbsolutePath() + ".zip");
try {
- logInfo("Downloading media files from %s", url.toString());
+ LogUtil.printLog(Log.LogLevel.INFO, LOG_TAG,
+ String.format("Downloading media files from %s", url.toString()));
URLConnection conn = url.openConnection();
InputStream in = conn.getInputStream();
mediaFolderZip.createNewFile();
FileUtil.writeToFile(in, mediaFolderZip);
- logInfo("Unzipping media files");
+ LogUtil.printLog(Log.LogLevel.INFO, LOG_TAG, "Unzipping media files");
ZipUtil.extractZip(new ZipFile(mediaFolderZip), mediaFolder);
} catch (IOException e) {
FileUtil.recursiveDelete(mediaFolder);
@@ -237,6 +252,7 @@
} finally {
FileUtil.deleteFile(mediaFolderZip);
}
+ return mediaFolder;
}
/*
@@ -321,20 +337,8 @@
if (mLocalMediaPath == null) {
// Option 'local-media-path' has not been defined
// Get directory to store media files on this host
- File mediaFolder = getDefaultMediaDir();
- synchronized (MediaPreparer.class) {
- // Synchronize this block so that multiple shards won't download/extract
- // this file to the same location on the host. Only an issue in Android O and above,
- // where MediaPreparer is used for multiple, shardable modules.
- if(!mediaFolder.exists() || mediaFolder.list().length == 0){
- // If directory already exists and contains files, it has been created by
- // previous runs of MediaPreparer. Assume media files exist inside.
- // Else, create directory if needed and download/extract media files inside.
- mediaFolder.mkdirs();
- downloadMediaToHost(device, buildInfo, mediaFolder);
- }
- }
- // set mLocalMediaPath to where the CTS media files have been extracted
+ File mediaFolder = downloadMediaToHost(device, buildInfo);
+ // set mLocalMediaPath to extraction location of media files
updateLocalMediaPath(device, mediaFolder);
}
logInfo("Media files located on host at: %s", mLocalMediaPath);
diff --git a/hostsidetests/incident/apps/graphicsstatsapp/src/com/android/server/cts/device/graphicsstats/DrawFramesActivity.java b/hostsidetests/incident/apps/graphicsstatsapp/src/com/android/server/cts/device/graphicsstats/DrawFramesActivity.java
index 2b9e5a6..65fd3ff 100644
--- a/hostsidetests/incident/apps/graphicsstatsapp/src/com/android/server/cts/device/graphicsstats/DrawFramesActivity.java
+++ b/hostsidetests/incident/apps/graphicsstatsapp/src/com/android/server/cts/device/graphicsstats/DrawFramesActivity.java
@@ -114,7 +114,7 @@
}
private void jank() {
- spinSleep(20);
+ spinSleep(24);
}
private void spinSleep(int durationMs) {
@@ -128,7 +128,7 @@
jankIf(FRAME_JANK_ANIMATION);
});
if (isFrameFlagSet(FRAME_JANK_MISS_VSYNC)) {
- spinSleep(32);
+ spinSleep(45);
}
}
@@ -161,7 +161,7 @@
long timeoutDurationMs = 0;
for (int frame : framesToDraw) {
// 50ms base time + 20ms for every extra jank event
- timeoutDurationMs += 50 + (20 * Integer.bitCount(frame));
+ timeoutDurationMs += 50 + (24 * Integer.bitCount(frame));
if ((frame & FRAME_JANK_DAVEY_JR) != 0) {
timeoutDurationMs += 150;
}
diff --git a/hostsidetests/security/src/android/security/cts/SELinuxHostTest.java b/hostsidetests/security/src/android/security/cts/SELinuxHostTest.java
index 1f0a567..7a9a534 100644
--- a/hostsidetests/security/src/android/security/cts/SELinuxHostTest.java
+++ b/hostsidetests/security/src/android/security/cts/SELinuxHostTest.java
@@ -147,8 +147,13 @@
if (mDevice.doesFileExist("/system/etc/selinux/plat_file_contexts")) {
devicePlatFcFile = getDeviceFile(mDevice, cachedDevicePlatFcFiles,
"/system/etc/selinux/plat_file_contexts", "plat_file_contexts");
- deviceNonplatFcFile = getDeviceFile(mDevice, cachedDeviceNonplatFcFiles,
- "/vendor/etc/selinux/nonplat_file_contexts", "nonplat_file_contexts");
+ if (mDevice.doesFileExist("/vendor/etc/selinux/nonplat_file_contexts")){
+ deviceNonplatFcFile = getDeviceFile(mDevice, cachedDeviceNonplatFcFiles,
+ "/vendor/etc/selinux/nonplat_file_contexts", "nonplat_file_contexts");
+ } else {
+ deviceNonplatFcFile = getDeviceFile(mDevice, cachedDeviceNonplatFcFiles,
+ "/vendor/etc/selinux/vendor_file_contexts", "vendor_file_contexts");
+ }
} else {
devicePlatFcFile = getDeviceFile(mDevice, cachedDevicePlatFcFiles,
"/plat_file_contexts", "plat_file_contexts");
@@ -167,6 +172,9 @@
private static File getDeviceFile(ITestDevice device,
Map<ITestDevice, File> cache, String deviceFilePath,
String tmpFileName) throws Exception {
+ if (!device.doesFileExist(deviceFilePath)){
+ throw new Exception();
+ }
File file;
synchronized (cache) {
file = cache.get(device);
@@ -614,6 +622,7 @@
/* run property_info_checker on property_contexts */
ProcessBuilder pb = new ProcessBuilder(propertyInfoChecker.getAbsolutePath(),
+ devicePolicyFile.getAbsolutePath(),
devicePcFile.getAbsolutePath());
pb.redirectOutput(ProcessBuilder.Redirect.PIPE);
pb.redirectErrorStream(true);
@@ -728,6 +737,24 @@
}
/**
+ * Tests that all types in /proc have the proc_type attribute.
+ *
+ * @throws Exception
+ */
+ public void testProcTypeViolators() throws Exception {
+ assertSepolicyTests("TestProcTypeViolations", "/sepolicy_tests");
+ }
+
+ /**
+ * Tests that all types in /sys have the sysfs_type attribute.
+ *
+ * @throws Exception
+ */
+ public void testSysfsTypeViolators() throws Exception {
+ assertSepolicyTests("TestSysfsTypeViolations", "/sepolicy_tests");
+ }
+
+ /**
* Tests that all types on /vendor have the vendor_file_type attribute.
*
* @throws Exception
diff --git a/hostsidetests/security/src/android/security/cts/SecurityTestCase.java b/hostsidetests/security/src/android/security/cts/SecurityTestCase.java
index 277d591..b6d647a 100644
--- a/hostsidetests/security/src/android/security/cts/SecurityTestCase.java
+++ b/hostsidetests/security/src/android/security/cts/SecurityTestCase.java
@@ -35,10 +35,9 @@
public void setUp() throws Exception {
super.setUp();
- String cmdOut = getDevice().executeShellCommand("dumpsys meminfo");
- long uptime = Long.parseLong(cmdOut.substring(cmdOut.indexOf("Uptime: ") + 8,
- cmdOut.indexOf("Realtime: ") - 1))/1000;
- kernelStartTime = System.currentTimeMillis()/1000 - uptime;
+ String uptime = getDevice().executeShellCommand("cat /proc/uptime");
+ kernelStartTime = System.currentTimeMillis()/1000 -
+ Integer.parseInt(uptime.substring(0, uptime.indexOf('.')));
//TODO:(badash@): Watch for other things to track.
// Specifically time when app framework starts
}
@@ -86,11 +85,11 @@
@Override
public void tearDown() throws Exception {
getDevice().waitForDeviceOnline(60 * 1000);
- String cmdOut = getDevice().executeShellCommand("dumpsys meminfo");
- long uptime = Long.parseLong(cmdOut.substring(cmdOut.indexOf("Uptime: ") + 8,
- cmdOut.indexOf("Realtime: ") - 1))/1000;
+ String uptime = getDevice().executeShellCommand("cat /proc/uptime");
assertTrue("Phone has had a hard reset",
- (System.currentTimeMillis()/1000 - uptime - kernelStartTime < 2));
+ (System.currentTimeMillis()/1000 -
+ Integer.parseInt(uptime.substring(0, uptime.indexOf('.')))
+ - kernelStartTime < 2));
//TODO(badash@): add ability to catch runtime restart
getDevice().disableAdbRoot();
}
diff --git a/hostsidetests/theme/assets/26/213dpi.zip b/hostsidetests/theme/assets/26/213dpi.zip
new file mode 100755
index 0000000..38531ba
--- /dev/null
+++ b/hostsidetests/theme/assets/26/213dpi.zip
Binary files differ
diff --git a/tests/autofillservice/src/android/autofillservice/cts/AutofillLoggingTestRule.java b/tests/autofillservice/src/android/autofillservice/cts/AutofillLoggingTestRule.java
index 92a19a3..e0ff683 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/AutofillLoggingTestRule.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/AutofillLoggingTestRule.java
@@ -20,6 +20,7 @@
import android.util.Log;
+import org.junit.AssumptionViolatedException;
import org.junit.rules.TestRule;
import org.junit.runner.Description;
import org.junit.runners.model.Statement;
@@ -52,8 +53,14 @@
try {
base.evaluate();
} catch (Throwable t) {
- final String dump = runShellCommand("dumpsys autofill");
- Log.e(mTag, "dump for " + description.getDisplayName() + ": \n" + dump, t);
+ if ((t instanceof AssumptionViolatedException)) {
+ // This exception is used to indicate a test should be skipped and is
+ // ignored by JUnit runners - we don't need to dump it...
+ Log.w(mTag, "ignoring exception: " + t);
+ } else {
+ final String dump = runShellCommand("dumpsys autofill");
+ Log.e(mTag, "dump for " + description.getDisplayName() + ": \n" + dump, t);
+ }
throw t;
} finally {
if (!levelBefore.equals("verbose")) {
diff --git a/tests/autofillservice/src/android/autofillservice/cts/CustomDescriptionWithLinkTestCase.java b/tests/autofillservice/src/android/autofillservice/cts/CustomDescriptionWithLinkTestCase.java
index 9130810..8d66e15 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/CustomDescriptionWithLinkTestCase.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/CustomDescriptionWithLinkTestCase.java
@@ -19,12 +19,15 @@
import static com.google.common.truth.Truth.assertThat;
+import static org.junit.Assume.assumeTrue;
+
import android.app.Activity;
import android.app.PendingIntent;
import android.content.Intent;
import android.service.autofill.CustomDescription;
import android.support.test.uiautomator.By;
import android.support.test.uiautomator.UiObject2;
+import android.util.Log;
import android.widget.RemoteViews;
import org.junit.Ignore;
@@ -46,6 +49,7 @@
*/
abstract class CustomDescriptionWithLinkTestCase extends AutoFillServiceTestCase {
+ private static final String TAG = "CustomDescriptionWithLinkTestCase";
private static final String ID_LINK = "link";
/**
@@ -64,8 +68,17 @@
*/
@Test
public final void testTapLink_changeOrientationThenTapBack() throws Exception {
+ final int width = sUiBot.getDevice().getDisplayWidth();
+ final int heigth = sUiBot.getDevice().getDisplayHeight();
+ final int min = Math.min(width, heigth);
+
+ assumeTrue("Screen size is too small (" + width + "x" + heigth + ")", min >= 500);
+ Log.d(TAG, "testTapLink_changeOrientationThenTapBack(): screen size is "
+ + width + "x" + heigth);
+
sUiBot.setScreenOrientation(UiBot.PORTRAIT);
try {
+ runShellCommand("wm size 1080x1920");
runShellCommand("wm density 420");
saveUiRestoredAfterTappingLinkTest(
PostSaveLinkTappedAction.ROTATE_THEN_TAP_BACK_BUTTON);
@@ -75,6 +88,7 @@
cleanUpAfterScreenOrientationIsBackToPortrait();
} finally {
runShellCommand("wm density reset");
+ runShellCommand("wm size reset");
}
}
}
diff --git a/tests/autofillservice/src/android/autofillservice/cts/UiBot.java b/tests/autofillservice/src/android/autofillservice/cts/UiBot.java
index fffde3e..db81baf 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/UiBot.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/UiBot.java
@@ -99,6 +99,10 @@
mAutoman = instrumentation.getUiAutomation();
}
+ UiDevice getDevice() {
+ return mDevice;
+ }
+
/**
* Asserts the dataset chooser is not shown.
*/
diff --git a/tests/tests/carrierapi/src/android/carrierapi/cts/ApnDatabaseTest.java b/tests/tests/carrierapi/src/android/carrierapi/cts/ApnDatabaseTest.java
index 372f22c..28afabc 100644
--- a/tests/tests/carrierapi/src/android/carrierapi/cts/ApnDatabaseTest.java
+++ b/tests/tests/carrierapi/src/android/carrierapi/cts/ApnDatabaseTest.java
@@ -17,23 +17,19 @@
import android.content.ContentResolver;
import android.content.ContentValues;
+import android.content.pm.PackageManager;
import android.database.Cursor;
import android.database.sqlite.SQLiteException;
import android.net.Uri;
import android.provider.Telephony.Carriers;
import android.support.test.InstrumentationRegistry;
import android.support.test.runner.AndroidJUnit4;
-import android.test.InstrumentationTestCase;
import android.util.Log;
-import com.android.internal.telephony.uicc.IccUtils;
-
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
@@ -53,6 +49,8 @@
private static final String TAG = "ApnDatabaseTest";
private ContentResolver mContentResolver;
+ private PackageManager mPackageManager;
+ private boolean mHasCellular;
private static final String NAME = "carrierName";
private static final String APN = "apn";
@@ -99,6 +97,12 @@
@Before
public void setUp() throws Exception {
mContentResolver = InstrumentationRegistry.getContext().getContentResolver();
+ mPackageManager = InstrumentationRegistry.getContext().getPackageManager();
+ // Checks whether the cellular stack should be running on this device.
+ mHasCellular = mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY);
+ if (!mHasCellular) {
+ Log.e(TAG, "No cellular support, all tests will be skipped.");
+ }
}
private void failMessage() {
@@ -112,6 +116,7 @@
*/
@Test
public void testValidCase() {
+ if (!mHasCellular) return;
Uri uri = Carriers.CONTENT_URI;
// CONTENT_URI = Uri.parse("content://telephony/carriers");
// Create A set of column_name/value pairs to add to the database.
@@ -179,6 +184,7 @@
@Test
public void testQueryConflictCase() {
+ if (!mHasCellular) return;
String invalidColumn = "random";
Uri uri = Carriers.CONTENT_URI;
// CONTENT_URI = Uri.parse("content://telephony/carriers");
@@ -234,6 +240,7 @@
@Test
public void testUpdateConflictCase() {
+ if (!mHasCellular) return;
Uri uri = Carriers.CONTENT_URI;
// CONTENT_URI = Uri.parse("content://telephony/carriers");
// Create A set of column_name/value pairs to add to the database.
@@ -300,6 +307,7 @@
@Test
public void testDeleteConflictCase() {
+ if (!mHasCellular) return;
String invalidColumn = "random";
Uri uri = Carriers.CONTENT_URI;
// CONTENT_URI = Uri.parse("content://telephony/carriers");
diff --git a/tests/tests/carrierapi/src/android/carrierapi/cts/NetworkScanApiTest.java b/tests/tests/carrierapi/src/android/carrierapi/cts/NetworkScanApiTest.java
index 63f8347..353b04a 100644
--- a/tests/tests/carrierapi/src/android/carrierapi/cts/NetworkScanApiTest.java
+++ b/tests/tests/carrierapi/src/android/carrierapi/cts/NetworkScanApiTest.java
@@ -16,6 +16,7 @@
package android.carrierapi.cts;
import android.content.Context;
+import android.content.pm.PackageManager;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Message;
@@ -52,6 +53,7 @@
@RunWith(AndroidJUnit4.class)
public class NetworkScanApiTest {
private TelephonyManager mTelephonyManager;
+ private PackageManager mPackageManager;
private static final String TAG = "NetworkScanApiTest";
private int mNetworkScanStatus;
private static final int EVENT_NETWORK_SCAN_START = 100;
@@ -72,6 +74,7 @@
public void setUp() throws Exception {
mTelephonyManager = (TelephonyManager)
InstrumentationRegistry.getContext().getSystemService(Context.TELEPHONY_SERVICE);
+ mPackageManager = InstrumentationRegistry.getContext().getPackageManager();
mTestHandlerThread = new NetworkScanHandlerThread(TAG);
mTestHandlerThread.start();
}
@@ -179,6 +182,11 @@
*/
@Test
public void testRequestNetworkScan() throws InterruptedException {
+ if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
+ // Checks whether the cellular stack should be running on this device.
+ Log.e(TAG, "No cellular support, the test will be skipped.");
+ return;
+ }
if (!mTelephonyManager.hasCarrierPrivileges()) {
fail("This test requires a SIM card with carrier privilege rule on it.");
}
diff --git a/tests/tests/content/src/android/content/cts/AvailableIntentsTest.java b/tests/tests/content/src/android/content/cts/AvailableIntentsTest.java
index dbebbc0..3a016bc 100644
--- a/tests/tests/content/src/android/content/cts/AvailableIntentsTest.java
+++ b/tests/tests/content/src/android/content/cts/AvailableIntentsTest.java
@@ -331,8 +331,12 @@
public void testManageStorage() {
assertCanBeHandled(new Intent(StorageManager.ACTION_MANAGE_STORAGE));
}
-
+
public void testVoiceCommand() {
+ if (FeatureUtil.isLowRam()) {
+ // Low ram devices do not support voice command, skip this test
+ return;
+ }
PackageManager packageManager = mContext.getPackageManager();
if (packageManager.hasSystemFeature(PackageManager.FEATURE_MICROPHONE)) {
Intent intent = new Intent(Intent.ACTION_VOICE_COMMAND);
diff --git a/tests/tests/graphics/src/android/graphics/drawable/cts/InsetDrawableTest.java b/tests/tests/graphics/src/android/graphics/drawable/cts/InsetDrawableTest.java
index fd1ed3e..b1c1f03 100644
--- a/tests/tests/graphics/src/android/graphics/drawable/cts/InsetDrawableTest.java
+++ b/tests/tests/graphics/src/android/graphics/drawable/cts/InsetDrawableTest.java
@@ -498,8 +498,8 @@
final Theme t = res.newTheme();
halfDrawable.applyTheme(t);
float approxDouble = 1 / approxHalf;
- // Reproduce imprecise truncated scale down, and back up. Note that we don't round.
- assertEquals((int)(approxDouble * ((int)(origInsetHoriz * approxHalf))),
+ // Reproduce imprecise truncated scale down, and back up.
+ assertEquals(Math.round(approxDouble * Math.round(origInsetHoriz * approxHalf)),
halfDrawable.getIntrinsicWidth() - halfDrawable.getDrawable().getIntrinsicWidth());
doubleDrawable.applyTheme(t);
assertEquals(origInsetHoriz, doubleDrawable.getIntrinsicWidth()
diff --git a/tests/tests/media/Android.mk b/tests/tests/media/Android.mk
index aab6b26..549f3d5 100644
--- a/tests/tests/media/Android.mk
+++ b/tests/tests/media/Android.mk
@@ -57,6 +57,8 @@
LOCAL_JNI_SHARED_LIBRARIES := \
libaudio_jni \
+ libc++ \
+ libctscodecutils_jni \
libctsimagereader_jni \
libctsmediadrm_jni \
libctsmediacodec_jni \
diff --git a/tests/tests/media/libaudiojni/Android.mk b/tests/tests/media/libaudiojni/Android.mk
index d1b1ced..af9d989 100644
--- a/tests/tests/media/libaudiojni/Android.mk
+++ b/tests/tests/media/libaudiojni/Android.mk
@@ -35,7 +35,7 @@
$(call include-path-for, wilhelm)
LOCAL_SHARED_LIBRARIES := libandroid liblog libnativehelper_compat_libc++ libOpenSLES
-LOCAL_CXX_STL := libc++_static
+LOCAL_CXX_STL := libc++
LOCAL_CFLAGS := -Werror -Wall
diff --git a/tests/tests/media/libimagereaderjni/Android.mk b/tests/tests/media/libimagereaderjni/Android.mk
index 70699a7..6ce591c 100644
--- a/tests/tests/media/libimagereaderjni/Android.mk
+++ b/tests/tests/media/libimagereaderjni/Android.mk
@@ -31,8 +31,7 @@
libnativewindow \
liblog
-LOCAL_SDK_VERSION := current
-LOCAL_NDK_STL_VARIANT := c++_static
+LOCAL_CXX_STL := libc++
LOCAL_CFLAGS := -Werror -Wall
diff --git a/tests/tests/media/libmediandkjni/Android.mk b/tests/tests/media/libmediandkjni/Android.mk
index 287fc3e..e0af7dc 100644
--- a/tests/tests/media/libmediandkjni/Android.mk
+++ b/tests/tests/media/libmediandkjni/Android.mk
@@ -15,6 +15,37 @@
LOCAL_PATH := $(call my-dir)
#------------------------------------------------------------------------------
+# Builds libctscodecutils_jni.so
+#
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := libctscodecutils_jni
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_SRC_FILES := \
+ codec-utils-jni.cpp \
+ md5_utils.cpp
+
+LOCAL_C_INCLUDES := \
+ $(JNI_H_INCLUDE) \
+ system/core/include
+
+LOCAL_C_INCLUDES += $(call include-path-for, mediandk)
+
+LOCAL_SHARED_LIBRARIES := \
+ libnativehelper_compat_libc++ \
+ liblog
+
+LOCAL_SDK_VERSION := current
+
+LOCAL_NDK_STL_VARIANT := system
+
+LOCAL_CFLAGS := -Werror -Wall -DEGL_EGLEXT_PROTOTYPES -std=gnu++14
+
+include $(BUILD_SHARED_LIBRARY)
+
+#------------------------------------------------------------------------------
# Builds libctsmediacodec_jni.so
#
include $(CLEAR_VARS)
@@ -25,8 +56,6 @@
LOCAL_SRC_FILES := \
native-media-jni.cpp \
- codec-utils-jni.cpp \
- md5_utils.cpp \
native_media_utils.cpp \
native_media_decoder_source.cpp \
native_media_encoder_jni.cpp
@@ -40,14 +69,14 @@
LOCAL_SHARED_LIBRARIES := \
libandroid libnativehelper_compat_libc++ \
liblog libmediandk libEGL
-LOCAL_NDK_STL_VARIANT := c++_static
-LOCAL_SDK_VERSION := current
+LOCAL_CXX_STL := libc++
LOCAL_CFLAGS := -Werror -Wall -DEGL_EGLEXT_PROTOTYPES -std=gnu++14
include $(BUILD_SHARED_LIBRARY)
+
#------------------------------------------------------------------------------
# Builds libctsmediadrm_jni.so
#
@@ -75,10 +104,8 @@
libandroid libnativehelper_compat_libc++ \
liblog libmediandk libdl libEGL
-LOCAL_SDK_VERSION := current
-
LOCAL_CFLAGS := -Werror -Wall -DEGL_EGLEXT_PROTOTYPES
-LOCAL_NDK_STL_VARIANT := c++_static
+LOCAL_CXX_STL := libc++
include $(BUILD_SHARED_LIBRARY)
diff --git a/tests/tests/media/libmediandkjni/codec-utils-jni.cpp b/tests/tests/media/libmediandkjni/codec-utils-jni.cpp
index d7bd74e..5525e4e 100644
--- a/tests/tests/media/libmediandkjni/codec-utils-jni.cpp
+++ b/tests/tests/media/libmediandkjni/codec-utils-jni.cpp
@@ -24,6 +24,13 @@
#include <sys/types.h>
#include <jni.h>
+// workaround for using ScopedLocalRef with system runtime
+// TODO: Remove this after b/74632104 is fixed
+namespace std
+{
+ typedef decltype(nullptr) nullptr_t;
+}
+
#include <nativehelper/JNIHelp.h>
#include <nativehelper/ScopedLocalRef.h>
diff --git a/tests/tests/media/libndkaudio/Android.mk b/tests/tests/media/libndkaudio/Android.mk
index 29e2118..16e490e 100644
--- a/tests/tests/media/libndkaudio/Android.mk
+++ b/tests/tests/media/libndkaudio/Android.mk
@@ -37,7 +37,7 @@
AudioRecorder.cpp \
com_android_ndkaudio_AudioRecorder.cpp
-LOCAL_CXX_STL := libc++_static
+LOCAL_CXX_STL := libc++
LOCAL_SHARED_LIBRARIES := liblog libOpenSLES
diff --git a/tests/tests/media/src/android/media/cts/CodecUtils.java b/tests/tests/media/src/android/media/cts/CodecUtils.java
index 24c1174..ae785b2 100644
--- a/tests/tests/media/src/android/media/cts/CodecUtils.java
+++ b/tests/tests/media/src/android/media/cts/CodecUtils.java
@@ -38,7 +38,7 @@
/** Load jni on initialization */
static {
Log.i(TAG, "before loadlibrary");
- System.loadLibrary("ctsmediacodec_jni");
+ System.loadLibrary("ctscodecutils_jni");
Log.i(TAG, "after loadlibrary");
}
diff --git a/tests/tests/media/src/android/media/cts/MediaMetadataRetrieverTest.java b/tests/tests/media/src/android/media/cts/MediaMetadataRetrieverTest.java
index c453f4d..58d803e 100644
--- a/tests/tests/media/src/android/media/cts/MediaMetadataRetrieverTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaMetadataRetrieverTest.java
@@ -342,6 +342,12 @@
*/
public void testGetScaledFrameAtTime() {
int resId = R.raw.binary_counter_320x240_30fps_600frames;
+ if (!MediaUtils.hasCodecForResourceAndDomain(getContext(), resId, "video/")
+ && mPackageManager.hasSystemFeature(PackageManager.FEATURE_WATCH)) {
+ MediaUtils.skipTest("no video codecs for resource on watch");
+ return;
+ }
+
MediaMetadataRetriever retriever = new MediaMetadataRetriever();
Resources resources = getContext().getResources();
AssetFileDescriptor afd = resources.openRawResourceFd(resId);
diff --git a/tests/tests/net/src/android/net/cts/ConnectivityManagerTest.java b/tests/tests/net/src/android/net/cts/ConnectivityManagerTest.java
index c885942..9de47bf 100644
--- a/tests/tests/net/src/android/net/cts/ConnectivityManagerTest.java
+++ b/tests/tests/net/src/android/net/cts/ConnectivityManagerTest.java
@@ -18,11 +18,16 @@
import static android.net.NetworkCapabilities.NET_CAPABILITY_IMS;
import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED;
import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
+import static android.provider.Settings.Global.NETWORK_METERED_MULTIPATH_PREFERENCE;
+import static com.android.compatibility.common.util.SystemUtil.runShellCommand;
+import android.app.Instrumentation;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
+import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
@@ -38,12 +43,17 @@
import android.net.NetworkRequest;
import android.net.wifi.WifiManager;
import android.os.Looper;
+import android.os.SystemClock;
import android.os.SystemProperties;
+import android.provider.Settings;
+import android.support.test.InstrumentationRegistry;
import android.system.Os;
import android.system.OsConstants;
import android.test.AndroidTestCase;
+import android.text.TextUtils;
import android.util.Log;
+import com.android.internal.R;
import com.android.internal.telephony.PhoneConstants;
import java.io.File;
@@ -51,6 +61,7 @@
import java.io.InputStream;
import java.io.IOException;
import java.io.OutputStream;
+import java.lang.NumberFormatException;
import java.net.Socket;
import java.net.InetSocketAddress;
import java.util.HashMap;
@@ -58,6 +69,8 @@
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
public class ConnectivityManagerTest extends AndroidTestCase {
@@ -72,6 +85,9 @@
private static final String TEST_HOST = "connectivitycheck.gstatic.com";
private static final int SOCKET_TIMEOUT_MS = 2000;
private static final int SEND_BROADCAST_TIMEOUT = 30000;
+ private static final int NETWORK_CHANGE_METEREDNESS_TIMEOUT = 5000;
+ private static final int NUM_TRIES_MULTIPATH_PREF_CHECK = 20;
+ private static final long INTERVAL_MULTIPATH_PREF_CHECK_MS = 500;
private static final int HTTP_PORT = 80;
private static final String HTTP_REQUEST =
"GET /generate_204 HTTP/1.0\r\n" +
@@ -101,6 +117,7 @@
private static final int MIN_NUM_NETWORK_TYPES = 1;
private Context mContext;
+ private Instrumentation mInstrumentation;
private ConnectivityManager mCm;
private WifiManager mWifiManager;
private PackageManager mPackageManager;
@@ -113,6 +130,7 @@
super.setUp();
Looper.prepare();
mContext = getContext();
+ mInstrumentation = InstrumentationRegistry.getInstrumentation();
mCm = (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
mWifiManager = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE);
mPackageManager = mContext.getPackageManager();
@@ -835,4 +853,146 @@
assertTrue(lowerBoundSec <= interval);
assertTrue(interval <= upperBoundSec);
}
+
+ // Returns "true", "false" or "none"
+ private String getWifiMeteredStatus(String ssid) throws Exception {
+ // Interestingly giving the SSID as an argument to list wifi-networks
+ // only works iff the network in question has the "false" policy.
+ // Also unfortunately runShellCommand does not pass the command to the interpreter
+ // so it's not possible to | grep the ssid.
+ final String command = "cmd netpolicy list wifi-networks";
+ final String policyString = runShellCommand(mInstrumentation, command);
+
+ final Matcher m = Pattern.compile("^" + ssid + ";(true|false|none)$",
+ Pattern.MULTILINE | Pattern.UNIX_LINES).matcher(policyString);
+ if (!m.find()) {
+ fail("Unexpected format from cmd netpolicy");
+ }
+ return m.group(1);
+ }
+
+ // metered should be "true", "false" or "none"
+ private void setWifiMeteredStatus(String ssid, String metered) throws Exception {
+ final String setCommand = "cmd netpolicy set metered-network " + ssid + " " + metered;
+ runShellCommand(mInstrumentation, setCommand);
+ assertEquals(getWifiMeteredStatus(ssid), metered);
+ }
+
+ private String unquoteSSID(String ssid) {
+ // SSID is returned surrounded by quotes if it can be decoded as UTF-8.
+ // Otherwise it's guaranteed not to start with a quote.
+ if (ssid.charAt(0) == '"') {
+ return ssid.substring(1, ssid.length() - 1);
+ } else {
+ return ssid;
+ }
+ }
+
+ private void waitForActiveNetworkMetered(boolean requestedMeteredness) throws Exception {
+ final CountDownLatch latch = new CountDownLatch(1);
+ final NetworkCallback networkCallback = new NetworkCallback() {
+ @Override
+ public void onCapabilitiesChanged(Network network, NetworkCapabilities nc) {
+ final boolean metered = !nc.hasCapability(NET_CAPABILITY_NOT_METERED);
+ if (metered == requestedMeteredness) {
+ latch.countDown();
+ }
+ }
+ };
+ // Registering a callback here guarantees onCapabilitiesChanged is called immediately
+ // with the current setting. Therefore, if the setting has already been changed,
+ // this method will return right away, and if not it will wait for the setting to change.
+ mCm.registerDefaultNetworkCallback(networkCallback);
+ if (!latch.await(NETWORK_CHANGE_METEREDNESS_TIMEOUT, TimeUnit.MILLISECONDS)) {
+ fail("Timed out waiting for active network metered status to change to "
+ + requestedMeteredness + " ; network = " + mCm.getActiveNetwork());
+ }
+ mCm.unregisterNetworkCallback(networkCallback);
+ }
+
+ private void assertMultipathPreferenceIsEventually(Network network, int oldValue,
+ int expectedValue) {
+ // Sanity check : if oldValue == expectedValue, there is no way to guarantee the test
+ // is not flaky.
+ assertNotSame(oldValue, expectedValue);
+
+ for (int i = 0; i < NUM_TRIES_MULTIPATH_PREF_CHECK; ++i) {
+ final int actualValue = mCm.getMultipathPreference(network);
+ if (actualValue == expectedValue) {
+ return;
+ }
+ if (actualValue != oldValue) {
+ fail("Multipath preference is neither previous (" + oldValue
+ + ") nor expected (" + expectedValue + ")");
+ }
+ SystemClock.sleep(INTERVAL_MULTIPATH_PREF_CHECK_MS);
+ }
+ fail("Timed out waiting for multipath preference to change. expected = "
+ + expectedValue + " ; actual = " + mCm.getMultipathPreference(network));
+ }
+
+ private int getCurrentMeteredMultipathPreference(ContentResolver resolver) {
+ final String rawMeteredPref = Settings.Global.getString(resolver,
+ NETWORK_METERED_MULTIPATH_PREFERENCE);
+ return TextUtils.isEmpty(rawMeteredPref)
+ ? mContext.getResources().getInteger(R.integer.config_networkMeteredMultipathPreference)
+ : Integer.parseInt(rawMeteredPref);
+ }
+
+ private int findNextPrefValue(ContentResolver resolver) {
+ // A bit of a nuclear hammer, but race conditions in CTS are bad. To be able to
+ // detect a correct setting value without race conditions, the next pref must
+ // be a valid value (range 0..3) that is different from the old setting of the
+ // metered preference and from the unmetered preference.
+ final int meteredPref = getCurrentMeteredMultipathPreference(resolver);
+ final int unmeteredPref = ConnectivityManager.MULTIPATH_PREFERENCE_UNMETERED;
+ if (0 != meteredPref && 0 != unmeteredPref) return 0;
+ if (1 != meteredPref && 1 != unmeteredPref) return 1;
+ return 2;
+ }
+
+ /**
+ * Verify that getMultipathPreference does return appropriate values
+ * for metered and unmetered networks.
+ */
+ public void testGetMultipathPreference() throws Exception {
+ final ContentResolver resolver = mContext.getContentResolver();
+ final Network network = ensureWifiConnected();
+ final String ssid = unquoteSSID(mWifiManager.getConnectionInfo().getSSID());
+ final String oldMeteredSetting = getWifiMeteredStatus(ssid);
+ final String oldMeteredMultipathPreference = Settings.Global.getString(
+ resolver, NETWORK_METERED_MULTIPATH_PREFERENCE);
+ try {
+ final int initialMeteredPreference = getCurrentMeteredMultipathPreference(resolver);
+ int newMeteredPreference = findNextPrefValue(resolver);
+ Settings.Global.putString(resolver, NETWORK_METERED_MULTIPATH_PREFERENCE,
+ Integer.toString(newMeteredPreference));
+ setWifiMeteredStatus(ssid, "true");
+ waitForActiveNetworkMetered(true);
+ assertEquals(mCm.getNetworkCapabilities(network).hasCapability(
+ NET_CAPABILITY_NOT_METERED), false);
+ assertMultipathPreferenceIsEventually(network, initialMeteredPreference,
+ newMeteredPreference);
+
+ final int oldMeteredPreference = newMeteredPreference;
+ newMeteredPreference = findNextPrefValue(resolver);
+ Settings.Global.putString(resolver, NETWORK_METERED_MULTIPATH_PREFERENCE,
+ Integer.toString(newMeteredPreference));
+ assertEquals(mCm.getNetworkCapabilities(network).hasCapability(
+ NET_CAPABILITY_NOT_METERED), false);
+ assertMultipathPreferenceIsEventually(network,
+ oldMeteredPreference, newMeteredPreference);
+
+ setWifiMeteredStatus(ssid, "false");
+ waitForActiveNetworkMetered(false);
+ assertEquals(mCm.getNetworkCapabilities(network).hasCapability(
+ NET_CAPABILITY_NOT_METERED), true);
+ assertMultipathPreferenceIsEventually(network, newMeteredPreference,
+ ConnectivityManager.MULTIPATH_PREFERENCE_UNMETERED);
+ } finally {
+ Settings.Global.putString(resolver, NETWORK_METERED_MULTIPATH_PREFERENCE,
+ oldMeteredMultipathPreference);
+ setWifiMeteredStatus(ssid, oldMeteredSetting);
+ }
+ }
}
diff --git a/tests/tests/net/src/android/net/cts/IpSecBaseTest.java b/tests/tests/net/src/android/net/cts/IpSecBaseTest.java
new file mode 100644
index 0000000..7132ecf
--- /dev/null
+++ b/tests/tests/net/src/android/net/cts/IpSecBaseTest.java
@@ -0,0 +1,518 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.cts;
+
+import static org.junit.Assert.assertArrayEquals;
+
+import android.content.Context;
+import android.net.IpSecAlgorithm;
+import android.net.IpSecManager;
+import android.net.IpSecTransform;
+import android.system.Os;
+import android.system.OsConstants;
+import android.test.AndroidTestCase;
+import android.util.Log;
+
+import java.io.FileDescriptor;
+import java.io.IOException;
+import java.net.DatagramPacket;
+import java.net.DatagramSocket;
+import java.net.Inet4Address;
+import java.net.Inet6Address;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.net.SocketException;
+import java.util.Arrays;
+import java.util.concurrent.atomic.AtomicInteger;
+
+public class IpSecBaseTest extends AndroidTestCase {
+
+ private static final String TAG = IpSecBaseTest.class.getSimpleName();
+
+ protected static final String IPV4_LOOPBACK = "127.0.0.1";
+ protected static final String IPV6_LOOPBACK = "::1";
+ protected static final String[] LOOPBACK_ADDRS = new String[] {IPV4_LOOPBACK, IPV6_LOOPBACK};
+ protected static final int[] DIRECTIONS =
+ new int[] {IpSecManager.DIRECTION_IN, IpSecManager.DIRECTION_OUT};
+
+ protected static final byte[] TEST_DATA = "Best test data ever!".getBytes();
+ protected static final int DATA_BUFFER_LEN = 4096;
+ protected static final int SOCK_TIMEOUT = 500;
+
+ private static final byte[] KEY_DATA = {
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
+ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+ 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
+ 0x20, 0x21, 0x22, 0x23
+ };
+
+ protected static final byte[] AUTH_KEY = getKey(256);
+ protected static final byte[] CRYPT_KEY = getKey(256);
+
+ protected IpSecManager mISM;
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ mISM = (IpSecManager) getContext().getSystemService(Context.IPSEC_SERVICE);
+ }
+
+ protected static byte[] getKey(int bitLength) {
+ return Arrays.copyOf(KEY_DATA, bitLength / 8);
+ }
+
+ protected static int getDomain(InetAddress address) {
+ int domain;
+ if (address instanceof Inet6Address) {
+ domain = OsConstants.AF_INET6;
+ } else {
+ domain = OsConstants.AF_INET;
+ }
+ return domain;
+ }
+
+ protected static int getPort(FileDescriptor sock) throws Exception {
+ return ((InetSocketAddress) Os.getsockname(sock)).getPort();
+ }
+
+ public static interface GenericSocket extends AutoCloseable {
+ void send(byte[] data) throws Exception;
+
+ byte[] receive() throws Exception;
+
+ int getPort() throws Exception;
+
+ void close() throws Exception;
+
+ void applyTransportModeTransform(
+ IpSecManager ism, int direction, IpSecTransform transform) throws Exception;
+
+ void removeTransportModeTransforms(IpSecManager ism) throws Exception;
+ }
+
+ public static interface GenericTcpSocket extends GenericSocket {}
+
+ public static interface GenericUdpSocket extends GenericSocket {
+ void sendTo(byte[] data, InetAddress dstAddr, int port) throws Exception;
+ }
+
+ public abstract static class NativeSocket implements GenericSocket {
+ public FileDescriptor mFd;
+
+ public NativeSocket(FileDescriptor fd) {
+ mFd = fd;
+ }
+
+ @Override
+ public void send(byte[] data) throws Exception {
+ Os.write(mFd, data, 0, data.length);
+ }
+
+ @Override
+ public byte[] receive() throws Exception {
+ byte[] in = new byte[DATA_BUFFER_LEN];
+ AtomicInteger bytesRead = new AtomicInteger(-1);
+
+ Thread readSockThread = new Thread(() -> {
+ long startTime = System.currentTimeMillis();
+ while (bytesRead.get() < 0 && System.currentTimeMillis() < startTime + SOCK_TIMEOUT) {
+ try {
+ bytesRead.set(Os.recvfrom(mFd, in, 0, DATA_BUFFER_LEN, 0, null));
+ } catch (Exception e) {
+ Log.e(TAG, "Error encountered reading from socket", e);
+ }
+ }
+ });
+
+ readSockThread.start();
+ readSockThread.join(SOCK_TIMEOUT);
+
+ if (bytesRead.get() < 0) {
+ throw new IOException("No data received from socket");
+ }
+
+ return Arrays.copyOfRange(in, 0, bytesRead.get());
+ }
+
+ @Override
+ public int getPort() throws Exception {
+ return IpSecBaseTest.getPort(mFd);
+ }
+
+ @Override
+ public void close() throws Exception {
+ Os.close(mFd);
+ }
+
+ @Override
+ public void applyTransportModeTransform(
+ IpSecManager ism, int direction, IpSecTransform transform) throws Exception {
+ ism.applyTransportModeTransform(mFd, direction, transform);
+ }
+
+ @Override
+ public void removeTransportModeTransforms(IpSecManager ism) throws Exception {
+ ism.removeTransportModeTransforms(mFd);
+ }
+ }
+
+ public static class NativeTcpSocket extends NativeSocket implements GenericTcpSocket {
+ public NativeTcpSocket(FileDescriptor fd) {
+ super(fd);
+ }
+ }
+
+ public static class NativeUdpSocket extends NativeSocket implements GenericUdpSocket {
+ public NativeUdpSocket(FileDescriptor fd) {
+ super(fd);
+ }
+
+ @Override
+ public void sendTo(byte[] data, InetAddress dstAddr, int port) throws Exception {
+ Os.sendto(mFd, data, 0, data.length, 0, dstAddr, port);
+ }
+ }
+
+ public static class JavaUdpSocket implements GenericUdpSocket {
+ public final DatagramSocket mSocket;
+
+ public JavaUdpSocket(InetAddress localAddr) {
+ try {
+ mSocket = new DatagramSocket(0, localAddr);
+ mSocket.setSoTimeout(SOCK_TIMEOUT);
+ } catch (SocketException e) {
+ // Fail loudly if we can't set up sockets properly. And without the timeout, we
+ // could easily end up in an endless wait.
+ throw new RuntimeException(e);
+ }
+ }
+
+ @Override
+ public void send(byte[] data) throws Exception {
+ mSocket.send(new DatagramPacket(data, data.length));
+ }
+
+ @Override
+ public void sendTo(byte[] data, InetAddress dstAddr, int port) throws Exception {
+ mSocket.send(new DatagramPacket(data, data.length, dstAddr, port));
+ }
+
+ @Override
+ public int getPort() throws Exception {
+ return mSocket.getLocalPort();
+ }
+
+ @Override
+ public void close() throws Exception {
+ mSocket.close();
+ }
+
+ @Override
+ public byte[] receive() throws Exception {
+ DatagramPacket data = new DatagramPacket(new byte[DATA_BUFFER_LEN], DATA_BUFFER_LEN);
+ mSocket.receive(data);
+ return Arrays.copyOfRange(data.getData(), 0, data.getLength());
+ }
+
+ @Override
+ public void applyTransportModeTransform(
+ IpSecManager ism, int direction, IpSecTransform transform) throws Exception {
+ ism.applyTransportModeTransform(mSocket, direction, transform);
+ }
+
+ @Override
+ public void removeTransportModeTransforms(IpSecManager ism) throws Exception {
+ ism.removeTransportModeTransforms(mSocket);
+ }
+ }
+
+ public static class JavaTcpSocket implements GenericTcpSocket {
+ public final Socket mSocket;
+
+ public JavaTcpSocket(Socket socket) {
+ mSocket = socket;
+ try {
+ mSocket.setSoTimeout(SOCK_TIMEOUT);
+ } catch (SocketException e) {
+ // Fail loudly if we can't set up sockets properly. And without the timeout, we
+ // could easily end up in an endless wait.
+ throw new RuntimeException(e);
+ }
+ }
+
+ @Override
+ public void send(byte[] data) throws Exception {
+ mSocket.getOutputStream().write(data);
+ }
+
+ @Override
+ public byte[] receive() throws Exception {
+ byte[] in = new byte[DATA_BUFFER_LEN];
+ int bytesRead = mSocket.getInputStream().read(in);
+ return Arrays.copyOfRange(in, 0, bytesRead);
+ }
+
+ @Override
+ public int getPort() throws Exception {
+ return mSocket.getLocalPort();
+ }
+
+ @Override
+ public void close() throws Exception {
+ mSocket.close();
+ }
+
+ @Override
+ public void applyTransportModeTransform(
+ IpSecManager ism, int direction, IpSecTransform transform) throws Exception {
+ ism.applyTransportModeTransform(mSocket, direction, transform);
+ }
+
+ @Override
+ public void removeTransportModeTransforms(IpSecManager ism) throws Exception {
+ ism.removeTransportModeTransforms(mSocket);
+ }
+ }
+
+ public static class SocketPair<T> {
+ public final T mLeftSock;
+ public final T mRightSock;
+
+ public SocketPair(T leftSock, T rightSock) {
+ mLeftSock = leftSock;
+ mRightSock = rightSock;
+ }
+ }
+
+ protected static void applyTransformBidirectionally(
+ IpSecManager ism, IpSecTransform transform, GenericSocket socket) throws Exception {
+ for (int direction : DIRECTIONS) {
+ socket.applyTransportModeTransform(ism, direction, transform);
+ }
+ }
+
+ public static SocketPair<NativeUdpSocket> getNativeUdpSocketPair(
+ InetAddress localAddr, IpSecManager ism, IpSecTransform transform, boolean connected)
+ throws Exception {
+ int domain = getDomain(localAddr);
+
+ NativeUdpSocket leftSock = new NativeUdpSocket(
+ Os.socket(domain, OsConstants.SOCK_DGRAM, OsConstants.IPPROTO_UDP));
+ NativeUdpSocket rightSock = new NativeUdpSocket(
+ Os.socket(domain, OsConstants.SOCK_DGRAM, OsConstants.IPPROTO_UDP));
+
+ for (NativeUdpSocket sock : new NativeUdpSocket[] {leftSock, rightSock}) {
+ applyTransformBidirectionally(ism, transform, sock);
+ Os.bind(sock.mFd, localAddr, 0);
+ }
+
+ if (connected) {
+ Os.connect(leftSock.mFd, localAddr, rightSock.getPort());
+ Os.connect(rightSock.mFd, localAddr, leftSock.getPort());
+ }
+
+ return new SocketPair<>(leftSock, rightSock);
+ }
+
+ public static SocketPair<NativeTcpSocket> getNativeTcpSocketPair(
+ InetAddress localAddr, IpSecManager ism, IpSecTransform transform) throws Exception {
+ int domain = getDomain(localAddr);
+
+ NativeTcpSocket server = new NativeTcpSocket(
+ Os.socket(domain, OsConstants.SOCK_STREAM, OsConstants.IPPROTO_TCP));
+ NativeTcpSocket client = new NativeTcpSocket(
+ Os.socket(domain, OsConstants.SOCK_STREAM, OsConstants.IPPROTO_TCP));
+
+ Os.bind(server.mFd, localAddr, 0);
+
+ applyTransformBidirectionally(ism, transform, server);
+ applyTransformBidirectionally(ism, transform, client);
+
+ Os.listen(server.mFd, 10);
+ Os.connect(client.mFd, localAddr, server.getPort());
+ NativeTcpSocket accepted = new NativeTcpSocket(Os.accept(server.mFd, null));
+
+ applyTransformBidirectionally(ism, transform, accepted);
+ server.close();
+
+ return new SocketPair<>(client, accepted);
+ }
+
+ public static SocketPair<JavaUdpSocket> getJavaUdpSocketPair(
+ InetAddress localAddr, IpSecManager ism, IpSecTransform transform, boolean connected)
+ throws Exception {
+ JavaUdpSocket leftSock = new JavaUdpSocket(localAddr);
+ JavaUdpSocket rightSock = new JavaUdpSocket(localAddr);
+
+ applyTransformBidirectionally(ism, transform, leftSock);
+ applyTransformBidirectionally(ism, transform, rightSock);
+
+ if (connected) {
+ leftSock.mSocket.connect(localAddr, rightSock.mSocket.getLocalPort());
+ rightSock.mSocket.connect(localAddr, leftSock.mSocket.getLocalPort());
+ }
+
+ return new SocketPair<>(leftSock, rightSock);
+ }
+
+ public static SocketPair<JavaTcpSocket> getJavaTcpSocketPair(
+ InetAddress localAddr, IpSecManager ism, IpSecTransform transform) throws Exception {
+ JavaTcpSocket clientSock = new JavaTcpSocket(new Socket());
+ ServerSocket serverSocket = new ServerSocket();
+ serverSocket.bind(new InetSocketAddress(localAddr, 0));
+
+ // While technically the client socket does not need to be bound, the OpenJDK implementation
+ // of Socket only allocates an FD when bind() or connect() or other similar methods are
+ // called. So we call bind to force the FD creation, so that we can apply a transform to it
+ // prior to socket connect.
+ clientSock.mSocket.bind(new InetSocketAddress(localAddr, 0));
+
+ // IpSecService doesn't support serverSockets at the moment; workaround using FD
+ FileDescriptor serverFd = serverSocket.getImpl().getFD$();
+
+ applyTransformBidirectionally(ism, transform, new NativeTcpSocket(serverFd));
+ applyTransformBidirectionally(ism, transform, clientSock);
+
+ clientSock.mSocket.connect(new InetSocketAddress(localAddr, serverSocket.getLocalPort()));
+ JavaTcpSocket acceptedSock = new JavaTcpSocket(serverSocket.accept());
+
+ applyTransformBidirectionally(ism, transform, acceptedSock);
+ serverSocket.close();
+
+ return new SocketPair<>(clientSock, acceptedSock);
+ }
+
+ private void checkSocketPair(GenericSocket left, GenericSocket right) throws Exception {
+ left.send(TEST_DATA);
+ assertArrayEquals(TEST_DATA, right.receive());
+
+ right.send(TEST_DATA);
+ assertArrayEquals(TEST_DATA, left.receive());
+
+ left.close();
+ right.close();
+ }
+
+ private void checkUnconnectedUdpSocketPair(
+ GenericUdpSocket left, GenericUdpSocket right, InetAddress localAddr) throws Exception {
+ left.sendTo(TEST_DATA, localAddr, right.getPort());
+ assertArrayEquals(TEST_DATA, right.receive());
+
+ right.sendTo(TEST_DATA, localAddr, left.getPort());
+ assertArrayEquals(TEST_DATA, left.receive());
+
+ left.close();
+ right.close();
+ }
+
+ protected static IpSecTransform buildIpSecTransform(
+ Context mContext,
+ IpSecManager.SecurityParameterIndex spi,
+ IpSecManager.UdpEncapsulationSocket encapSocket,
+ InetAddress remoteAddr)
+ throws Exception {
+ String localAddr = (remoteAddr instanceof Inet4Address) ? IPV4_LOOPBACK : IPV6_LOOPBACK;
+ IpSecTransform.Builder builder =
+ new IpSecTransform.Builder(mContext)
+ .setEncryption(new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY))
+ .setAuthentication(
+ new IpSecAlgorithm(
+ IpSecAlgorithm.AUTH_HMAC_SHA256,
+ AUTH_KEY,
+ AUTH_KEY.length * 4));
+
+ if (encapSocket != null) {
+ builder.setIpv4Encapsulation(encapSocket, encapSocket.getPort());
+ }
+
+ return builder.buildTransportModeTransform(InetAddress.getByName(localAddr), spi);
+ }
+
+ private IpSecTransform buildDefaultTransform(InetAddress localAddr) throws Exception {
+ try (IpSecManager.SecurityParameterIndex spi =
+ mISM.allocateSecurityParameterIndex(localAddr)) {
+ return buildIpSecTransform(mContext, spi, null, localAddr);
+ }
+ }
+
+ public void testJavaTcpSocketPair() throws Exception {
+ for (String addr : LOOPBACK_ADDRS) {
+ InetAddress local = InetAddress.getByName(addr);
+ try (IpSecTransform transform = buildDefaultTransform(local)) {
+ SocketPair<JavaTcpSocket> sockets = getJavaTcpSocketPair(local, mISM, transform);
+ checkSocketPair(sockets.mLeftSock, sockets.mRightSock);
+ }
+ }
+ }
+
+ public void testJavaUdpSocketPair() throws Exception {
+ for (String addr : LOOPBACK_ADDRS) {
+ InetAddress local = InetAddress.getByName(addr);
+ try (IpSecTransform transform = buildDefaultTransform(local)) {
+ SocketPair<JavaUdpSocket> sockets =
+ getJavaUdpSocketPair(local, mISM, transform, true);
+ checkSocketPair(sockets.mLeftSock, sockets.mRightSock);
+ }
+ }
+ }
+
+ public void testJavaUdpSocketPairUnconnected() throws Exception {
+ for (String addr : LOOPBACK_ADDRS) {
+ InetAddress local = InetAddress.getByName(addr);
+ try (IpSecTransform transform = buildDefaultTransform(local)) {
+ SocketPair<JavaUdpSocket> sockets =
+ getJavaUdpSocketPair(local, mISM, transform, false);
+ checkUnconnectedUdpSocketPair(sockets.mLeftSock, sockets.mRightSock, local);
+ }
+ }
+ }
+
+ public void testNativeTcpSocketPair() throws Exception {
+ for (String addr : LOOPBACK_ADDRS) {
+ InetAddress local = InetAddress.getByName(addr);
+ try (IpSecTransform transform = buildDefaultTransform(local)) {
+ SocketPair<NativeTcpSocket> sockets =
+ getNativeTcpSocketPair(local, mISM, transform);
+ checkSocketPair(sockets.mLeftSock, sockets.mRightSock);
+ }
+ }
+ }
+
+ public void testNativeUdpSocketPair() throws Exception {
+ for (String addr : LOOPBACK_ADDRS) {
+ InetAddress local = InetAddress.getByName(addr);
+ try (IpSecTransform transform = buildDefaultTransform(local)) {
+ SocketPair<NativeUdpSocket> sockets =
+ getNativeUdpSocketPair(local, mISM, transform, true);
+ checkSocketPair(sockets.mLeftSock, sockets.mRightSock);
+ }
+ }
+ }
+
+ public void testNativeUdpSocketPairUnconnected() throws Exception {
+ for (String addr : LOOPBACK_ADDRS) {
+ InetAddress local = InetAddress.getByName(addr);
+ try (IpSecTransform transform = buildDefaultTransform(local)) {
+ SocketPair<NativeUdpSocket> sockets =
+ getNativeUdpSocketPair(local, mISM, transform, false);
+ checkUnconnectedUdpSocketPair(sockets.mLeftSock, sockets.mRightSock, local);
+ }
+ }
+ }
+}
diff --git a/tests/tests/net/src/android/net/cts/IpSecManagerTest.java b/tests/tests/net/src/android/net/cts/IpSecManagerTest.java
index 7c09e41..95d91a2 100644
--- a/tests/tests/net/src/android/net/cts/IpSecManagerTest.java
+++ b/tests/tests/net/src/android/net/cts/IpSecManagerTest.java
@@ -27,30 +27,23 @@
import android.net.IpSecManager;
import android.net.IpSecTransform;
import android.net.TrafficStats;
-import android.os.ParcelFileDescriptor;
import android.system.ErrnoException;
import android.system.Os;
import android.system.OsConstants;
-import android.test.AndroidTestCase;
import java.io.FileDescriptor;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
-import java.net.Inet4Address;
import java.net.Inet6Address;
import java.net.InetAddress;
-import java.net.InetSocketAddress;
-import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Arrays;
-public class IpSecManagerTest extends AndroidTestCase {
+public class IpSecManagerTest extends IpSecBaseTest {
private static final String TAG = IpSecManagerTest.class.getSimpleName();
- private IpSecManager mISM;
-
private ConnectivityManager mCM;
private static InetAddress IpAddress(String addrString) {
@@ -70,36 +63,22 @@
private static final int DROID_SPI = 0xD1201D;
private static final int MAX_PORT_BIND_ATTEMPTS = 10;
- private static final byte[] CRYPT_KEY = {
- 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
- 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
- 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
- 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F
- };
- private static final byte[] AUTH_KEY = {
- 0x7A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F,
- 0x7A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F
- };
+ private static final byte[] AEAD_KEY = getKey(288);
- private static final String IPV4_LOOPBACK = "127.0.0.1";
- private static final String IPV6_LOOPBACK = "::1";
private static final int TCP_HDRLEN_WITH_OPTIONS = 32;
private static final int UDP_HDRLEN = 8;
private static final int IP4_HDRLEN = 20;
private static final int IP6_HDRLEN = 40;
- private static final byte[] TEST_DATA = "Best test data ever!".getBytes();
-
// Encryption parameters
+ private static final int AES_GCM_IV_LEN = 8;
private static final int AES_CBC_IV_LEN = 16;
+ private static final int AES_GCM_BLK_SIZE = 4;
private static final int AES_CBC_BLK_SIZE = 16;
protected void setUp() throws Exception {
super.setUp();
mCM = (ConnectivityManager) getContext().getSystemService(Context.CONNECTIVITY_SERVICE);
- mISM = (IpSecManager) getContext().getSystemService(Context.IPSEC_SERVICE);
}
/*
@@ -132,19 +111,6 @@
}
}
- private byte[] getAuthKey(int bitLength) {
- return Arrays.copyOf(AUTH_KEY, bitLength / 8);
- }
-
- private static int getDomain(InetAddress address) {
- int domain;
- if (address instanceof Inet6Address)
- domain = OsConstants.AF_INET6;
- else
- domain = OsConstants.AF_INET;
- return domain;
- }
-
/** This function finds an available port */
private static int findUnusedPort() throws Exception {
// Get an available port.
@@ -180,92 +146,65 @@
private void checkUnconnectedUdp(IpSecTransform transform, InetAddress local, int sendCount,
boolean useJavaSockets) throws Exception {
- FileDescriptor udpSocket = null;
- int localPort;
-
+ GenericUdpSocket sockLeft = null, sockRight = null;
if (useJavaSockets) {
- DatagramSocket localSocket = new DatagramSocket(0, local);
- localSocket.setSoTimeout(500);
- ParcelFileDescriptor pfd = ParcelFileDescriptor.fromDatagramSocket(localSocket);
-
- localPort = localSocket.getLocalPort();
- udpSocket = pfd.getFileDescriptor();
+ SocketPair<JavaUdpSocket> sockets = getJavaUdpSocketPair(local, mISM, transform, false);
+ sockLeft = sockets.mLeftSock;
+ sockRight = sockets.mRightSock;
} else {
- udpSocket = getBoundUdpSocket(local);
- localPort = getPort(udpSocket);
+ SocketPair<NativeUdpSocket> sockets =
+ getNativeUdpSocketPair(local, mISM, transform, false);
+ sockLeft = sockets.mLeftSock;
+ sockRight = sockets.mRightSock;
}
- mISM.applyTransportModeTransform(udpSocket, IpSecManager.DIRECTION_IN, transform);
- mISM.applyTransportModeTransform(udpSocket, IpSecManager.DIRECTION_OUT, transform);
-
for (int i = 0; i < sendCount; i++) {
- byte[] in = new byte[TEST_DATA.length];
- Os.sendto(udpSocket, TEST_DATA, 0, TEST_DATA.length, 0, local, localPort);
- Os.read(udpSocket, in, 0, in.length);
- assertArrayEquals("Encapsulated data did not match.", TEST_DATA, in);
+ byte[] in;
+
+ sockLeft.sendTo(TEST_DATA, local, sockRight.getPort());
+ in = sockRight.receive();
+ assertArrayEquals("Left-to-right encrypted data did not match.", TEST_DATA, in);
+
+ sockRight.sendTo(TEST_DATA, local, sockLeft.getPort());
+ in = sockLeft.receive();
+ assertArrayEquals("Right-to-left encrypted data did not match.", TEST_DATA, in);
}
- mISM.removeTransportModeTransforms(udpSocket);
- Os.close(udpSocket);
+ sockLeft.close();
+ sockRight.close();
}
private void checkTcp(IpSecTransform transform, InetAddress local, int sendCount,
boolean useJavaSockets) throws Exception {
-
- FileDescriptor server = null, client = null;
-
+ GenericTcpSocket client = null, accepted = null;
if (useJavaSockets) {
- Socket serverSocket = new Socket();
- serverSocket.setSoTimeout(500);
- ParcelFileDescriptor serverPfd = ParcelFileDescriptor.fromSocket(serverSocket);
- server = serverPfd.getFileDescriptor();
-
- Socket clientSocket = new Socket();
- clientSocket.setSoTimeout(500);
- ParcelFileDescriptor clientPfd = ParcelFileDescriptor.fromSocket(clientSocket);
- client = clientPfd.getFileDescriptor();
+ SocketPair<JavaTcpSocket> sockets = getJavaTcpSocketPair(local, mISM, transform);
+ client = sockets.mLeftSock;
+ accepted = sockets.mRightSock;
} else {
- final int domain = getDomain(local);
- server =
- Os.socket(domain, OsConstants.SOCK_STREAM, IPPROTO_TCP);
- client =
- Os.socket(domain, OsConstants.SOCK_STREAM, IPPROTO_TCP);
+ SocketPair<NativeTcpSocket> sockets = getNativeTcpSocketPair(local, mISM, transform);
+ client = sockets.mLeftSock;
+ accepted = sockets.mRightSock;
}
- Os.bind(server, local, 0);
- int port = ((InetSocketAddress) Os.getsockname(server)).getPort();
-
- mISM.applyTransportModeTransform(client, IpSecManager.DIRECTION_IN, transform);
- mISM.applyTransportModeTransform(client, IpSecManager.DIRECTION_OUT, transform);
- mISM.applyTransportModeTransform(server, IpSecManager.DIRECTION_IN, transform);
- mISM.applyTransportModeTransform(server, IpSecManager.DIRECTION_OUT, transform);
-
- Os.listen(server, 10);
- Os.connect(client, local, port);
- FileDescriptor accepted = Os.accept(server, null);
-
- mISM.applyTransportModeTransform(accepted, IpSecManager.DIRECTION_IN, transform);
- mISM.applyTransportModeTransform(accepted, IpSecManager.DIRECTION_OUT, transform);
-
// Wait for TCP handshake packets to be counted
StatsChecker.waitForNumPackets(3); // (SYN, SYN+ACK, ACK)
// Reset StatsChecker, to ignore negotiation overhead.
StatsChecker.initStatsChecker();
for (int i = 0; i < sendCount; i++) {
- byte[] in = new byte[TEST_DATA.length];
+ byte[] in;
- Os.write(client, TEST_DATA, 0, TEST_DATA.length);
- Os.read(accepted, in, 0, in.length);
+ client.send(TEST_DATA);
+ in = accepted.receive();
assertArrayEquals("Client-to-server encrypted data did not match.", TEST_DATA, in);
// Allow for newest data + ack packets to be returned before sending next packet
// Also add the number of expected packets in each of the previous runs (4 per run)
StatsChecker.waitForNumPackets(2 + (4 * i));
- in = new byte[TEST_DATA.length];
- Os.write(accepted, TEST_DATA, 0, TEST_DATA.length);
- Os.read(client, in, 0, in.length);
+ accepted.send(TEST_DATA);
+ in = client.receive();
assertArrayEquals("Server-to-client encrypted data did not match.", TEST_DATA, in);
// Allow for all data + ack packets to be returned before sending next packet
@@ -273,13 +212,20 @@
StatsChecker.waitForNumPackets(4 * (i + 1));
}
- mISM.removeTransportModeTransforms(server);
- mISM.removeTransportModeTransforms(client);
- mISM.removeTransportModeTransforms(accepted);
+ // Transforms should not be removed from the sockets, otherwise FIN packets will be sent
+ // unencrypted.
+ // This test also unfortunately happens to rely on a nuance of the cleanup order. By
+ // keeping the policy on the socket, but removing the SA before lingering FIN packets
+ // are sent (at an undetermined later time), the FIN packets are dropped. Without this,
+ // we run into all kinds of headaches trying to test data accounting (unsolicited
+ // packets mysteriously appearing and messing up our counters)
+ // The right way to close sockets is to set SO_LINGER to ensure synchronous closure,
+ // closing the sockets, and then closing the transforms. See documentation for the
+ // Socket or FileDescriptor flavors of applyTransportModeTransform() in IpSecManager
+ // for more details.
- Os.close(server);
- Os.close(client);
- Os.close(accepted);
+ client.close();
+ accepted.close();
}
/*
@@ -299,8 +245,7 @@
IpSecTransform transform =
new IpSecTransform.Builder(mContext)
- .setEncryption(
- new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY))
+ .setEncryption(new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY))
.setAuthentication(
new IpSecAlgorithm(
IpSecAlgorithm.AUTH_HMAC_SHA256,
@@ -363,7 +308,6 @@
/** Snapshot of TrafficStats as of initStatsChecker call for later comparisons */
private static class StatsChecker {
- private static final String LOOPBACK_INTERFACE = "lo";
private static final double ERROR_MARGIN_BYTES = 1.05;
private static final double ERROR_MARGIN_PKTS = 1.05;
private static final int MAX_WAIT_TIME_MILLIS = 1000;
@@ -451,7 +395,7 @@
assertTrue((expectedDelta * errorMargin) > newStats - oldStats);
}
- private static void initStatsChecker() throws IOException {
+ private static void initStatsChecker() throws Exception {
uidTxBytes = TrafficStats.getUidTxBytes(Os.getuid());
uidRxBytes = TrafficStats.getUidRxBytes(Os.getuid());
uidTxPackets = TrafficStats.getUidTxPackets(Os.getuid());
@@ -464,35 +408,37 @@
}
}
- private int getTruncLenBits(IpSecAlgorithm auth) {
- return auth == null ? 0 : auth.getTruncationLengthBits();
+ private int getTruncLenBits(IpSecAlgorithm authOrAead) {
+ return authOrAead == null ? 0 : authOrAead.getTruncationLengthBits();
}
- private int getIvLen(IpSecAlgorithm crypt) {
- if (crypt == null) {
- return 0;
- }
+ private int getIvLen(IpSecAlgorithm cryptOrAead) {
+ if (cryptOrAead == null) { return 0; }
- switch (crypt.getName()) {
+ switch (cryptOrAead.getName()) {
case IpSecAlgorithm.CRYPT_AES_CBC:
return AES_CBC_IV_LEN;
+ case IpSecAlgorithm.AUTH_CRYPT_AES_GCM:
+ return AES_GCM_IV_LEN;
default:
throw new IllegalArgumentException(
- "IV length unknown for algorithm" + crypt.getName());
+ "IV length unknown for algorithm" + cryptOrAead.getName());
}
}
- private int getBlkSize(IpSecAlgorithm crypt) {
- if (crypt == null) {
- return 4;
- }
+ private int getBlkSize(IpSecAlgorithm cryptOrAead) {
+ // RFC 4303, section 2.4 states that ciphertext plus pad_len, next_header fields must
+ // terminate on a 4-byte boundary. Thus, the minimum ciphertext block size is 4 bytes.
+ if (cryptOrAead == null) { return 4; }
- switch (crypt.getName()) {
+ switch (cryptOrAead.getName()) {
case IpSecAlgorithm.CRYPT_AES_CBC:
return AES_CBC_BLK_SIZE;
+ case IpSecAlgorithm.AUTH_CRYPT_AES_GCM:
+ return AES_GCM_BLK_SIZE;
default:
throw new IllegalArgumentException(
- "Blk size unknown for algorithm" + crypt.getName());
+ "Blk size unknown for algorithm" + cryptOrAead.getName());
}
}
@@ -514,6 +460,7 @@
String localAddress,
IpSecAlgorithm crypt,
IpSecAlgorithm auth,
+ IpSecAlgorithm aead,
boolean doUdpEncap,
int sendCount,
boolean useJavaSockets)
@@ -532,6 +479,9 @@
if (auth != null) {
transformBuilder.setAuthentication(auth);
}
+ if (aead != null) {
+ transformBuilder.setAuthenticatedEncryption(aead);
+ }
if (doUdpEncap) {
transformBuilder =
@@ -563,9 +513,9 @@
transportHdrLen,
udpEncapLen,
sendCount,
- getIvLen(crypt),
- getBlkSize(crypt),
- getTruncLenBits(auth));
+ getIvLen(crypt != null ? crypt : aead),
+ getBlkSize(crypt != null ? crypt : aead),
+ getTruncLenBits(auth != null ? auth : aead));
}
}
@@ -591,16 +541,17 @@
int expectedInnerBytes = innerPacketSize * sendCount;
int expectedPackets = sendCount;
+ // Each run sends two packets, one in each direction.
+ sendCount *= 2;
+ expectedOuterBytes *= 2;
+ expectedInnerBytes *= 2;
+ expectedPackets *= 2;
+
// Add TCP ACKs for data packets
if (protocol == IPPROTO_TCP) {
int encryptedTcpPktSize =
calculateEspPacketSize(TCP_HDRLEN_WITH_OPTIONS, ivLen, blkSize, truncLenBits);
- // Each run sends two packets, one in each direction.
- sendCount *= 2;
- expectedOuterBytes *= 2;
- expectedInnerBytes *= 2;
- expectedPackets *= 2;
// Add data packet ACKs
expectedOuterBytes += (encryptedTcpPktSize + udpEncapLen + ipHdrLen) * (sendCount);
@@ -625,34 +576,68 @@
}
}
- public void testIkeOverUdpEncapSocket() throws Exception {
- // IPv6 not supported for UDP-encap-ESP
- InetAddress local = InetAddress.getByName(IPV4_LOOPBACK);
+ private void checkIkePacket(
+ NativeUdpSocket wrappedEncapSocket, InetAddress localAddr) throws Exception {
StatsChecker.initStatsChecker();
- try (IpSecManager.UdpEncapsulationSocket encapSocket = mISM.openUdpEncapsulationSocket()) {
- int localPort = getPort(encapSocket.getSocket());
+ try (NativeUdpSocket remoteSocket = new NativeUdpSocket(getBoundUdpSocket(localAddr))) {
- // Append ESP header - 4 bytes of SPI, 4 bytes of seq number
+ // Append IKE/ESP header - 4 bytes of SPI, 4 bytes of seq number, all zeroed out
+ // If the first four bytes are zero, assume non-ESP (IKE traffic)
byte[] dataWithEspHeader = new byte[TEST_DATA.length + 8];
System.arraycopy(TEST_DATA, 0, dataWithEspHeader, 8, TEST_DATA.length);
- byte[] in = new byte[dataWithEspHeader.length];
- Os.sendto(
- encapSocket.getSocket(),
- dataWithEspHeader,
- 0,
- dataWithEspHeader.length,
- 0,
- local,
- localPort);
- Os.read(encapSocket.getSocket(), in, 0, in.length);
+ // Send the IKE packet from remoteSocket to wrappedEncapSocket. Since IKE packets
+ // are multiplexed over the socket, we expect them to appear on the encap socket
+ // (as opposed to being decrypted and received on the non-encap socket)
+ remoteSocket.sendTo(dataWithEspHeader, localAddr, wrappedEncapSocket.getPort());
+ byte[] in = wrappedEncapSocket.receive();
assertArrayEquals("Encapsulated data did not match.", dataWithEspHeader, in);
- int ipHdrLen = local instanceof Inet6Address ? IP6_HDRLEN : IP4_HDRLEN;
- int expectedPacketSize = dataWithEspHeader.length + UDP_HDRLEN + ipHdrLen;
- StatsChecker.assertUidStatsDelta(expectedPacketSize, 1, expectedPacketSize, 1);
- StatsChecker.assertIfaceStatsDelta(expectedPacketSize, 1, expectedPacketSize, 1);
+ // Also test that the IKE socket can send data out.
+ wrappedEncapSocket.sendTo(dataWithEspHeader, localAddr, remoteSocket.getPort());
+ in = remoteSocket.receive();
+ assertArrayEquals("Encapsulated data did not match.", dataWithEspHeader, in);
+
+ // Calculate expected packet sizes. Always use IPv4 header, since our kernels only
+ // guarantee support of UDP encap on IPv4.
+ int expectedNumPkts = 2;
+ int expectedPacketSize =
+ expectedNumPkts * (dataWithEspHeader.length + UDP_HDRLEN + IP4_HDRLEN);
+
+ StatsChecker.waitForNumPackets(expectedNumPkts);
+ StatsChecker.assertUidStatsDelta(
+ expectedPacketSize, expectedNumPkts, expectedPacketSize, expectedNumPkts);
+ StatsChecker.assertIfaceStatsDelta(
+ expectedPacketSize, expectedNumPkts, expectedPacketSize, expectedNumPkts);
+ }
+ }
+
+ public void testIkeOverUdpEncapSocket() throws Exception {
+ // IPv6 not supported for UDP-encap-ESP
+ InetAddress local = InetAddress.getByName(IPV4_LOOPBACK);
+ try (IpSecManager.UdpEncapsulationSocket encapSocket = mISM.openUdpEncapsulationSocket()) {
+ NativeUdpSocket wrappedEncapSocket =
+ new NativeUdpSocket(encapSocket.getFileDescriptor());
+ checkIkePacket(wrappedEncapSocket, local);
+
+ // Now try with a transform applied to a socket using this Encap socket
+ IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY);
+ IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_MD5, getKey(128), 96);
+
+ try (IpSecManager.SecurityParameterIndex spi =
+ mISM.allocateSecurityParameterIndex(local);
+ IpSecTransform transform =
+ new IpSecTransform.Builder(mContext)
+ .setEncryption(crypt)
+ .setAuthentication(auth)
+ .setIpv4Encapsulation(encapSocket, encapSocket.getPort())
+ .buildTransportModeTransform(local, spi);
+ JavaUdpSocket localSocket = new JavaUdpSocket(local)) {
+ applyTransformBidirectionally(mISM, transform, localSocket);
+
+ checkIkePacket(wrappedEncapSocket, local);
+ }
}
}
@@ -668,346 +653,448 @@
// public void testInterfaceCountersTcp4() throws Exception {
// IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY);
// IpSecAlgorithm auth = new IpSecAlgorithm(
- // IpSecAlgorithm.AUTH_HMAC_MD5, getAuthKey(128), 96);
+ // IpSecAlgorithm.AUTH_HMAC_MD5, getKey(128), 96);
// checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, false, 1000);
// }
// public void testInterfaceCountersTcp6() throws Exception {
// IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY);
// IpSecAlgorithm auth = new IpSecAlgorithm(
- // IpSecAlgorithm.AUTH_HMAC_MD5, getAuthKey(128), 96);
+ // IpSecAlgorithm.AUTH_HMAC_MD5, getKey(128), 96);
// checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, crypt, auth, false, 1000);
// }
// public void testInterfaceCountersTcp4UdpEncap() throws Exception {
// IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY);
// IpSecAlgorithm auth =
- // new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_MD5, getAuthKey(128), 96);
+ // new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_MD5, getKey(128), 96);
// checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, true, 1000);
// }
public void testInterfaceCountersUdp4() throws Exception {
IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY);
- IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_MD5, getAuthKey(128), 96);
- checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, false, 1000, false);
+ IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_MD5, getKey(128), 96);
+ checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, false, 1000, false);
}
public void testInterfaceCountersUdp6() throws Exception {
IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY);
- IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_MD5, getAuthKey(128), 96);
- checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, crypt, auth, false, 1000, false);
+ IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_MD5, getKey(128), 96);
+ checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, crypt, auth, null, false, 1000, false);
}
public void testInterfaceCountersUdp4UdpEncap() throws Exception {
IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY);
- IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_MD5, getAuthKey(128), 96);
- checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, true, 1000, false);
+ IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_MD5, getKey(128), 96);
+ checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, true, 1000, false);
}
public void testAesCbcHmacMd5Tcp4() throws Exception {
IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY);
- IpSecAlgorithm auth = new IpSecAlgorithm(
- IpSecAlgorithm.AUTH_HMAC_MD5, getAuthKey(128), 96);
- checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, false, 1, false);
- checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, false, 1, true);
+ IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_MD5, getKey(128), 96);
+ checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, false, 1, false);
+ checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, false, 1, true);
}
public void testAesCbcHmacMd5Tcp6() throws Exception {
IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY);
- IpSecAlgorithm auth = new IpSecAlgorithm(
- IpSecAlgorithm.AUTH_HMAC_MD5, getAuthKey(128), 96);
- checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, crypt, auth, false, 1, false);
- checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, crypt, auth, false, 1, true);
+ IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_MD5, getKey(128), 96);
+ checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, crypt, auth, null, false, 1, false);
+ checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, crypt, auth, null, false, 1, true);
}
public void testAesCbcHmacMd5Udp4() throws Exception {
IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY);
- IpSecAlgorithm auth = new IpSecAlgorithm(
- IpSecAlgorithm.AUTH_HMAC_MD5, getAuthKey(128), 96);
- checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, false, 1, false);
- checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, false, 1, true);
+ IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_MD5, getKey(128), 96);
+ checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, false, 1, false);
+ checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, false, 1, true);
}
public void testAesCbcHmacMd5Udp6() throws Exception {
IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY);
- IpSecAlgorithm auth = new IpSecAlgorithm(
- IpSecAlgorithm.AUTH_HMAC_MD5, getAuthKey(128), 96);
- checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, crypt, auth, false, 1, false);
- checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, crypt, auth, false, 1, true);
+ IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_MD5, getKey(128), 96);
+ checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, crypt, auth, null, false, 1, false);
+ checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, crypt, auth, null, false, 1, true);
}
public void testAesCbcHmacSha1Tcp4() throws Exception {
IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY);
- IpSecAlgorithm auth = new IpSecAlgorithm(
- IpSecAlgorithm.AUTH_HMAC_SHA1, getAuthKey(160), 96);
- checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, false, 1, false);
- checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, false, 1, true);
+ IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA1, getKey(160), 96);
+ checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, false, 1, false);
+ checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, false, 1, true);
}
public void testAesCbcHmacSha1Tcp6() throws Exception {
IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY);
- IpSecAlgorithm auth = new IpSecAlgorithm(
- IpSecAlgorithm.AUTH_HMAC_SHA1, getAuthKey(160), 96);
- checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, crypt, auth, false, 1, false);
- checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, crypt, auth, false, 1, true);
+ IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA1, getKey(160), 96);
+ checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, crypt, auth, null, false, 1, false);
+ checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, crypt, auth, null, false, 1, true);
}
public void testAesCbcHmacSha1Udp4() throws Exception {
IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY);
- IpSecAlgorithm auth = new IpSecAlgorithm(
- IpSecAlgorithm.AUTH_HMAC_SHA1, getAuthKey(160), 96);
- checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, false, 1, false);
- checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, false, 1, true);
+ IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA1, getKey(160), 96);
+ checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, false, 1, false);
+ checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, false, 1, true);
}
public void testAesCbcHmacSha1Udp6() throws Exception {
IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY);
- IpSecAlgorithm auth = new IpSecAlgorithm(
- IpSecAlgorithm.AUTH_HMAC_SHA1, getAuthKey(160), 96);
- checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, crypt, auth, false, 1, false);
- checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, crypt, auth, false, 1, true);
+ IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA1, getKey(160), 96);
+ checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, crypt, auth, null, false, 1, false);
+ checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, crypt, auth, null, false, 1, true);
}
public void testAesCbcHmacSha256Tcp4() throws Exception {
IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY);
- IpSecAlgorithm auth = new IpSecAlgorithm(
- IpSecAlgorithm.AUTH_HMAC_SHA256, getAuthKey(256), 128);
- checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, false, 1, false);
- checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, false, 1, true);
+ IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA256, getKey(256), 128);
+ checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, false, 1, false);
+ checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, false, 1, true);
}
public void testAesCbcHmacSha256Tcp6() throws Exception {
IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY);
- IpSecAlgorithm auth = new IpSecAlgorithm(
- IpSecAlgorithm.AUTH_HMAC_SHA256, getAuthKey(256), 128);
- checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, crypt, auth, false, 1, false);
- checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, crypt, auth, false, 1, true);
+ IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA256, getKey(256), 128);
+ checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, crypt, auth, null, false, 1, false);
+ checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, crypt, auth, null, false, 1, true);
}
public void testAesCbcHmacSha256Udp4() throws Exception {
IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY);
- IpSecAlgorithm auth = new IpSecAlgorithm(
- IpSecAlgorithm.AUTH_HMAC_SHA256, getAuthKey(256), 128);
- checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, false, 1, false);
- checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, false, 1, true);
+ IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA256, getKey(256), 128);
+ checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, false, 1, false);
+ checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, false, 1, true);
}
public void testAesCbcHmacSha256Udp6() throws Exception {
IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY);
- IpSecAlgorithm auth = new IpSecAlgorithm(
- IpSecAlgorithm.AUTH_HMAC_SHA256, getAuthKey(256), 128);
- checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, crypt, auth, false, 1, false);
- checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, crypt, auth, false, 1, true);
+ IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA256, getKey(256), 128);
+ checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, crypt, auth, null, false, 1, false);
+ checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, crypt, auth, null, false, 1, true);
}
public void testAesCbcHmacSha384Tcp4() throws Exception {
IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY);
- IpSecAlgorithm auth = new IpSecAlgorithm(
- IpSecAlgorithm.AUTH_HMAC_SHA384, getAuthKey(384), 192);
- checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, false, 1, false);
- checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, false, 1, true);
+ IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA384, getKey(384), 192);
+ checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, false, 1, false);
+ checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, false, 1, true);
}
public void testAesCbcHmacSha384Tcp6() throws Exception {
IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY);
- IpSecAlgorithm auth = new IpSecAlgorithm(
- IpSecAlgorithm.AUTH_HMAC_SHA384, getAuthKey(384), 192);
- checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, crypt, auth, false, 1, false);
- checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, crypt, auth, false, 1, true);
+ IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA384, getKey(384), 192);
+ checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, crypt, auth, null, false, 1, false);
+ checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, crypt, auth, null, false, 1, true);
}
public void testAesCbcHmacSha384Udp4() throws Exception {
IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY);
- IpSecAlgorithm auth = new IpSecAlgorithm(
- IpSecAlgorithm.AUTH_HMAC_SHA384, getAuthKey(384), 192);
- checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, false, 1, false);
- checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, false, 1, true);
+ IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA384, getKey(384), 192);
+ checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, false, 1, false);
+ checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, false, 1, true);
}
public void testAesCbcHmacSha384Udp6() throws Exception {
IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY);
- IpSecAlgorithm auth = new IpSecAlgorithm(
- IpSecAlgorithm.AUTH_HMAC_SHA384, getAuthKey(384), 192);
- checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, crypt, auth, false, 1, false);
- checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, crypt, auth, false, 1, true);
+ IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA384, getKey(384), 192);
+ checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, crypt, auth, null, false, 1, false);
+ checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, crypt, auth, null, false, 1, true);
}
public void testAesCbcHmacSha512Tcp4() throws Exception {
IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY);
- IpSecAlgorithm auth = new IpSecAlgorithm(
- IpSecAlgorithm.AUTH_HMAC_SHA512, getAuthKey(512), 256);
- checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, false, 1, false);
- checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, false, 1, true);
+ IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA512, getKey(512), 256);
+ checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, false, 1, false);
+ checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, false, 1, true);
}
public void testAesCbcHmacSha512Tcp6() throws Exception {
IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY);
- IpSecAlgorithm auth = new IpSecAlgorithm(
- IpSecAlgorithm.AUTH_HMAC_SHA512, getAuthKey(512), 256);
- checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, crypt, auth, false, 1, false);
- checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, crypt, auth, false, 1, true);
+ IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA512, getKey(512), 256);
+ checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, crypt, auth, null, false, 1, false);
+ checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, crypt, auth, null, false, 1, true);
}
public void testAesCbcHmacSha512Udp4() throws Exception {
IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY);
- IpSecAlgorithm auth = new IpSecAlgorithm(
- IpSecAlgorithm.AUTH_HMAC_SHA512, getAuthKey(512), 256);
- checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, false, 1, false);
- checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, false, 1, true);
+ IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA512, getKey(512), 256);
+ checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, false, 1, false);
+ checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, false, 1, true);
}
public void testAesCbcHmacSha512Udp6() throws Exception {
IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY);
- IpSecAlgorithm auth = new IpSecAlgorithm(
- IpSecAlgorithm.AUTH_HMAC_SHA512, getAuthKey(512), 256);
- checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, crypt, auth, false, 1, false);
- checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, crypt, auth, false, 1, true);
+ IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA512, getKey(512), 256);
+ checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, crypt, auth, null, false, 1, false);
+ checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, crypt, auth, null, false, 1, true);
+ }
+
+ public void testAesGcm64Tcp4() throws Exception {
+ IpSecAlgorithm authCrypt =
+ new IpSecAlgorithm(IpSecAlgorithm.AUTH_CRYPT_AES_GCM, AEAD_KEY, 64);
+ checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, null, null, authCrypt, false, 1, false);
+ checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, null, null, authCrypt, false, 1, true);
+ }
+
+ public void testAesGcm64Tcp6() throws Exception {
+ IpSecAlgorithm authCrypt =
+ new IpSecAlgorithm(IpSecAlgorithm.AUTH_CRYPT_AES_GCM, AEAD_KEY, 64);
+ checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, null, null, authCrypt, false, 1, false);
+ checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, null, null, authCrypt, false, 1, true);
+ }
+
+ public void testAesGcm64Udp4() throws Exception {
+ IpSecAlgorithm authCrypt =
+ new IpSecAlgorithm(IpSecAlgorithm.AUTH_CRYPT_AES_GCM, AEAD_KEY, 64);
+ checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, null, null, authCrypt, false, 1, false);
+ checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, null, null, authCrypt, false, 1, true);
+ }
+
+ public void testAesGcm64Udp6() throws Exception {
+ IpSecAlgorithm authCrypt =
+ new IpSecAlgorithm(IpSecAlgorithm.AUTH_CRYPT_AES_GCM, AEAD_KEY, 64);
+ checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, null, null, authCrypt, false, 1, false);
+ checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, null, null, authCrypt, false, 1, true);
+ }
+
+ public void testAesGcm96Tcp4() throws Exception {
+ IpSecAlgorithm authCrypt =
+ new IpSecAlgorithm(IpSecAlgorithm.AUTH_CRYPT_AES_GCM, AEAD_KEY, 96);
+ checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, null, null, authCrypt, false, 1, false);
+ checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, null, null, authCrypt, false, 1, true);
+ }
+
+ public void testAesGcm96Tcp6() throws Exception {
+ IpSecAlgorithm authCrypt =
+ new IpSecAlgorithm(IpSecAlgorithm.AUTH_CRYPT_AES_GCM, AEAD_KEY, 96);
+ checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, null, null, authCrypt, false, 1, false);
+ checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, null, null, authCrypt, false, 1, true);
+ }
+
+ public void testAesGcm96Udp4() throws Exception {
+ IpSecAlgorithm authCrypt =
+ new IpSecAlgorithm(IpSecAlgorithm.AUTH_CRYPT_AES_GCM, AEAD_KEY, 96);
+ checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, null, null, authCrypt, false, 1, false);
+ checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, null, null, authCrypt, false, 1, true);
+ }
+
+ public void testAesGcm96Udp6() throws Exception {
+ IpSecAlgorithm authCrypt =
+ new IpSecAlgorithm(IpSecAlgorithm.AUTH_CRYPT_AES_GCM, AEAD_KEY, 96);
+ checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, null, null, authCrypt, false, 1, false);
+ checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, null, null, authCrypt, false, 1, true);
+ }
+
+ public void testAesGcm128Tcp4() throws Exception {
+ IpSecAlgorithm authCrypt =
+ new IpSecAlgorithm(IpSecAlgorithm.AUTH_CRYPT_AES_GCM, AEAD_KEY, 128);
+ checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, null, null, authCrypt, false, 1, false);
+ checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, null, null, authCrypt, false, 1, true);
+ }
+
+ public void testAesGcm128Tcp6() throws Exception {
+ IpSecAlgorithm authCrypt =
+ new IpSecAlgorithm(IpSecAlgorithm.AUTH_CRYPT_AES_GCM, AEAD_KEY, 128);
+ checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, null, null, authCrypt, false, 1, false);
+ checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, null, null, authCrypt, false, 1, true);
+ }
+
+ public void testAesGcm128Udp4() throws Exception {
+ IpSecAlgorithm authCrypt =
+ new IpSecAlgorithm(IpSecAlgorithm.AUTH_CRYPT_AES_GCM, AEAD_KEY, 128);
+ checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, null, null, authCrypt, false, 1, false);
+ checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, null, null, authCrypt, false, 1, true);
+ }
+
+ public void testAesGcm128Udp6() throws Exception {
+ IpSecAlgorithm authCrypt =
+ new IpSecAlgorithm(IpSecAlgorithm.AUTH_CRYPT_AES_GCM, AEAD_KEY, 128);
+ checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, null, null, authCrypt, false, 1, false);
+ checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, null, null, authCrypt, false, 1, true);
}
public void testAesCbcHmacMd5Tcp4UdpEncap() throws Exception {
IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY);
- IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_MD5, getAuthKey(128), 96);
- checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, true, 1, false);
+ IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_MD5, getKey(128), 96);
+ checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, true, 1, false);
+ checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, true, 1, true);
}
public void testAesCbcHmacMd5Udp4UdpEncap() throws Exception {
IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY);
- IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_MD5, getAuthKey(128), 96);
- checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, true, 1, false);
+ IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_MD5, getKey(128), 96);
+ checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, true, 1, false);
+ checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, true, 1, true);
}
public void testAesCbcHmacSha1Tcp4UdpEncap() throws Exception {
IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY);
- IpSecAlgorithm auth =
- new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA1, getAuthKey(160), 96);
- checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, true, 1, false);
+ IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA1, getKey(160), 96);
+ checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, true, 1, false);
+ checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, true, 1, true);
}
public void testAesCbcHmacSha1Udp4UdpEncap() throws Exception {
IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY);
- IpSecAlgorithm auth =
- new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA1, getAuthKey(160), 96);
- checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, true, 1, false);
+ IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA1, getKey(160), 96);
+ checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, true, 1, false);
+ checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, true, 1, true);
}
public void testAesCbcHmacSha256Tcp4UdpEncap() throws Exception {
IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY);
- IpSecAlgorithm auth =
- new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA256, getAuthKey(256), 128);
- checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, true, 1, false);
+ IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA256, getKey(256), 128);
+ checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, true, 1, false);
+ checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, true, 1, true);
}
public void testAesCbcHmacSha256Udp4UdpEncap() throws Exception {
IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY);
- IpSecAlgorithm auth =
- new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA256, getAuthKey(256), 128);
- checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, true, 1, false);
+ IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA256, getKey(256), 128);
+ checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, true, 1, false);
+ checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, true, 1, true);
}
public void testAesCbcHmacSha384Tcp4UdpEncap() throws Exception {
IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY);
- IpSecAlgorithm auth =
- new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA384, getAuthKey(384), 192);
- checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, true, 1, false);
+ IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA384, getKey(384), 192);
+ checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, true, 1, false);
+ checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, true, 1, true);
}
public void testAesCbcHmacSha384Udp4UdpEncap() throws Exception {
IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY);
- IpSecAlgorithm auth =
- new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA384, getAuthKey(384), 192);
- checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, true, 1, false);
+ IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA384, getKey(384), 192);
+ checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, true, 1, false);
+ checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, true, 1, true);
}
public void testAesCbcHmacSha512Tcp4UdpEncap() throws Exception {
IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY);
- IpSecAlgorithm auth =
- new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA512, getAuthKey(512), 256);
- checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, true, 1, false);
+ IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA512, getKey(512), 256);
+ checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, true, 1, false);
+ checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, true, 1, true);
}
public void testAesCbcHmacSha512Udp4UdpEncap() throws Exception {
IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY);
- IpSecAlgorithm auth =
- new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA512, getAuthKey(512), 256);
- checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, true, 1, false);
+ IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA512, getKey(512), 256);
+ checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, true, 1, false);
+ checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, true, 1, true);
+ }
+
+ public void testAesGcm64Tcp4UdpEncap() throws Exception {
+ IpSecAlgorithm authCrypt =
+ new IpSecAlgorithm(IpSecAlgorithm.AUTH_CRYPT_AES_GCM, AEAD_KEY, 64);
+ checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, null, null, authCrypt, true, 1, false);
+ checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, null, null, authCrypt, true, 1, true);
+ }
+
+ public void testAesGcm64Udp4UdpEncap() throws Exception {
+ IpSecAlgorithm authCrypt =
+ new IpSecAlgorithm(IpSecAlgorithm.AUTH_CRYPT_AES_GCM, AEAD_KEY, 64);
+ checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, null, null, authCrypt, true, 1, false);
+ checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, null, null, authCrypt, true, 1, true);
+ }
+
+ public void testAesGcm96Tcp4UdpEncap() throws Exception {
+ IpSecAlgorithm authCrypt =
+ new IpSecAlgorithm(IpSecAlgorithm.AUTH_CRYPT_AES_GCM, AEAD_KEY, 96);
+ checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, null, null, authCrypt, true, 1, false);
+ checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, null, null, authCrypt, true, 1, true);
+ }
+
+ public void testAesGcm96Udp4UdpEncap() throws Exception {
+ IpSecAlgorithm authCrypt =
+ new IpSecAlgorithm(IpSecAlgorithm.AUTH_CRYPT_AES_GCM, AEAD_KEY, 96);
+ checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, null, null, authCrypt, true, 1, false);
+ checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, null, null, authCrypt, true, 1, true);
+ }
+
+ public void testAesGcm128Tcp4UdpEncap() throws Exception {
+ IpSecAlgorithm authCrypt =
+ new IpSecAlgorithm(IpSecAlgorithm.AUTH_CRYPT_AES_GCM, AEAD_KEY, 128);
+ checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, null, null, authCrypt, true, 1, false);
+ checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, null, null, authCrypt, true, 1, true);
+ }
+
+ public void testAesGcm128Udp4UdpEncap() throws Exception {
+ IpSecAlgorithm authCrypt =
+ new IpSecAlgorithm(IpSecAlgorithm.AUTH_CRYPT_AES_GCM, AEAD_KEY, 128);
+ checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, null, null, authCrypt, true, 1, false);
+ checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, null, null, authCrypt, true, 1, true);
}
public void testCryptUdp4() throws Exception {
IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY);
- checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, null, false, 1, false);
- checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, null, false, 1, true);
+ checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, null, null, false, 1, false);
+ checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, null, null, false, 1, true);
}
public void testAuthUdp4() throws Exception {
- IpSecAlgorithm auth =
- new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA256, getAuthKey(256), 128);
- checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, null, auth, false, 1, false);
- checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, null, auth, false, 1, true);
+ IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA256, getKey(256), 128);
+ checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, null, auth, null, false, 1, false);
+ checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, null, auth, null, false, 1, true);
}
public void testCryptUdp6() throws Exception {
IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY);
- checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, crypt, null, false, 1, false);
- checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, crypt, null, false, 1, true);
+ checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, crypt, null, null, false, 1, false);
+ checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, crypt, null, null, false, 1, true);
}
public void testAuthUdp6() throws Exception {
- IpSecAlgorithm auth =
- new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA256, getAuthKey(256), 128);
- checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, null, auth, false, 1, false);
- checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, null, auth, false, 1, true);
+ IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA256, getKey(256), 128);
+ checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, null, auth, null, false, 1, false);
+ checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, null, auth, null, false, 1, true);
}
public void testCryptTcp4() throws Exception {
IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY);
- checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, null, false, 1, false);
- checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, null, false, 1, true);
+ checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, null, null, false, 1, false);
+ checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, null, null, false, 1, true);
}
public void testAuthTcp4() throws Exception {
- IpSecAlgorithm auth =
- new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA256, getAuthKey(256), 128);
- checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, null, auth, false, 1, false);
- checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, null, auth, false, 1, true);
+ IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA256, getKey(256), 128);
+ checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, null, auth, null, false, 1, false);
+ checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, null, auth, null, false, 1, true);
}
public void testCryptTcp6() throws Exception {
IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY);
- checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, crypt, null, false, 1, false);
- checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, crypt, null, false, 1, true);
+ checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, crypt, null, null, false, 1, false);
+ checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, crypt, null, null, false, 1, true);
}
public void testAuthTcp6() throws Exception {
- IpSecAlgorithm auth =
- new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA256, getAuthKey(256), 128);
- checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, null, auth, false, 1, false);
- checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, null, auth, false, 1, true);
+ IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA256, getKey(256), 128);
+ checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, null, auth, null, false, 1, false);
+ checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, null, auth, null, false, 1, true);
}
public void testCryptUdp4UdpEncap() throws Exception {
IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY);
- checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, null, true, 1, false);
- checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, null, true, 1, true);
+ checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, null, null, true, 1, false);
+ checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, null, null, true, 1, true);
}
public void testAuthUdp4UdpEncap() throws Exception {
- IpSecAlgorithm auth =
- new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA256, getAuthKey(256), 128);
- checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, null, auth, true, 1, false);
- checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, null, auth, true, 1, true);
+ IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA256, getKey(256), 128);
+ checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, null, auth, null, true, 1, false);
+ checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, null, auth, null, true, 1, true);
}
public void testCryptTcp4UdpEncap() throws Exception {
IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY);
- checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, null, true, 1, false);
- checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, null, true, 1, true);
+ checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, null, null, true, 1, false);
+ checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, null, null, true, 1, true);
}
public void testAuthTcp4UdpEncap() throws Exception {
- IpSecAlgorithm auth =
- new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA256, getAuthKey(256), 128);
- checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, null, auth, true, 1, false);
- checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, null, auth, true, 1, true);
+ IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA256, getKey(256), 128);
+ checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, null, auth, null, true, 1, false);
+ checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, null, auth, null, true, 1, true);
}
public void testOpenUdpEncapSocketSpecificPort() throws Exception {
@@ -1043,153 +1130,4 @@
assertTrue("Returned invalid port", encapSocket.getPort() != 0);
}
}
-
- public void testUdpEncapsulation() throws Exception {
- InetAddress local = InetAddress.getByName(IPV4_LOOPBACK);
-
- // TODO: Refactor to make this more representative of a normal application use case. (use
- // separate sockets for inbound and outbound)
- // Create SPIs, UDP encap socket
- try (IpSecManager.UdpEncapsulationSocket encapSocket = mISM.openUdpEncapsulationSocket();
- IpSecManager.SecurityParameterIndex spi =
- mISM.allocateSecurityParameterIndex(local);
- IpSecTransform transform =
- buildIpSecTransform(mContext, spi, encapSocket, local)) {
-
- // Create user socket, apply transform to it
- FileDescriptor udpSocket = null;
- try {
- udpSocket = getBoundUdpSocket(local);
- int port = getPort(udpSocket);
-
- mISM.applyTransportModeTransform(
- udpSocket, IpSecManager.DIRECTION_IN, transform);
- mISM.applyTransportModeTransform(
- udpSocket, IpSecManager.DIRECTION_OUT, transform);
-
- // Send an ESP packet from this socket to itself. Since the inbound and
- // outbound transforms match, we should receive the data we sent.
- byte[] data = new String("IPSec UDP-encap-ESP test data").getBytes("UTF-8");
- Os.sendto(udpSocket, data, 0, data.length, 0, local, port);
- byte[] in = new byte[data.length];
- Os.read(udpSocket, in, 0, in.length);
- assertTrue("Encapsulated data did not match.", Arrays.equals(data, in));
-
- // Send an IKE packet from this socket to itself. IKE packets (SPI of 0)
- // are not transformed in any way, and should be sent in the clear
- // We expect this to work too (no inbound transforms)
- final byte[] header = new byte[] {0, 0, 0, 0};
- final String message = "Sample IKE Packet";
- data = (new String(header) + message).getBytes("UTF-8");
- Os.sendto(
- encapSocket.getSocket(),
- data,
- 0,
- data.length,
- 0,
- local,
- encapSocket.getPort());
- in = new byte[data.length];
- Os.read(encapSocket.getSocket(), in, 0, in.length);
- assertTrue(
- "Encap socket was unable to send/receive IKE data",
- Arrays.equals(data, in));
-
- mISM.removeTransportModeTransforms(udpSocket);
- } finally {
- if (udpSocket != null) {
- Os.close(udpSocket);
- }
- }
- }
- }
-
- public void testIke() throws Exception {
- InetAddress localAddr = InetAddress.getByName(IPV4_LOOPBACK);
-
- // TODO: Refactor to make this more representative of a normal application use case. (use
- // separate sockets for inbound and outbound)
- try (IpSecManager.UdpEncapsulationSocket encapSocket = mISM.openUdpEncapsulationSocket();
- IpSecManager.SecurityParameterIndex spi =
- mISM.allocateSecurityParameterIndex(localAddr);
- IpSecTransform transform =
- buildIpSecTransform(mContext, spi, encapSocket, localAddr)) {
-
- // Create user socket, apply transform to it
- FileDescriptor sock = null;
-
- try {
- sock = getBoundUdpSocket(localAddr);
- int port = getPort(sock);
-
- mISM.applyTransportModeTransform(sock, IpSecManager.DIRECTION_IN, transform);
- mISM.applyTransportModeTransform(sock, IpSecManager.DIRECTION_OUT, transform);
-
- // TODO: Find a way to set a timeout on the socket, and assert the ESP packet
- // doesn't make it through. Setting sockopts currently throws EPERM (possibly
- // because it is owned by a different UID).
-
- // Send ESP packet from our socket to the encap socket. The SPIs do not
- // match, and we should expect this packet to be dropped.
- byte[] header = new byte[] {1, 1, 1, 1};
- String message = "Sample ESP Packet";
- byte[] data = (new String(header) + message).getBytes("UTF-8");
- Os.sendto(sock, data, 0, data.length, 0, localAddr, encapSocket.getPort());
-
- // Send IKE packet from the encap socket to itself. Since IKE is not
- // transformed in any way, this should succeed.
- header = new byte[] {0, 0, 0, 0};
- message = "Sample IKE Packet";
- data = (new String(header) + message).getBytes("UTF-8");
- Os.sendto(
- encapSocket.getSocket(),
- data,
- 0,
- data.length,
- 0,
- localAddr,
- encapSocket.getPort());
-
- // ESP data should be dropped, due to different input SPI (as opposed to being
- // readable from the encapSocket)
- // Thus, only IKE data should be received from the socket.
- // If the first four bytes are zero, assume non-ESP (IKE) traffic.
- // Expect an nulled out SPI just as we sent out, without being modified.
- byte[] in = new byte[4];
- in[0] = 1; // Make sure the array has to be overwritten to pass
- Os.read(encapSocket.getSocket(), in, 0, in.length);
- assertTrue(
- "Encap socket received UDP-encap-ESP data despite invalid SPIs",
- Arrays.equals(header, in));
-
- mISM.removeTransportModeTransforms(sock);
- } finally {
- if (sock != null) {
- Os.close(sock);
- }
- }
- }
- }
-
- private static IpSecTransform buildIpSecTransform(
- Context mContext,
- IpSecManager.SecurityParameterIndex spi,
- IpSecManager.UdpEncapsulationSocket encapSocket,
- InetAddress remoteAddr)
- throws Exception {
- String localAddr = (remoteAddr instanceof Inet4Address)
- ? IPV4_LOOPBACK : IPV6_LOOPBACK;
- return new IpSecTransform.Builder(mContext)
- .setEncryption(
- new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY))
- .setAuthentication(
- new IpSecAlgorithm(
- IpSecAlgorithm.AUTH_HMAC_SHA256, AUTH_KEY, AUTH_KEY.length * 4))
- .setIpv4Encapsulation(encapSocket, encapSocket.getPort())
- .buildTransportModeTransform(InetAddress.getByName(localAddr), spi);
- }
-
- private static int getPort(FileDescriptor sock) throws Exception {
- return ((InetSocketAddress) Os.getsockname(sock)).getPort();
- }
}
diff --git a/tests/tests/print/AndroidManifest.xml b/tests/tests/print/AndroidManifest.xml
index c5148c8..b398db7 100644
--- a/tests/tests/print/AndroidManifest.xml
+++ b/tests/tests/print/AndroidManifest.xml
@@ -25,7 +25,8 @@
<uses-library android:name="android.test.runner"/>
- <activity android:name="android.print.cts.PrintDocumentActivity"/>
+ <activity android:name="android.print.cts.PrintDocumentActivity"
+ android:configChanges="mnc|mnc|touchscreen|navigation|screenLayout|screenSize|smallestScreenSize|orientation|locale|keyboard|keyboardHidden|fontScale|uiMode|layoutDirection|density"/>
<service
android:name="android.print.cts.services.FirstPrintService"
diff --git a/tests/tests/print/src/android/print/cts/BasePrintTest.java b/tests/tests/print/src/android/print/cts/BasePrintTest.java
index db1efd7..a352ca6 100644
--- a/tests/tests/print/src/android/print/cts/BasePrintTest.java
+++ b/tests/tests/print/src/android/print/cts/BasePrintTest.java
@@ -133,7 +133,7 @@
*
* @return the UI device
*/
- public UiDevice getUiDevice() {
+ public static UiDevice getUiDevice() {
return UiDevice.getInstance(getInstrumentation());
}
@@ -196,6 +196,13 @@
Instrumentation instrumentation = getInstrumentation();
+ // Prevent rotation
+ getUiDevice().freezeRotation();
+ while (!getUiDevice().isNaturalOrientation()) {
+ getUiDevice().setOrientationNatural();
+ getUiDevice().waitForIdle();
+ }
+
// Make sure we start with a clean slate.
Log.d(LOG_TAG, "clearPrintSpoolerData()");
clearPrintSpoolerData();
@@ -313,6 +320,9 @@
SystemUtil.runShellCommand(instrumentation, "settings put secure "
+ Settings.Secure.DISABLED_PRINT_SERVICES + " null");
+ // Allow rotation
+ getUiDevice().unfreezeRotation();
+
Log.d(LOG_TAG, "tearDownClass() done");
}
diff --git a/tests/tests/print/src/android/print/cts/PrintDocumentActivity.java b/tests/tests/print/src/android/print/cts/PrintDocumentActivity.java
index c3e6e96..8c0cb8a 100644
--- a/tests/tests/print/src/android/print/cts/PrintDocumentActivity.java
+++ b/tests/tests/print/src/android/print/cts/PrintDocumentActivity.java
@@ -18,6 +18,7 @@
import android.app.Activity;
import android.app.KeyguardManager;
+import android.content.res.Configuration;
import android.os.Bundle;
import android.util.Log;
import android.view.WindowManager;
@@ -45,6 +46,13 @@
}
@Override
+ public void onConfigurationChanged(Configuration newConfig) {
+ super.onConfigurationChanged(newConfig);
+
+ Log.d(LOG_TAG, "onConfigurationChanged(" + newConfig + ")");
+ }
+
+ @Override
protected void onDestroy() {
Log.d(LOG_TAG, "onDestroy() " + this);
BasePrintTest.onActivityDestroyCalled(mTestId);
diff --git a/tests/tests/telephony/EmbmsMiddlewareTestApp/src/android/telephony/cts/embmstestapp/CtsDownloadService.java b/tests/tests/telephony/EmbmsMiddlewareTestApp/src/android/telephony/cts/embmstestapp/CtsDownloadService.java
index 06e88c0..30447b8 100644
--- a/tests/tests/telephony/EmbmsMiddlewareTestApp/src/android/telephony/cts/embmstestapp/CtsDownloadService.java
+++ b/tests/tests/telephony/EmbmsMiddlewareTestApp/src/android/telephony/cts/embmstestapp/CtsDownloadService.java
@@ -31,8 +31,9 @@
import android.os.ParcelFileDescriptor;
import android.os.RemoteException;
import android.telephony.MbmsDownloadSession;
+import android.telephony.mbms.DownloadProgressListener;
import android.telephony.mbms.DownloadRequest;
-import android.telephony.mbms.DownloadStateCallback;
+import android.telephony.mbms.DownloadStatusListener;
import android.telephony.mbms.FileInfo;
import android.telephony.mbms.FileServiceInfo;
import android.telephony.mbms.MbmsDownloadSessionCallback;
@@ -91,15 +92,30 @@
ComponentName.unflattenFromString(
"android.telephony.cts/android.telephony.mbms.MbmsDownloadReceiver");
- public static final Uri DOWNLOAD_SOURCE_URI = Uri.parse("http://www.example.com/file_download");
+ public static final Uri DOWNLOAD_SOURCE_URI_ROOT =
+ Uri.parse("http://www.example.com/file_download");
public static final FileServiceInfo FILE_SERVICE_INFO;
- public static final FileInfo FILE_INFO = new FileInfo(
- DOWNLOAD_SOURCE_URI.buildUpon().appendPath("file1.txt").build(),
+ public static final FileInfo FILE_INFO_1 = new FileInfo(
+ DOWNLOAD_SOURCE_URI_ROOT.buildUpon().appendPath("file1.txt").build(),
+ "text/plain");
+ public static final FileInfo FILE_INFO_2 = new FileInfo(
+ DOWNLOAD_SOURCE_URI_ROOT.buildUpon().appendPath("sub_dir1")
+ .appendPath("sub_dir2")
+ .appendPath("file2.txt")
+ .build(),
"text/plain");
public static final byte[] SAMPLE_FILE_DATA = "this is some sample file data".getBytes();
+ // Define allowed source URIs so that we don't have to do the prefix matching calculation
+ public static final Uri SOURCE_URI_1 = DOWNLOAD_SOURCE_URI_ROOT.buildUpon()
+ .appendPath("file1.txt").build();
+ public static final Uri SOURCE_URI_2 = DOWNLOAD_SOURCE_URI_ROOT.buildUpon()
+ .appendPath("sub_dir1").appendPath("*").build();
+ public static final Uri SOURCE_URI_3 = DOWNLOAD_SOURCE_URI_ROOT.buildUpon()
+ .appendPath("*").build();
+
static {
- String id = "FileServiceId";
+ String id = "urn:3GPP:service_0-0";
Map<Locale, String> localeDict = new HashMap<Locale, String>() {{
put(Locale.US, "Entertainment Source 1");
put(Locale.CANADA, "Entertainment Source 1, eh?");
@@ -108,13 +124,18 @@
add(Locale.CANADA);
add(Locale.US);
}};
+ List<FileInfo> files = new ArrayList<FileInfo>() {{
+ add(FILE_INFO_1);
+ add(FILE_INFO_2);
+ }};
FILE_SERVICE_INFO = new FileServiceInfo(localeDict, "class1", locales,
id, new Date(2017, 8, 21, 18, 20, 29),
- new Date(2017, 8, 21, 18, 23, 9), Collections.singletonList(FILE_INFO));
+ new Date(2017, 8, 21, 18, 23, 9), files);
}
private MbmsDownloadSessionCallback mAppCallback;
- private DownloadStateCallback mDownloadStateCallback;
+ private DownloadStatusListener mDownloadStatusListener;
+ private DownloadProgressListener mDownloadProgressListener;
private HandlerThread mHandlerThread;
private Handler mHandler;
@@ -203,9 +224,16 @@
}
@Override
- public int registerStateCallback(DownloadRequest downloadRequest,
- DownloadStateCallback listener) throws RemoteException {
- mDownloadStateCallback = listener;
+ public int addProgressListener(DownloadRequest downloadRequest,
+ DownloadProgressListener listener) throws RemoteException {
+ mDownloadProgressListener = listener;
+ return MbmsErrors.SUCCESS;
+ }
+
+ @Override
+ public int addStatusListener(DownloadRequest downloadRequest,
+ DownloadStatusListener listener) throws RemoteException {
+ mDownloadStatusListener = listener;
return MbmsErrors.SUCCESS;
}
@@ -243,9 +271,9 @@
}
@Override
- public int unregisterStateCallback(DownloadRequest downloadRequest,
- DownloadStateCallback callback) {
- mDownloadStateCallback = null;
+ public int removeStatusListener(DownloadRequest downloadRequest,
+ DownloadStatusListener callback) {
+ mDownloadStatusListener = null;
return MbmsErrors.SUCCESS;
}
@@ -272,7 +300,7 @@
mAppCallback = null;
mErrorCodeOverride = MbmsErrors.SUCCESS;
mReceivedRequests.clear();
- mDownloadStateCallback = null;
+ mDownloadStatusListener = null;
mTempFileRootDirPath = null;
}
@@ -295,28 +323,30 @@
public void fireOnProgressUpdated(DownloadRequest request, FileInfo fileInfo,
int currentDownloadSize, int fullDownloadSize,
int currentDecodedSize, int fullDecodedSize) {
- if (mDownloadStateCallback == null) {
+ if (mDownloadStatusListener == null) {
return;
}
- mHandler.post(() -> mDownloadStateCallback.onProgressUpdated(request, fileInfo,
+ mHandler.post(() -> mDownloadProgressListener.onProgressUpdated(request, fileInfo,
currentDownloadSize, fullDownloadSize, currentDecodedSize, fullDecodedSize));
}
@Override
public void fireOnStateUpdated(DownloadRequest request, FileInfo fileInfo, int state) {
- if (mDownloadStateCallback == null) {
+ if (mDownloadStatusListener == null) {
return;
}
- mHandler.post(() -> mDownloadStateCallback.onStateUpdated(request, fileInfo, state));
+ mHandler.post(() -> mDownloadStatusListener.onStatusUpdated(request, fileInfo, state));
}
@Override
public void actuallyStartDownloadFlow() {
DownloadRequest request = mReceivedRequests.get(0);
+ List<FileInfo> requestedFiles = getRequestedFiles(request);
// Compose the FILE_DESCRIPTOR_REQUEST_INTENT to get some FDs to write to
Intent requestIntent = new Intent(VendorUtils.ACTION_FILE_DESCRIPTOR_REQUEST);
requestIntent.putExtra(VendorUtils.EXTRA_SERVICE_ID, request.getFileServiceId());
- requestIntent.putExtra(VendorUtils.EXTRA_FD_COUNT, 1);
+
+ requestIntent.putExtra(VendorUtils.EXTRA_FD_COUNT, requestedFiles.size());
requestIntent.putExtra(VendorUtils.EXTRA_TEMP_FILE_ROOT, mTempFileRootDirPath);
requestIntent.setComponent(CTS_TEST_RECEIVER_COMPONENT);
@@ -330,52 +360,36 @@
public void onReceive(Context context, Intent intent) {
logd("Got file-descriptors");
Bundle extras = getResultExtras(false);
- UriPathPair tempFile = (UriPathPair) extras.getParcelableArrayList(
- VendorUtils.EXTRA_FREE_URI_LIST).get(0);
- int result = MbmsDownloadSession.RESULT_SUCCESSFUL;
- try {
- ParcelFileDescriptor tempFileFd =
- getContentResolver().openFileDescriptor(
- tempFile.getContentUri(), "rw");
- OutputStream destinationStream =
- new ParcelFileDescriptor.AutoCloseOutputStream(tempFileFd);
+ List<UriPathPair> tempFiles = extras.getParcelableArrayList(
+ VendorUtils.EXTRA_FREE_URI_LIST);
- destinationStream.write(SAMPLE_FILE_DATA);
- destinationStream.flush();
- } catch (IOException e) {
- result = MbmsDownloadSession.RESULT_CANCELLED;
- }
+ for (int i = 0; i < tempFiles.size(); i++) {
+ UriPathPair tempFile = tempFiles.get(i);
+ FileInfo requestedFile = requestedFiles.get(i);
+ int result = writeContentsToTempFile(tempFile);
- Intent downloadResultIntent =
- new Intent(VendorUtils.ACTION_DOWNLOAD_RESULT_INTERNAL);
- downloadResultIntent.putExtra(
- MbmsDownloadSession.EXTRA_MBMS_DOWNLOAD_REQUEST, request);
- downloadResultIntent.putExtra(VendorUtils.EXTRA_FINAL_URI,
- tempFile.getFilePathUri());
- downloadResultIntent.putExtra(MbmsDownloadSession.EXTRA_MBMS_FILE_INFO,
- FILE_INFO);
- downloadResultIntent.putExtra(VendorUtils.EXTRA_TEMP_FILE_ROOT,
- mTempFileRootDirPath);
- downloadResultIntent.putExtra(
- MbmsDownloadSession.EXTRA_MBMS_DOWNLOAD_RESULT, result);
- downloadResultIntent.setComponent(CTS_TEST_RECEIVER_COMPONENT);
+ Intent downloadResultIntent = composeDownloadResultIntent(
+ tempFile, request, result, requestedFile);
- logd("Sending broadcast to app: " + downloadResultIntent.toString());
- sendOrderedBroadcast(downloadResultIntent,
- null, // receiverPermission
- new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- Bundle b = new Bundle();
- b.putString(METHOD_NAME, METHOD_DOWNLOAD_RESULT_ACK);
- b.putInt(ARGUMENT_RESULT_CODE, getResultCode());
- mReceivedCalls.add(b);
- }
- },
- null, // scheduler
- Activity.RESULT_OK,
- null, // initialData
- null /* initialExtras */);
+ logd("Sending broadcast to app: "
+ + downloadResultIntent.toString());
+ sendOrderedBroadcast(downloadResultIntent,
+ null, // receiverPermission
+ new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ Bundle b = new Bundle();
+ b.putString(METHOD_NAME,
+ METHOD_DOWNLOAD_RESULT_ACK);
+ b.putInt(ARGUMENT_RESULT_CODE, getResultCode());
+ mReceivedCalls.add(b);
+ }
+ },
+ null, // scheduler
+ Activity.RESULT_OK,
+ null, // initialData
+ null /* initialExtras */);
+ }
}
},
mHandler, // scheduler
@@ -386,6 +400,54 @@
}
};
+ private List<FileInfo> getRequestedFiles(DownloadRequest request) {
+ if (SOURCE_URI_1.equals(request.getSourceUri())) {
+ return Collections.singletonList(FILE_INFO_1);
+ }
+ if (SOURCE_URI_2.equals(request.getSourceUri())) {
+ return Collections.singletonList(FILE_INFO_2);
+ }
+ if (SOURCE_URI_3.equals(request.getSourceUri())) {
+ return FILE_SERVICE_INFO.getFiles();
+ }
+ return Collections.emptyList();
+ }
+
+ private Intent composeDownloadResultIntent(UriPathPair tempFile, DownloadRequest request,
+ int result, FileInfo downloadedFile) {
+ Intent downloadResultIntent =
+ new Intent(VendorUtils.ACTION_DOWNLOAD_RESULT_INTERNAL);
+ downloadResultIntent.putExtra(
+ MbmsDownloadSession.EXTRA_MBMS_DOWNLOAD_REQUEST, request);
+ downloadResultIntent.putExtra(VendorUtils.EXTRA_FINAL_URI,
+ tempFile.getFilePathUri());
+ downloadResultIntent.putExtra(
+ MbmsDownloadSession.EXTRA_MBMS_FILE_INFO, downloadedFile);
+ downloadResultIntent.putExtra(VendorUtils.EXTRA_TEMP_FILE_ROOT,
+ mTempFileRootDirPath);
+ downloadResultIntent.putExtra(
+ MbmsDownloadSession.EXTRA_MBMS_DOWNLOAD_RESULT, result);
+ downloadResultIntent.setComponent(CTS_TEST_RECEIVER_COMPONENT);
+ return downloadResultIntent;
+ }
+
+ private int writeContentsToTempFile(UriPathPair tempFile) {
+ int result = MbmsDownloadSession.RESULT_SUCCESSFUL;
+ try {
+ ParcelFileDescriptor tempFileFd =
+ getContentResolver().openFileDescriptor(
+ tempFile.getContentUri(), "rw");
+ OutputStream destinationStream =
+ new ParcelFileDescriptor.AutoCloseOutputStream(tempFileFd);
+
+ destinationStream.write(SAMPLE_FILE_DATA);
+ destinationStream.flush();
+ } catch (IOException e) {
+ result = MbmsDownloadSession.RESULT_CANCELLED;
+ }
+ return result;
+ }
+
@Override
public void onDestroy() {
super.onCreate();
diff --git a/tests/tests/telephony/src/android/telephony/embms/cts/MbmsDownloadCallbackTest.java b/tests/tests/telephony/src/android/telephony/embms/cts/MbmsDownloadCallbackTest.java
new file mode 100644
index 0000000..98b7ec4
--- /dev/null
+++ b/tests/tests/telephony/src/android/telephony/embms/cts/MbmsDownloadCallbackTest.java
@@ -0,0 +1,121 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package android.telephony.embms.cts;
+
+import android.telephony.MbmsDownloadSession;
+import android.telephony.cts.embmstestapp.CtsDownloadService;
+import android.telephony.mbms.DownloadProgressListener;
+import android.telephony.mbms.DownloadRequest;
+import android.telephony.mbms.DownloadStatusListener;
+import android.telephony.mbms.FileInfo;
+
+import com.android.internal.os.SomeArgs;
+
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.TimeUnit;
+
+public class MbmsDownloadCallbackTest extends MbmsDownloadTestBase {
+ private static final long SHORT_TIMEOUT = 500;
+
+ private class TestDSCallback extends DownloadStatusListener {
+ private final BlockingQueue<SomeArgs> mCalls = new LinkedBlockingQueue<>();
+
+ @Override
+ public void onStatusUpdated(DownloadRequest request, FileInfo fileInfo,
+ @MbmsDownloadSession.DownloadStatus int state) {
+ SomeArgs args = SomeArgs.obtain();
+ args.arg1 = request;
+ args.arg2 = fileInfo;
+ args.arg3 = state;
+ mCalls.add(args);
+ }
+
+ public SomeArgs waitOnStatusUpdated(long timeout) {
+ try {
+ return mCalls.poll(timeout, TimeUnit.MILLISECONDS);
+ } catch (InterruptedException e) {
+ return null;
+ }
+ }
+ }
+
+ private class TestDPCallback extends DownloadProgressListener {
+ private final BlockingQueue<SomeArgs> mProgressUpdatedCalls = new LinkedBlockingQueue<>();
+
+ @Override
+ public void onProgressUpdated(DownloadRequest request, FileInfo fileInfo, int
+ currentDownloadSize, int fullDownloadSize, int currentDecodedSize, int
+ fullDecodedSize) {
+ SomeArgs args = SomeArgs.obtain();
+ args.arg1 = request;
+ args.arg2 = fileInfo;
+ args.arg3 = currentDownloadSize;
+ args.arg4 = fullDownloadSize;
+ args.arg5 = currentDecodedSize;
+ args.arg6 = fullDecodedSize;
+ mProgressUpdatedCalls.add(args);
+ }
+
+ public SomeArgs waitOnProgressUpdated(long timeout) {
+ try {
+ return mProgressUpdatedCalls.poll(timeout, TimeUnit.MILLISECONDS);
+ } catch (InterruptedException e) {
+ return null;
+ }
+ }
+ }
+
+ public void testFullCallback() throws Exception {
+ int sampleInt = 10;
+ TestDSCallback statusCallback = new TestDSCallback();
+ TestDPCallback progressCallback = new TestDPCallback();
+ DownloadRequest request = downloadRequestTemplate.build();
+ mDownloadSession.addStatusListener(request, mCallbackExecutor, statusCallback);
+ mDownloadSession.addProgressListener(request, mCallbackExecutor, progressCallback);
+ mMiddlewareControl.fireOnProgressUpdated(request, CtsDownloadService.FILE_INFO_1,
+ sampleInt, sampleInt, sampleInt, sampleInt);
+ SomeArgs progressArgs = progressCallback.waitOnProgressUpdated(ASYNC_TIMEOUT);
+ assertEquals(request, progressArgs.arg1);
+ assertEquals(CtsDownloadService.FILE_INFO_1, progressArgs.arg2);
+ assertEquals(sampleInt, progressArgs.arg3);
+ assertEquals(sampleInt, progressArgs.arg4);
+ assertEquals(sampleInt, progressArgs.arg5);
+ assertEquals(sampleInt, progressArgs.arg6);
+
+ mMiddlewareControl.fireOnStateUpdated(request, CtsDownloadService.FILE_INFO_1, sampleInt);
+ SomeArgs stateArgs = statusCallback.waitOnStatusUpdated(ASYNC_TIMEOUT);
+ assertEquals(request, stateArgs.arg1);
+ assertEquals(CtsDownloadService.FILE_INFO_1, stateArgs.arg2);
+ assertEquals(sampleInt, stateArgs.arg3);
+ }
+
+ public void testDeregistration() throws Exception {
+ TestDSCallback statusCallback = new TestDSCallback();
+ TestDPCallback progressCallback = new TestDPCallback();
+ DownloadRequest request = downloadRequestTemplate.build();
+ mDownloadSession.addProgressListener(request, mCallbackExecutor, progressCallback);
+ mDownloadSession.addStatusListener(request, mCallbackExecutor, statusCallback);
+ mDownloadSession.removeProgressListener(request, progressCallback);
+ mDownloadSession.removeStatusListener(request, statusCallback);
+
+ mMiddlewareControl.fireOnStateUpdated(null, null, 0);
+ assertNull(statusCallback.waitOnStatusUpdated(SHORT_TIMEOUT));
+ mMiddlewareControl.fireOnProgressUpdated(null, null, 0, 0, 0, 0);
+ assertNull(progressCallback.waitOnProgressUpdated(SHORT_TIMEOUT));
+ }
+}
diff --git a/tests/tests/telephony/src/android/telephony/embms/cts/MbmsDownloadFlowTest.java b/tests/tests/telephony/src/android/telephony/embms/cts/MbmsDownloadFlowTest.java
index e6a97ed..119ac66 100644
--- a/tests/tests/telephony/src/android/telephony/embms/cts/MbmsDownloadFlowTest.java
+++ b/tests/tests/telephony/src/android/telephony/embms/cts/MbmsDownloadFlowTest.java
@@ -22,6 +22,7 @@
import android.telephony.MbmsDownloadSession;
import android.telephony.cts.embmstestapp.CtsDownloadService;
import android.telephony.mbms.DownloadRequest;
+import android.telephony.mbms.FileInfo;
import android.telephony.mbms.MbmsDownloadReceiver;
import java.io.File;
@@ -30,14 +31,10 @@
public class MbmsDownloadFlowTest extends MbmsDownloadTestBase {
private File tempFileRootDir;
- private DownloadRequest testDownloadRequest;
@Override
public void setUp() throws Exception {
super.setUp();
- testDownloadRequest = downloadRequestTemplate
- .setAppIntent(new Intent(MbmsDownloadReceiverTest.APP_INTENT_ACTION))
- .build();
tempFileRootDir = new File(mContext.getFilesDir(), "CtsTestDir");
tempFileRootDir.mkdir();
mDownloadSession.setTempFileRootDirectory(tempFileRootDir);
@@ -50,34 +47,109 @@
super.tearDown();
}
- public void testFileDownloadFlow() throws Exception {
+ public void testSingleFileDownloadFlow() throws Exception {
MbmsDownloadReceiverTest.AppIntentCapture captor =
new MbmsDownloadReceiverTest.AppIntentCapture(mContext, mHandler);
- mDownloadSession.download(testDownloadRequest);
+ DownloadRequest request = downloadRequestTemplate
+ .setAppIntent(new Intent(MbmsDownloadReceiverTest.APP_INTENT_ACTION))
+ .build();
+ mDownloadSession.download(request);
mMiddlewareControl.actuallyStartDownloadFlow();
- Intent downloadDoneIntent = captor.getIntent();
+ Uri fileUri = checkReceivedDownloadCompleteIntent(captor.getIntent(), request,
+ CtsDownloadService.FILE_INFO_1);
+ checkFileContentIntegrity(CtsDownloadService.FILE_INFO_1, fileUri);
+ checkDownloadResultAck(1);
+ }
+
+ public void testFileInSubdirectoryDownloadFlow() throws Exception {
+ MbmsDownloadReceiverTest.AppIntentCapture captor =
+ new MbmsDownloadReceiverTest.AppIntentCapture(mContext, mHandler);
+ DownloadRequest request = new DownloadRequest.Builder(
+ CtsDownloadService.SOURCE_URI_2, destinationDirectoryUri)
+ .setServiceInfo(CtsDownloadService.FILE_SERVICE_INFO)
+ .setAppIntent(new Intent(MbmsDownloadReceiverTest.APP_INTENT_ACTION))
+ .build();
+
+ mDownloadSession.download(request);
+ mMiddlewareControl.actuallyStartDownloadFlow();
+
+ Uri fileUri = checkReceivedDownloadCompleteIntent(captor.getIntent(), request,
+ CtsDownloadService.FILE_INFO_2);
+ // Make sure that the received file is placed in the proper subdirectory.
+ String file2RelativePath = CtsDownloadService.FILE_INFO_2.getUri().getPath().substring(
+ CtsDownloadService.SOURCE_URI_2.getPath().length());
+ assertTrue("got path: " + fileUri.getPath() + ", should end with: " + file2RelativePath,
+ fileUri.getPath().endsWith(file2RelativePath));
+ checkFileContentIntegrity(CtsDownloadService.FILE_INFO_2, fileUri);
+ checkDownloadResultAck(1);
+ }
+
+ public void testMultiFileDownloadFlow() throws Exception {
+ MbmsDownloadReceiverTest.AppIntentCapture captor =
+ new MbmsDownloadReceiverTest.AppIntentCapture(mContext, mHandler);
+ DownloadRequest request = new DownloadRequest.Builder(
+ CtsDownloadService.SOURCE_URI_3, destinationDirectoryUri)
+ .setServiceInfo(CtsDownloadService.FILE_SERVICE_INFO)
+ .setAppIntent(new Intent(MbmsDownloadReceiverTest.APP_INTENT_ACTION))
+ .build();
+
+ mDownloadSession.download(request);
+ mMiddlewareControl.actuallyStartDownloadFlow();
+
+ for (Intent i : captor.getIntents(2)) {
+ FileInfo fileInfo = i.getParcelableExtra(MbmsDownloadSession.EXTRA_MBMS_FILE_INFO);
+ Uri fileUri = null;
+ if (CtsDownloadService.FILE_INFO_1.equals(fileInfo)) {
+ fileUri = checkReceivedDownloadCompleteIntent(
+ i, request, CtsDownloadService.FILE_INFO_1);
+ } else if (CtsDownloadService.FILE_INFO_2.equals(fileInfo)) {
+ fileUri = checkReceivedDownloadCompleteIntent(
+ i, request, CtsDownloadService.FILE_INFO_2);
+ } else {
+ fail("Got unknown file info: " + fileInfo);
+ }
+ String relativePath = fileInfo.getUri().getPath().substring(
+ CtsDownloadService.SOURCE_URI_3.getPath().length());
+ assertTrue("got path: " + fileUri.getPath() + ", should end with: " + relativePath,
+ fileUri.getPath().endsWith(relativePath));
+ checkFileContentIntegrity(fileInfo, fileUri);
+ }
+ checkDownloadResultAck(2);
+ }
+
+
+ private Uri checkReceivedDownloadCompleteIntent(Intent downloadDoneIntent,
+ DownloadRequest downloadRequest, FileInfo expectedFileInfo) {
assertEquals(MbmsDownloadReceiverTest.APP_INTENT_ACTION, downloadDoneIntent.getAction());
assertEquals(MbmsDownloadSession.RESULT_SUCCESSFUL,
downloadDoneIntent.getIntExtra(MbmsDownloadSession.EXTRA_MBMS_DOWNLOAD_RESULT, -1));
- assertEquals(testDownloadRequest,
+ assertEquals(downloadRequest,
downloadDoneIntent.getParcelableExtra(
MbmsDownloadSession.EXTRA_MBMS_DOWNLOAD_REQUEST));
- assertEquals(CtsDownloadService.FILE_INFO,
+ assertEquals(expectedFileInfo,
downloadDoneIntent.getParcelableExtra(MbmsDownloadSession.EXTRA_MBMS_FILE_INFO));
- Uri fileUri = downloadDoneIntent.getParcelableExtra(
+ return downloadDoneIntent.getParcelableExtra(
MbmsDownloadSession.EXTRA_MBMS_COMPLETED_FILE_URI);
- InputStream is = mContext.getContentResolver().openInputStream(fileUri);
+ }
+
+ private void checkFileContentIntegrity(FileInfo fileInfo, Uri completedFileUri)
+ throws Exception {
+ assertEquals(fileInfo.getUri().getLastPathSegment(),
+ completedFileUri.getLastPathSegment());
+ InputStream is = mContext.getContentResolver().openInputStream(completedFileUri);
byte[] contents = new byte[CtsDownloadService.SAMPLE_FILE_DATA.length];
is.read(contents);
for (int i = 0; i < contents.length; i++) {
assertEquals(contents[i], CtsDownloadService.SAMPLE_FILE_DATA[i]);
}
+ }
+ private void checkDownloadResultAck(int numAcks) throws Exception {
List<Bundle> downloadResultAck =
getMiddlewareCalls(CtsDownloadService.METHOD_DOWNLOAD_RESULT_ACK);
- assertEquals(1, downloadResultAck.size());
- assertEquals(MbmsDownloadReceiver.RESULT_OK,
- downloadResultAck.get(0).getInt(CtsDownloadService.ARGUMENT_RESULT_CODE, -1));
+ assertEquals(numAcks, downloadResultAck.size());
+ downloadResultAck.forEach((ack) -> assertEquals(MbmsDownloadReceiver.RESULT_OK,
+ ack.getInt(CtsDownloadService.ARGUMENT_RESULT_CODE, -1)));
}
}
diff --git a/tests/tests/telephony/src/android/telephony/embms/cts/MbmsDownloadReceiverTest.java b/tests/tests/telephony/src/android/telephony/embms/cts/MbmsDownloadReceiverTest.java
index 8232271..59d9a1b 100644
--- a/tests/tests/telephony/src/android/telephony/embms/cts/MbmsDownloadReceiverTest.java
+++ b/tests/tests/telephony/src/android/telephony/embms/cts/MbmsDownloadReceiverTest.java
@@ -65,15 +65,30 @@
}
public Intent getIntent() {
+ return getIntent(true);
+ }
+
+ public Intent getIntent(boolean unregister) {
try {
Intent result = mReceivedIntent.poll(ASYNC_TIMEOUT, TimeUnit.MILLISECONDS);
- mContext.unregisterReceiver(mAppIntentReceiver);
+ if (unregister) {
+ mContext.unregisterReceiver(mAppIntentReceiver);
+ }
return result;
} catch (InterruptedException e) {
fail("test was interrupted");
return null;
}
}
+
+ public List<Intent> getIntents(int numExpected) {
+ ArrayList<Intent> result = new ArrayList<>(numExpected);
+ for (int i = 0; i < numExpected; i++) {
+ result.add(getIntent(false));
+ }
+ mContext.unregisterReceiver(mAppIntentReceiver);
+ return result;
+ }
}
private MbmsDownloadReceiver mReceiver;
@@ -165,7 +180,7 @@
intentForReceiverTest.putExtra(MbmsDownloadSession.EXTRA_MBMS_DOWNLOAD_REQUEST,
testDownloadRequest);
intentForReceiverTest.putExtra(MbmsDownloadSession.EXTRA_MBMS_FILE_INFO,
- CtsDownloadService.FILE_INFO);
+ CtsDownloadService.FILE_INFO_1);
intentForReceiverTest.putExtra(VendorUtils.EXTRA_FINAL_URI,
Uri.fromFile(new File(new File(tempFileRootDir, TEST_SERVICE_ID), "file1")));
diff --git a/tests/tests/telephony/src/android/telephony/embms/cts/MbmsDownloadSessionTest.java b/tests/tests/telephony/src/android/telephony/embms/cts/MbmsDownloadSessionTest.java
index 5e70828..ac65030 100644
--- a/tests/tests/telephony/src/android/telephony/embms/cts/MbmsDownloadSessionTest.java
+++ b/tests/tests/telephony/src/android/telephony/embms/cts/MbmsDownloadSessionTest.java
@@ -151,14 +151,14 @@
public void testGetDownloadStatus() throws Exception {
DownloadRequest request = downloadRequestTemplate.build();
- mDownloadSession.requestDownloadState(request, CtsDownloadService.FILE_INFO);
+ mDownloadSession.requestDownloadState(request, CtsDownloadService.FILE_INFO_1);
List<Bundle> getDownloadStatusCalls =
getMiddlewareCalls(CtsDownloadService.METHOD_GET_DOWNLOAD_STATUS);
assertEquals(1, getDownloadStatusCalls.size());
assertEquals(request, getDownloadStatusCalls.get(0).getParcelable(
CtsDownloadService.ARGUMENT_DOWNLOAD_REQUEST));
- assertEquals(CtsDownloadService.FILE_INFO, getDownloadStatusCalls.get(0).getParcelable(
+ assertEquals(CtsDownloadService.FILE_INFO_1, getDownloadStatusCalls.get(0).getParcelable(
CtsDownloadService.ARGUMENT_FILE_INFO));
}
diff --git a/tests/tests/telephony/src/android/telephony/embms/cts/MbmsDownloadStateCallbackTest.java b/tests/tests/telephony/src/android/telephony/embms/cts/MbmsDownloadStateCallbackTest.java
deleted file mode 100644
index c01de7c..0000000
--- a/tests/tests/telephony/src/android/telephony/embms/cts/MbmsDownloadStateCallbackTest.java
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package android.telephony.embms.cts;
-
-import android.telephony.MbmsDownloadSession;
-import android.telephony.cts.embmstestapp.CtsDownloadService;
-import android.telephony.mbms.DownloadRequest;
-import android.telephony.mbms.DownloadStateCallback;
-import android.telephony.mbms.FileInfo;
-
-import com.android.internal.os.SomeArgs;
-
-import java.util.concurrent.BlockingQueue;
-import java.util.concurrent.LinkedBlockingQueue;
-import java.util.concurrent.TimeUnit;
-
-public class MbmsDownloadStateCallbackTest extends MbmsDownloadTestBase {
- private static final long SHORT_TIMEOUT = 500;
-
- private class TestDSCallback extends DownloadStateCallback {
- private final BlockingQueue<SomeArgs> mProgressUpdatedCalls = new LinkedBlockingQueue<>();
- private final BlockingQueue<SomeArgs> mStateUpdatedCalls = new LinkedBlockingQueue<>();
-
- public TestDSCallback(int filterFlags) {
- super(filterFlags);
- }
-
- @Override
- public void onProgressUpdated(DownloadRequest request, FileInfo fileInfo, int
- currentDownloadSize, int fullDownloadSize, int currentDecodedSize, int
- fullDecodedSize) {
- SomeArgs args = SomeArgs.obtain();
- args.arg1 = request;
- args.arg2 = fileInfo;
- args.arg3 = currentDownloadSize;
- args.arg4 = fullDownloadSize;
- args.arg5 = currentDecodedSize;
- args.arg6 = fullDecodedSize;
- mProgressUpdatedCalls.add(args);
- }
-
- @Override
- public void onStateUpdated(DownloadRequest request, FileInfo fileInfo,
- @MbmsDownloadSession.DownloadStatus int state) {
- SomeArgs args = SomeArgs.obtain();
- args.arg1 = request;
- args.arg2 = fileInfo;
- args.arg3 = state;
- mStateUpdatedCalls.add(args);
- }
-
- public SomeArgs waitOnProgressUpdated(long timeout) {
- try {
- return mProgressUpdatedCalls.poll(timeout, TimeUnit.MILLISECONDS);
- } catch (InterruptedException e) {
- return null;
- }
- }
-
- public SomeArgs waitOnStateUpdated(long timeout) {
- try {
- return mStateUpdatedCalls.poll(timeout, TimeUnit.MILLISECONDS);
- } catch (InterruptedException e) {
- return null;
- }
- }
- }
-
- public void testFullCallback() throws Exception {
- int sampleInt = 10;
- TestDSCallback callback = new TestDSCallback(DownloadStateCallback.ALL_UPDATES);
- DownloadRequest request = downloadRequestTemplate.build();
- mDownloadSession.registerStateCallback(request, mCallbackExecutor, callback);
- mMiddlewareControl.fireOnProgressUpdated(request, CtsDownloadService.FILE_INFO,
- sampleInt, sampleInt, sampleInt, sampleInt);
- SomeArgs progressArgs = callback.waitOnProgressUpdated(ASYNC_TIMEOUT);
- assertEquals(request, progressArgs.arg1);
- assertEquals(CtsDownloadService.FILE_INFO, progressArgs.arg2);
- assertEquals(sampleInt, progressArgs.arg3);
- assertEquals(sampleInt, progressArgs.arg4);
- assertEquals(sampleInt, progressArgs.arg5);
- assertEquals(sampleInt, progressArgs.arg6);
-
- mMiddlewareControl.fireOnStateUpdated(request, CtsDownloadService.FILE_INFO, sampleInt);
- SomeArgs stateArgs = callback.waitOnStateUpdated(ASYNC_TIMEOUT);
- assertEquals(request, stateArgs.arg1);
- assertEquals(CtsDownloadService.FILE_INFO, stateArgs.arg2);
- assertEquals(sampleInt, stateArgs.arg3);
- }
-
- public void testDeregistration() throws Exception {
- TestDSCallback callback = new TestDSCallback(DownloadStateCallback.ALL_UPDATES);
- DownloadRequest request = downloadRequestTemplate.build();
- mDownloadSession.registerStateCallback(request, mCallbackExecutor, callback);
- mDownloadSession.unregisterStateCallback(request, callback);
-
- mMiddlewareControl.fireOnStateUpdated(null, null, 0);
- assertNull(callback.waitOnStateUpdated(SHORT_TIMEOUT));
- mMiddlewareControl.fireOnProgressUpdated(null, null, 0, 0, 0, 0);
- assertNull(callback.waitOnProgressUpdated(SHORT_TIMEOUT));
- }
-
- public void testCallbackFiltering1() throws Exception {
- TestDSCallback callback = new TestDSCallback(DownloadStateCallback.PROGRESS_UPDATES);
- DownloadRequest request = downloadRequestTemplate.build();
- mDownloadSession.registerStateCallback(request, mCallbackExecutor, callback);
-
- mMiddlewareControl.fireOnStateUpdated(null, null, 0);
- assertNull(callback.waitOnStateUpdated(SHORT_TIMEOUT));
- mMiddlewareControl.fireOnProgressUpdated(null, null, 0, 0, 0, 0);
- assertNotNull(callback.waitOnProgressUpdated(SHORT_TIMEOUT));
- }
-
- public void testCallbackFiltering2() throws Exception {
- TestDSCallback callback = new TestDSCallback(DownloadStateCallback.STATE_UPDATES);
- DownloadRequest request = downloadRequestTemplate.build();
- mDownloadSession.registerStateCallback(request, mCallbackExecutor, callback);
-
- mMiddlewareControl.fireOnStateUpdated(null, null, 0);
- assertNotNull(callback.waitOnStateUpdated(SHORT_TIMEOUT));
- mMiddlewareControl.fireOnProgressUpdated(null, null, 0, 0, 0, 0);
- assertNull(callback.waitOnProgressUpdated(SHORT_TIMEOUT));
- }
-}
diff --git a/tests/tests/telephony/src/android/telephony/embms/cts/MbmsDownloadTestBase.java b/tests/tests/telephony/src/android/telephony/embms/cts/MbmsDownloadTestBase.java
index bde9de6..2a27cb0 100644
--- a/tests/tests/telephony/src/android/telephony/embms/cts/MbmsDownloadTestBase.java
+++ b/tests/tests/telephony/src/android/telephony/embms/cts/MbmsDownloadTestBase.java
@@ -110,6 +110,7 @@
}
DownloadRequest.Builder downloadRequestTemplate;
+ Uri destinationDirectoryUri;
Context mContext;
HandlerThread mHandlerThread;
@@ -130,9 +131,9 @@
File destinationDirectory = new File(mContext.getFilesDir(), "downloads");
destinationDirectory.mkdirs();
- Uri destinationDirectoryUri = Uri.fromFile(destinationDirectory);
+ destinationDirectoryUri = Uri.fromFile(destinationDirectory);
downloadRequestTemplate = new DownloadRequest.Builder(
- CtsDownloadService.DOWNLOAD_SOURCE_URI, destinationDirectoryUri)
+ CtsDownloadService.SOURCE_URI_1, destinationDirectoryUri)
.setServiceInfo(CtsDownloadService.FILE_SERVICE_INFO);
getControlBinder();
setupDownloadSession();
diff --git a/tests/video/Android.mk b/tests/video/Android.mk
index c70cfaf..176eddf 100644
--- a/tests/video/Android.mk
+++ b/tests/video/Android.mk
@@ -25,7 +25,7 @@
LOCAL_STATIC_JAVA_LIBRARIES := ctsmediautil compatibility-device-util ctstestrunner
-LOCAL_JNI_SHARED_LIBRARIES := libctsmediacodec_jni libnativehelper_compat_libc++
+LOCAL_JNI_SHARED_LIBRARIES := libctscodecutils_jni libnativehelper_compat_libc++
LOCAL_SRC_FILES := $(call all-java-files-under, src)