Merge "Updates the status of some HTML5 storage layout tests in the DumpRenderTree skipped list"
diff --git a/cmds/dumpstate/dumpstate.c b/cmds/dumpstate/dumpstate.c
index cc1167f..e9b21f1 100644
--- a/cmds/dumpstate/dumpstate.c
+++ b/cmds/dumpstate/dumpstate.c
@@ -115,8 +115,8 @@
dump_file("KERNEL WAKELOCKS", "/proc/wakelocks");
dump_file("KERNEL CPUFREQ", "/sys/devices/system/cpu/cpu0/cpufreq/stats/time_in_state");
+ run_command("VOLD DUMP", 10, "vdc", "dump", NULL);
run_command("SECURE CONTAINERS", 10, "vdc", "asec", "list", NULL);
- run_command("MOUNTED FILESYSTEMS", 10, "df", NULL);
run_command("PROCESSES", 10, "ps", "-P", NULL);
run_command("PROCESSES AND THREADS", 10, "ps", "-t", "-p", "-P", NULL);
diff --git a/core/java/android/app/SearchDialog.java b/core/java/android/app/SearchDialog.java
index ebc64d7..add99d7 100644
--- a/core/java/android/app/SearchDialog.java
+++ b/core/java/android/app/SearchDialog.java
@@ -483,7 +483,7 @@
int textId = mSearchable.getSearchButtonText();
if (isBrowserSearch()){
iconLabel = getContext().getResources()
- .getDrawable(com.android.internal.R.drawable.ic_btn_search_play);
+ .getDrawable(com.android.internal.R.drawable.ic_btn_search_go);
} else if (textId != 0) {
textLabel = mActivityContext.getResources().getString(textId);
} else {
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 034a631..3a34fb4 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -3851,7 +3851,6 @@
|| keyCode == KeyEvent.KEYCODE_SHIFT_RIGHT) {
if (nativeFocusIsPlugin()) {
mShiftIsPressed = false;
- return true;
} else if (commitCopy()) {
return true;
}
diff --git a/core/java/android/widget/AutoCompleteTextView.java b/core/java/android/widget/AutoCompleteTextView.java
index 9537ba0..5482958 100644
--- a/core/java/android/widget/AutoCompleteTextView.java
+++ b/core/java/android/widget/AutoCompleteTextView.java
@@ -985,6 +985,11 @@
/** {@inheritDoc} */
public void onFilterComplete(int count) {
+ updateDropDownForFilter(count);
+
+ }
+
+ private void updateDropDownForFilter(int count) {
// Not attached to window, don't update drop-down
if (getWindowVisibility() == View.GONE) return;
@@ -1214,18 +1219,30 @@
ViewGroup dropDownView;
int otherHeights = 0;
- if (mAdapter != null) {
+ final ListAdapter adapter = mAdapter;
+ if (adapter != null) {
InputMethodManager imm = InputMethodManager.peekInstance();
if (imm != null) {
- int N = mAdapter.getCount();
- if (N > 20) N = 20;
- CompletionInfo[] completions = new CompletionInfo[N];
- for (int i = 0; i < N; i++) {
- Object item = mAdapter.getItem(i);
- long id = mAdapter.getItemId(i);
- completions[i] = new CompletionInfo(id, i,
- convertSelectionToString(item));
+ final int count = Math.min(adapter.getCount(), 20);
+ CompletionInfo[] completions = new CompletionInfo[count];
+ int realCount = 0;
+
+ for (int i = 0; i < count; i++) {
+ if (adapter.isEnabled(i)) {
+ realCount++;
+ Object item = adapter.getItem(i);
+ long id = adapter.getItemId(i);
+ completions[i] = new CompletionInfo(id, i,
+ convertSelectionToString(item));
+ }
}
+
+ if (realCount != count) {
+ CompletionInfo[] tmp = new CompletionInfo[realCount];
+ System.arraycopy(completions, 0, tmp, 0, realCount);
+ completions = tmp;
+ }
+
imm.displayCompletions(this, completions);
}
}
@@ -1253,7 +1270,7 @@
mDropDownList = new DropDownListView(context);
mDropDownList.setSelector(mDropDownListHighlight);
- mDropDownList.setAdapter(mAdapter);
+ mDropDownList.setAdapter(adapter);
mDropDownList.setVerticalFadingEdgeEnabled(true);
mDropDownList.setOnItemClickListener(mDropDownItemClickListener);
mDropDownList.setFocusable(true);
@@ -1599,6 +1616,16 @@
if (isPopupShowing()) {
// This will resize the popup to fit the new adapter's content
showDropDown();
+ } else if (mAdapter != null) {
+ // If the popup is not showing already, showing it will cause
+ // the list of data set observers attached to the adapter to
+ // change. We can't do it from here, because we are in the middle
+ // of iterating throught he list of observers.
+ post(new Runnable() {
+ public void run() {
+ updateDropDownForFilter(mAdapter.getCount());
+ }
+ });
}
}
diff --git a/core/res/res/drawable-hdpi/ic_btn_search_go.png b/core/res/res/drawable-hdpi/ic_btn_search_go.png
new file mode 100644
index 0000000..8a3a402
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_btn_search_go.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_btn_search_play.png b/core/res/res/drawable-hdpi/ic_btn_search_play.png
deleted file mode 100644
index fb1b974..0000000
--- a/core/res/res/drawable-hdpi/ic_btn_search_play.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_btn_search_go.png b/core/res/res/drawable-mdpi/ic_btn_search_go.png
new file mode 100644
index 0000000..0ed9e8e
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_btn_search_go.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_btn_search_play.png b/core/res/res/drawable-mdpi/ic_btn_search_play.png
deleted file mode 100644
index dc25dae..0000000
--- a/core/res/res/drawable-mdpi/ic_btn_search_play.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/layout-land/usb_storage_activity.xml b/core/res/res/layout-land/usb_storage_activity.xml
index d714479..50ca569 100644
--- a/core/res/res/layout-land/usb_storage_activity.xml
+++ b/core/res/res/layout-land/usb_storage_activity.xml
@@ -24,7 +24,7 @@
<TextView android:id="@+id/banner"
android:layout_centerHorizontal="true"
- android:layout_below="@id/icon"
+ android:layout_alignParentTop="true"
android:layout_marginTop="10dip"
android:layout_width="match_parent"
android:layout_height="wrap_content"
@@ -45,8 +45,8 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
- android:layout_below="@id/message"
- android:layout_marginTop="20dip"
+ android:layout_alignParentBottom="true"
+ android:layout_marginBottom="20dip"
>
<Button android:id="@+id/mount_button"
@@ -64,6 +64,13 @@
android:paddingRight="18dip"
android:text="@string/usb_storage_stop_button_mount"
/>
+ <ProgressBar android:id="@+id/progress"
+ android:visibility="gone"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:indeterminate="true"
+ style="?android:attr/progressBarStyle"
+ />
</RelativeLayout>
</RelativeLayout>
diff --git a/core/res/res/layout/usb_storage_activity.xml b/core/res/res/layout/usb_storage_activity.xml
index 86bfadb..76c30fd 100644
--- a/core/res/res/layout/usb_storage_activity.xml
+++ b/core/res/res/layout/usb_storage_activity.xml
@@ -37,8 +37,8 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
- android:layout_below="@id/message"
- android:layout_marginTop="20dip"
+ android:layout_alignParentBottom="true"
+ android:layout_marginBottom="20dip"
>
<Button android:id="@+id/mount_button"
@@ -56,6 +56,13 @@
android:paddingRight="18dip"
android:text="@string/usb_storage_stop_button_mount"
/>
+ <ProgressBar android:id="@+id/progress"
+ android:visibility="gone"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:indeterminate="true"
+ style="?android:attr/progressBarStyle"
+ />
</RelativeLayout>
</RelativeLayout>
diff --git a/libs/audioflinger/AudioFlinger.cpp b/libs/audioflinger/AudioFlinger.cpp
index 7902212..815a367 100644
--- a/libs/audioflinger/AudioFlinger.cpp
+++ b/libs/audioflinger/AudioFlinger.cpp
@@ -72,6 +72,10 @@
// 50 * ~20msecs = 1 second
static const int8_t kMaxTrackRetries = 50;
static const int8_t kMaxTrackStartupRetries = 50;
+// allow less retry attempts on direct output thread.
+// direct outputs can be a scarce resource in audio hardware and should
+// be released as quickly as possible.
+static const int8_t kMaxTrackRetriesDirect = 2;
static const int kDumpLockRetries = 50;
static const int kDumpLockSleep = 20000;
@@ -1794,6 +1798,9 @@
uint32_t activeSleepTime = activeSleepTimeUs();
uint32_t idleSleepTime = idleSleepTimeUs();
uint32_t sleepTime = idleSleepTime;
+ // use shorter standby delay as on normal output to release
+ // hardware resources as soon as possible
+ nsecs_t standbyDelay = microseconds(activeSleepTime*2);
while (!exitPending())
@@ -1810,6 +1817,7 @@
mixBufferSize = mFrameCount*mFrameSize;
activeSleepTime = activeSleepTimeUs();
idleSleepTime = idleSleepTimeUs();
+ standbyDelay = microseconds(activeSleepTime*2);
}
// put audio hardware into standby after short delay
@@ -1842,7 +1850,7 @@
}
}
- standbyTime = systemTime() + kStandbyTimeInNsecs;
+ standbyTime = systemTime() + standbyDelay;
sleepTime = idleSleepTime;
continue;
}
@@ -1896,7 +1904,7 @@
}
// reset retry count
- track->mRetryCount = kMaxTrackRetries;
+ track->mRetryCount = kMaxTrackRetriesDirect;
activeTrack = t;
mixerStatus = MIXER_TRACKS_READY;
} else {
@@ -1949,7 +1957,7 @@
activeTrack->releaseBuffer(&buffer);
}
sleepTime = 0;
- standbyTime = systemTime() + kStandbyTimeInNsecs;
+ standbyTime = systemTime() + standbyDelay;
} else {
if (sleepTime == 0) {
if (mixerStatus == MIXER_TRACKS_ENABLED) {
diff --git a/libs/audioflinger/AudioPolicyManagerBase.cpp b/libs/audioflinger/AudioPolicyManagerBase.cpp
index a61221a..c8b3f48 100644
--- a/libs/audioflinger/AudioPolicyManagerBase.cpp
+++ b/libs/audioflinger/AudioPolicyManagerBase.cpp
@@ -458,11 +458,8 @@
}
#endif //AUDIO_POLICY_TEST
- // open a direct output if:
- // 1 a direct output is explicitely requested
- // 2 the audio format is compressed
- if ((flags & AudioSystem::OUTPUT_FLAG_DIRECT) ||
- (format !=0 && !AudioSystem::isLinearPCM(format))) {
+ // open a direct output if required by specified parameters
+ if (needsDirectOuput(stream, samplingRate, format, channels, flags, device)) {
LOGV("getOutput() opening direct output device %x", device);
AudioOutputDescriptor *outputDesc = new AudioOutputDescriptor();
@@ -472,7 +469,7 @@
outputDesc->mChannels = channels;
outputDesc->mLatency = 0;
outputDesc->mFlags = (AudioSystem::output_flags)(flags | AudioSystem::OUTPUT_FLAG_DIRECT);
- outputDesc->mRefCount[stream] = 1;
+ outputDesc->mRefCount[stream] = 0;
output = mpClientInterface->openOutput(&outputDesc->mDevice,
&outputDesc->mSamplingRate,
&outputDesc->mFormat,
@@ -609,6 +606,9 @@
setStrategyMute(STRATEGY_MEDIA, false, mA2dpOutput, mOutputs.valueFor(mHardwareOutput)->mLatency*2);
}
#endif
+ if (output != mHardwareOutput) {
+ setOutputDevice(mHardwareOutput, getNewDevice(mHardwareOutput), true);
+ }
return NO_ERROR;
} else {
LOGW("stopOutput() refcount is already 0 for output %d", output);
@@ -1550,10 +1550,10 @@
}
#ifdef WITH_A2DP
// filter devices according to output selected
- if (output == mHardwareOutput) {
- device &= ~AudioSystem::DEVICE_OUT_ALL_A2DP;
- } else {
+ if (output == mA2dpOutput) {
device &= AudioSystem::DEVICE_OUT_ALL_A2DP;
+ } else {
+ device &= ~AudioSystem::DEVICE_OUT_ALL_A2DP;
}
#endif
@@ -1562,8 +1562,7 @@
// - the requestede device is 0
// - the requested device is the same as current device and force is not specified.
// Doing this check here allows the caller to call setOutputDevice() without conditions
- if (device == 0 ||
- (device == prevDevice && !force)) {
+ if ((device == 0 || device == prevDevice) && !force) {
LOGV("setOutputDevice() setting same device %x or null device for output %d", device, output);
return;
}
@@ -1666,7 +1665,7 @@
int volInt = (100 * (index - streamDesc.mIndexMin)) / (streamDesc.mIndexMax - streamDesc.mIndexMin);
volume = AudioSystem::linearToLog(volInt);
- // if a heaset is connected, apply the following rules to ring tones and notifications
+ // if a headset is connected, apply the following rules to ring tones and notifications
// to avoid sound level bursts in user's ears:
// - always attenuate ring tones and notifications volume by 6dB
// - if music is playing, always limit the volume to current music volume,
@@ -1825,6 +1824,17 @@
}
}
+bool AudioPolicyManagerBase::needsDirectOuput(AudioSystem::stream_type stream,
+ uint32_t samplingRate,
+ uint32_t format,
+ uint32_t channels,
+ AudioSystem::output_flags flags,
+ uint32_t device)
+{
+ return ((flags & AudioSystem::OUTPUT_FLAG_DIRECT) ||
+ (format !=0 && !AudioSystem::isLinearPCM(format)));
+}
+
// --- AudioOutputDescriptor class implementation
AudioPolicyManagerBase::AudioOutputDescriptor::AudioOutputDescriptor()
diff --git a/media/libmedia/AudioSystem.cpp b/media/libmedia/AudioSystem.cpp
index 4b364f2..5e6ce42 100644
--- a/media/libmedia/AudioSystem.cpp
+++ b/media/libmedia/AudioSystem.cpp
@@ -358,7 +358,7 @@
const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
unsigned int result = 0;
if (af == 0) return result;
- if (ioHandle == NULL) return result;
+ if (ioHandle == 0) return result;
result = af->getInputFramesLost(ioHandle);
return result;
@@ -556,7 +556,18 @@
output_flags flags)
{
audio_io_handle_t output = 0;
- if ((flags & AudioSystem::OUTPUT_FLAG_DIRECT) == 0) {
+ // Do not use stream to output map cache if the direct output
+ // flag is set or if we are likely to use a direct output
+ // (e.g voice call stream @ 8kHz could use BT SCO device and be routed to
+ // a direct output on some platforms).
+ // TODO: the output cache and stream to output mapping implementation needs to
+ // be reworked for proper operation with direct outputs. This code is too specific
+ // to the first use case we want to cover (Voice Recognition and Voice Dialer over
+ // Bluetooth SCO
+ if ((flags & AudioSystem::OUTPUT_FLAG_DIRECT) == 0 &&
+ ((stream != AudioSystem::VOICE_CALL && stream != AudioSystem::BLUETOOTH_SCO) ||
+ channels != AudioSystem::CHANNEL_OUT_MONO ||
+ (samplingRate != 8000 && samplingRate != 16000))) {
Mutex::Autolock _l(gLock);
output = AudioSystem::gStreamOutputMap.valueFor(stream);
LOGV_IF((output != 0), "getOutput() read %d from cache for stream %d", output, stream);
diff --git a/services/java/com/android/server/status/UsbStorageActivity.java b/services/java/com/android/server/status/UsbStorageActivity.java
index c1c8c22..b3ee257 100644
--- a/services/java/com/android/server/status/UsbStorageActivity.java
+++ b/services/java/com/android/server/status/UsbStorageActivity.java
@@ -28,6 +28,7 @@
import android.content.DialogInterface.OnCancelListener;
import android.os.Bundle;
import android.os.Environment;
+import android.os.Handler;
import android.os.IBinder;
import android.os.storage.IMountService;
import android.os.storage.StorageManager;
@@ -36,8 +37,10 @@
import android.os.ServiceManager;
import android.widget.ImageView;
import android.widget.Button;
+import android.widget.ProgressBar;
import android.widget.TextView;
import android.view.View;
+import android.view.Window;
import android.util.Log;
/**
@@ -48,8 +51,10 @@
public class UsbStorageActivity extends Activity
implements View.OnClickListener, OnCancelListener {
private static final String TAG = "UsbStorageActivity";
+
private Button mMountButton;
private Button mUnmountButton;
+ private ProgressBar mProgressBar;
private TextView mBanner;
private TextView mMessage;
private ImageView mIcon;
@@ -71,11 +76,8 @@
private StorageEventListener mStorageListener = new StorageEventListener() {
@Override
public void onStorageStateChanged(String path, String oldState, String newState) {
- if (newState.equals(Environment.MEDIA_SHARED)) {
- switchDisplay(true);
- } else {
- switchDisplay(false);
- }
+ final boolean on = newState.equals(Environment.MEDIA_SHARED);
+ switchDisplay(on);
}
};
@@ -90,6 +92,9 @@
}
}
+ requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
+ setProgressBarIndeterminateVisibility(true);
+
setTitle(getString(com.android.internal.R.string.usb_storage_activity_title));
setContentView(com.android.internal.R.layout.usb_storage_activity);
@@ -102,16 +107,19 @@
mMountButton.setOnClickListener(this);
mUnmountButton = (Button) findViewById(com.android.internal.R.id.unmount_button);
mUnmountButton.setOnClickListener(this);
+ mProgressBar = (ProgressBar) findViewById(com.android.internal.R.id.progress);
}
private void switchDisplay(boolean usbStorageInUse) {
if (usbStorageInUse) {
+ mProgressBar.setVisibility(View.GONE);
mUnmountButton.setVisibility(View.VISIBLE);
mMountButton.setVisibility(View.GONE);
mIcon.setImageResource(com.android.internal.R.drawable.usb_android_connected);
mBanner.setText(com.android.internal.R.string.usb_storage_stop_title);
mMessage.setText(com.android.internal.R.string.usb_storage_stop_message);
} else {
+ mProgressBar.setVisibility(View.GONE);
mUnmountButton.setVisibility(View.GONE);
mMountButton.setVisibility(View.VISIBLE);
mIcon.setImageResource(com.android.internal.R.drawable.usb_android);
@@ -189,6 +197,25 @@
showDialog(id);
}
+ private void switchUsbMassStorageAsync(boolean on) {
+ mUnmountButton.setVisibility(View.GONE);
+ mMountButton.setVisibility(View.GONE);
+
+ mProgressBar.setVisibility(View.VISIBLE);
+ // will be hidden once USB mass storage kicks in (or fails)
+
+ final boolean _on = on;
+ new Thread() {
+ public void run() {
+ if (_on) {
+ mStorageManager.enableUsbMassStorage();
+ } else {
+ mStorageManager.disableUsbMassStorage();
+ }
+ }
+ }.start();
+ }
+
private void checkStorageUsers() {
IMountService ims = getMountService();
if (ims == null) {
@@ -208,18 +235,17 @@
showDialogInner(DLG_CONFIRM_KILL_STORAGE_USERS);
} else {
if (localLOGV) Log.i(TAG, "Enabling UMS");
- mStorageManager.enableUsbMassStorage();
+ switchUsbMassStorageAsync(true);
}
}
public void onClick(View v) {
- Log.i(TAG, "Clicked button");
if (v == mMountButton) {
// Check for list of storage users and display dialog if needed.
checkStorageUsers();
} else if (v == mUnmountButton) {
if (localLOGV) Log.i(TAG, "Disabling UMS");
- mStorageManager.disableUsbMassStorage();
+ switchUsbMassStorageAsync(false);
}
}
diff --git a/tests/AndroidTests/src/com/android/unit_tests/internal/util/HanziToPinyinTest.java b/tests/AndroidTests/src/com/android/unit_tests/internal/util/HanziToPinyinTest.java
index 8e1ff0b..71a8ea7 100644
--- a/tests/AndroidTests/src/com/android/unit_tests/internal/util/HanziToPinyinTest.java
+++ b/tests/AndroidTests/src/com/android/unit_tests/internal/util/HanziToPinyinTest.java
@@ -17,6 +17,7 @@
package com.android.unit_tests.internal.util;
import java.text.Collator;
+import java.util.Arrays;
import java.util.ArrayList;
import java.util.Locale;
@@ -37,6 +38,9 @@
@SmallTest
public void testGetToken() throws Exception {
+ if (!Arrays.asList(Collator.getAvailableLocales()).contains(Locale.CHINA)) {
+ return;
+ }
ArrayList<Token> tokens = HanziToPinyin.getInstance().get(ONE_HANZI);
assertEquals(tokens.size(), 1);
assertEquals(tokens.get(0).type, Token.PINYIN);