Merge change 25440 into eclair
* changes:
Fix a minor bug in is_alnum_string()...
diff --git a/api/current.xml b/api/current.xml
index d6db119..448da7c 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -129444,6 +129444,17 @@
visibility="public"
>
</field>
+<field name="TYPE_TEXT_FLAG_NO_SUGGESTIONS"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="524288"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="TYPE_TEXT_VARIATION_EMAIL_ADDRESS"
type="int"
transient="false"
diff --git a/core/java/android/accounts/AccountManagerService.java b/core/java/android/accounts/AccountManagerService.java
index 0bdcc1d..4217957 100644
--- a/core/java/android/accounts/AccountManagerService.java
+++ b/core/java/android/accounts/AccountManagerService.java
@@ -46,7 +46,6 @@
import android.app.PendingIntent;
import android.app.NotificationManager;
import android.app.Notification;
-import android.app.Activity;
import android.Manifest;
import java.io.FileDescriptor;
@@ -471,6 +470,7 @@
}
private boolean saveAuthTokenToDatabase(Account account, String type, String authToken) {
+ cancelNotification(getSigninRequiredNotificationId(account));
SQLiteDatabase db = mOpenHelper.getWritableDatabase();
db.beginTransaction();
try {
@@ -523,7 +523,7 @@
checkAuthenticateAccountsPermission(account);
long identityToken = clearCallingIdentity();
try {
- cacheAuthToken(account, authTokenType, authToken);
+ saveAuthTokenToDatabase(account, authTokenType, authToken);
} finally {
restoreCallingIdentity(identityToken);
}
@@ -686,7 +686,8 @@
"the type and name should not be empty");
return;
}
- cacheAuthToken(new Account(name, type), authTokenType, authToken);
+ saveAuthTokenToDatabase(new Account(name, type),
+ authTokenType, authToken);
}
Intent intent = result.getParcelable(Constants.INTENT_KEY);
@@ -1004,10 +1005,6 @@
}
}
- private boolean cacheAuthToken(Account account, String authTokenType, String authToken) {
- return saveAuthTokenToDatabase(account, authTokenType, authToken);
- }
-
private long getAccountId(SQLiteDatabase db, Account account) {
Cursor cursor = db.query(TABLE_ACCOUNTS, new String[]{ACCOUNTS_ID},
"name=? AND type=?", new String[]{account.name, account.type}, null, null, null);
diff --git a/core/java/android/bluetooth/BluetoothDevice.java b/core/java/android/bluetooth/BluetoothDevice.java
index b1861ac..0b3f3c7 100644
--- a/core/java/android/bluetooth/BluetoothDevice.java
+++ b/core/java/android/bluetooth/BluetoothDevice.java
@@ -503,7 +503,7 @@
}
/** @hide */
- public String[] getUuids() {
+ public ParcelUuid[] getUuids() {
try {
return sService.getRemoteUuids(mAddress);
} catch (RemoteException e) {Log.e(TAG, "", e);}
@@ -511,7 +511,7 @@
}
/** @hide */
- public int getServiceChannel(String uuid) {
+ public int getServiceChannel(ParcelUuid uuid) {
try {
return sService.getRemoteServiceChannel(mAddress, uuid);
} catch (RemoteException e) {Log.e(TAG, "", e);}
diff --git a/core/java/android/bluetooth/BluetoothUuid.java b/core/java/android/bluetooth/BluetoothUuid.java
index c15bc20..409c744 100644
--- a/core/java/android/bluetooth/BluetoothUuid.java
+++ b/core/java/android/bluetooth/BluetoothUuid.java
@@ -16,10 +16,11 @@
package android.bluetooth;
-import java.util.UUID;
+import java.util.Arrays;
+import java.util.HashSet;
/**
-* Static helper methods and constants to decode the UUID of remote devices.
+* Static helper methods and constants to decode the ParcelUuid of remote devices.
* @hide
*/
public final class BluetoothUuid {
@@ -30,40 +31,99 @@
* The following 128 bit values are calculated as:
* uuid * 2^96 + BASE_UUID
*/
- public static final UUID AudioSink = UUID.fromString("0000110B-0000-1000-8000-00805F9B34FB");
- public static final UUID AudioSource = UUID.fromString("0000110A-0000-1000-8000-00805F9B34FB");
- public static final UUID AdvAudioDist = UUID.fromString("0000110D-0000-1000-8000-00805F9B34FB");
- public static final UUID HSP = UUID.fromString("00001108-0000-1000-8000-00805F9B34FB");
- public static final UUID Handsfree = UUID.fromString("0000111E-0000-1000-8000-00805F9B34FB");
- public static final UUID AvrcpController =
- UUID.fromString("0000110E-0000-1000-8000-00805F9B34FB");
- public static final UUID AvrcpTarget = UUID.fromString("0000110C-0000-1000-8000-00805F9B34FB");
+ public static final ParcelUuid AudioSink =
+ ParcelUuid.fromString("0000110B-0000-1000-8000-00805F9B34FB");
+ public static final ParcelUuid AudioSource =
+ ParcelUuid.fromString("0000110A-0000-1000-8000-00805F9B34FB");
+ public static final ParcelUuid AdvAudioDist =
+ ParcelUuid.fromString("0000110D-0000-1000-8000-00805F9B34FB");
+ public static final ParcelUuid HSP =
+ ParcelUuid.fromString("00001108-0000-1000-8000-00805F9B34FB");
+ public static final ParcelUuid Handsfree =
+ ParcelUuid.fromString("0000111E-0000-1000-8000-00805F9B34FB");
+ public static final ParcelUuid AvrcpController =
+ ParcelUuid.fromString("0000110E-0000-1000-8000-00805F9B34FB");
+ public static final ParcelUuid AvrcpTarget =
+ ParcelUuid.fromString("0000110C-0000-1000-8000-00805F9B34FB");
+ public static final ParcelUuid ObexObjectPush =
+ ParcelUuid.fromString("00001105-0000-1000-8000-00805f9b34fb");
- public static boolean isAudioSource(UUID uuid) {
+ public static boolean isAudioSource(ParcelUuid uuid) {
return uuid.equals(AudioSource);
}
- public static boolean isAudioSink(UUID uuid) {
+ public static boolean isAudioSink(ParcelUuid uuid) {
return uuid.equals(AudioSink);
}
- public static boolean isAdvAudioDist(UUID uuid) {
+ public static boolean isAdvAudioDist(ParcelUuid uuid) {
return uuid.equals(AdvAudioDist);
}
- public static boolean isHandsfree(UUID uuid) {
+ public static boolean isHandsfree(ParcelUuid uuid) {
return uuid.equals(Handsfree);
}
- public static boolean isHeadset(UUID uuid) {
+ public static boolean isHeadset(ParcelUuid uuid) {
return uuid.equals(HSP);
}
- public static boolean isAvrcpController(UUID uuid) {
+ public static boolean isAvrcpController(ParcelUuid uuid) {
return uuid.equals(AvrcpController);
}
- public static boolean isAvrcpTarget(UUID uuid) {
+ public static boolean isAvrcpTarget(ParcelUuid uuid) {
return uuid.equals(AvrcpTarget);
}
+
+ /**
+ * Returns true if ParcelUuid is present in uuidArray
+ *
+ * @param uuidArray - Array of ParcelUuids
+ * @param uuid
+ */
+ public static boolean isUuidPresent(ParcelUuid[] uuidArray, ParcelUuid uuid) {
+ for (ParcelUuid element: uuidArray) {
+ if (element.equals(uuid)) return true;
+ }
+ return false;
+ }
+
+ /**
+ * Returns true if there any common ParcelUuids in uuidA and uuidB.
+ *
+ * @param uuidA - List of ParcelUuids
+ * @param uuidB - List of ParcelUuids
+ *
+ */
+ public static boolean containsAnyUuid(ParcelUuid[] uuidA, ParcelUuid[] uuidB) {
+ if (uuidA == null && uuidB == null) return true;
+ if (uuidA == null || uuidB == null) return false;
+
+ HashSet<ParcelUuid> uuidSet = new HashSet<ParcelUuid> (Arrays.asList(uuidA));
+ for (ParcelUuid uuid: uuidB) {
+ if (uuidSet.contains(uuid)) return true;
+ }
+ return false;
+ }
+
+ /**
+ * Returns true if all the ParcelUuids in ParcelUuidB are present in
+ * ParcelUuidA
+ *
+ * @param uuidA - Array of ParcelUuidsA
+ * @param uuidB - Array of ParcelUuidsB
+ *
+ */
+ public static boolean containsAllUuids(ParcelUuid[] uuidA, ParcelUuid[] uuidB) {
+ if (uuidA == null && uuidB == null) return true;
+ if (uuidA == null || uuidB == null) return false;
+
+ HashSet<ParcelUuid> uuidSet = new HashSet<ParcelUuid> (Arrays.asList(uuidA));
+ for (ParcelUuid uuid: uuidB) {
+ if (!uuidSet.contains(uuid)) return false;
+ }
+ return true;
+ }
+
}
diff --git a/core/java/android/bluetooth/IBluetooth.aidl b/core/java/android/bluetooth/IBluetooth.aidl
index a11ceac..04c8ec9 100644
--- a/core/java/android/bluetooth/IBluetooth.aidl
+++ b/core/java/android/bluetooth/IBluetooth.aidl
@@ -16,6 +16,8 @@
package android.bluetooth;
+import android.bluetooth.ParcelUuid;
+
/**
* System private API for talking with the Bluetooth service.
*
@@ -50,8 +52,8 @@
String getRemoteName(in String address);
int getRemoteClass(in String address);
- String[] getRemoteUuids(in String address);
- int getRemoteServiceChannel(in String address, String uuid);
+ ParcelUuid[] getRemoteUuids(in String address);
+ int getRemoteServiceChannel(in String address,in ParcelUuid uuid);
boolean setPin(in String address, in byte[] pin);
boolean setPasskey(in String address, int passkey);
diff --git a/core/java/android/provider/ContactsContract.java b/core/java/android/provider/ContactsContract.java
index afa0a7c..6eaf9dd 100644
--- a/core/java/android/provider/ContactsContract.java
+++ b/core/java/android/provider/ContactsContract.java
@@ -1039,6 +1039,7 @@
public static final int TYPE_WORK_MOBILE = 17;
public static final int TYPE_WORK_PAGER = 18;
public static final int TYPE_ASSISTANT = 19;
+ public static final int TYPE_MMS = 20;
/**
* The phone number as the user entered it.
diff --git a/core/java/android/server/BluetoothA2dpService.java b/core/java/android/server/BluetoothA2dpService.java
index 9c687e2..be8c777 100644
--- a/core/java/android/server/BluetoothA2dpService.java
+++ b/core/java/android/server/BluetoothA2dpService.java
@@ -27,6 +27,7 @@
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothUuid;
import android.bluetooth.IBluetoothA2dp;
+import android.bluetooth.ParcelUuid;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
@@ -42,7 +43,6 @@
import java.util.HashMap;
import java.util.HashSet;
import java.util.Set;
-import java.util.UUID;
public class BluetoothA2dpService extends IBluetoothA2dp.Stub {
private static final String TAG = "BluetoothA2dpService";
@@ -188,15 +188,9 @@
}
private boolean isSinkDevice(BluetoothDevice device) {
- String uuids[] = mBluetoothService.getRemoteUuids(device.getAddress());
- UUID uuid;
- if (uuids != null) {
- for (String deviceUuid: uuids) {
- uuid = UUID.fromString(deviceUuid);
- if (BluetoothUuid.isAudioSink(uuid)) {
- return true;
- }
- }
+ ParcelUuid[] uuids = mBluetoothService.getRemoteUuids(device.getAddress());
+ if (uuids != null && BluetoothUuid.isUuidPresent(uuids, BluetoothUuid.AudioSink)) {
+ return true;
}
return false;
}
@@ -229,18 +223,14 @@
for (String path: paths) {
String address = mBluetoothService.getAddressFromObjectPath(path);
BluetoothDevice device = mAdapter.getRemoteDevice(address);
- String []uuids = mBluetoothService.getRemoteUuids(address);
- if (uuids != null)
- for (String uuid: uuids) {
- UUID remoteUuid = UUID.fromString(uuid);
- if (BluetoothUuid.isAudioSink(remoteUuid) ||
- BluetoothUuid.isAudioSource(remoteUuid) ||
- BluetoothUuid.isAdvAudioDist(remoteUuid)) {
- addAudioSink(device);
- break;
- }
+ ParcelUuid[] remoteUuids = mBluetoothService.getRemoteUuids(address);
+ if (remoteUuids != null)
+ if (BluetoothUuid.containsAnyUuid(remoteUuids,
+ new ParcelUuid[] {BluetoothUuid.AudioSink,
+ BluetoothUuid.AdvAudioDist})) {
+ addAudioSink(device);
}
- }
+ }
}
mAudioManager.setParameters(BLUETOOTH_ENABLED+"=true");
}
diff --git a/core/java/android/server/BluetoothEventLoop.java b/core/java/android/server/BluetoothEventLoop.java
index 1ed5c49..ba53307 100644
--- a/core/java/android/server/BluetoothEventLoop.java
+++ b/core/java/android/server/BluetoothEventLoop.java
@@ -21,6 +21,7 @@
import android.bluetooth.BluetoothClass;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothUuid;
+import android.bluetooth.ParcelUuid;
import android.content.Context;
import android.content.Intent;
import android.os.Handler;
@@ -28,7 +29,6 @@
import android.util.Log;
import java.util.HashMap;
-import java.util.UUID;
/**
* TODO: Move this to
@@ -501,7 +501,7 @@
}
boolean authorized = false;
- UUID uuid = UUID.fromString(deviceUuid);
+ ParcelUuid uuid = ParcelUuid.fromString(deviceUuid);
// Bluez sends the UUID of the local service being accessed, _not_ the
// remote service
if (mBluetoothService.isEnabled() &&
diff --git a/core/java/android/server/BluetoothService.java b/core/java/android/server/BluetoothService.java
index de0cad7..c0e4f34 100644
--- a/core/java/android/server/BluetoothService.java
+++ b/core/java/android/server/BluetoothService.java
@@ -24,11 +24,12 @@
package android.server;
-import android.bluetooth.BluetoothClass;
import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothClass;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothHeadset;
import android.bluetooth.IBluetooth;
+import android.bluetooth.ParcelUuid;
import android.content.BroadcastReceiver;
import android.content.ContentResolver;
import android.content.Context;
@@ -51,7 +52,6 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
-import java.util.Iterator;
import java.util.Map;
public class BluetoothService extends IBluetooth.Stub {
@@ -967,22 +967,26 @@
/**
- * Gets the remote features encoded as bit mask.
+ * Gets the UUIDs supported by the remote device
*
- * Note: This method may be obsoleted soon.
- *
- * @return String array of 128bit UUIDs
+ * @return array of 128bit ParcelUuids
*/
- public synchronized String[] getRemoteUuids(String address) {
+ public synchronized ParcelUuid[] getRemoteUuids(String address) {
mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
if (!BluetoothAdapter.checkBluetoothAddress(address)) {
return null;
}
String value = getRemoteDeviceProperty(address, "UUIDs");
- String[] uuids = null;
+ if (value == null) return null;
+
+ String[] uuidStrings = null;
// The UUIDs are stored as a "," separated string.
- if (value != null)
- uuids = value.split(",");
+ uuidStrings = value.split(",");
+ ParcelUuid[] uuids = new ParcelUuid[uuidStrings.length];
+
+ for (int i = 0; i < uuidStrings.length; i++) {
+ uuids[i] = ParcelUuid.fromString(uuidStrings[i]);
+ }
return uuids;
}
@@ -990,16 +994,17 @@
* Gets the rfcomm channel associated with the UUID.
*
* @param address Address of the remote device
- * @param uuid UUID of the service attribute
+ * @param uuid ParcelUuid of the service attribute
*
* @return rfcomm channel associated with the service attribute
*/
- public int getRemoteServiceChannel(String address, String uuid) {
+ public int getRemoteServiceChannel(String address, ParcelUuid uuid) {
mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
if (!BluetoothAdapter.checkBluetoothAddress(address)) {
return BluetoothDevice.ERROR;
}
- return getDeviceServiceChannelNative(getObjectPathFromAddress(address), uuid, 0x0004);
+ return getDeviceServiceChannelNative(getObjectPathFromAddress(address), uuid.toString(),
+ 0x0004);
}
public synchronized boolean setPin(String address, byte[] pin) {
@@ -1148,11 +1153,11 @@
mBondState.getAttempt(address),
getRemoteName(address));
if (bondState == BluetoothDevice.BOND_BONDED) {
- String[] uuids = getRemoteUuids(address);
+ ParcelUuid[] uuids = getRemoteUuids(address);
if (uuids == null) {
pw.printf("\tuuids = null\n");
} else {
- for (String uuid : uuids) {
+ for (ParcelUuid uuid : uuids) {
pw.printf("\t" + uuid + "\n");
}
}
diff --git a/core/java/android/text/InputType.java b/core/java/android/text/InputType.java
index d50684a..14b8308 100644
--- a/core/java/android/text/InputType.java
+++ b/core/java/android/text/InputType.java
@@ -128,6 +128,15 @@
*/
public static final int TYPE_TEXT_FLAG_IME_MULTI_LINE = 0x00040000;
+ /**
+ * Flag for {@link #TYPE_CLASS_TEXT}: the input method does not need to
+ * display any dictionary-based candidates. This is useful for text views that
+ * do not contain words from the language and do not benefit from any
+ * dictionary-based completions or corrections. It overrides the
+ * {@link #TYPE_TEXT_FLAG_AUTO_CORRECT} value when set.
+ */
+ public static final int TYPE_TEXT_FLAG_NO_SUGGESTIONS = 0x00080000;
+
// ----------------------------------------------------------------------
/**
diff --git a/core/jni/android_server_BluetoothA2dpService.cpp b/core/jni/android_server_BluetoothA2dpService.cpp
index a185d8d..ba13519 100644
--- a/core/jni/android_server_BluetoothA2dpService.cpp
+++ b/core/jni/android_server_BluetoothA2dpService.cpp
@@ -133,23 +133,13 @@
LOGV(__FUNCTION__);
if (nat) {
const char *c_path = env->GetStringUTFChars(path, NULL);
- DBusError err;
- dbus_error_init(&err);
- DBusMessage *reply =
- dbus_func_args_timeout(env, nat->conn, -1, c_path,
- "org.bluez.AudioSink", "Connect",
- DBUS_TYPE_INVALID);
+ bool ret = dbus_func_args_async(env, nat->conn, -1, NULL, NULL, nat,
+ c_path, "org.bluez.AudioSink", "Connect",
+ DBUS_TYPE_INVALID);
+
env->ReleaseStringUTFChars(path, c_path);
-
- if (!reply && dbus_error_is_set(&err)) {
- LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, reply);
- return JNI_FALSE;
- } else if (!reply) {
- LOGE("DBus reply is NULL in function %s", __FUNCTION__);
- return JNI_FALSE;
- }
- return JNI_TRUE;
+ return ret ? JNI_TRUE : JNI_FALSE;
}
#endif
return JNI_FALSE;
@@ -161,23 +151,13 @@
LOGV(__FUNCTION__);
if (nat) {
const char *c_path = env->GetStringUTFChars(path, NULL);
- DBusError err;
- dbus_error_init(&err);
- DBusMessage *reply =
- dbus_func_args_timeout(env, nat->conn, -1, c_path,
- "org.bluez.AudioSink", "Disconnect",
- DBUS_TYPE_INVALID);
+ bool ret = dbus_func_args_async(env, nat->conn, -1, NULL, NULL, nat,
+ c_path, "org.bluez.AudioSink", "Disconnect",
+ DBUS_TYPE_INVALID);
+
env->ReleaseStringUTFChars(path, c_path);
-
- if (!reply && dbus_error_is_set(&err)) {
- LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, reply);
- return JNI_FALSE;
- } else if (!reply) {
- LOGE("DBus reply is NULL in function %s", __FUNCTION__);
- return JNI_FALSE;
- }
- return JNI_TRUE;
+ return ret ? JNI_TRUE : JNI_FALSE;
}
#endif
return JNI_FALSE;
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index a1a179b..eae838a 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -530,6 +530,11 @@
lines, the IME should provide multiple lines if it can. Corresponds to
{@link android.text.InputType#TYPE_TEXT_FLAG_IME_MULTI_LINE}. -->
<flag name="textImeMultiLine" value="0x00040001" />
+ <!-- Can be combined with <var>text</var> and its variations to
+ indicate that the IME should not show any
+ dictionary-based word suggestions. Corresponds to
+ {@link android.text.InputType#TYPE_TEXT_FLAG_NO_SUGGESTIONS}. -->
+ <flag name="textNoSuggestions" value="0x00080001" />
<!-- Text that will be used as a URI. Corresponds to
{@link android.text.InputType#TYPE_CLASS_TEXT} |
{@link android.text.InputType#TYPE_TEXT_VARIATION_URI}. -->
diff --git a/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp b/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp
index d893f0a..cc913cbd 100644
--- a/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp
+++ b/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp
@@ -174,6 +174,13 @@
surface = eglCreateWindowSurface(display, config, mNativeWindow.get(), NULL);
+ if (mFlags & UPDATE_ON_DEMAND) {
+ // if we have update on demand, we definitely don't need to
+ // preserve the backbuffer, which is usually costly.
+ eglSurfaceAttrib(display, surface,
+ EGL_SWAP_BEHAVIOR, EGL_BUFFER_DESTROYED);
+ }
+
if (eglQuerySurface(display, surface, EGL_SWAP_BEHAVIOR, &dummy) == EGL_TRUE) {
if (dummy == EGL_BUFFER_PRESERVED) {
mFlags |= BUFFER_PRESERVED;
diff --git a/libs/surfaceflinger/Layer.cpp b/libs/surfaceflinger/Layer.cpp
index 1e7f1e6..7387c85 100644
--- a/libs/surfaceflinger/Layer.cpp
+++ b/libs/surfaceflinger/Layer.cpp
@@ -303,7 +303,6 @@
// Index of the back buffer
const bool backbufferChanged = (front.w != temp.w) || (front.h != temp.h);
-
if (backbufferChanged) {
// the size changed, we need to ask our client to request a new buffer
LOGD_IF(DEBUG_RESIZE,
@@ -318,17 +317,6 @@
// buffer, it'll get the new size.
setDrawingSize(temp.w, temp.h);
- // all buffers need reallocation
- lcblk->reallocate();
-
- // recompute the visible region
- // FIXME: ideally we would do that only when we have received
- // a buffer of the right size
- flags |= Layer::eVisibleRegion;
- this->contentDirty = true;
-
-#if 0
- // FIXME: handle freeze lock
// we're being resized and there is a freeze display request,
// acquire a freeze lock, so that the screen stays put
// until we've redrawn at the new size; this is to avoid
@@ -340,7 +328,12 @@
mFreezeLock = mFlinger->getFreezeLock();
}
}
-#endif
+
+ // recompute the visible region
+ flags |= Layer::eVisibleRegion;
+ this->contentDirty = true;
+ // all buffers need reallocation
+ lcblk->reallocate();
}
if (temp.sequence != front.sequence) {
@@ -382,6 +375,13 @@
const Region dirty(lcblk->getDirtyRegion(buf));
mPostedDirtyRegion = dirty.intersect( newFrontBuffer->getBounds() );
+
+ const Layer::State& front(drawingState());
+ if (newFrontBuffer->getWidth() == front.w &&
+ newFrontBuffer->getHeight() ==front.h) {
+ mFreezeLock.clear();
+ }
+
// FIXME: signal an event if we have more buffers waiting
// mFlinger->signalEvent();
diff --git a/libs/surfaceflinger/LayerBuffer.cpp b/libs/surfaceflinger/LayerBuffer.cpp
index 38a897d..667571b 100644
--- a/libs/surfaceflinger/LayerBuffer.cpp
+++ b/libs/surfaceflinger/LayerBuffer.cpp
@@ -595,6 +595,7 @@
*overlayRef = new OverlayRef(mOverlayHandle, channel,
mWidth, mHeight, mFormat, mWidthStride, mHeightStride);
+ mLayer.mFlinger->signalEvent();
}
LayerBuffer::OverlaySource::~OverlaySource()
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/MediaRecorderStressTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/MediaRecorderStressTest.java
index 69e93a1..10796f1 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/MediaRecorderStressTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/MediaRecorderStressTest.java
@@ -16,6 +16,7 @@
package com.android.mediaframeworktest.stress;
+
import com.android.mediaframeworktest.MediaFrameworkTest;
import java.io.BufferedWriter;
@@ -26,6 +27,7 @@
import android.hardware.Camera;
import android.media.MediaPlayer;
import android.media.MediaRecorder;
+import android.os.Looper;
import android.test.ActivityInstrumentationTestCase2;
import android.test.suitebuilder.annotation.LargeTest;
import android.util.Log;
@@ -54,7 +56,14 @@
private static final String OUTPUT_FILE_EXT = ".3gp";
private static final String MEDIA_STRESS_OUTPUT =
"/sdcard/mediaStressOutput.txt";
-
+ private Looper mCameraLooper = null;
+ private Looper mRecorderLooper = null;
+ private final Object lock = new Object();
+ private final Object recorderlock = new Object();
+ private static int WAIT_FOR_COMMAND_TO_COMPLETE = 10000; // Milliseconds.
+ private final CameraErrorCallback mCameraErrorCallback = new CameraErrorCallback();
+ private final RecorderErrorCallback mRecorderErrorCallback = new RecorderErrorCallback();
+
public MediaRecorderStressTest() {
super("com.android.mediaframeworktest", MediaFrameworkTest.class);
}
@@ -63,41 +72,129 @@
getActivity();
super.setUp();
}
-
+
+ private final class CameraErrorCallback implements android.hardware.Camera.ErrorCallback {
+ public void onError(int error, android.hardware.Camera camera) {
+ if (error == android.hardware.Camera.CAMERA_ERROR_SERVER_DIED) {
+ assertTrue("Camera test mediaserver died", false);
+ }
+ }
+ }
+
+ private final class RecorderErrorCallback implements MediaRecorder.OnErrorListener {
+ public void onError(MediaRecorder mr, int what, int extra) {
+ // fail the test case no matter what error come up
+ assertTrue("mediaRecorder error", false);
+ }
+ }
+
+ private void initializeCameraMessageLooper() {
+ Log.v(TAG, "start looper");
+ new Thread() {
+ @Override
+ public void run() {
+ // Set up a looper to be used by camera.
+ Looper.prepare();
+ Log.v(TAG, "start loopRun");
+ mCameraLooper = Looper.myLooper();
+ mCamera = Camera.open();
+ synchronized (lock) {
+ lock.notify();
+ }
+ Looper.loop();
+ Log.v(TAG, "initializeMessageLooper: quit.");
+ }
+ }.start();
+ }
+
+ private void initializeRecorderMessageLooper() {
+ Log.v(TAG, "start looper");
+ new Thread() {
+ @Override
+ public void run() {
+ Looper.prepare();
+ Log.v(TAG, "start loopRun");
+ mRecorderLooper = Looper.myLooper();
+ mRecorder = new MediaRecorder();
+ synchronized (recorderlock) {
+ recorderlock.notify();
+ }
+ Looper.loop(); // Blocks forever until Looper.quit() is called.
+ Log.v(TAG, "initializeMessageLooper: quit.");
+ }
+ }.start();
+ }
+
+ /*
+ * Terminates the message looper thread.
+ */
+ private void terminateCameraMessageLooper() {
+ mCameraLooper.quit();
+ try {
+ Thread.sleep(1000);
+ } catch (Exception e){
+ Log.v(TAG, e.toString());
+ }
+ mCamera.release();
+ }
+
+ /*
+ * Terminates the message looper thread.
+ */
+ private void terminateRecorderMessageLooper() {
+ mRecorderLooper.quit();
+ try {
+ Thread.sleep(1000);
+ } catch (Exception e){
+ Log.v(TAG, e.toString());
+ }
+ mRecorder.release();
+ }
+
//Test case for stressing the camera preview.
@LargeTest
public void testStressCamera() throws Exception {
- SurfaceHolder mSurfaceHolder;
+ SurfaceHolder mSurfaceHolder;
mSurfaceHolder = MediaFrameworkTest.mSurfaceView.getHolder();
File stressOutFile = new File(MEDIA_STRESS_OUTPUT);
Writer output = new BufferedWriter(new FileWriter(stressOutFile, true));
output.write("Camera start preview stress:\n");
- output.write("Total number of loops:" +
+ output.write("Total number of loops:" +
NUMBER_OF_CAMERA_STRESS_LOOPS + "\n");
- try {
+ try {
Log.v(TAG, "Start preview");
output.write("No of loop: ");
+
for (int i = 0; i< NUMBER_OF_CAMERA_STRESS_LOOPS; i++){
- mCamera = Camera.open();
+ synchronized (lock) {
+ initializeCameraMessageLooper();
+ try {
+ lock.wait(WAIT_FOR_COMMAND_TO_COMPLETE);
+ } catch(Exception e) {
+ Log.v(TAG, "wait was interrupted.");
+ }
+ }
+ mCamera.setErrorCallback(mCameraErrorCallback);
mCamera.setPreviewDisplay(mSurfaceHolder);
mCamera.startPreview();
Thread.sleep(WAIT_TIME_CAMERA_TEST);
mCamera.stopPreview();
- mCamera.release();
+ terminateCameraMessageLooper();
output.write(" ," + i);
}
} catch (Exception e) {
- Log.v(TAG, e.toString());
+ assertTrue("CameraStressTest", false);
+ Log.v(TAG, e.toString());
}
output.write("\n\n");
output.close();
}
-
+
//Test case for stressing the camera preview.
@LargeTest
public void testStressRecorder() throws Exception {
String filename;
- SurfaceHolder mSurfaceHolder;
+ SurfaceHolder mSurfaceHolder;
mSurfaceHolder = MediaFrameworkTest.mSurfaceView.getHolder();
File stressOutFile = new File(MEDIA_STRESS_OUTPUT);
Writer output = new BufferedWriter(new FileWriter(stressOutFile, true));
@@ -108,12 +205,20 @@
output.write("No of loop: ");
Log.v(TAG, "Start preview");
for (int i = 0; i < NUMBER_OF_RECORDER_STRESS_LOOPS; i++){
+ synchronized (recorderlock) {
+ initializeRecorderMessageLooper();
+ try {
+ recorderlock.wait(WAIT_FOR_COMMAND_TO_COMPLETE);
+ } catch(Exception e) {
+ Log.v(TAG, "wait was interrupted.");
+ }
+ }
Log.v(TAG, "counter = " + i);
filename = OUTPUT_FILE + i + OUTPUT_FILE_EXT;
Log.v(TAG, filename);
- mRecorder = new MediaRecorder();
+ mRecorder.setOnErrorListener(mRecorderErrorCallback);
mRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
- mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
+ mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
mRecorder.setOutputFile(filename);
mRecorder.setVideoFrameRate(20);
mRecorder.setVideoSize(176,144);
@@ -125,47 +230,63 @@
Log.v(TAG, "prepare");
mRecorder.prepare();
Log.v(TAG, "before release");
- Thread.sleep(WAIT_TIME_RECORDER_TEST);
+ Thread.sleep(WAIT_TIME_RECORDER_TEST);
mRecorder.reset();
- mRecorder.release();
+ terminateRecorderMessageLooper();
output.write(", " + i);
}
} catch (Exception e) {
- Log.v(TAG, e.toString());
+ assertTrue("Recorder Stress test", false);
+ Log.v(TAG, e.toString());
}
output.write("\n\n");
output.close();
}
-
-
+
//Stress test case for switching camera and video recorder preview.
@LargeTest
public void testStressCameraSwitchRecorder() throws Exception {
String filename;
- SurfaceHolder mSurfaceHolder;
+ SurfaceHolder mSurfaceHolder;
mSurfaceHolder = MediaFrameworkTest.mSurfaceView.getHolder();
File stressOutFile = new File(MEDIA_STRESS_OUTPUT);
Writer output = new BufferedWriter(new FileWriter(stressOutFile, true));
output.write("Camera and video recorder preview switching\n");
output.write("Total number of loops:"
+ NUMBER_OF_SWTICHING_LOOPS_BW_CAMERA_AND_RECORDER + "\n");
- try {
+ try {
Log.v(TAG, "Start preview");
output.write("No of loop: ");
for (int i = 0; i < NUMBER_OF_SWTICHING_LOOPS_BW_CAMERA_AND_RECORDER; i++){
- mCamera = Camera.open();
+ synchronized (lock) {
+ initializeCameraMessageLooper();
+ try {
+ lock.wait(WAIT_FOR_COMMAND_TO_COMPLETE);
+ } catch(Exception e) {
+ Log.v(TAG, "wait was interrupted.");
+ }
+ }
+ mCamera.setErrorCallback(mCameraErrorCallback);
mCamera.setPreviewDisplay(mSurfaceHolder);
mCamera.startPreview();
Thread.sleep(WAIT_TIME_CAMERA_TEST);
mCamera.stopPreview();
- mCamera.release();
+ terminateCameraMessageLooper();
mCamera = null;
Log.v(TAG, "release camera");
filename = OUTPUT_FILE + i + OUTPUT_FILE_EXT;
Log.v(TAG, filename);
- mRecorder = new MediaRecorder();
+ synchronized (recorderlock) {
+ initializeRecorderMessageLooper();
+ try {
+ recorderlock.wait(WAIT_FOR_COMMAND_TO_COMPLETE);
+ } catch(Exception e) {
+ Log.v(TAG, "wait was interrupted.");
+ }
+ }
+ mRecorder.setOnErrorListener(mRecorderErrorCallback);
mRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
- mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
+ mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
mRecorder.setOutputFile(filename);
mRecorder.setVideoFrameRate(20);
mRecorder.setVideoSize(176,144);
@@ -176,23 +297,24 @@
Log.v(TAG, "prepare");
mRecorder.prepare();
Log.v(TAG, "before release");
- Thread.sleep(WAIT_TIME_CAMERA_TEST);
- mRecorder.release();
+ Thread.sleep(WAIT_TIME_CAMERA_TEST);
+ terminateRecorderMessageLooper();
Log.v(TAG, "release video recorder");
output.write(", " + i);
}
} catch (Exception e) {
+ assertTrue("Camer and recorder switch mode", false);
Log.v(TAG, e.toString());
}
output.write("\n\n");
output.close();
}
-
+
//Stress test case for record a video and play right away.
@LargeTest
public void testStressRecordVideoAndPlayback() throws Exception {
String filename;
- SurfaceHolder mSurfaceHolder;
+ SurfaceHolder mSurfaceHolder;
mSurfaceHolder = MediaFrameworkTest.mSurfaceView.getHolder();
File stressOutFile = new File(MEDIA_STRESS_OUTPUT);
Writer output = new BufferedWriter(new FileWriter(stressOutFile, true));
@@ -204,10 +326,18 @@
for (int i = 0; i < NUMBER_OF_RECORDERANDPLAY_STRESS_LOOPS; i++){
filename = OUTPUT_FILE + i + OUTPUT_FILE_EXT;
Log.v(TAG, filename);
- mRecorder = new MediaRecorder();
+ synchronized (recorderlock) {
+ initializeRecorderMessageLooper();
+ try {
+ recorderlock.wait(WAIT_FOR_COMMAND_TO_COMPLETE);
+ } catch(Exception e) {
+ Log.v(TAG, "wait was interrupted.");
+ }
+ }
+ mRecorder.setOnErrorListener(mRecorderErrorCallback);
mRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
- mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
+ mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
mRecorder.setOutputFile(filename);
mRecorder.setVideoFrameRate(20);
mRecorder.setVideoSize(352,288);
@@ -216,11 +346,11 @@
Log.v(TAG, "mediaRecorder setPreview");
mRecorder.setPreviewDisplay(mSurfaceHolder.getSurface());
mRecorder.prepare();
- mRecorder.start();
+ mRecorder.start();
Thread.sleep(WAIT_TIME_RECORD);
Log.v(TAG, "Before stop");
mRecorder.stop();
- mRecorder.release();
+ terminateRecorderMessageLooper();
//start the playback
MediaPlayer mp = new MediaPlayer();
mp.setDataSource(filename);
@@ -232,10 +362,10 @@
output.write(", " + i);
}
} catch (Exception e) {
+ assertTrue("record and playback", false);
Log.v(TAG, e.toString());
}
output.write("\n\n");
output.close();
- }
+ }
}
-
diff --git a/services/java/com/android/server/BackupManagerService.java b/services/java/com/android/server/BackupManagerService.java
index 0e60dd6..c6be61d 100644
--- a/services/java/com/android/server/BackupManagerService.java
+++ b/services/java/com/android/server/BackupManagerService.java
@@ -649,11 +649,21 @@
int N = packages.size();
for (int a = N-1; a >= 0; a--) {
PackageInfo pkg = packages.get(a);
- ApplicationInfo app = pkg.applicationInfo;
- if (((app.flags&ApplicationInfo.FLAG_ALLOW_BACKUP) == 0)
- || app.backupAgentName == null
- || (mPackageManager.checkPermission(android.Manifest.permission.BACKUP_DATA,
- pkg.packageName) != PackageManager.PERMISSION_GRANTED)) {
+ try {
+ ApplicationInfo app = pkg.applicationInfo;
+ if (((app.flags&ApplicationInfo.FLAG_ALLOW_BACKUP) == 0)
+ || app.backupAgentName == null
+ || (mPackageManager.checkPermission(android.Manifest.permission.BACKUP_DATA,
+ pkg.packageName) != PackageManager.PERMISSION_GRANTED)) {
+ packages.remove(a);
+ }
+ else {
+ // we will need the shared library path, so look that up and store it here
+ app = mPackageManager.getApplicationInfo(pkg.packageName,
+ PackageManager.GET_SHARED_LIBRARY_FILES);
+ pkg.applicationInfo.sharedLibraryFiles = app.sharedLibraryFiles;
+ }
+ } catch (NameNotFoundException e) {
packages.remove(a);
}
}
diff --git a/wifi/java/android/net/wifi/WifiStateTracker.java b/wifi/java/android/net/wifi/WifiStateTracker.java
index 9a11404..e3d8bf4 100644
--- a/wifi/java/android/net/wifi/WifiStateTracker.java
+++ b/wifi/java/android/net/wifi/WifiStateTracker.java
@@ -1350,7 +1350,7 @@
*/
private synchronized void requestPolledInfo(WifiInfo info, boolean polling)
{
- int newRssi = WifiNative.getRssiCommand();
+ int newRssi = (polling ? WifiNative.getRssiApproxCommand() : WifiNative.getRssiCommand());
if (newRssi != -1 && -200 < newRssi && newRssi < 256) { // screen out invalid values
/* some implementations avoid negative values by adding 256
* so we need to adjust for that here.