Merge "New CTS tests for unstable content provider references." into jb-dev
diff --git a/suite/audio_quality/client/src/com/android/cts/audiotest/AudioProtocol.java b/suite/audio_quality/client/src/com/android/cts/audiotest/AudioProtocol.java
index 3670bd9..32cc3ed 100644
--- a/suite/audio_quality/client/src/com/android/cts/audiotest/AudioProtocol.java
+++ b/suite/audio_quality/client/src/com/android/cts/audiotest/AudioProtocol.java
@@ -117,6 +117,10 @@
Log.e(TAG, "ignore exception", e);
} finally {
track.stop();
+ track.flush();
+ track.release();
+ mPlaybackThread.quitLoop(false);
+ mPlaybackThread = null;
}
}
@@ -195,18 +199,19 @@
mRecord = null;
}
if (mRecordThread != null) {
- mRecordThread.quitLoop();
+ mRecordThread.quitLoop(true);
mRecordThread = null;
}
if (mPlayback != null) {
if (mPlayback.getState() != AudioTrack.STATE_UNINITIALIZED) {
mPlayback.stop();
+ mPlayback.flush();
}
mPlayback.release();
mPlayback = null;
}
if (mPlaybackThread != null) {
- mPlaybackThread.quitLoop();
+ mPlaybackThread.quitLoop(true);
mPlaybackThread = null;
}
mDataMap.clear();
@@ -241,12 +246,17 @@
if (samplingRate != 44100) {
throw new ProtocolError("wrong rate");
}
+ //FIXME cannot start playback again
//TODO repeat
//FIXME in MODE_STATIC, setNotificationMarkerPosition does not work with full length
mPlaybackThread = new LoopThread(new Runnable() {
@Override
public void run() {
+ if (mPlayback != null) {
+ mPlayback.release();
+ mPlayback = null;
+ }
int type = (mode == 0) ? AudioManager.STREAM_VOICE_CALL :
AudioManager.STREAM_MUSIC;
mPlayback = new AudioTrack(type, samplingRate,
@@ -282,12 +292,14 @@
Log.d(TAG, "stopPlayback");
assertProtocol(len == 0, "wrong payload len");
if (mPlayback != null) {
+ Log.d(TAG, "release AudioTrack");
mPlayback.stop();
+ mPlayback.flush();
mPlayback.release();
mPlayback = null;
}
if (mPlaybackThread != null) {
- mPlaybackThread.quitLoop();
+ mPlaybackThread.quitLoop(true);
mPlaybackThread = null;
}
sendSimpleReplyHeader(CMD_STOP_PLAYBACK, PROTOCOL_OK);
@@ -381,7 +393,7 @@
mRecord = null;
}
if (mRecordThread != null) {
- mRecordThread.quitLoop();
+ mRecordThread.quitLoop(true);
mRecordThread = null;
}
sendSimpleReplyHeader(CMD_STOP_RECORDING, PROTOCOL_OK);
@@ -421,17 +433,20 @@
mLooper = Looper.myLooper();
Log.d(TAG, "run runnable");
super.run();
- Log.d(TAG, "loop");
+ //Log.d(TAG, "loop");
Looper.loop();
}
// should be called outside this thread
- public void quitLoop() {
+ public void quitLoop(boolean wait) {
mLooper.quit();
try {
- join();
+ if (wait) {
+ join();
+ }
} catch (InterruptedException e) {
// ignore
}
+ Log.d(TAG, "quit thread");
}
}
diff --git a/suite/audio_quality/lib/include/task/TaskAll.h b/suite/audio_quality/lib/include/task/TaskAll.h
index 2f04fc6..3729ef8 100644
--- a/suite/audio_quality/lib/include/task/TaskAll.h
+++ b/suite/audio_quality/lib/include/task/TaskAll.h
@@ -30,5 +30,6 @@
#include "TaskSound.h"
#include "TaskSave.h"
#include "TaskMessage.h"
+#include "TaskDownload.h"
#endif // CTSAUDIO_TASKALL_H
diff --git a/suite/audio_quality/lib/include/task/TaskDownload.h b/suite/audio_quality/lib/include/task/TaskDownload.h
new file mode 100644
index 0000000..64aae45
--- /dev/null
+++ b/suite/audio_quality/lib/include/task/TaskDownload.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+
+#ifndef CTSAUDIO_TASKDOWNLOAD_H
+#define CTSAUDIO_TASKDOWNLOAD_H
+#include <utils/String8.h>
+#include <utils/StrongPointer.h>
+#include "audio/Buffer.h"
+#include "TaskGeneric.h"
+
+
+class TaskDownload: public TaskGeneric {
+public:
+ TaskDownload();
+ virtual ~TaskDownload();
+ virtual TaskGeneric::ExecutionResult run();
+};
+
+
+#endif // CTSAUDIO_TASKDOWNLOAD_H
diff --git a/suite/audio_quality/lib/include/task/TaskGeneric.h b/suite/audio_quality/lib/include/task/TaskGeneric.h
index 6dc269e..fe5215d 100644
--- a/suite/audio_quality/lib/include/task/TaskGeneric.h
+++ b/suite/audio_quality/lib/include/task/TaskGeneric.h
@@ -43,7 +43,8 @@
ETaskSound = 9,
ETaskSave = 10,
ETaskMessage = 11,
- ETaskInvalidLast = 12,
+ ETaskDownload = 12,
+ ETaskInvalidLast = 13,
//no ETaskInclude include does not involve any action.
};
diff --git a/suite/audio_quality/lib/src/GenericFactory.cpp b/suite/audio_quality/lib/src/GenericFactory.cpp
index f615876..2402055 100644
--- a/suite/audio_quality/lib/src/GenericFactory.cpp
+++ b/suite/audio_quality/lib/src/GenericFactory.cpp
@@ -59,6 +59,9 @@
case TaskGeneric::ETaskMessage:
task = new TaskMessage();
break;
+ case TaskGeneric::ETaskDownload:
+ task = new TaskDownload();
+ break;
default:
LOGE("GenericFactory::createTask unsupported type %d", type);
return NULL;
diff --git a/suite/audio_quality/lib/src/audio/AudioProtocol.cpp b/suite/audio_quality/lib/src/audio/AudioProtocol.cpp
index a046432..bf1ca22 100644
--- a/suite/audio_quality/lib/src/audio/AudioProtocol.cpp
+++ b/suite/audio_quality/lib/src/audio/AudioProtocol.cpp
@@ -111,7 +111,7 @@
mBuffer[1] = htonl(20);
mBuffer[2] = htonl(param.mId);
mBuffer[3] = htonl(param.mSamplingF);
- uint32_t mode = param.mStereo ? 1<<31 : 0;
+ uint32_t mode = param.mStereo ? 0x80000000 : 0;
mode |= param.mMode;
mBuffer[4] = htonl(mode);
mBuffer[5] = htonl(param.mVolume);
@@ -132,7 +132,7 @@
mBuffer[0] = htonl(ECmdStartRecording);
mBuffer[1] = htonl(16);
mBuffer[2] = htonl(param.mSamplingF);
- uint32_t mode = param.mStereo ? 1<<31 : 0;
+ uint32_t mode = param.mStereo ? 0x80000000 : 0;
mode |= param.mMode;
mBuffer[3] = htonl(mode);
mBuffer[4] = htonl(param.mVolume);
diff --git a/suite/audio_quality/lib/src/audio/RemoteAudio.cpp b/suite/audio_quality/lib/src/audio/RemoteAudio.cpp
index 10ae14c..bb9474b 100644
--- a/suite/audio_quality/lib/src/audio/RemoteAudio.cpp
+++ b/suite/audio_quality/lib/src/audio/RemoteAudio.cpp
@@ -235,6 +235,7 @@
LOGE("Buffer id %d not registered", id);
return false;
}
+ LOGD("RemoteAudio::startPlayback stereo %d mode %d", stereo, mode);
handler->mActive = true;
handler->getParam().mStereo = stereo;
handler->getParam().mSamplingF = samplingF;
diff --git a/suite/audio_quality/lib/src/task/ModelBuilder.cpp b/suite/audio_quality/lib/src/task/ModelBuilder.cpp
index 87373ca..6f34f5c 100644
--- a/suite/audio_quality/lib/src/task/ModelBuilder.cpp
+++ b/suite/audio_quality/lib/src/task/ModelBuilder.cpp
@@ -30,7 +30,8 @@
};
static const ModelBuilder::ChildInfo SETUP_TABLE[] = {
{ TaskGeneric::ETaskSound, false },
- { TaskGeneric::ETaskProcess, false }
+ { TaskGeneric::ETaskProcess, false },
+ { TaskGeneric::ETaskDownload, false }
};
static const ModelBuilder::ChildInfo ACTION_TABLE[] = {
{ TaskGeneric::ETaskSequential, true }
@@ -58,7 +59,8 @@
{ "output", TaskGeneric::ETaskOutput, NULL, 0 },
{ "sound", TaskGeneric::ETaskSound, NULL, 0 },
{ "save", TaskGeneric::ETaskSave, NULL, 0 },
- { "message", TaskGeneric::ETaskMessage, NULL, 0 }
+ { "message", TaskGeneric::ETaskMessage, NULL, 0 },
+ { "download", TaskGeneric::ETaskDownload, NULL, 0 }
};
diff --git a/suite/audio_quality/lib/src/task/TaskDownload.cpp b/suite/audio_quality/lib/src/task/TaskDownload.cpp
new file mode 100644
index 0000000..dacefc5
--- /dev/null
+++ b/suite/audio_quality/lib/src/task/TaskDownload.cpp
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+#include <UniquePtr.h>
+#include "Log.h"
+#include "audio/AudioSignalFactory.h"
+#include "audio/RemoteAudio.h"
+#include "StringUtil.h"
+#include "task/TaskCase.h"
+#include "task/TaskDownload.h"
+
+static const android::String8 STR_ID("id");
+
+TaskDownload::TaskDownload()
+ : TaskGeneric(TaskGeneric::ETaskDownload)
+{
+ const android::String8* list[] = {&STR_ID, NULL};
+ registerSupportedStringAttributes(list);
+}
+
+TaskDownload::~TaskDownload()
+{
+
+}
+
+TaskGeneric::ExecutionResult TaskDownload::run()
+{
+ android::String8 id;
+ if (!findStringAttribute(STR_ID, id)) {
+ LOGE("TaskDownload::run %s string not found", STR_ID.string());
+ return TaskGeneric::EResultError;
+ }
+
+ android::sp<Buffer> buffer = getTestCase()->findBuffer(id);
+ if (buffer.get() == NULL) {
+ LOGE("TaskDownload::run cannot find buffer %s", id.string());
+ return TaskGeneric::EResultError;
+ }
+ int downloadId;
+ if (!getTestCase()->getRemoteAudio()->downloadData(id, buffer, downloadId)) {
+ return TaskGeneric::EResultError;
+ }
+ LOGI("Downloaded buffer %s to DUT with id %d", id.string(), downloadId);
+ return TaskGeneric::EResultOK;
+}
+
+
+
diff --git a/suite/audio_quality/lib/src/task/TaskOutput.cpp b/suite/audio_quality/lib/src/task/TaskOutput.cpp
index ce3a7d8..be6f4fd 100644
--- a/suite/audio_quality/lib/src/task/TaskOutput.cpp
+++ b/suite/audio_quality/lib/src/task/TaskOutput.cpp
@@ -54,15 +54,13 @@
LOGE("prepare failed");
return TaskGeneric::EResultError;
}
+ android::sp<Buffer> buffer = getTestCase()->findBuffer(mId);
+ if (buffer.get() == NULL) {
+ LOGE("cannot find buffer %s", mId.string());
+ return TaskGeneric::EResultError;
+ }
+ buffer->restart(); // reset to play from beginning
if (localDevice) {
- android::sp<Buffer> buffer;
- buffer = getTestCase()->findBuffer(mId);
- if (buffer.get() == NULL) {
- LOGE("cannot find buffer %s", mId.string());
- return TaskGeneric::EResultError;
- }
- buffer->restart(); // reset to play from beginning
-
if (!hw->startPlaybackOrRecord(buffer)) {
LOGE("play failed");
return TaskGeneric::EResultError;
@@ -73,7 +71,7 @@
return TaskGeneric::EResultError;
}
AudioRemotePlayback* remote = reinterpret_cast<AudioRemotePlayback*>(hw.get());
- if (!remote->startPlaybackForRemoteData(id, false)) { // mono always
+ if (!remote->startPlaybackForRemoteData(id, buffer->isStereo())) {
return TaskGeneric::EResultError;
}
}
diff --git a/suite/audio_quality/lib/src/task/TaskSound.cpp b/suite/audio_quality/lib/src/task/TaskSound.cpp
index f530203..8dd9b4a 100644
--- a/suite/audio_quality/lib/src/task/TaskSound.cpp
+++ b/suite/audio_quality/lib/src/task/TaskSound.cpp
@@ -51,7 +51,6 @@
TaskGeneric::ExecutionResult TaskSound::run()
{
- //TODO : needs to support data generated from process
android::String8 id;
if (!findStringAttribute(STR_ID, id)) {
LOGE("TaskSound::run %s string not found", STR_ID.string());
@@ -84,6 +83,7 @@
buffer = AudioSignalFactory::generateSineWave(AudioHardware::E2BPS, amplitude,
AudioHardware::ESampleRate_44100, freq, samples, true);
} else if (StringUtil::compare(tokens->at(0), "random") == 0) {
+ // TODO FIXME it does not seem to work well.
if (tokens->size() != 3) {
LOGE("Wrong number of parameters %d", tokens->size());
}
diff --git a/suite/audio_quality/test_description/all.xml b/suite/audio_quality/test_description/all_playback.xml
similarity index 75%
copy from suite/audio_quality/test_description/all.xml
copy to suite/audio_quality/test_description/all_playback.xml
index d022230..cf5af6f 100644
--- a/suite/audio_quality/test_description/all.xml
+++ b/suite/audio_quality/test_description/all_playback.xml
@@ -15,8 +15,8 @@
limitations under the License.
-->
-<batch name="cts_audio_all" version="1.0" description="All tests">
- <include file="host_speaker_calibration.xml" />
- <include file="dut_recording_thd.xml" />
- <include file="dut_recording_spectrum.xml" />
+<batch name="cts_audio_all_playback" version="1.0" description="All playback tests">
+ <include file="dut_speaker_calibration.xml" />
+ <include file="dut_playback_thd.xml" />
+ <include file="dut_playback_spectrum.xml" />
</batch>
diff --git a/suite/audio_quality/test_description/all.xml b/suite/audio_quality/test_description/all_recording.xml
similarity index 90%
rename from suite/audio_quality/test_description/all.xml
rename to suite/audio_quality/test_description/all_recording.xml
index d022230..f1e78b9 100644
--- a/suite/audio_quality/test_description/all.xml
+++ b/suite/audio_quality/test_description/all_recording.xml
@@ -15,7 +15,7 @@
limitations under the License.
-->
-<batch name="cts_audio_all" version="1.0" description="All tests">
+<batch name="cts_audio_all_recording" version="1.0" description="All recording tests">
<include file="host_speaker_calibration.xml" />
<include file="dut_recording_thd.xml" />
<include file="dut_recording_spectrum.xml" />
diff --git a/suite/audio_quality/test_description/conf/detect_usb_audio.py b/suite/audio_quality/test_description/conf/detect_usb_audio.py
old mode 100755
new mode 100644
diff --git a/suite/audio_quality/test_description/dut_playback_spectrum.xml b/suite/audio_quality/test_description/dut_playback_spectrum.xml
new file mode 100644
index 0000000..d945ff6
--- /dev/null
+++ b/suite/audio_quality/test_description/dut_playback_spectrum.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!-- Copyright (C) 2012 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.
+-->
+
+<case name="dut_playback_spectrum" version="1.0" description="Check frequency spectrum for playback">
+ <setup>
+ <!-- input: peak amplitude, duration in msec, sampling rate, high frequency, output: generated sound-->
+ <process method="script:gen_random" input="consti:10000,consti:4000,consti:44100,consti:20000" output="id:sound1" />
+ <download id="sound1" />
+ </setup>
+ <action>
+ <sequential repeat="1" index="i">
+ <input device="host" id="host_in_$i" gain="100" time="5000" sync="start" />
+ <output device="DUT" id="sound1" gain="100" mode="voice" sync="start" waitforcompletion="1" />
+ </sequential>
+ <sequential repeat="1" index="k">
+ <!-- input: host record, device record, samping rate, low frequency in Hz, high frequency in Hz, allowed error for pass in smaller side, allowed error in bigger side%, output: min value in lower side calculated normalized to 1.0, max value in higher side, calculated amplitude ratio in mannitude only between low f to high f -->
+ <process method="script:check_spectrum" input="id:sound1,id:host_in_$k,consti:44100,consti:500,consti:8000,constf:85.0,constf:150.0" output="val:min_val_$k,val:max_val_$k,id:spectrum_$k" />
+ </sequential>
+ </action>
+ <save file="sound1,host_in_.*,spectrum_.*" report="min_val_.*,max_val_.*" />
+</case>
diff --git a/suite/audio_quality/test_description/dut_playback_thd.xml b/suite/audio_quality/test_description/dut_playback_thd.xml
new file mode 100644
index 0000000..819e17f
--- /dev/null
+++ b/suite/audio_quality/test_description/dut_playback_thd.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!-- Copyright (C) 2012 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.
+-->
+
+<case name="dut_playback_thd" version="1.0" description="Check THD in DUT's playback side">
+ <setup>
+ <!-- prepare sound source id: to be used in output, sine 1000Hz, 4000ms long -->
+ <sound id="sound1" type="sin:32000:1000:4000" preload="1" />
+ </setup>
+ <action>
+ <sequential repeat="1" index="i">
+ <output device="DUT" id="sound1" gain="100" sync="start" waitforcompletion="0" />
+ <sequential repeat="1" index="j">
+ <!-- dummy recording to compensate for possible playback latency -->
+ <input device="host" id="dummy" gain="100" time="1000" sync="complete" />
+ <input device="host" id="host_in_$j" gain="100" time="2000" sync="complete" />
+ </sequential>
+ </sequential>
+ <sequential repeat="1" index="k">
+ <!-- input: host record, signal frequency in Hz, THD for pass in percentile, output: THD calculated -->
+ <process method="script:playback_thd" input="id:host_in_$k,consti:1000,constf:1.0" output="val:thd_device_$k" />
+ </sequential>
+ </action>
+ <save file="host_in_.*" report="thd_.*" />
+</case>
diff --git a/suite/audio_quality/test_description/dut_recording_thd.xml b/suite/audio_quality/test_description/dut_recording_thd.xml
index 49db0d2..4567ee2 100644
--- a/suite/audio_quality/test_description/dut_recording_thd.xml
+++ b/suite/audio_quality/test_description/dut_recording_thd.xml
@@ -25,12 +25,12 @@
<action>
<sequential repeat="1" index="i">
<output device="host" id="sound1" gain="100" sync="start" waitforcompletion="0" />
- <sequential repeat="5" index="j">
+ <sequential repeat="2" index="j">
<input device="host" id="host_in_$j" gain="100" time="4000" sync="start" />
<input device="DUT" id="dut_in_$j" gain="100" time="2000" sync="start" />
</sequential>
</sequential>
- <sequential repeat="5" index="k">
+ <sequential repeat="2" index="k">
<!-- input: host record, device record, signal frequency in Hz, THD for pass in percentile, output: THD calculated -->
<process method="script:recording_thd" input="id:host_in_$k,id:dut_in_$k,consti:1000,constf:1.0" output="val:thd_host_$k,val:thd_device_$k" />
</sequential>
diff --git a/suite/audio_quality/test_description/dut_speaker_calibration.xml b/suite/audio_quality/test_description/dut_speaker_calibration.xml
new file mode 100644
index 0000000..9cc655b
--- /dev/null
+++ b/suite/audio_quality/test_description/dut_speaker_calibration.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!-- Copyright (C) 2012 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.
+-->
+
+<case name="dut_speaker_calibration" version="1.0" description="Calibrate host recording gain">
+ <setup> <!-- 1 setup -->
+ <!-- prepare sound source id: to be used in output, sine 1000Hz, 20000ms long -->
+ <sound id="sound1" type="sin:32000:1000:5000" preload="1" />
+ </setup>
+
+ <action> <!-- 1 action -->
+ <!-- equivalent of for loop. all children will be completed before moving to the next
+ stage.repeat up to 100 times unless stopped by some condition -->
+ <sequential repeat="20" index="i">
+ <!-- sync start : execute only sync complete : execute + complete
+ For sync start, complete will be called when the parent completes -->
+ <output device="DUT" id="sound1" gain="100" sync="start"/>
+ <sequential repeat="8" index="j">
+ <input device="host" id="host_in" gain="100" time="500" sync="complete" />
+ <!-- ------------moving average RMS min for pass, max for pass result calculated -->
+ <process method="builtin:rms_mva" input="id:host_in,consti:3000,consti:8000" output="val:rms_$i_$j" />
+ <!-- <message input="val:passfail" output_low="Volume Low" output_ok="Volume OK" output_high="Volume High" /> -->
+ </sequential>
+ </sequential>
+ </action>
+ <save file="host_in" report="rms_.*" />
+</case>
diff --git a/suite/audio_quality/test_description/dut_speaker_calibration_no_pass.xml b/suite/audio_quality/test_description/dut_speaker_calibration_no_pass.xml
new file mode 100644
index 0000000..6c97ddc
--- /dev/null
+++ b/suite/audio_quality/test_description/dut_speaker_calibration_no_pass.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!-- Copyright (C) 2012 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.
+-->
+
+<case name="dut_speaker_calibration" version="1.0" description="Calibrate host recording gain">
+ <setup> <!-- 1 setup -->
+ <!-- prepare sound source id: to be used in output, sine 1000Hz, 20000ms long -->
+ <sound id="sound1" type="sin:32000:1000:5000" preload="1" />
+ </setup>
+
+ <action> <!-- 1 action -->
+ <!-- equivalent of for loop. all children will be completed before moving to the next
+ stage.repeat up to 100 times unless stopped by some condition -->
+ <sequential repeat="20" index="i">
+ <!-- sync start : execute only sync complete : execute + complete
+ For sync start, complete will be called when the parent completes -->
+ <output device="DUT" id="sound1" gain="100" sync="start" waitforcompletion="1" />
+ <sequential repeat="8" index="j">
+ <input device="host" id="host_in" gain="100" time="500" sync="complete" />
+ <!-- ------------moving average RMS min for pass, max for pass result calculated -->
+ <process method="builtin:rms_mva" input="id:host_in,consti:2,consti:1" output="val:rms_$i_$j" />
+ <!-- <message input="val:passfail" output_low="Volume Low" output_ok="Volume OK" output_high="Volume High" /> -->
+ </sequential>
+ </sequential>
+ </action>
+ <save file="host_in" report="rms_.*" />
+</case>
diff --git a/suite/audio_quality/test_description/experimental/chirp_400_20000.r2s b/suite/audio_quality/test_description/experimental/chirp_400_20000.r2s
new file mode 100644
index 0000000..46ba654
--- /dev/null
+++ b/suite/audio_quality/test_description/experimental/chirp_400_20000.r2s
Binary files differ
diff --git a/suite/audio_quality/test_description/experimental/dut_playback_spectrum_chirp.xml b/suite/audio_quality/test_description/experimental/dut_playback_spectrum_chirp.xml
new file mode 100644
index 0000000..63374eb
--- /dev/null
+++ b/suite/audio_quality/test_description/experimental/dut_playback_spectrum_chirp.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!-- Copyright (C) 2012 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.
+-->
+
+<case name="dut_playback_spectrum_chirp" version="1.0" description="Check frequency spectrum for playback">
+ <setup>
+ <!-- input: peak amplitude, duration in msec, sampling rate, high frequency, output: generated sound-->
+ <sound id="chirp" type="file:test_description/experimental/chirp_400_20000.r2s" preload="1" />
+ </setup>
+ <action>
+ <sequential repeat="1" index="i">
+ <input device="host" id="host_in_$i" gain="100" time="5000" sync="start" />
+ <output device="DUT" id="chirp" gain="100" mode="voice" sync="start" waitforcompletion="0" />
+ </sequential>
+ <sequential repeat="1" index="k">
+ <!-- input: host record, device record, samping rate, low frequency in Hz, high frequency in Hz, allowed error for pass in smaller side, allowed error in bigger side%, output: min value in lower side calculated normalized to 1.0, max value in higher side, calculated amplitude ratio in mannitude only between low f to high f -->
+ <process method="script:check_spectrum" input="id:chirp,id:host_in_$k,consti:44100,consti:500,consti:8000,constf:50.0,constf:100.0" output="val:min_val_$k,val:max_val_$k,id:spectrum_$k" />
+ </sequential>
+ </action>
+ <save file="chirp,host_in_.*,spectrum_.*" report="min_val_.*,max_val_.*" />
+</case>
diff --git a/suite/audio_quality/test_description/experimental/ref_playback_spectrum.xml b/suite/audio_quality/test_description/experimental/ref_playback_spectrum.xml
new file mode 100644
index 0000000..7653208
--- /dev/null
+++ b/suite/audio_quality/test_description/experimental/ref_playback_spectrum.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!-- Copyright (C) 2012 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.
+-->
+
+<case name="dut_playback_spectrum" version="1.0" description="Check frequency spectrum for playback">
+ <setup>
+ <!-- input: peak amplitude, duration in msec, sampling rate, high frequency, output: generated sound-->
+ <process method="script:gen_random" input="consti:10000,consti:5000,consti:44100,consti:20000" output="id:sound1" />
+ </setup>
+ <action>
+ <sequential repeat="1" index="i">
+ <input device="host" id="host_in_$i" gain="100" time="4000" sync="start" />
+ <output device="host" id="sound1" gain="100" sync="start" waitforcompletion="1" />
+ </sequential>
+ <sequential repeat="1" index="k">
+ <!-- input: host record, device record, samping rate, low frequency in Hz, high frequency in Hz, allowed error for pass in smaller side, allowed error in bigger side%, output: min value in lower side calculated normalized to 1.0, max value in higher side, calculated amplitude ratio in mannitude only between low f to high f -->
+ <process method="script:check_spectrum" input="id:sound1,id:host_in_$k,consti:44100,consti:500,consti:8000,constf:50.0,constf:100.0" output="val:min_val_$k,val:max_val_$k,id:spectrum_$k" />
+ </sequential>
+ </action>
+ <save file="sound1,host_in_.*,spectrum_.*" report="min_val_.*,max_val_.*" />
+</case>
diff --git a/suite/audio_quality/test_description/experimental/ref_playback_spectrum_chirp.xml b/suite/audio_quality/test_description/experimental/ref_playback_spectrum_chirp.xml
new file mode 100644
index 0000000..9e689f2
--- /dev/null
+++ b/suite/audio_quality/test_description/experimental/ref_playback_spectrum_chirp.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!-- Copyright (C) 2012 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.
+-->
+
+<case name="ref_playback_spectrum_chirp" version="1.0" description="Check frequency spectrum of reference speaker for playback">
+ <setup>
+ <!-- input: peak amplitude, duration in msec, sampling rate, high frequency, output: generated sound-->
+ <sound id="chirp" type="file:test_description/experimental/chirp_400_20000.r2s" />
+ </setup>
+ <action>
+ <sequential repeat="1" index="i">
+ <input device="host" id="host_in_$i" gain="100" time="5000" sync="start" />
+ <output device="host" id="chirp" gain="100" sync="start" waitforcompletion="0" />
+ </sequential>
+ <sequential repeat="1" index="k">
+ <!-- input: host record, device record, samping rate, low frequency in Hz, high frequency in Hz, allowed error for pass in smaller side, allowed error in bigger side%, output: min value in lower side calculated normalized to 1.0, max value in higher side, calculated amplitude ratio in mannitude only between low f to high f -->
+ <process method="script:check_spectrum" input="id:chirp,id:host_in_$k,consti:44100,consti:500,consti:8000,constf:50.0,constf:100.0" output="val:min_val_$k,val:max_val_$k,id:spectrum_$k" />
+ </sequential>
+ </action>
+ <save file="chirp,host_in_.*,spectrum_.*" report="min_val_.*,max_val_.*" />
+</case>
diff --git a/suite/audio_quality/test_description/host_speaker_calibration.xml b/suite/audio_quality/test_description/host_speaker_calibration.xml
index 0bdd5a1..576d999 100644
--- a/suite/audio_quality/test_description/host_speaker_calibration.xml
+++ b/suite/audio_quality/test_description/host_speaker_calibration.xml
@@ -31,7 +31,7 @@
<sequential repeat="10" index="j">
<input device="host" id="host_in" gain="70" time="500" sync="complete" />
<!-- ------------moving average RMS min for pass, max for pass result calculated -->
- <process method="builtin:rms_mva" input="id:host_in,consti:4000,consti:5000" output="val:rms_$i_$j" />
+ <process method="builtin:rms_mva" input="id:host_in,consti:4000,consti:6000" output="val:rms_$i_$j" />
<!-- <message input="val:passfail" output_low="Volume Low" output_ok="Volume OK" output_high="Volume High" /> -->
</sequential>
</sequential>
diff --git a/suite/audio_quality/test_description/processing/check_spectrum.py b/suite/audio_quality/test_description/processing/check_spectrum.py
index a571fa4..598da96 100644
--- a/suite/audio_quality/test_description/processing/check_spectrum.py
+++ b/suite/audio_quality/test_description/processing/check_spectrum.py
@@ -38,7 +38,7 @@
def do_check_spectrum(hostData, DUTData, samplingRate, fLow, fHigh, margainLow, margainHigh):
# reduce FFT resolution to have averaging effects
- N = 256 if (len(hostData) > 512) else len(hostData)
+ N = 512 if (len(hostData) > 512) else len(hostData)
iLow = N * fLow / samplingRate + 1 # 1 for DC
if iLow > (N / 2 - 1):
iLow = (N / 2 - 1)
@@ -67,19 +67,26 @@
((1.0 - negativeMin) < margainLow / 100.0) else False
RatioResult = np.zeros(len(amplitudeRatio), dtype=np.int16)
for i in range(len(amplitudeRatio)):
- RatioResult[i] = amplitudeRatio[i] * 256 # make fixed point
+ RatioResult[i] = amplitudeRatio[i] * 1024 # make fixed point
print "positiveMax", positiveMax, "negativeMin", negativeMin
return (passFail, negativeMin, positiveMax, RatioResult)
+def toMono(stereoData):
+ n = len(stereoData)/2
+ monoData = np.zeros(n)
+ for i in range(n):
+ monoData[i] = stereoData[2 * i]
+ return monoData
+
def check_spectrum(inputData, inputTypes):
output = []
outputData = []
outputTypes = []
# basic sanity check
inputError = False
- if (inputTypes[0] != TYPE_MONO):
+ if (inputTypes[0] != TYPE_MONO) and (inputTypes[0] != TYPE_STEREO):
inputError = True
- if (inputTypes[1] != TYPE_MONO):
+ if (inputTypes[1] != TYPE_MONO) and (inputTypes[1] != TYPE_STEREO):
inputError = True
if (inputTypes[2] != TYPE_I64):
inputError = True
@@ -92,21 +99,37 @@
if (inputTypes[6] != TYPE_DOUBLE):
inputError = True
if inputError:
+ print "input error"
output.append(RESULT_ERROR)
output.append(outputData)
output.append(outputTypes)
return output
hostData = inputData[0]
+ if inputTypes[0] == TYPE_STEREO:
+ hostData = toMono(hostData)
dutData = inputData[1]
+ if inputTypes[1] == TYPE_STEREO:
+ dutData = toMono(dutData)
samplingRate = inputData[2]
fLow = inputData[3]
fHigh = inputData[4]
margainLow = inputData[5]
margainHigh = inputData[6]
- delay = calc_delay.calc_delay(hostData, dutData)
- N = len(dutData)
+ delay = 0
+ N = 0
+ hostData_ = hostData
+ dutData_ = dutData
+ if len(hostData) > len(dutData):
+ delay = calc_delay.calc_delay(hostData, dutData)
+ N = len(dutData)
+ hostData_ = hostData[delay:delay+N]
+ if len(hostData) < len(dutData):
+ delay = calc_delay.calc_delay(dutData, hostData)
+ N = len(hostData)
+ dutData_ = dutData[delay:delay+N]
+
print "delay ", delay, "deviceRecording samples ", N
- (passFail, minError, maxError, TF) = do_check_spectrum(hostData[delay:delay+N], dutData,\
+ (passFail, minError, maxError, TF) = do_check_spectrum(hostData_, dutData_,\
samplingRate, fLow, fHigh, margainLow, margainHigh)
if passFail:
diff --git a/suite/audio_quality/test_description/processing/check_spectrum_playback.py b/suite/audio_quality/test_description/processing/check_spectrum_playback.py
new file mode 100644
index 0000000..54cf91f
--- /dev/null
+++ b/suite/audio_quality/test_description/processing/check_spectrum_playback.py
@@ -0,0 +1,130 @@
+#!/usr/bin/python
+
+# Copyright (C) 2012 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.
+
+from consts import *
+import numpy as np
+import scipy as sp
+import scipy.fftpack as fft
+import matplotlib.pyplot as plt
+import sys
+sys.path.append(sys.path[0])
+import calc_delay
+
+# check if amplitude of DUT's playback
+# lies in the given error boundary
+# input: host record
+# sampling rate
+# low frequency in Hz,
+# high frequency in Hz,
+# allowed error in negative side for pass in %,
+# allowed error ih positive side for pass
+# output: min value in negative side, normalized to 1.0
+# max value in positive side
+# calculated freq spectrum in amplittude
+
+def do_check_spectrum_playback(hostData, samplingRate, fLow, fHigh, margainLow, margainHigh):
+ # reduce FFT resolution to have averaging effects
+ N = 512 if (len(hostData) > 512) else len(hostData)
+ iLow = N * fLow / samplingRate + 1 # 1 for DC
+ if iLow > (N / 2 - 1):
+ iLow = (N / 2 - 1)
+ iHigh = N * fHigh / samplingRate + 1 # 1 for DC
+ if iHigh > (N / 2 + 1):
+ iHigh = N / 2 + 1
+ print fLow, iLow, fHigh, iHigh, samplingRate
+
+ Phh, freqs = plt.psd(hostData, NFFT=N, Fs=samplingRate, Fc=0, detrend=plt.mlab.detrend_none,\
+ window=plt.mlab.window_hanning, noverlap=0, pad_to=None, sides='onesided',\
+ scale_by_freq=False)
+ print len(Phh)
+ print "Phh", abs(Phh[iLow:iHigh])
+ spectrum = np.sqrt(abs(Phh[iLow:iHigh]))
+ spectrumMean = np.mean(spectrum)
+ spectrum = spectrum / spectrumMean
+ print "Mean ", spectrumMean
+ print "Normalized spectrum", spectrum
+ positiveMax = abs(max(spectrum))
+ negativeMin = abs(min(spectrum))
+ passFail = True if (positiveMax < (margainHigh / 100.0 + 1.0)) and\
+ ((1.0 - negativeMin) < margainLow / 100.0) else False
+ spectrumResult = np.zeros(len(spectrum), dtype=np.int16)
+ for i in range(len(spectrum)):
+ spectrumResult[i] = spectrum[i] * 1024 # make fixed point
+ print "positiveMax", positiveMax, "negativeMin", negativeMin
+ return (passFail, negativeMin, positiveMax, spectrumResult)
+
+def check_spectrum_playback(inputData, inputTypes):
+ output = []
+ outputData = []
+ outputTypes = []
+ # basic sanity check
+ inputError = False
+ if (inputTypes[0] != TYPE_MONO):
+ inputError = True
+ if (inputTypes[1] != TYPE_I64):
+ inputError = True
+ if (inputTypes[2] != TYPE_I64):
+ inputError = True
+ if (inputTypes[3] != TYPE_I64):
+ inputError = True
+ if (inputTypes[4] != TYPE_DOUBLE):
+ inputError = True
+ if (inputTypes[5] != TYPE_DOUBLE):
+ inputError = True
+ if inputError:
+ output.append(RESULT_ERROR)
+ output.append(outputData)
+ output.append(outputTypes)
+ return output
+ hostData = inputData[0]
+ samplingRate = inputData[1]
+ fLow = inputData[2]
+ fHigh = inputData[3]
+ margainLow = inputData[4]
+ margainHigh = inputData[5]
+ (passFail, minError, maxError, Spectrum) = do_check_spectrum_playback(hostData, \
+ samplingRate, fLow, fHigh, margainLow, margainHigh)
+
+ if passFail:
+ output.append(RESULT_PASS)
+ else:
+ output.append(RESULT_OK)
+ outputData.append(minError)
+ outputTypes.append(TYPE_DOUBLE)
+ outputData.append(maxError)
+ outputTypes.append(TYPE_DOUBLE)
+ outputData.append(Spectrum)
+ outputTypes.append(TYPE_MONO)
+ output.append(outputData)
+ output.append(outputTypes)
+ return output
+
+# test code
+if __name__=="__main__":
+ sys.path.append(sys.path[0])
+ mod = __import__("gen_random")
+ peakAmpl = 10000
+ durationInMSec = 1000
+ samplingRate = 44100
+ fLow = 500
+ fHigh = 15000
+ data = getattr(mod, "do_gen_random")(peakAmpl, durationInMSec, samplingRate, fHigh,\
+ stereo=False)
+ print len(data)
+ (passFail, minVal, maxVal, amp) = do_check_spectrum_playback(data, samplingRate, fLow,\
+ fHigh, 1.0, 1.0)
+ plt.plot(amp)
+ plt.show()
diff --git a/suite/audio_quality/test_description/processing/playback_thd.py b/suite/audio_quality/test_description/processing/playback_thd.py
new file mode 100644
index 0000000..7242ef8
--- /dev/null
+++ b/suite/audio_quality/test_description/processing/playback_thd.py
@@ -0,0 +1,62 @@
+#!/usr/bin/python
+
+# Copyright (C) 2012 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.
+
+from consts import *
+import numpy as np
+import scipy as sp
+from calc_thd import *
+import calc_delay
+
+# calculate THD for dut_playback_thd case
+# Input: host recording (mono),
+# frequency of sine in Hz (i64)
+# THD pass level in percentile (double)
+# Output: THD device (double) in percentile
+
+def playback_thd(inputData, inputTypes):
+ output = []
+ outputData = []
+ outputTypes = []
+ # basic sanity check
+ inputError = False
+ if (inputTypes[0] != TYPE_MONO):
+ inputError = True
+ if (inputTypes[1] != TYPE_I64):
+ inputError = True
+ if (inputTypes[2] != TYPE_DOUBLE):
+ inputError = True
+ if inputError:
+ output.append(RESULT_ERROR)
+ output.append(outputData)
+ output.append(outputTypes)
+ return output
+
+ hostRecording = inputData[0]
+ signalFrequency = inputData[1]
+ thdPassPercentile = inputData[2]
+ samplingRate = 44100
+
+ thd = calc_thd(hostRecording, signalFrequency, samplingRate, 0.02) * 100
+ print "THD %", thd, "Margain % ", thdPassPercentile
+ if (thd < thdPassPercentile):
+ output.append(RESULT_PASS)
+ else:
+ output.append(RESULT_OK)
+ outputData.append(thd)
+ outputTypes.append(TYPE_DOUBLE)
+ output.append(outputData)
+ output.append(outputTypes)
+ return output
diff --git a/tests/tests/media/src/android/media/cts/MediaScannerTest.java b/tests/tests/media/src/android/media/cts/MediaScannerTest.java
index d58528d..eaa2032 100644
--- a/tests/tests/media/src/android/media/cts/MediaScannerTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaScannerTest.java
@@ -37,6 +37,7 @@
import android.provider.MediaStore;
import android.provider.cts.FileCopyHelper;
import android.test.AndroidTestCase;
+import android.util.Log;
import java.io.File;
import java.io.IOException;
@@ -184,6 +185,7 @@
c.close();
assertTrue("song id should not be 0", song1a != 0);
assertTrue("song id should not be 0", song1b != 0);
+ assertTrue("song ids should not be same", song1a != song1b);
// 2nd playlist should have the same songs, in reverse order
c = res.query(MediaStore.Audio.Playlists.EXTERNAL_CONTENT_URI, null,
@@ -210,6 +212,87 @@
checkConnectionState(false);
}
+ public void testWildcardPaths() throws InterruptedException, IOException {
+ mMediaScannerConnectionClient = new MockMediaScannerConnectionClient();
+ mMediaScannerConnection = new MockMediaScannerConnection(getContext(),
+ mMediaScannerConnectionClient);
+
+ assertFalse(mMediaScannerConnection.isConnected());
+
+ // start connection and wait until connected
+ mMediaScannerConnection.connect();
+ checkConnectionState(true);
+
+ long now = System.currentTimeMillis();
+ String dir1 = mFileDir + "/test-" + now;
+ String file1 = dir1 + "/test.mp3";
+ String dir2 = mFileDir + "/test_" + now;
+ String file2 = dir2 + "/test.mp3";
+ assertTrue(new File(dir1).mkdir());
+ writeFile(R.raw.testmp3, file1);
+ mMediaScannerConnection.scanFile(file1, MEDIA_TYPE);
+ checkMediaScannerConnection();
+ Uri file1Uri = mMediaScannerConnectionClient.mediaUri;
+
+ assertTrue(new File(dir2).mkdir());
+ writeFile(R.raw.testmp3, file2);
+ mMediaScannerConnectionClient.reset();
+ mMediaScannerConnection.scanFile(file2, MEDIA_TYPE);
+ checkMediaScannerConnection();
+ Uri file2Uri = mMediaScannerConnectionClient.mediaUri;
+
+ // if the URIs are the same, then the media scanner likely treated the _ character
+ // in the second path as a wildcard, and matched it with the first path
+ assertFalse(file1Uri.equals(file2Uri));
+
+ // rewrite Uris to use the file scheme
+ long file1id = Long.valueOf(file1Uri.getLastPathSegment());
+ long file2id = Long.valueOf(file2Uri.getLastPathSegment());
+ file1Uri = MediaStore.Files.getContentUri("external", file1id);
+ file2Uri = MediaStore.Files.getContentUri("external", file2id);
+
+ ContentResolver res = mContext.getContentResolver();
+ Cursor c = res.query(file1Uri, new String[] { "parent" }, null, null, null);
+ c.moveToFirst();
+ long parent1id = c.getLong(0);
+ c.close();
+ c = res.query(file2Uri, new String[] { "parent" }, null, null, null);
+ c.moveToFirst();
+ long parent2id = c.getLong(0);
+ c.close();
+ // if the parent ids are the same, then the media provider likely
+ // treated the _ character in the second path as a wildcard
+ assertTrue("same parent", parent1id != parent2id);
+
+ // check the parent paths are correct
+ c = res.query(MediaStore.Files.getContentUri("external", parent1id),
+ new String[] { "_data" }, null, null, null);
+ c.moveToFirst();
+ assertEquals(dir1, c.getString(0));
+ c.close();
+
+ c = res.query(MediaStore.Files.getContentUri("external", parent2id),
+ new String[] { "_data" }, null, null, null);
+ c.moveToFirst();
+ assertEquals(dir2, c.getString(0));
+ c.close();
+
+ // clean up
+ new File(file1).delete();
+ new File(dir1).delete();
+ new File(file2).delete();
+ new File(dir2).delete();
+ res.delete(file1Uri, null, null);
+ res.delete(file2Uri, null, null);
+ res.delete(MediaStore.Files.getContentUri("external", parent1id), null, null);
+ res.delete(MediaStore.Files.getContentUri("external", parent2id), null, null);
+
+ mMediaScannerConnection.disconnect();
+
+ checkConnectionState(false);
+ }
+
+
private void startMediaScanAndWait() throws InterruptedException {
ScannerNotificationReceiver finishedReceiver = new ScannerNotificationReceiver(
Intent.ACTION_MEDIA_SCANNER_FINISHED);
diff --git a/tests/tests/permission/src/android/permission/cts/FileSystemPermissionTest.java b/tests/tests/permission/src/android/permission/cts/FileSystemPermissionTest.java
index 3485574..f533239 100644
--- a/tests/tests/permission/src/android/permission/cts/FileSystemPermissionTest.java
+++ b/tests/tests/permission/src/android/permission/cts/FileSystemPermissionTest.java
@@ -269,6 +269,7 @@
"/data/gpscfg",
"/data/hwvefs",
"/data/htcfs",
+ "/data/install",
"/data/internal-device",
"/data/internal-device/DCIM",
"/data/local",
diff --git a/tests/tests/provider/src/android/provider/cts/MediaStore_FilesTest.java b/tests/tests/provider/src/android/provider/cts/MediaStore_FilesTest.java
index 9432066..1e8a4ac 100644
--- a/tests/tests/provider/src/android/provider/cts/MediaStore_FilesTest.java
+++ b/tests/tests/provider/src/android/provider/cts/MediaStore_FilesTest.java
@@ -16,15 +16,22 @@
package android.provider.cts;
+import com.android.cts.stub.R;
+
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.ContentValues;
import android.database.Cursor;
import android.net.Uri;
+import android.os.Environment;
+import android.os.ParcelFileDescriptor;
import android.provider.MediaStore;
import android.provider.MediaStore.MediaColumns;
import android.test.AndroidTestCase;
+import java.io.File;
+import java.io.IOException;
+
public class MediaStore_FilesTest extends AndroidTestCase {
private ContentResolver mResolver;
@@ -88,6 +95,63 @@
} finally {
cursor.close();
}
+
+ // insert file and check its parent
+ values.clear();
+ try {
+ String b = mContext.getExternalFilesDir(Environment.DIRECTORY_MUSIC).getCanonicalPath();
+ values.put(MediaColumns.DATA, b + "/testing");
+ fileUri = mResolver.insert(allFilesUri, values);
+ cursor = mResolver.query(fileUri, new String[] { MediaStore.Files.FileColumns.PARENT },
+ null, null, null);
+ assertEquals(1, cursor.getCount());
+ cursor.moveToFirst();
+ long parentid = cursor.getLong(0);
+ assertTrue("got 0 parent for non root file", parentid != 0);
+
+ cursor.close();
+ cursor = mResolver.query(ContentUris.withAppendedId(allFilesUri, parentid),
+ new String[] { MediaColumns.DATA }, null, null, null);
+ assertEquals(1, cursor.getCount());
+ cursor.moveToFirst();
+ String parentPath = cursor.getString(0);
+ assertEquals(b, parentPath);
+
+ mResolver.delete(fileUri, null, null);
+ } catch (IOException e) {
+ fail(e.getMessage());
+ } finally {
+ cursor.close();
+ }
+ }
+
+ public void testCaseSensitivity() throws IOException {
+ String fileDir = Environment.getExternalStorageDirectory() +
+ "/" + getClass().getCanonicalName();
+ String fileName = fileDir + "/Test.Mp3";
+ writeFile(R.raw.testmp3, fileName);
+
+ String volumeName = MediaStoreAudioTestHelper.EXTERNAL_VOLUME_NAME;
+ Uri allFilesUri = MediaStore.Files.getContentUri(volumeName);
+ ContentValues values = new ContentValues();
+ values.put(MediaColumns.DATA, fileDir + "/test.mp3");
+ Uri fileUri = mResolver.insert(allFilesUri, values);
+ try {
+ ParcelFileDescriptor pfd = mResolver.openFileDescriptor(fileUri, "r");
+ pfd.close();
+ } finally {
+ mResolver.delete(fileUri, null, null);
+ new File(fileName).delete();
+ new File(fileDir).delete();
+ }
+ }
+
+ private void writeFile(int resid, String path) throws IOException {
+ File out = new File(path);
+ File dir = out.getParentFile();
+ dir.mkdirs();
+ FileCopyHelper copier = new FileCopyHelper(mContext);
+ copier.copyToExternalStorage(resid, out);
}
private int getFileCount(Uri uri) {
diff --git a/tests/tests/view/src/android/view/inputmethod/cts/InputMethodManagerTest.java b/tests/tests/view/src/android/view/inputmethod/cts/InputMethodManagerTest.java
index 6b0a0b9..636c376 100755
--- a/tests/tests/view/src/android/view/inputmethod/cts/InputMethodManagerTest.java
+++ b/tests/tests/view/src/android/view/inputmethod/cts/InputMethodManagerTest.java
@@ -17,15 +17,14 @@
import com.android.cts.stub.R;
-
import android.app.Instrumentation;
import android.content.Context;
+import android.cts.util.PollingCheck;
import android.os.Handler;
import android.os.IBinder;
import android.os.ResultReceiver;
import android.test.ActivityInstrumentationTestCase2;
import android.view.KeyEvent;
-import android.view.View;
import android.view.Window;
import android.view.inputmethod.BaseInputConnection;
import android.view.inputmethod.InputMethodInfo;
@@ -74,7 +73,14 @@
Context context = mInstrumentation.getTargetContext();
final InputMethodManager imManager = (InputMethodManager) context
.getSystemService(Context.INPUT_METHOD_SERVICE);
- assertTrue(imManager.isActive());
+
+ new PollingCheck() {
+ @Override
+ protected boolean check() {
+ return imManager.isActive();
+ }
+ }.run();
+
assertTrue(imManager.isAcceptingText());
assertTrue(imManager.isActive(view));