Merge change Icae1a990 into eclair-mr2
* changes:
Adding NAME_RAW_CONTACT_ID column to Contacts.
diff --git a/api/current.xml b/api/current.xml
index ef8f78f..7057866 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -976,7 +976,7 @@
value=""android.permission.SET_PREFERRED_APPLICATIONS""
static="true"
final="true"
- deprecated="not deprecated"
+ deprecated="deprecated"
visibility="public"
>
</field>
@@ -41108,7 +41108,7 @@
synchronized="false"
static="false"
final="false"
- deprecated="not deprecated"
+ deprecated="deprecated"
visibility="public"
>
<parameter name="packageName" type="java.lang.String">
@@ -41861,7 +41861,7 @@
synchronized="false"
static="false"
final="false"
- deprecated="not deprecated"
+ deprecated="deprecated"
visibility="public"
>
<parameter name="packageName" type="java.lang.String">
@@ -125196,6 +125196,20 @@
deprecated="not deprecated"
visibility="public"
>
+<parameter name="rssi" type="int">
+</parameter>
+<parameter name="location" type="java.lang.String">
+</parameter>
+<parameter name="radioType" type="int">
+</parameter>
+</constructor>
+<constructor name="NeighboringCellInfo"
+ type="android.telephony.NeighboringCellInfo"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
<parameter name="in" type="android.os.Parcel">
</parameter>
</constructor>
@@ -126007,6 +126021,21 @@
<parameter name="state" type="int">
</parameter>
</method>
+<method name="onDataConnectionStateChanged"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="state" type="int">
+</parameter>
+<parameter name="networkType" type="int">
+</parameter>
+</method>
<method name="onMessageWaitingIndicatorChanged"
return="void"
abstract="false"
@@ -126046,6 +126075,19 @@
<parameter name="asu" type="int">
</parameter>
</method>
+<method name="onSignalStrengthsChanged"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="signalStrength" type="android.telephony.SignalStrength">
+</parameter>
+</method>
<field name="LISTEN_CALL_FORWARDING_INDICATOR"
type="int"
transient="false"
@@ -126141,6 +126183,17 @@
value="2"
static="true"
final="true"
+ deprecated="deprecated"
+ visibility="public"
+>
+</field>
+<field name="LISTEN_SIGNAL_STRENGTHS"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="256"
+ static="true"
+ final="true"
deprecated="not deprecated"
visibility="public"
>
@@ -126422,6 +126475,131 @@
>
</field>
</class>
+<class name="SignalStrength"
+ extends="java.lang.Object"
+ abstract="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<implements name="android.os.Parcelable">
+</implements>
+<method name="describeContents"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getCdmaDbm"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getCdmaEcio"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getEvdoDbm"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getEvdoEcio"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getEvdoSnr"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getGsmBitErrorRate"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getGsmSignalStrength"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="isGsm"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="writeToParcel"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="out" type="android.os.Parcel">
+</parameter>
+<parameter name="flags" type="int">
+</parameter>
+</method>
+</class>
<class name="SmsManager"
extends="java.lang.Object"
abstract="false"
diff --git a/calendar/Android.mk b/calendar/Android.mk
new file mode 100644
index 0000000..fd20dfa
--- /dev/null
+++ b/calendar/Android.mk
@@ -0,0 +1,18 @@
+# Copyright 2009 Google, Inc.
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := calendar
+LOCAL_SRC_FILES := \
+ ../core/java/android/provider/Calendar.java \
+ ../core/java/android/pim/EventRecurrence.java \
+ ../core/java/android/pim/ICalendar.java \
+ ../core/java/android/pim/RecurrenceSet.java \
+ ../core/java/android/pim/ContactsAsyncHelper.java \
+ ../core/java/android/pim/DateException.java
+
+include $(BUILD_STATIC_JAVA_LIBRARY)
+
+# Include this library in the build server's output directory
+$(call dist-for-goals, droid, $(LOCAL_BUILT_MODULE):calendar.jar)
diff --git a/camera/libcameraservice/CameraService.cpp b/camera/libcameraservice/CameraService.cpp
index df59dcf..6419a5c 100644
--- a/camera/libcameraservice/CameraService.cpp
+++ b/camera/libcameraservice/CameraService.cpp
@@ -669,8 +669,14 @@
LOGD("startRecording (pid %d)", getCallingPid());
if (mMediaPlayerBeep.get() != NULL) {
- mMediaPlayerBeep->seekTo(0);
- mMediaPlayerBeep->start();
+ // do not play record jingle if stream volume is 0
+ // (typically because ringer mode is silent).
+ int index;
+ AudioSystem::getStreamVolumeIndex(AudioSystem::ENFORCED_AUDIBLE, &index);
+ if (index != 0) {
+ mMediaPlayerBeep->seekTo(0);
+ mMediaPlayerBeep->start();
+ }
}
mHardware->enableMsgType(CAMERA_MSG_VIDEO_FRAME);
@@ -888,8 +894,14 @@
{
// Play shutter sound.
if (mMediaPlayerClick.get() != NULL) {
- mMediaPlayerClick->seekTo(0);
- mMediaPlayerClick->start();
+ // do not play shutter sound if stream volume is 0
+ // (typically because ringer mode is silent).
+ int index;
+ AudioSystem::getStreamVolumeIndex(AudioSystem::ENFORCED_AUDIBLE, &index);
+ if (index != 0) {
+ mMediaPlayerClick->seekTo(0);
+ mMediaPlayerClick->start();
+ }
}
// Screen goes black after the buffer is unregistered.
diff --git a/camera/tests/CameraServiceTest/Android.mk b/camera/tests/CameraServiceTest/Android.mk
new file mode 100644
index 0000000..c2a02bb
--- /dev/null
+++ b/camera/tests/CameraServiceTest/Android.mk
@@ -0,0 +1,21 @@
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= CameraServiceTest.cpp
+
+LOCAL_MODULE:= CameraServiceTest
+
+LOCAL_MODULE_TAGS := tests
+
+LOCAL_C_INCLUDES += \
+ frameworks/base/libs
+
+LOCAL_CFLAGS :=
+
+LOCAL_SHARED_LIBRARIES += \
+ libcutils \
+ libutils \
+ libui
+
+include $(BUILD_EXECUTABLE)
diff --git a/camera/tests/CameraServiceTest/CameraServiceTest.cpp b/camera/tests/CameraServiceTest/CameraServiceTest.cpp
new file mode 100644
index 0000000..29320e0
--- /dev/null
+++ b/camera/tests/CameraServiceTest/CameraServiceTest.cpp
@@ -0,0 +1,848 @@
+#define LOG_TAG "CameraServiceTest"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+#include <ui/ISurface.h>
+#include <ui/Camera.h>
+#include <ui/CameraParameters.h>
+#include <ui/GraphicBuffer.h>
+#include <ui/ICamera.h>
+#include <ui/ICameraClient.h>
+#include <ui/ICameraService.h>
+#include <ui/Overlay.h>
+#include <binder/IPCThreadState.h>
+#include <binder/IServiceManager.h>
+#include <binder/ProcessState.h>
+#include <utils/KeyedVector.h>
+#include <utils/Log.h>
+#include <utils/Vector.h>
+#include <utils/threads.h>
+
+using namespace android;
+
+//
+// Assertion and Logging utilities
+//
+#define INFO(...) \
+ do { \
+ printf(__VA_ARGS__); \
+ printf("\n"); \
+ LOGD(__VA_ARGS__); \
+ } while(0)
+
+void assert_fail(const char *file, int line, const char *func, const char *expr) {
+ INFO("assertion failed at file %s, line %d, function %s:",
+ file, line, func);
+ INFO("%s", expr);
+ exit(1);
+}
+
+void assert_eq_fail(const char *file, int line, const char *func,
+ const char *expr, int actual) {
+ INFO("assertion failed at file %s, line %d, function %s:",
+ file, line, func);
+ INFO("(expected) %s != (actual) %d", expr, actual);
+ exit(1);
+}
+
+#define ASSERT(e) \
+ do { \
+ if (!(e)) \
+ assert_fail(__FILE__, __LINE__, __func__, #e); \
+ } while(0)
+
+#define ASSERT_EQ(expected, actual) \
+ do { \
+ int _x = (actual); \
+ if (_x != (expected)) \
+ assert_eq_fail(__FILE__, __LINE__, __func__, #expected, _x); \
+ } while(0)
+
+//
+// Holder service for pass objects between processes.
+//
+class IHolder : public IInterface {
+protected:
+ enum {
+ HOLDER_PUT = IBinder::FIRST_CALL_TRANSACTION,
+ HOLDER_GET,
+ HOLDER_CLEAR
+ };
+public:
+ DECLARE_META_INTERFACE(Holder);
+
+ virtual void put(sp<IBinder> obj) = 0;
+ virtual sp<IBinder> get() = 0;
+ virtual void clear() = 0;
+};
+
+class BnHolder : public BnInterface<IHolder> {
+ virtual status_t onTransact(uint32_t code,
+ const Parcel& data,
+ Parcel* reply,
+ uint32_t flags = 0);
+};
+
+class BpHolder : public BpInterface<IHolder> {
+public:
+ BpHolder(const sp<IBinder>& impl)
+ : BpInterface<IHolder>(impl) {
+ }
+
+ virtual void put(sp<IBinder> obj) {
+ Parcel data, reply;
+ data.writeStrongBinder(obj);
+ remote()->transact(HOLDER_PUT, data, &reply, IBinder::FLAG_ONEWAY);
+ }
+
+ virtual sp<IBinder> get() {
+ Parcel data, reply;
+ remote()->transact(HOLDER_GET, data, &reply);
+ return reply.readStrongBinder();
+ }
+
+ virtual void clear() {
+ Parcel data, reply;
+ remote()->transact(HOLDER_CLEAR, data, &reply);
+ }
+};
+
+IMPLEMENT_META_INTERFACE(Holder, "CameraServiceTest.Holder");
+
+status_t BnHolder::onTransact(
+ uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) {
+ switch(code) {
+ case HOLDER_PUT: {
+ put(data.readStrongBinder());
+ return NO_ERROR;
+ } break;
+ case HOLDER_GET: {
+ reply->writeStrongBinder(get());
+ return NO_ERROR;
+ } break;
+ case HOLDER_CLEAR: {
+ clear();
+ return NO_ERROR;
+ } break;
+ default:
+ return BBinder::onTransact(code, data, reply, flags);
+ }
+}
+
+class HolderService : public BnHolder {
+ virtual void put(sp<IBinder> obj) {
+ mObj = obj;
+ }
+ virtual sp<IBinder> get() {
+ return mObj;
+ }
+ virtual void clear() {
+ mObj.clear();
+ }
+private:
+ sp<IBinder> mObj;
+};
+
+//
+// A mock CameraClient
+//
+class MCameraClient : public BnCameraClient {
+public:
+ virtual void notifyCallback(int32_t msgType, int32_t ext1, int32_t ext2);
+ virtual void dataCallback(int32_t msgType, const sp<IMemory>& data);
+ virtual void dataCallbackTimestamp(nsecs_t timestamp,
+ int32_t msgType, const sp<IMemory>& data) {}
+
+ // new functions
+ void clearStat();
+ enum OP { EQ, GE, LE, GT, LT };
+ void assertNotify(int32_t msgType, OP op, int count);
+ void assertData(int32_t msgType, OP op, int count);
+ void waitNotify(int32_t msgType, OP op, int count);
+ void waitData(int32_t msgType, OP op, int count);
+ void assertDataSize(int32_t msgType, OP op, int dataSize);
+
+ void setReleaser(ICamera *releaser) {
+ mReleaser = releaser;
+ }
+private:
+ Mutex mLock;
+ Condition mCond;
+ DefaultKeyedVector<int32_t, int> mNotifyCount;
+ DefaultKeyedVector<int32_t, int> mDataCount;
+ DefaultKeyedVector<int32_t, int> mDataSize;
+ bool test(OP op, int v1, int v2);
+
+ ICamera *mReleaser;
+};
+
+void MCameraClient::clearStat() {
+ Mutex::Autolock _l(mLock);
+ mNotifyCount.clear();
+ mDataCount.clear();
+ mDataSize.clear();
+}
+
+bool MCameraClient::test(OP op, int v1, int v2) {
+ switch (op) {
+ case EQ: return v1 == v2;
+ case GT: return v1 > v2;
+ case LT: return v1 < v2;
+ case GE: return v1 >= v2;
+ case LE: return v1 <= v2;
+ default: ASSERT(0); break;
+ }
+ return false;
+}
+
+void MCameraClient::assertNotify(int32_t msgType, OP op, int count) {
+ Mutex::Autolock _l(mLock);
+ int v = mNotifyCount.valueFor(msgType);
+ ASSERT(test(op, v, count));
+}
+
+void MCameraClient::assertData(int32_t msgType, OP op, int count) {
+ Mutex::Autolock _l(mLock);
+ int v = mDataCount.valueFor(msgType);
+ ASSERT(test(op, v, count));
+}
+
+void MCameraClient::assertDataSize(int32_t msgType, OP op, int dataSize) {
+ Mutex::Autolock _l(mLock);
+ int v = mDataSize.valueFor(msgType);
+ ASSERT(test(op, v, dataSize));
+}
+
+void MCameraClient::notifyCallback(int32_t msgType, int32_t ext1, int32_t ext2) {
+ INFO(__func__);
+ Mutex::Autolock _l(mLock);
+ ssize_t i = mNotifyCount.indexOfKey(msgType);
+ if (i < 0) {
+ mNotifyCount.add(msgType, 1);
+ } else {
+ ++mNotifyCount.editValueAt(i);
+ }
+ mCond.signal();
+}
+
+void MCameraClient::dataCallback(int32_t msgType, const sp<IMemory>& data) {
+ INFO(__func__);
+ int dataSize = data->size();
+ INFO("data type = %d, size = %d", msgType, dataSize);
+ Mutex::Autolock _l(mLock);
+ ssize_t i = mDataCount.indexOfKey(msgType);
+ if (i < 0) {
+ mDataCount.add(msgType, 1);
+ mDataSize.add(msgType, dataSize);
+ } else {
+ ++mDataCount.editValueAt(i);
+ mDataSize.editValueAt(i) = dataSize;
+ }
+ mCond.signal();
+
+ if (msgType == CAMERA_MSG_VIDEO_FRAME) {
+ ASSERT(mReleaser != NULL);
+ mReleaser->releaseRecordingFrame(data);
+ }
+}
+
+void MCameraClient::waitNotify(int32_t msgType, OP op, int count) {
+ INFO("waitNotify: %d, %d, %d", msgType, op, count);
+ Mutex::Autolock _l(mLock);
+ while (true) {
+ int v = mNotifyCount.valueFor(msgType);
+ if (test(op, v, count)) {
+ break;
+ }
+ mCond.wait(mLock);
+ }
+}
+
+void MCameraClient::waitData(int32_t msgType, OP op, int count) {
+ INFO("waitData: %d, %d, %d", msgType, op, count);
+ Mutex::Autolock _l(mLock);
+ while (true) {
+ int v = mDataCount.valueFor(msgType);
+ if (test(op, v, count)) {
+ break;
+ }
+ mCond.wait(mLock);
+ }
+}
+
+//
+// A mock Surface
+//
+class MSurface : public BnSurface {
+public:
+ virtual status_t registerBuffers(const BufferHeap& buffers);
+ virtual void postBuffer(ssize_t offset);
+ virtual void unregisterBuffers();
+ virtual sp<OverlayRef> createOverlay(
+ uint32_t w, uint32_t h, int32_t format);
+ virtual sp<GraphicBuffer> requestBuffer(int bufferIdx, int usage);
+
+ // new functions
+ void clearStat();
+ void waitUntil(int c0, int c1, int c2);
+
+private:
+ // check callback count
+ Condition mCond;
+ Mutex mLock;
+ int registerBuffersCount;
+ int postBufferCount;
+ int unregisterBuffersCount;
+};
+
+status_t MSurface::registerBuffers(const BufferHeap& buffers) {
+ INFO(__func__);
+ Mutex::Autolock _l(mLock);
+ ++registerBuffersCount;
+ mCond.signal();
+ return NO_ERROR;
+}
+
+void MSurface::postBuffer(ssize_t offset) {
+ // INFO(__func__);
+ Mutex::Autolock _l(mLock);
+ ++postBufferCount;
+ mCond.signal();
+}
+
+void MSurface::unregisterBuffers() {
+ INFO(__func__);
+ Mutex::Autolock _l(mLock);
+ ++unregisterBuffersCount;
+ mCond.signal();
+}
+
+sp<GraphicBuffer> MSurface::requestBuffer(int bufferIdx, int usage) {
+ INFO(__func__);
+ return NULL;
+}
+
+void MSurface::clearStat() {
+ Mutex::Autolock _l(mLock);
+ registerBuffersCount = 0;
+ postBufferCount = 0;
+ unregisterBuffersCount = 0;
+}
+
+void MSurface::waitUntil(int c0, int c1, int c2) {
+ INFO("waitUntil: %d %d %d", c0, c1, c2);
+ Mutex::Autolock _l(mLock);
+ while (true) {
+ if (registerBuffersCount >= c0 &&
+ postBufferCount >= c1 &&
+ unregisterBuffersCount >= c2) {
+ break;
+ }
+ mCond.wait(mLock);
+ }
+}
+
+sp<OverlayRef> MSurface::createOverlay(uint32_t w, uint32_t h, int32_t format) {
+ // We don't expect this to be called in current hardware.
+ ASSERT(0);
+ sp<OverlayRef> dummy;
+ return dummy;
+}
+
+//
+// Utilities to use the Holder service
+//
+sp<IHolder> getHolder() {
+ sp<IServiceManager> sm = defaultServiceManager();
+ ASSERT(sm != 0);
+ sp<IBinder> binder = sm->getService(String16("CameraServiceTest.Holder"));
+ ASSERT(binder != 0);
+ sp<IHolder> holder = interface_cast<IHolder>(binder);
+ ASSERT(holder != 0);
+ return holder;
+}
+
+void putTempObject(sp<IBinder> obj) {
+ INFO(__func__);
+ getHolder()->put(obj);
+}
+
+sp<IBinder> getTempObject() {
+ INFO(__func__);
+ return getHolder()->get();
+}
+
+void clearTempObject() {
+ INFO(__func__);
+ getHolder()->clear();
+}
+
+//
+// Get a Camera Service
+//
+sp<ICameraService> getCameraService() {
+ sp<IServiceManager> sm = defaultServiceManager();
+ ASSERT(sm != 0);
+ sp<IBinder> binder = sm->getService(String16("media.camera"));
+ ASSERT(binder != 0);
+ sp<ICameraService> cs = interface_cast<ICameraService>(binder);
+ ASSERT(cs != 0);
+ return cs;
+}
+
+//
+// Various Connect Tests
+//
+void testConnect() {
+ INFO(__func__);
+ sp<ICameraService> cs = getCameraService();
+ sp<MCameraClient> cc = new MCameraClient();
+ sp<ICamera> c = cs->connect(cc);
+ ASSERT(c != 0);
+ c->disconnect();
+}
+
+void testAllowConnectOnceOnly() {
+ INFO(__func__);
+ sp<ICameraService> cs = getCameraService();
+ // Connect the first client.
+ sp<MCameraClient> cc = new MCameraClient();
+ sp<ICamera> c = cs->connect(cc);
+ ASSERT(c != 0);
+ // Same client -- ok.
+ ASSERT(cs->connect(cc) != 0);
+ // Different client -- not ok.
+ sp<MCameraClient> cc2 = new MCameraClient();
+ ASSERT(cs->connect(cc2) == 0);
+ c->disconnect();
+}
+
+void testReconnectFailed() {
+ INFO(__func__);
+ sp<ICamera> c = interface_cast<ICamera>(getTempObject());
+ sp<MCameraClient> cc2 = new MCameraClient();
+ ASSERT(c->connect(cc2) != NO_ERROR);
+}
+
+void testReconnectSuccess() {
+ INFO(__func__);
+ sp<ICamera> c = interface_cast<ICamera>(getTempObject());
+ sp<MCameraClient> cc = new MCameraClient();
+ ASSERT(c->connect(cc) == NO_ERROR);
+}
+
+void testLockFailed() {
+ INFO(__func__);
+ sp<ICamera> c = interface_cast<ICamera>(getTempObject());
+ ASSERT(c->lock() != NO_ERROR);
+}
+
+void testLockUnlockSuccess() {
+ INFO(__func__);
+ sp<ICamera> c = interface_cast<ICamera>(getTempObject());
+ ASSERT(c->lock() == NO_ERROR);
+ ASSERT(c->unlock() == NO_ERROR);
+}
+
+void testLockSuccess() {
+ INFO(__func__);
+ sp<ICamera> c = interface_cast<ICamera>(getTempObject());
+ ASSERT(c->lock() == NO_ERROR);
+}
+
+//
+// Run the connect tests in another process.
+//
+const char *gExecutable;
+
+struct FunctionTableEntry {
+ const char *name;
+ void (*func)();
+};
+
+FunctionTableEntry function_table[] = {
+#define ENTRY(x) {#x, &x}
+ ENTRY(testReconnectFailed),
+ ENTRY(testReconnectSuccess),
+ ENTRY(testLockUnlockSuccess),
+ ENTRY(testLockFailed),
+ ENTRY(testLockSuccess),
+#undef ENTRY
+};
+
+void runFunction(const char *tag) {
+ INFO("runFunction: %s", tag);
+ int entries = sizeof(function_table) / sizeof(function_table[0]);
+ for (int i = 0; i < entries; i++) {
+ if (strcmp(function_table[i].name, tag) == 0) {
+ (*function_table[i].func)();
+ return;
+ }
+ }
+ ASSERT(0);
+}
+
+void runInAnotherProcess(const char *tag) {
+ pid_t pid = fork();
+ if (pid == 0) {
+ execlp(gExecutable, gExecutable, tag, NULL);
+ ASSERT(0);
+ } else {
+ int status;
+ ASSERT_EQ(pid, wait(&status));
+ ASSERT_EQ(0, status);
+ }
+}
+
+void testReconnect() {
+ INFO(__func__);
+ sp<ICameraService> cs = getCameraService();
+ sp<MCameraClient> cc = new MCameraClient();
+ sp<ICamera> c = cs->connect(cc);
+ ASSERT(c != 0);
+ // Reconnect to the same client -- ok.
+ ASSERT(c->connect(cc) == NO_ERROR);
+ // Reconnect to a different client (but the same pid) -- ok.
+ sp<MCameraClient> cc2 = new MCameraClient();
+ ASSERT(c->connect(cc2) == NO_ERROR);
+ c->disconnect();
+ cc->assertNotify(CAMERA_MSG_ERROR, MCameraClient::EQ, 0);
+}
+
+void testLockUnlock() {
+ sp<ICameraService> cs = getCameraService();
+ sp<MCameraClient> cc = new MCameraClient();
+ sp<ICamera> c = cs->connect(cc);
+ ASSERT(c != 0);
+ // We can lock as many times as we want.
+ ASSERT(c->lock() == NO_ERROR);
+ ASSERT(c->lock() == NO_ERROR);
+ // Lock from a different process -- not ok.
+ putTempObject(c->asBinder());
+ runInAnotherProcess("testLockFailed");
+ // Unlock then lock from a different process -- ok.
+ ASSERT(c->unlock() == NO_ERROR);
+ runInAnotherProcess("testLockUnlockSuccess");
+ // Unlock then lock from a different process -- ok.
+ runInAnotherProcess("testLockSuccess");
+ c->disconnect();
+ clearTempObject();
+}
+
+void testReconnectFromAnotherProcess() {
+ INFO(__func__);
+
+ sp<ICameraService> cs = getCameraService();
+ sp<MCameraClient> cc = new MCameraClient();
+ sp<ICamera> c = cs->connect(cc);
+ ASSERT(c != 0);
+ // Reconnect from a different process -- not ok.
+ putTempObject(c->asBinder());
+ runInAnotherProcess("testReconnectFailed");
+ // Unlock then reconnect from a different process -- ok.
+ ASSERT(c->unlock() == NO_ERROR);
+ runInAnotherProcess("testReconnectSuccess");
+ c->disconnect();
+ clearTempObject();
+}
+
+// We need to flush the command buffer after the reference
+// to ICamera is gone. The sleep is for the server to run
+// the destructor for it.
+static void flushCommands() {
+ IPCThreadState::self()->flushCommands();
+ usleep(200000); // 200ms
+}
+
+// Run a test case
+#define RUN(class_name) do { \
+ { \
+ INFO(#class_name); \
+ class_name instance; \
+ instance.run(); \
+ } \
+ flushCommands(); \
+} while(0)
+
+// Base test case after the the camera is connected.
+class AfterConnect {
+protected:
+ sp<ICameraService> cs;
+ sp<MCameraClient> cc;
+ sp<ICamera> c;
+
+ AfterConnect() {
+ cs = getCameraService();
+ cc = new MCameraClient();
+ c = cs->connect(cc);
+ ASSERT(c != 0);
+ }
+
+ ~AfterConnect() {
+ c.clear();
+ cc.clear();
+ cs.clear();
+ }
+};
+
+class TestSetPreviewDisplay : public AfterConnect {
+public:
+ void run() {
+ sp<MSurface> surface = new MSurface();
+ ASSERT(c->setPreviewDisplay(surface) == NO_ERROR);
+ c->disconnect();
+ cc->assertNotify(CAMERA_MSG_ERROR, MCameraClient::EQ, 0);
+ }
+};
+
+class TestStartPreview : public AfterConnect {
+public:
+ void run() {
+ sp<MSurface> surface = new MSurface();
+ ASSERT(c->setPreviewDisplay(surface) == NO_ERROR);
+
+ ASSERT(c->startPreview() == NO_ERROR);
+ ASSERT(c->previewEnabled() == true);
+
+ surface->waitUntil(1, 10, 0); // needs 1 registerBuffers and 10 postBuffer
+ surface->clearStat();
+
+ c->disconnect();
+ // TODO: CameraService crashes for this. Fix it.
+#if 0
+ sp<MSurface> another_surface = new MSurface();
+ c->setPreviewDisplay(another_surface); // just to make sure unregisterBuffers
+ // is called.
+ surface->waitUntil(0, 0, 1); // needs unregisterBuffers
+#endif
+ cc->assertNotify(CAMERA_MSG_ERROR, MCameraClient::EQ, 0);
+ }
+};
+
+class TestStartPreviewWithoutDisplay : AfterConnect {
+public:
+ void run() {
+ ASSERT(c->startPreview() == NO_ERROR);
+ ASSERT(c->previewEnabled() == true);
+ c->disconnect();
+ cc->assertNotify(CAMERA_MSG_ERROR, MCameraClient::EQ, 0);
+ }
+};
+
+// Base test case after the the camera is connected and the preview is started.
+class AfterStartPreview : public AfterConnect {
+protected:
+ sp<MSurface> surface;
+
+ AfterStartPreview() {
+ surface = new MSurface();
+ ASSERT(c->setPreviewDisplay(surface) == NO_ERROR);
+ ASSERT(c->startPreview() == NO_ERROR);
+ }
+
+ ~AfterStartPreview() {
+ surface.clear();
+ }
+};
+
+class TestAutoFocus : public AfterStartPreview {
+public:
+ void run() {
+ cc->assertNotify(CAMERA_MSG_FOCUS, MCameraClient::EQ, 0);
+ c->autoFocus();
+ cc->waitNotify(CAMERA_MSG_FOCUS, MCameraClient::EQ, 1);
+ c->disconnect();
+ cc->assertNotify(CAMERA_MSG_ERROR, MCameraClient::EQ, 0);
+ }
+};
+
+class TestStopPreview : public AfterStartPreview {
+public:
+ void run() {
+ ASSERT(c->previewEnabled() == true);
+ c->stopPreview();
+ ASSERT(c->previewEnabled() == false);
+ c->disconnect();
+ cc->assertNotify(CAMERA_MSG_ERROR, MCameraClient::EQ, 0);
+ }
+};
+
+class TestTakePicture: public AfterStartPreview {
+public:
+ void run() {
+ ASSERT(c->takePicture() == NO_ERROR);
+ cc->waitNotify(CAMERA_MSG_SHUTTER, MCameraClient::EQ, 1);
+ cc->waitData(CAMERA_MSG_RAW_IMAGE, MCameraClient::EQ, 1);
+ cc->waitData(CAMERA_MSG_COMPRESSED_IMAGE, MCameraClient::EQ, 1);
+ c->stopPreview();
+#if 1 // TODO: It crashes if we don't have this. Fix it.
+ usleep(100000);
+#endif
+ c->disconnect();
+ cc->assertNotify(CAMERA_MSG_ERROR, MCameraClient::EQ, 0);
+ }
+};
+
+class TestTakeMultiplePictures: public AfterStartPreview {
+public:
+ void run() {
+ for (int i = 0; i < 10; i++) {
+ cc->clearStat();
+ ASSERT(c->takePicture() == NO_ERROR);
+ cc->waitNotify(CAMERA_MSG_SHUTTER, MCameraClient::EQ, 1);
+ cc->waitData(CAMERA_MSG_RAW_IMAGE, MCameraClient::EQ, 1);
+ cc->waitData(CAMERA_MSG_COMPRESSED_IMAGE, MCameraClient::EQ, 1);
+ usleep(100000); // 100ms
+ }
+ c->disconnect();
+ cc->assertNotify(CAMERA_MSG_ERROR, MCameraClient::EQ, 0);
+ }
+};
+
+class TestGetParameters: public AfterStartPreview {
+public:
+ void run() {
+ String8 param_str = c->getParameters();
+ INFO(param_str);
+ }
+};
+
+class TestPictureSize : public AfterStartPreview {
+public:
+ void checkOnePicture(int w, int h) {
+ const float rate = 0.5; // byte per pixel limit
+ int pixels = w * h;
+
+ CameraParameters param(c->getParameters());
+ param.setPictureSize(w, h);
+ c->setParameters(param.flatten());
+
+ cc->clearStat();
+ ASSERT(c->takePicture() == NO_ERROR);
+ cc->waitData(CAMERA_MSG_RAW_IMAGE, MCameraClient::EQ, 1);
+ cc->assertDataSize(CAMERA_MSG_RAW_IMAGE, MCameraClient::EQ, pixels*3/2);
+ cc->waitData(CAMERA_MSG_COMPRESSED_IMAGE, MCameraClient::EQ, 1);
+ cc->assertDataSize(CAMERA_MSG_COMPRESSED_IMAGE, MCameraClient::LT,
+ int(pixels * rate));
+ cc->assertDataSize(CAMERA_MSG_COMPRESSED_IMAGE, MCameraClient::GT, 0);
+ cc->assertNotify(CAMERA_MSG_ERROR, MCameraClient::EQ, 0);
+ usleep(100000); // 100ms
+ }
+
+ void run() {
+ checkOnePicture(2048, 1536);
+ checkOnePicture(1600, 1200);
+ checkOnePicture(1024, 768);
+ }
+};
+
+class TestPreviewCallbackFlag : public AfterConnect {
+public:
+ void run() {
+ sp<MSurface> surface = new MSurface();
+ ASSERT(c->setPreviewDisplay(surface) == NO_ERROR);
+
+ // Try all flag combinations.
+ for (int v = 0; v < 8; v++) {
+ cc->clearStat();
+ c->setPreviewCallbackFlag(v);
+ ASSERT(c->previewEnabled() == false);
+ ASSERT(c->startPreview() == NO_ERROR);
+ ASSERT(c->previewEnabled() == true);
+ sleep(2);
+ c->stopPreview();
+ if ((v & FRAME_CALLBACK_FLAG_ENABLE_MASK) == 0) {
+ cc->assertData(CAMERA_MSG_PREVIEW_FRAME, MCameraClient::EQ, 0);
+ } else {
+ if ((v & FRAME_CALLBACK_FLAG_ONE_SHOT_MASK) == 0) {
+ cc->assertData(CAMERA_MSG_PREVIEW_FRAME, MCameraClient::GE, 10);
+ } else {
+ cc->assertData(CAMERA_MSG_PREVIEW_FRAME, MCameraClient::EQ, 1);
+ }
+ }
+ }
+ }
+};
+
+class TestRecording : public AfterConnect {
+public:
+ void run() {
+ ASSERT(c->recordingEnabled() == false);
+ sp<MSurface> surface = new MSurface();
+ ASSERT(c->setPreviewDisplay(surface) == NO_ERROR);
+ c->setPreviewCallbackFlag(FRAME_CALLBACK_FLAG_ENABLE_MASK);
+ cc->setReleaser(c.get());
+ c->startRecording();
+ ASSERT(c->recordingEnabled() == true);
+ sleep(2);
+ c->stopRecording();
+ cc->setReleaser(NULL);
+ cc->assertData(CAMERA_MSG_VIDEO_FRAME, MCameraClient::GE, 10);
+ }
+};
+
+class TestPreviewSize : public AfterStartPreview {
+public:
+ void checkOnePicture(int w, int h) {
+ int size = w*h*3/2; // should read from parameters
+
+ c->stopPreview();
+
+ CameraParameters param(c->getParameters());
+ param.setPreviewSize(w, h);
+ c->setPreviewCallbackFlag(FRAME_CALLBACK_FLAG_ENABLE_MASK);
+ c->setParameters(param.flatten());
+
+ c->startPreview();
+
+ cc->clearStat();
+ cc->waitData(CAMERA_MSG_PREVIEW_FRAME, MCameraClient::GE, 1);
+ cc->assertDataSize(CAMERA_MSG_PREVIEW_FRAME, MCameraClient::EQ, size);
+ }
+
+ void run() {
+ checkOnePicture(480, 320);
+ checkOnePicture(352, 288);
+ checkOnePicture(176, 144);
+ }
+};
+
+void runHolderService() {
+ defaultServiceManager()->addService(
+ String16("CameraServiceTest.Holder"), new HolderService());
+ ProcessState::self()->startThreadPool();
+}
+
+int main(int argc, char **argv)
+{
+ if (argc != 1) {
+ runFunction(argv[1]);
+ return 0;
+ }
+ INFO("CameraServiceTest start");
+ gExecutable = argv[0];
+ runHolderService();
+
+ testConnect(); flushCommands();
+ testAllowConnectOnceOnly(); flushCommands();
+ testReconnect(); flushCommands();
+ testLockUnlock(); flushCommands();
+ testReconnectFromAnotherProcess(); flushCommands();
+
+ RUN(TestSetPreviewDisplay);
+ RUN(TestStartPreview);
+ RUN(TestStartPreviewWithoutDisplay);
+ RUN(TestAutoFocus);
+ RUN(TestStopPreview);
+ RUN(TestTakePicture);
+ RUN(TestTakeMultiplePictures);
+ RUN(TestGetParameters);
+ RUN(TestPictureSize);
+ RUN(TestPreviewCallbackFlag);
+ RUN(TestRecording);
+ RUN(TestPreviewSize);
+}
diff --git a/cmds/stagefright/Android.mk b/cmds/stagefright/Android.mk
index 5b55252..100af89 100644
--- a/cmds/stagefright/Android.mk
+++ b/cmds/stagefright/Android.mk
@@ -43,4 +43,26 @@
include $(BUILD_EXECUTABLE)
+################################################################################
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= \
+ SineSource.cpp \
+ audioloop.cpp
+
+LOCAL_SHARED_LIBRARIES := \
+ libstagefright
+
+LOCAL_C_INCLUDES:= \
+ $(JNI_H_INCLUDE) \
+ frameworks/base/media/libstagefright \
+ $(TOP)/external/opencore/extern_libs_v2/khronos/openmax/include
+
+LOCAL_CFLAGS += -Wno-multichar
+
+LOCAL_MODULE:= audioloop
+
+include $(BUILD_EXECUTABLE)
+
endif
diff --git a/cmds/stagefright/SineSource.cpp b/cmds/stagefright/SineSource.cpp
index e272a65..021f636 100644
--- a/cmds/stagefright/SineSource.cpp
+++ b/cmds/stagefright/SineSource.cpp
@@ -52,6 +52,7 @@
meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_RAW);
meta->setInt32(kKeyChannelCount, mNumChannels);
meta->setInt32(kKeySampleRate, mSampleRate);
+ meta->setInt32(kKeyMaxInputSize, kBufferSize);
return meta;
}
diff --git a/cmds/stagefright/audioloop.cpp b/cmds/stagefright/audioloop.cpp
new file mode 100644
index 0000000..70ab559
--- /dev/null
+++ b/cmds/stagefright/audioloop.cpp
@@ -0,0 +1,81 @@
+#include "SineSource.h"
+
+#include <binder/ProcessState.h>
+#include <media/stagefright/AudioPlayer.h>
+#include <media/stagefright/MediaDebug.h>
+#include <media/stagefright/MediaDefs.h>
+#include <media/stagefright/MetaData.h>
+#include <media/stagefright/OMXClient.h>
+#include <media/stagefright/OMXCodec.h>
+
+using namespace android;
+
+int main() {
+ // We only have an AMR-WB encoder on sholes...
+ static bool outputWBAMR = false;
+ static const int32_t kSampleRate = outputWBAMR ? 16000 : 8000;
+ static const int32_t kNumChannels = 1;
+
+ android::ProcessState::self()->startThreadPool();
+
+ OMXClient client;
+ CHECK_EQ(client.connect(), OK);
+
+ sp<MediaSource> source = new SineSource(kSampleRate, kNumChannels);
+
+ sp<MetaData> meta = new MetaData;
+
+ meta->setCString(
+ kKeyMIMEType,
+ outputWBAMR ? MEDIA_MIMETYPE_AUDIO_AMR_WB
+ : MEDIA_MIMETYPE_AUDIO_AMR_NB);
+
+ meta->setInt32(kKeyChannelCount, kNumChannels);
+ meta->setInt32(kKeySampleRate, kSampleRate);
+
+ int32_t maxInputSize;
+ if (source->getFormat()->findInt32(kKeyMaxInputSize, &maxInputSize)) {
+ meta->setInt32(kKeyMaxInputSize, maxInputSize);
+ }
+
+ sp<OMXCodec> encoder = OMXCodec::Create(
+ client.interface(),
+ meta, true /* createEncoder */,
+ source);
+
+ sp<OMXCodec> decoder = OMXCodec::Create(
+ client.interface(),
+ meta, false /* createEncoder */,
+ encoder);
+
+#if 1
+ AudioPlayer *player = new AudioPlayer(NULL);
+ player->setSource(decoder);
+
+ player->start();
+
+ sleep(10);
+
+ player->stop();
+
+ delete player;
+ player = NULL;
+#else
+ CHECK_EQ(decoder->start(), OK);
+
+ MediaBuffer *buffer;
+ while (decoder->read(&buffer) == OK) {
+ // do something with buffer
+
+ putchar('.');
+ fflush(stdout);
+
+ buffer->release();
+ buffer = NULL;
+ }
+
+ CHECK_EQ(decoder->stop(), OK);
+#endif
+
+ return 0;
+}
diff --git a/core/java/android/accounts/AccountManagerService.java b/core/java/android/accounts/AccountManagerService.java
index 1a8d9b6..de01153 100644
--- a/core/java/android/accounts/AccountManagerService.java
+++ b/core/java/android/accounts/AccountManagerService.java
@@ -225,6 +225,35 @@
mSimWatcher = new SimWatcher(mContext);
sThis.set(this);
+
+ validateAccounts();
+ }
+
+ private void validateAccounts() {
+ boolean accountDeleted = false;
+ SQLiteDatabase db = mOpenHelper.getWritableDatabase();
+ Cursor cursor = db.query(TABLE_ACCOUNTS,
+ new String[]{ACCOUNTS_ID, ACCOUNTS_TYPE, ACCOUNTS_NAME},
+ null, null, null, null, null);
+ try {
+ while (cursor.moveToNext()) {
+ final long accountId = cursor.getLong(0);
+ final String accountType = cursor.getString(1);
+ final String accountName = cursor.getString(2);
+ if (mAuthenticatorCache.getServiceInfo(AuthenticatorDescription.newKey(accountType))
+ == null) {
+ Log.d(TAG, "deleting account " + accountName + " because type "
+ + accountType + " no longer has a registered authenticator");
+ db.delete(TABLE_ACCOUNTS, ACCOUNTS_ID + "=" + accountId, null);
+ accountDeleted = true;
+ }
+ }
+ } finally {
+ cursor.close();
+ if (accountDeleted) {
+ sendAccountsChangedBroadcast();
+ }
+ }
}
public void onServiceChanged(AuthenticatorDescription desc, boolean removed) {
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index e2030be..03d2a6d 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -1656,21 +1656,19 @@
IPackageStatsObserver observer);
/**
- * Add a new package to the list of preferred packages. This new package
- * will be added to the front of the list (removed from its current location
- * if already listed), meaning it will now be preferred over all other
- * packages when resolving conflicts.
- *
- * @param packageName The package name of the new package to make preferred.
+ * @deprecated This function no longer does anything; it was an old
+ * approach to managing preferred activities, which has been superceeded
+ * (and conflicts with) the modern activity-based preferences.
*/
+ @Deprecated
public abstract void addPackageToPreferred(String packageName);
/**
- * Remove a package from the list of preferred packages. If it was on
- * the list, it will no longer be preferred over other packages.
- *
- * @param packageName The package name to remove.
+ * @deprecated This function no longer does anything; it was an old
+ * approach to managing preferred activities, which has been superceeded
+ * (and conflicts with) the modern activity-based preferences.
*/
+ @Deprecated
public abstract void removePackageFromPreferred(String packageName);
/**
diff --git a/core/java/android/provider/Im.java b/core/java/android/provider/Im.java
index 025d5c2..ff52199 100644
--- a/core/java/android/provider/Im.java
+++ b/core/java/android/provider/Im.java
@@ -879,7 +879,7 @@
* The thread_id column stores the contact id of the contact the message belongs to.
* For groupchat messages, the thread_id stores the group id, which is the contact id
* of the temporary group contact created for the groupchat. So there should be no
- * collision between groupchat message thread id and regular message thread id.
+ * collision between groupchat message thread id and regular message thread id.
*/
String THREAD_ID = "thread_id";
@@ -947,6 +947,12 @@
* <P>Type: INTEGER</P>
*/
String DISPLAY_SENT_TIME = "show_ts";
+
+ /*
+ * For rows which have been consolidated this is the row id of the
+ * row into which they have been consolidated.
+ */
+ String CONSOLIDATION_KEY = "consolidation_key";
}
/**
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index df40946..e826db9 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -1434,6 +1434,13 @@
public static final String SHOW_WEB_SUGGESTIONS = "show_web_suggestions";
/**
+ * Whether the notification LED should repeatedly flash when a notification is
+ * pending. The value is boolean (1 or 0).
+ * @hide
+ */
+ public static final String NOTIFICATION_LIGHT_PULSE = "notification_light_pulse";
+
+ /**
* Settings to backup. This is here so that it's in the same place as the settings
* keys and easy to update.
* @hide
@@ -1487,7 +1494,8 @@
TTY_MODE,
SOUND_EFFECTS_ENABLED,
HAPTIC_FEEDBACK_ENABLED,
- SHOW_WEB_SUGGESTIONS
+ SHOW_WEB_SUGGESTIONS,
+ NOTIFICATION_LIGHT_PULSE
};
// Settings moved to Settings.Secure
diff --git a/core/java/android/text/method/Touch.java b/core/java/android/text/method/Touch.java
index 6995107..aa8d979 100644
--- a/core/java/android/text/method/Touch.java
+++ b/core/java/android/text/method/Touch.java
@@ -20,6 +20,7 @@
import android.text.NoCopySpan;
import android.text.Layout.Alignment;
import android.text.Spannable;
+import android.util.Log;
import android.view.MotionEvent;
import android.view.ViewConfiguration;
import android.widget.TextView;
@@ -156,8 +157,17 @@
padding));
ny = Math.max(ny, 0);
+ int oldX = widget.getScrollX();
+ int oldY = widget.getScrollY();
+
scrollTo(widget, layout, nx, ny);
- widget.cancelLongPress();
+
+ // If we actually scrolled, then cancel the up action.
+ if (oldX != widget.getScrollX()
+ || oldY != widget.getScrollY()) {
+ widget.cancelLongPress();
+ }
+
return true;
}
}
diff --git a/core/java/android/webkit/BrowserFrame.java b/core/java/android/webkit/BrowserFrame.java
index e6e26fa..1496f1b 100644
--- a/core/java/android/webkit/BrowserFrame.java
+++ b/core/java/android/webkit/BrowserFrame.java
@@ -105,10 +105,13 @@
*/
public BrowserFrame(Context context, WebViewCore w, CallbackProxy proxy,
WebSettings settings, Map<String, Object> javascriptInterfaces) {
+
+ Context appContext = context.getApplicationContext();
+
// Create a global JWebCoreJavaBridge to handle timers and
// cookies in the WebCore thread.
if (sJavaBridge == null) {
- sJavaBridge = new JWebCoreJavaBridge(context);
+ sJavaBridge = new JWebCoreJavaBridge(appContext);
// set WebCore native cache size
ActivityManager am = (ActivityManager) context
.getSystemService(Context.ACTIVITY_SERVICE);
@@ -118,18 +121,18 @@
sJavaBridge.setCacheSize(4 * 1024 * 1024);
}
// initialize CacheManager
- CacheManager.init(context);
+ CacheManager.init(appContext);
// create CookieSyncManager with current Context
- CookieSyncManager.createInstance(context);
+ CookieSyncManager.createInstance(appContext);
// create PluginManager with current Context
- PluginManager.getInstance(context);
+ PluginManager.getInstance(appContext);
}
mJSInterfaceMap = javascriptInterfaces;
mSettings = settings;
mContext = context;
mCallbackProxy = proxy;
- mDatabase = WebViewDatabase.getInstance(context);
+ mDatabase = WebViewDatabase.getInstance(appContext);
mWebViewCore = w;
AssetManager am = context.getAssets();
@@ -496,7 +499,7 @@
* @param uri A String representing the URI of the desired file.
* @param buffer The byte array to copy the data into.
* @param offset The offet into buffer to place the data.
- * @param expectSize The size that the buffer has allocated for this file.
+ * @param expectedSize The size that the buffer has allocated for this file.
* @return int The size of the given file, or zero if it fails.
*/
private int getFile(String uri, byte[] buffer, int offset,
diff --git a/core/java/android/webkit/CacheManager.java b/core/java/android/webkit/CacheManager.java
index c167414..c4e26bc 100644
--- a/core/java/android/webkit/CacheManager.java
+++ b/core/java/android/webkit/CacheManager.java
@@ -167,7 +167,7 @@
* @param context The application context.
*/
static void init(Context context) {
- mDataBase = WebViewDatabase.getInstance(context);
+ mDataBase = WebViewDatabase.getInstance(context.getApplicationContext());
mBaseDir = new File(context.getCacheDir(), "webviewCache");
if (createCacheDirectory() && mClearCacheOnInit) {
removeAllCacheFiles();
diff --git a/core/java/android/webkit/CookieSyncManager.java b/core/java/android/webkit/CookieSyncManager.java
index 14375d2..abe9178 100644
--- a/core/java/android/webkit/CookieSyncManager.java
+++ b/core/java/android/webkit/CookieSyncManager.java
@@ -93,7 +93,7 @@
public static synchronized CookieSyncManager createInstance(
Context context) {
if (sRef == null) {
- sRef = new CookieSyncManager(context);
+ sRef = new CookieSyncManager(context.getApplicationContext());
}
return sRef;
}
diff --git a/core/java/android/webkit/PluginManager.java b/core/java/android/webkit/PluginManager.java
index 88429c5..141984a 100644
--- a/core/java/android/webkit/PluginManager.java
+++ b/core/java/android/webkit/PluginManager.java
@@ -96,7 +96,7 @@
throw new IllegalStateException(
"First call to PluginManager need a valid context.");
}
- mInstance = new PluginManager(context);
+ mInstance = new PluginManager(context.getApplicationContext());
}
return mInstance;
}
diff --git a/core/java/android/webkit/WebSettings.java b/core/java/android/webkit/WebSettings.java
index 8e40b23..d5bb572 100644
--- a/core/java/android/webkit/WebSettings.java
+++ b/core/java/android/webkit/WebSettings.java
@@ -152,6 +152,7 @@
private int mMinimumLogicalFontSize = 8;
private int mDefaultFontSize = 16;
private int mDefaultFixedFontSize = 13;
+ private int mPageCacheCapacity = 0;
private boolean mLoadsImagesAutomatically = true;
private boolean mBlockNetworkImage = false;
private boolean mBlockNetworkLoads;
@@ -879,6 +880,20 @@
}
/**
+ * Set the number of pages cached by the WebKit for the history navigation.
+ * @param size A non-negative integer between 0 (no cache) and 20 (max).
+ * @hide
+ */
+ public synchronized void setPageCacheCapacity(int size) {
+ if (size < 0) size = 0;
+ if (size > 20) size = 20;
+ if (mPageCacheCapacity != size) {
+ mPageCacheCapacity = size;
+ postSync();
+ }
+ }
+
+ /**
* Tell the WebView to load image resources automatically.
* @param flag True if the WebView should load images automatically.
*/
diff --git a/core/java/android/webkit/WebTextView.java b/core/java/android/webkit/WebTextView.java
index 412e0d9..f04b04f 100644
--- a/core/java/android/webkit/WebTextView.java
+++ b/core/java/android/webkit/WebTextView.java
@@ -644,7 +644,22 @@
/* package */ void setDefaultSelection() {
Spannable text = (Spannable) getText();
int selection = mSingle ? text.length() : 0;
- Selection. setSelection(text, selection, selection);
+ if (Selection.getSelectionStart(text) == selection
+ && Selection.getSelectionEnd(text) == selection) {
+ // The selection of the UI copy is set correctly, but the
+ // WebTextView still needs to inform the webkit thread to set the
+ // selection. Normally that is done in onSelectionChanged, but
+ // onSelectionChanged will not be called because the UI copy is not
+ // changing. (This can happen when the WebTextView takes focus.
+ // That onSelectionChanged was blocked because the selection set
+ // when focusing is not necessarily the desirable selection for
+ // WebTextView.)
+ if (mWebView != null) {
+ mWebView.setSelection(selection, selection);
+ }
+ } else {
+ Selection.setSelection(text, selection, selection);
+ }
}
/**
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 3207c79..7885b8a 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -732,7 +732,7 @@
/**
* Construct a new WebView with layout parameters, a default style and a set
* of custom Javscript interfaces to be added to the WebView at initialization
- * time. This guraratees that these interfaces will be available when the JS
+ * time. This guarantees that these interfaces will be available when the JS
* context is initialized.
* @param context A Context object used to access application assets.
* @param attrs An AttributeSet passed to our parent.
@@ -3241,24 +3241,29 @@
mWebTextView.setNodePointer(nodePointer);
int maxLength = -1;
boolean isTextField = nativeFocusCandidateIsTextField();
+ boolean isPassword;
if (isTextField) {
maxLength = nativeFocusCandidateMaxLength();
String name = nativeFocusCandidateName();
- if (mWebViewCore.getSettings().getSaveFormData()
- && name != null) {
+ isPassword = nativeFocusCandidateIsPassword();
+ if (!isPassword && mWebViewCore.getSettings().getSaveFormData()
+ && name != null && name.length() > 0) {
Message update = mPrivateHandler.obtainMessage(
- REQUEST_FORM_DATA, nodePointer);
+ REQUEST_FORM_DATA);
+ update.arg1 = nodePointer;
RequestFormData updater = new RequestFormData(name,
getUrl(), update);
Thread t = new Thread(updater);
t.start();
}
+ } else {
+ isPassword = false;
}
mWebTextView.setMaxLength(maxLength);
AutoCompleteAdapter adapter = null;
mWebTextView.setAdapterCustom(adapter);
mWebTextView.setSingleLine(isTextField);
- mWebTextView.setInPassword(nativeFocusCandidateIsPassword());
+ mWebTextView.setInPassword(isPassword);
if (null == text) {
if (DebugFlags.WEB_VIEW) {
Log.v(LOGTAG, "rebuildWebTextView null == text");
@@ -3990,6 +3995,13 @@
}
mTouchMode = TOUCH_DRAG_MODE;
+ mLastTouchX = x;
+ mLastTouchY = y;
+ fDeltaX = 0.0f;
+ fDeltaY = 0.0f;
+ deltaX = 0;
+ deltaY = 0;
+
WebViewCore.pauseUpdate(mWebViewCore);
if (!mDragFromTextInput) {
nativeHideCursor();
diff --git a/core/java/android/widget/ScrollView.java b/core/java/android/widget/ScrollView.java
index 24d97a5..bf16e28 100644
--- a/core/java/android/widget/ScrollView.java
+++ b/core/java/android/widget/ScrollView.java
@@ -51,8 +51,6 @@
* <p>ScrollView only supports vertical scrolling.
*/
public class ScrollView extends FrameLayout {
- static final String TAG = "ScrollView";
-
static final int ANIMATED_SCROLL_GAP = 250;
static final float MAX_SCROLL_FACTOR = 0.5f;
@@ -401,6 +399,7 @@
final int yDiff = (int) Math.abs(y - mLastMotionY);
if (yDiff > mTouchSlop) {
mIsBeingDragged = true;
+ mLastMotionY = y;
}
break;
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index f55ca3f..201cc0c 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -6529,6 +6529,7 @@
// Reset this state; it will be re-set if super.onTouchEvent
// causes focus to move to the view.
mTouchFocusSelected = false;
+ mScrolled = false;
}
final boolean superResult = super.onTouchEvent(event);
@@ -6545,10 +6546,6 @@
if ((mMovement != null || onCheckIsTextEditor()) && mText instanceof Spannable && mLayout != null) {
- if (action == MotionEvent.ACTION_DOWN) {
- mScrolled = false;
- }
-
boolean handled = false;
int oldSelStart = Selection.getSelectionStart(mText);
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 8047436..4a7adcc 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -597,11 +597,9 @@
android:label="@string/permlab_getPackageSize"
android:description="@string/permdesc_getPackageSize" />
- <!-- Allows an application to modify the list of preferred applications
- with the {@link android.content.pm.PackageManager#addPackageToPreferred
- PackageManager.addPackageToPreferred()} and
- {@link android.content.pm.PackageManager#removePackageFromPreferred
- PackageManager.removePackageFromPreferred()} methods. -->
+ <!-- @deprecated No longer useful, see
+ {@link android.content.pm.PackageManager#addPackageToPreferred}
+ for details. -->
<permission android:name="android.permission.SET_PREFERRED_APPLICATIONS"
android:permissionGroup="android.permission-group.SYSTEM_TOOLS"
android:protectionLevel="dangerous"
diff --git a/docs/html/guide/appendix/api-levels.jd b/docs/html/guide/appendix/api-levels.jd
index 5487487..2c255a99 100644
--- a/docs/html/guide/appendix/api-levels.jd
+++ b/docs/html/guide/appendix/api-levels.jd
@@ -123,7 +123,9 @@
API Level, rather than being restricted to using only those defined
for the minimum API Level.</li>
<li><code>android:maxSdkVersion</code> — Specifies the maximum API Level
-on which the application is able to run.</li>
+on which the application is able to run. <strong>Important:</strong> Please read the <a
+href="{@docRoot}guide/topics/manifest/uses-sdk-element.html"><code><uses-sdk></code></a>
+documentation before using this attribute. </li>
</ul>
<p>For example, to specify the minimum system API Level that an application
@@ -133,10 +135,11 @@
corresponding to the API Level of the earliest version of the Android platform
under which the application can run. </p>
-<p>When the user attempts to install an application, the Android system first
-checks the <code><uses-sdk></code> attributes in the application's
-manifest and compares them against its own internal API Level. The system
-allows the installation to begin only if these conditions are met:</p>
+<p>When the user attempts to install an application, or when revalidating an
+appplication after a system update, the Android system first checks the
+<code><uses-sdk></code> attributes in the application's manifest and
+compares the values against its own internal API Level. The system allows the
+installation to begin only if these conditions are met:</p>
<ul>
<li>If a <code>android:minSdkVersion</code> attribute is declared, its value
@@ -145,7 +148,9 @@
<li>If a <code>android:maxSdkVersion</code> attribute is declared, its value
must be equal to or greater than the system's API Level integer.
If not declared, the system assumes that the application
-has no maximum API Level. </li>
+has no maximum API Level. Please read the <a
+href="{@docRoot}guide/topics/manifest/uses-sdk-element.html"><code><uses-sdk></code></a>
+documentation for more information about how the system handles this attribute.</li>
</ul>
<p>When declared in an application's manifest, a <code><uses-sdk></code>
diff --git a/docs/html/guide/publishing/versioning.jd b/docs/html/guide/publishing/versioning.jd
index 0bec658..e2ee684 100644
--- a/docs/html/guide/publishing/versioning.jd
+++ b/docs/html/guide/publishing/versioning.jd
@@ -141,9 +141,16 @@
<li><code>android:minSdkVersion</code> — The minimum version
of the Android platform on which the application will run, specified
by the platform's API Level identifier. </li>
+<li><code>android:targetSdkVersion</code> — Specifies the API Level
+on which the application is designed to run. In some cases, this allows the
+application to use manifest elements or behaviors defined in the target
+API Level, rather than being restricted to using only those defined
+for the minimum API Level.</li>
<li><code>android:maxSdkVersion</code> — The maximum version
of the Android platform on which the application is designed to run,
-specified by the platform's API Level identifier. </li>
+specified by the platform's API Level identifier. <strong>Important:</strong> Please read the <a
+href="{@docRoot}guide/topics/manifest/uses-sdk-element.html"><code><uses-sdk></code></a>
+documentation before using this attribute. </li>
</ul>
<p>When preparing to install your application, the system checks the value of this
diff --git a/docs/html/guide/samples/images/BluetoothChat1.png b/docs/html/guide/samples/images/BluetoothChat1.png
new file mode 100644
index 0000000..f87da6a
--- /dev/null
+++ b/docs/html/guide/samples/images/BluetoothChat1.png
Binary files differ
diff --git a/docs/html/guide/samples/images/BluetoothChat2.png b/docs/html/guide/samples/images/BluetoothChat2.png
new file mode 100644
index 0000000..6218eff
--- /dev/null
+++ b/docs/html/guide/samples/images/BluetoothChat2.png
Binary files differ
diff --git a/docs/html/guide/topics/manifest/supports-screens-element.jd b/docs/html/guide/topics/manifest/supports-screens-element.jd
index 3fb0172..5494320 100644
--- a/docs/html/guide/topics/manifest/supports-screens-element.jd
+++ b/docs/html/guide/topics/manifest/supports-screens-element.jd
@@ -84,7 +84,7 @@
<dt>see also:</dt>
<dd>
<ul>
- <li><a href="{@docRoot}guide/practices/screens_suppport.html">Multiple Screens Support</a></li>
+ <li><a href="{@docRoot}guide/practices/screens_support.html">Multiple Screens Support</a></li>
<li>{@link android.util.DisplayMetrics}</li>
</ul>
</dd>
diff --git a/docs/html/guide/topics/manifest/uses-sdk-element.jd b/docs/html/guide/topics/manifest/uses-sdk-element.jd
index aa1e8ae..f8aff1e 100644
--- a/docs/html/guide/topics/manifest/uses-sdk-element.jd
+++ b/docs/html/guide/topics/manifest/uses-sdk-element.jd
@@ -5,8 +5,8 @@
<dt>syntax:</dt>
<dd><pre>
<uses-sdk android:<a href="#min">minSdkVersion</a>="<i>integer</i>"
- android:<a href="#max">maxSdkVersion</a>="<i>integer</i>"
- android:<a href="#target">targetSdkVersion</a>="<i>integer</i>" /></pre></dd>
+ android:<a href="#target">targetSdkVersion</a>="<i>integer</i>"
+ android:<a href="#max">maxSdkVersion</a>="<i>integer</i>" /></pre></dd>
<dt>contained in:</dt>
<dd><code><a href="{@docRoot}guide/topics/manifest/manifest-element.html"><manifest></a></code></dd>
@@ -17,19 +17,31 @@
API Level of a given Android system, which may vary among different Android devices.
</p>
-<p>
-Despite its name, this element is used to specify the API Level, <em>not</em> the
-version number of the SDK (software development kit). The API Level is always
-a single integer; the SDK version may be split into major and minor components
-(such as 1.5). You cannot derive the API Level from the SDK version number
-(for example, it is not the same as the major version or the sum of the major
-and minor versions).</p>
+<p>Despite its name, this element is used to specify the API Level, <em>not</em>
+the version number of the SDK (software development kit) or Android platform.
+The API Level is always a single integer. You cannot derive the API Level from
+its associated Android version number (for example, it is not the same as the
+major version or the sum of the major and minor versions).</p>
<p>For more information, read about
<a href="{@docRoot}guide/appendix/api-levels.html">Android API Levels</a> and
<a href="{@docRoot}guide/publishing/versioning.html">Versioning Your Applications</a>.
</p></dd>
+ <div class="sidebox-wrapper" xstyle="margin-bottom:2em;margin-top:.5em;width:90%;">
+ <img id="rule" src="{@docRoot}assets/images/grad-rule-qv.png">
+ <div id="qv-sub-rule">
+ <img src="{@docRoot}assets/images/icon_market.jpg" style="float:left;margin:0;padding:0;">
+ <p style="color:#669999;">Android Market and <uses-sdk> attributes</p>
+ <p>Android Market filters the applications that are visible to users, so
+that users can only see and download applications that are compatible with their
+devices. One of the ways Market filters applications is by Android
+version-compatibility. To do this, Market checks the <code><uses-sdk></code>
+attributes in each application's manifest to establish its version-compatibility
+range, then shows or hides the application based on a comparison with the API
+Level of the user's Android system version. </p>
+ </div>
+</div>
<dt>attributes:</dt>
@@ -40,44 +52,86 @@
for the application to run. The Android system will prevent the user from installing
the application if the system's API Level is lower than the value specified in
this attribute. You should always declare this attribute.
-
- <p class="caution"><strong>Caution:</strong>
- If you do not declare this attribute, then a value of "1" is assumed, which
- indicates that your application is compatible with all versions of Android. If your
- application is <em>not</em> compatible with all versions (for instance, it uses APIs
- introduced in API Level 3) and you have not declared the proper <code>minSdkVersion</code>,
- then when installed on a system with an API Level less than 3, the application will crash
- during runtime when attempting to access the unavailable APIs. For this reason,
- be certain to declare the appropriate API Level
- in the <code>minSdkVersion</code> attribute.</p>
+
+ <p class="caution"><strong>Caution:</strong> If you do not declare this
+ attribute, the system assumes a default value of "1", which indicates that your
+ application is compatible with all versions of Android. If your application is
+ <em>not</em> compatible with all versions (for instance, it uses APIs introduced
+ in API Level 3) and you have not declared the proper <code>android:minSdkVersion</code>,
+ then when installed on a system with an API Level less than 3, the application
+ will crash during runtime when attempting to access the unavailable APIs. For
+ this reason, be certain to declare the appropriate API Level in the
+ <code>minSdkVersion</code> attribute.</p>
</dd>
-
- <dt><a name="max"></a>{@code android:maxSdkVersion}</dt>
- <dd>An integer designating the maximum API Level on which the application is
- designed to run. The Android system will prevent the user from installing the
- application if the system's API Level is higher than the value specified
- in this attribute.
-
- <p>Introduced in: API Level 4</p>
- </dd>
-
+
<dt><a name="target"></a>{@code android:targetSdkVersion}</dt>
<dd>An integer designating the API Level that the application is targetting.
-
- <p>With this attribute set, the application says that it is able to run on
- older versions (down to {@code minSdkVersion}), but was explicitly tested to work
- with the version specified here.
- Specifying this target version allows the platform to disable compatibility
- settings that are not required for the target version (which may otherwise be turned on
- in order to maintain forward-compatibility) or enable newer features that are not
- available to older applications. This does not mean that you can program different
- features for different versions of the platform—it simply informs the platform that you
- have tested against the target version and the platform should not perform any extra
- work to maintain forward-compatibility with the target version.</p>
-
+
+ <p>With this attribute set, the application says that it is able to run on
+ older versions (down to {@code minSdkVersion}), but was explicitly tested to
+ work with the version specified here. Specifying this target version allows the
+ platform to disable compatibility settings that are not required for the target
+ version (which may otherwise be turned on in order to maintain
+ forward-compatibility) or enable newer features that are not available to older
+ applications. This does not mean that you can program different features for
+ different versions of the platform—it simply informs the platform that you
+ have tested against the target version and the platform should not perform any
+ extra work to maintain forward-compatibility with the target version.</p>
+
<p>Introduced in: API Level 4</p>
</dd>
+ <dt><a name="max"></a>{@code android:maxSdkVersion}</dt>
+ <dd>An integer designating the maximum API Level on which the application is
+ designed to run.
+
+ <p>In Android 1.5, 1.6, 2.0, and 2.0.1, the system checks the value of this
+ attribute when installing an application and when revalidating the application
+ after a system update. In either case, if the application's
+ <code>android:maxSdkVersion</code> attribute is lower than the API Level used by
+ the system itself, then the system will not allow the application to be
+ installed. In the case of revalidation after system update, this effectively
+ removes your application from the device.
+
+ <p>To illustrate how this attribute can affect your application after system
+ updates, consider the following example: </p>
+
+ <p>An application declaring <code>android:maxSdkVersion="5"</code> in its
+ manifest is published on Android Market. A user whose device is running Android
+ 1.6 (API Level 4) downloads and installs the app. After a few weeks, the user
+ receives an over-the-air system update to Android 2.0 (API Level 5). After the
+ update is installed, the system checks the application's
+ <code>android:maxSdkVersion</code> and successfully revalidates it. The
+ application functions as normal. However, some time later, the device receives
+ another system update, this time to Android 2.0.1 (API Level 6). After the
+ update, the system can no longer revalidate the application because the system's
+ own API Level (6) is now higher than the maximum supported by the application
+ (5). The system prevents the application from being visible to the user, in
+ effect removing it from the device.</p>
+
+ <p class="warning"><strong>Warning:</strong> Declaring this attribute is not
+ recommended. First, there is no need to set the attribute as means of blocking
+ deployment of your application onto new versions of the Android platform as they
+ are released. By design, new versions of the platform are fully
+ backward-compatible. Your application should work properly on new versions,
+ provided it uses only standard APIs and follows development best practices.
+ Second, note that in some cases, declaring the attribute can <strong>result in
+ your application being removed from users' devices after a system
+ update</strong> to a higher API Level. Most devices on which your appplication
+ is likely to be installed will receive periodic system updates over the air, so
+ you should consider their effect on your application before setting this
+ attribute.</p>
+
+ <p style="margin-bottom:1em;">Introduced in: API Level 4</p>
+
+ <div class="special">Future versions of Android (beyond Android 2.0.1) will no
+longer check or enforce the <code>android:maxSdkVersion</code> attribute during
+installation or revalidation. Android Market will continue to use the attribute
+as a filter, however, when presenting users with applications available for
+download. </div>
+ </dd>
+
+
</dl></dd>
<!-- ##api level indication## -->
diff --git a/docs/html/sdk/android-1.6.jd b/docs/html/sdk/android-1.6.jd
index 646b61d..7151325 100644
--- a/docs/html/sdk/android-1.6.jd
+++ b/docs/html/sdk/android-1.6.jd
@@ -74,7 +74,7 @@
<p>API related:</p>
<ul>
-<li>Properly exposes CDMA-related constants {@link android.telephony.TelephonyManager}: <code>DATA_ACTIVITY_DORMANT</code>,
+<li>Properly exposes CDMA-related constants in {@link android.telephony.TelephonyManager android.telephony.TelephonyManager}: <code>DATA_ACTIVITY_DORMANT</code>,
<code>PHONE_TYPE_CDMA</code>, <code>NETWORK_TYPE_CDMA</code>,
<code>NETWORK_TYPE_EVDO_0</code>, <code>NETWORK_TYPE_EVDO_A</code>, and
<code>NETWORK_TYPE_1xRTT</code>.</li>
@@ -362,15 +362,15 @@
<li>New attributes for the
<a href="{@docRoot}guide/topics/manifest/uses-sdk-element.html">{@code <uses-sdk>}</a> element:
<ul>
- <li><code>maxSdkVersion</code>: This indicates the maximum API Level on which an application is
- designed to run. If an application declares this attribute, the Android system prevents the user
- from installing the application if the system's API Level is higher than the value specified in
- this attribute. </li>
- <li><code>targetSdkVersion</code>: This indicates the API Level that the application is targeting.
+ <li><code>targetSdkVersion</code>: Indicates the API Level that the application is targeting.
It is able to run on older versions (down to minSdkVersion), but was explicitly tested to
work with the version specified here. Specifying this version allows the platform to
disable compatibility code that is not required or enable newer features that are not
available to older applications. </li>
+ <li><code>maxSdkVersion</code>: Indicates the maximum API Level on which an application is
+ designed to run. <strong>Important:</strong> Please read the <a
+ href="{@docRoot}guide/topics/manifest/uses-sdk-element.html"><code><uses-sdk></code></a>
+ documentation before using this attribute. </li>
</ul>
</li>
diff --git a/docs/html/sdk/android-2.0.1.jd b/docs/html/sdk/android-2.0.1.jd
index f5df1ac..fbce45e 100644
--- a/docs/html/sdk/android-2.0.1.jd
+++ b/docs/html/sdk/android-2.0.1.jd
@@ -287,8 +287,6 @@
<h4>Other Framework fixes</h4>
<ul>
-<li>{@link android.content.res.Resources#getDisplayMetrics()} now properly
-reports the screen DPI for the Verizon Droid.</li>
<li>{@link android.app.Activity#getCallingPackage()} now properly reports the
package name, rather than the process name.</li>
</ul>
diff --git a/docs/html/sdk/index.jd b/docs/html/sdk/index.jd
index fd0576a..6ca02b6 100644
--- a/docs/html/sdk/index.jd
+++ b/docs/html/sdk/index.jd
@@ -3,15 +3,15 @@
sdk.version=2.0.1
sdk.date=December 2009
-sdk.win_download=android-sdk_r4-windows.zip
+sdk.win_download=android-sdk_r04-windows.zip
sdk.win_bytes=23069119
sdk.win_checksum=c48b407de852ba483869f17337e90997
-sdk.mac_download=android-sdk_r4-mac.zip
+sdk.mac_download=android-sdk_r04-mac_86.zip
sdk.mac_bytes=19657927
sdk.mac_checksum=b08512765aa9b0369bb9b8fecdf763e3
-sdk.linux_download=android-sdk_r4-linux.tgz
+sdk.linux_download=android-sdk_r04-linux_86.tgz
sdk.linux_bytes=15984887
sdk.linux_checksum=ef84b08fd9da84f4c4ae77564fe4eaee
diff --git a/include/media/stagefright/OMXCodec.h b/include/media/stagefright/OMXCodec.h
index 4c60623..4199252 100644
--- a/include/media/stagefright/OMXCodec.h
+++ b/include/media/stagefright/OMXCodec.h
@@ -146,8 +146,7 @@
void setComponentRole();
- void setAMRFormat();
- void setAMRWBFormat();
+ void setAMRFormat(bool isWAMR);
void setAACFormat(int32_t numChannels, int32_t sampleRate);
status_t setVideoPortFormatType(
diff --git a/libs/audioflinger/AudioFlinger.cpp b/libs/audioflinger/AudioFlinger.cpp
index daec6e8..9ec8de5 100644
--- a/libs/audioflinger/AudioFlinger.cpp
+++ b/libs/audioflinger/AudioFlinger.cpp
@@ -2277,10 +2277,8 @@
LOGV("PlaybackThread::Track destructor");
sp<ThreadBase> thread = mThread.promote();
if (thread != 0) {
- thread->mLock.lock();
+ Mutex::Autolock _l(thread->mLock);
mState = TERMINATED;
- thread->mLock.unlock();
- AudioSystem::releaseOutput(thread->id());
}
}
@@ -2298,8 +2296,11 @@
{ // scope for mLock
sp<ThreadBase> thread = mThread.promote();
if (thread != 0) {
- if (!isOutputTrack() && (mState == ACTIVE || mState == RESUMING)) {
- AudioSystem::stopOutput(thread->id(), (AudioSystem::stream_type)mStreamType);
+ if (!isOutputTrack()) {
+ if (mState == ACTIVE || mState == RESUMING) {
+ AudioSystem::stopOutput(thread->id(), (AudioSystem::stream_type)mStreamType);
+ }
+ AudioSystem::releaseOutput(thread->id());
}
Mutex::Autolock _l(thread->mLock);
PlaybackThread *playbackThread = (PlaybackThread *)thread.get();
diff --git a/libs/surfaceflinger/Layer.cpp b/libs/surfaceflinger/Layer.cpp
index f5a5a0b..f11bf18 100644
--- a/libs/surfaceflinger/Layer.cpp
+++ b/libs/surfaceflinger/Layer.cpp
@@ -515,6 +515,11 @@
dirtyRegion.andSelf(visibleRegionScreen);
outDirtyRegion.orSelf(dirtyRegion);
}
+ if (visibleRegionScreen.isEmpty()) {
+ // an invisible layer should not hold a freeze-lock
+ // (because it may never be updated and thereore never release it)
+ mFreezeLock.clear();
+ }
}
void Layer::finishPageFlip()
diff --git a/libs/surfaceflinger/LayerBuffer.cpp b/libs/surfaceflinger/LayerBuffer.cpp
index 88ef7e4..eb017bf 100644
--- a/libs/surfaceflinger/LayerBuffer.cpp
+++ b/libs/surfaceflinger/LayerBuffer.cpp
@@ -266,7 +266,16 @@
: mBufferHeap(buffers)
{
NativeBuffer& src(mNativeBuffer);
- src.img.handle = 0;
+ src.crop.l = 0;
+ src.crop.t = 0;
+ src.crop.r = buffers.w;
+ src.crop.b = buffers.h;
+
+ src.img.w = buffers.hor_stride ?: buffers.w;
+ src.img.h = buffers.ver_stride ?: buffers.h;
+ src.img.format = buffers.format;
+ src.img.base = (void*)(intptr_t(buffers.heap->base()) + offset);
+ src.img.handle = 0;
gralloc_module_t const * module = LayerBuffer::getGrallocModule();
if (module && module->perform) {
@@ -276,19 +285,12 @@
offset, buffers.heap->base(),
&src.img.handle);
- if (err == NO_ERROR) {
- src.crop.l = 0;
- src.crop.t = 0;
- src.crop.r = buffers.w;
- src.crop.b = buffers.h;
-
- src.img.w = buffers.hor_stride ?: buffers.w;
- src.img.h = buffers.ver_stride ?: buffers.h;
- src.img.format = buffers.format;
- src.img.base = (void*)(intptr_t(buffers.heap->base()) + offset);
- }
+ LOGE_IF(err, "CREATE_HANDLE_FROM_BUFFER (heapId=%d, size=%d, "
+ "offset=%ld, base=%p) failed (%s)",
+ buffers.heap->heapID(), buffers.heap->getSize(),
+ offset, buffers.heap->base(), strerror(-err));
}
-}
+ }
LayerBuffer::Buffer::~Buffer()
{
diff --git a/libs/surfaceflinger/SurfaceFlinger.cpp b/libs/surfaceflinger/SurfaceFlinger.cpp
index 9694cf1..965b7dd 100644
--- a/libs/surfaceflinger/SurfaceFlinger.cpp
+++ b/libs/surfaceflinger/SurfaceFlinger.cpp
@@ -417,9 +417,9 @@
{
while (true) {
nsecs_t timeout = -1;
+ const nsecs_t freezeDisplayTimeout = ms2ns(5000);
if (UNLIKELY(isFrozen())) {
// wait 5 seconds
- const nsecs_t freezeDisplayTimeout = ms2ns(5000);
const nsecs_t now = systemTime();
if (mFreezeDisplayTime == 0) {
mFreezeDisplayTime = now;
@@ -429,23 +429,27 @@
}
MessageList::value_type msg = mEventQueue.waitMessage(timeout);
+
+ // see if we timed out
+ if (isFrozen()) {
+ const nsecs_t now = systemTime();
+ nsecs_t frozenTime = (now - mFreezeDisplayTime);
+ if (frozenTime >= freezeDisplayTimeout) {
+ // we timed out and are still frozen
+ LOGW("timeout expired mFreezeDisplay=%d, mFreezeCount=%d",
+ mFreezeDisplay, mFreezeCount);
+ mFreezeDisplayTime = 0;
+ mFreezeCount = 0;
+ mFreezeDisplay = false;
+ }
+ }
+
if (msg != 0) {
- mFreezeDisplayTime = 0;
switch (msg->what) {
case MessageQueue::INVALIDATE:
// invalidate message, just return to the main loop
return;
}
- } else {
- // we timed out
- if (isFrozen()) {
- // we timed out and are still frozen
- LOGW("timeout expired mFreezeDisplay=%d, mFreezeCount=%d",
- mFreezeDisplay, mFreezeCount);
- mFreezeCount = 0;
- mFreezeDisplay = false;
- return;
- }
}
}
}
@@ -1646,6 +1650,7 @@
}
case 1007: // set mFreezeCount
mFreezeCount = data.readInt32();
+ mFreezeDisplayTime = 0;
return NO_ERROR;
case 1010: // interrogate.
reply->writeInt32(0);
diff --git a/libs/surfaceflinger/SurfaceFlinger.h b/libs/surfaceflinger/SurfaceFlinger.h
index f9bfe6c..c0ab73d 100644
--- a/libs/surfaceflinger/SurfaceFlinger.h
+++ b/libs/surfaceflinger/SurfaceFlinger.h
@@ -291,7 +291,11 @@
friend class FreezeLock;
sp<FreezeLock> getFreezeLock() const;
- inline void incFreezeCount() { mFreezeCount++; }
+ inline void incFreezeCount() {
+ if (mFreezeCount == 0)
+ mFreezeDisplayTime = 0;
+ mFreezeCount++;
+ }
inline void decFreezeCount() { if (mFreezeCount > 0) mFreezeCount--; }
inline bool hasFreezeRequest() const { return mFreezeDisplay; }
inline bool isFrozen() const {
diff --git a/media/java/android/media/MediaScanner.java b/media/java/android/media/MediaScanner.java
index da25f97..079b4c3 100644
--- a/media/java/android/media/MediaScanner.java
+++ b/media/java/android/media/MediaScanner.java
@@ -640,13 +640,13 @@
map.put(Video.Media.ARTIST, (mArtist != null && mArtist.length() > 0 ? mArtist : MediaFile.UNKNOWN_STRING));
map.put(Video.Media.ALBUM, (mAlbum != null && mAlbum.length() > 0 ? mAlbum : MediaFile.UNKNOWN_STRING));
map.put(Video.Media.DURATION, mDuration);
- map.put(Video.Media.DATE_TAKEN, mLastModified);
+ map.put(Video.Media.DATE_TAKEN, mLastModified * 1000);
// FIXME - add RESOLUTION
} else if (MediaFile.isImageFileType(mFileType)) {
// FIXME - add DESCRIPTION
// DATE_TAKEN will be overridden later if this is a JPEG image whose EXIF data
// contains date time information.
- map.put(Images.Media.DATE_TAKEN, mLastModified);
+ map.put(Images.Media.DATE_TAKEN, mLastModified * 1000);
} else if (MediaFile.isAudioFileType(mFileType)) {
map.put(Audio.Media.ARTIST, (mArtist != null && mArtist.length() > 0 ? mArtist : MediaFile.UNKNOWN_STRING));
map.put(Audio.Media.ALBUM, (mAlbum != null && mAlbum.length() > 0 ? mAlbum : MediaFile.UNKNOWN_STRING));
@@ -746,7 +746,7 @@
long time = exif.getDateTime();
if (time != -1) {
- values.put(Images.Media.DATE_TAKEN, time);
+ values.put(Images.Media.DATE_TAKEN, time * 1000);
}
int orientation = exif.getAttributeInt(
diff --git a/media/java/android/media/Ringtone.java b/media/java/android/media/Ringtone.java
index 1713324..0ce3526 100644
--- a/media/java/android/media/Ringtone.java
+++ b/media/java/android/media/Ringtone.java
@@ -63,11 +63,13 @@
private AssetFileDescriptor mAssetFileDescriptor;
private int mStreamType = AudioManager.STREAM_RING;
+ private AudioManager mAudioManager;
private Context mContext;
Ringtone(Context context) {
mContext = context;
+ mAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
}
/**
@@ -215,7 +217,11 @@
}
}
if (mAudio != null) {
- mAudio.start();
+ // do not ringtones if stream volume is 0
+ // (typically because ringer mode is silent).
+ if (mAudioManager.getStreamVolume(mStreamType) != 0) {
+ mAudio.start();
+ }
}
}
diff --git a/media/libstagefright/OMXCodec.cpp b/media/libstagefright/OMXCodec.cpp
index c5e935d0..670f748 100644
--- a/media/libstagefright/OMXCodec.cpp
+++ b/media/libstagefright/OMXCodec.cpp
@@ -416,10 +416,10 @@
}
if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_NB, mime)) {
- codec->setAMRFormat();
+ codec->setAMRFormat(false /* isWAMR */);
}
if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_WB, mime)) {
- codec->setAMRWBFormat();
+ codec->setAMRFormat(true /* isWAMR */);
}
if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AAC, mime)) {
int32_t numChannels, sampleRate;
@@ -1900,54 +1900,24 @@
CHECK_EQ(err, OK);
}
-void OMXCodec::setAMRFormat() {
- if (!mIsEncoder) {
- OMX_AUDIO_PARAM_AMRTYPE def;
- InitOMXParams(&def);
- def.nPortIndex = kPortIndexInput;
+void OMXCodec::setAMRFormat(bool isWAMR) {
+ OMX_U32 portIndex = mIsEncoder ? kPortIndexOutput : kPortIndexInput;
- status_t err =
- mOMX->getParameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
+ OMX_AUDIO_PARAM_AMRTYPE def;
+ InitOMXParams(&def);
+ def.nPortIndex = portIndex;
- CHECK_EQ(err, OK);
+ status_t err =
+ mOMX->getParameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
- def.eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatFSF;
- def.eAMRBandMode = OMX_AUDIO_AMRBandModeNB0;
+ CHECK_EQ(err, OK);
- err = mOMX->setParameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
- CHECK_EQ(err, OK);
- }
+ def.eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatFSF;
+ def.eAMRBandMode =
+ isWAMR ? OMX_AUDIO_AMRBandModeWB0 : OMX_AUDIO_AMRBandModeNB0;
- ////////////////////////
-
- if (mIsEncoder) {
- sp<MetaData> format = mSource->getFormat();
- int32_t sampleRate;
- int32_t numChannels;
- CHECK(format->findInt32(kKeySampleRate, &sampleRate));
- CHECK(format->findInt32(kKeyChannelCount, &numChannels));
-
- setRawAudioFormat(kPortIndexInput, sampleRate, numChannels);
- }
-}
-
-void OMXCodec::setAMRWBFormat() {
- if (!mIsEncoder) {
- OMX_AUDIO_PARAM_AMRTYPE def;
- InitOMXParams(&def);
- def.nPortIndex = kPortIndexInput;
-
- status_t err =
- mOMX->getParameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
-
- CHECK_EQ(err, OK);
-
- def.eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatFSF;
- def.eAMRBandMode = OMX_AUDIO_AMRBandModeWB0;
-
- err = mOMX->setParameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
- CHECK_EQ(err, OK);
- }
+ err = mOMX->setParameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
+ CHECK_EQ(err, OK);
////////////////////////
diff --git a/opengl/libagl/copybit.cpp b/opengl/libagl/copybit.cpp
index a68750e..4cacc11 100644
--- a/opengl/libagl/copybit.cpp
+++ b/opengl/libagl/copybit.cpp
@@ -38,7 +38,7 @@
#include <ui/Rect.h>
-#define DEBUG_COPYBIT true
+#define DEBUG_COPYBIT false
// ----------------------------------------------------------------------------
diff --git a/packages/SettingsProvider/res/values/defaults.xml b/packages/SettingsProvider/res/values/defaults.xml
index fbfe755..ab93d8c 100644
--- a/packages/SettingsProvider/res/values/defaults.xml
+++ b/packages/SettingsProvider/res/values/defaults.xml
@@ -48,4 +48,7 @@
<bool name="def_backup_enabled">false</bool>
<string name="def_backup_transport" translatable="false"></string>
+ <!-- Default value for whether or not to pulse the notification LED when there is a
+ pending notification -->
+ <bool name="def_notification_pulse">true</bool>
</resources>
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
index e25c648..1a64e20 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
@@ -71,7 +71,7 @@
// database gets upgraded properly. At a minimum, please confirm that 'upgradeVersion'
// is properly propagated through your change. Not doing so will result in a loss of user
// settings.
- private static final int DATABASE_VERSION = 42;
+ private static final int DATABASE_VERSION = 43;
private Context mContext;
@@ -521,6 +521,24 @@
upgradeVersion = 42;
}
+ if (upgradeVersion == 42) {
+ /*
+ * Initialize new notification pulse setting
+ */
+ db.beginTransaction();
+ try {
+ SQLiteStatement stmt = db.compileStatement("INSERT INTO system(name,value)"
+ + " VALUES(?,?);");
+ loadBooleanSetting(stmt, Settings.System.NOTIFICATION_LIGHT_PULSE,
+ R.bool.def_notification_pulse);
+ stmt.close();
+ db.setTransactionSuccessful();
+ } finally {
+ db.endTransaction();
+ }
+ upgradeVersion = 43;
+ }
+
if (upgradeVersion != currentVersion) {
Log.w(TAG, "Got stuck trying to upgrade from version " + upgradeVersion
+ ", must wipe the settings provider");
@@ -767,6 +785,8 @@
loadDefaultHapticSettings(stmt);
+ loadBooleanSetting(stmt, Settings.System.NOTIFICATION_LIGHT_PULSE,
+ R.bool.def_notification_pulse);
stmt.close();
}
diff --git a/services/java/com/android/server/NotificationManagerService.java b/services/java/com/android/server/NotificationManagerService.java
index c179eb8..147580b 100755
--- a/services/java/com/android/server/NotificationManagerService.java
+++ b/services/java/com/android/server/NotificationManagerService.java
@@ -99,7 +99,11 @@
private NotificationRecord mVibrateNotification;
private Vibrator mVibrator = new Vibrator();
- // adb
+ // for enabling and disabling notification pulse behavior
+ private boolean mScreenOn = true;
+ private boolean mNotificationPulseEnabled;
+
+ // for adb connected notifications
private boolean mUsbConnected;
private boolean mAdbEnabled = false;
private boolean mAdbNotificationShown = false;
@@ -336,6 +340,12 @@
return;
}
cancelAllNotificationsInt(pkgName, 0, 0);
+ } else if (action.equals(Intent.ACTION_SCREEN_ON)) {
+ mScreenOn = true;
+ updateNotificationPulse();
+ } else if (action.equals(Intent.ACTION_SCREEN_OFF)) {
+ mScreenOn = false;
+ updateNotificationPulse();
}
}
};
@@ -349,6 +359,8 @@
ContentResolver resolver = mContext.getContentResolver();
resolver.registerContentObserver(Settings.Secure.getUriFor(
Settings.Secure.ADB_ENABLED), false, this);
+ resolver.registerContentObserver(Settings.System.getUriFor(
+ Settings.System.NOTIFICATION_LIGHT_PULSE), false, this);
update();
}
@@ -358,13 +370,21 @@
public void update() {
ContentResolver resolver = mContext.getContentResolver();
- mAdbEnabled = Settings.Secure.getInt(resolver,
+ boolean adbEnabled = Settings.Secure.getInt(resolver,
Settings.Secure.ADB_ENABLED, 0) != 0;
- updateAdbNotification();
+ if (mAdbEnabled != adbEnabled) {
+ mAdbEnabled = adbEnabled;
+ updateAdbNotification();
+ }
+ boolean pulseEnabled = Settings.System.getInt(resolver,
+ Settings.System.NOTIFICATION_LIGHT_PULSE, 0) != 0;
+ if (mNotificationPulseEnabled != pulseEnabled) {
+ mNotificationPulseEnabled = pulseEnabled;
+ updateNotificationPulse();
+ }
}
}
- private final SettingsObserver mSettingsObserver;
-
+
NotificationManagerService(Context context, StatusBarService statusBar,
LightsService lights)
{
@@ -399,10 +419,12 @@
filter.addAction(Intent.ACTION_UMS_DISCONNECTED);
filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
filter.addAction(Intent.ACTION_PACKAGE_RESTARTED);
+ filter.addAction(Intent.ACTION_SCREEN_ON);
+ filter.addAction(Intent.ACTION_SCREEN_OFF);
mContext.registerReceiver(mIntentReceiver, filter);
- mSettingsObserver = new SettingsObserver(mHandler);
- mSettingsObserver.observe();
+ SettingsObserver observer = new SettingsObserver(mHandler);
+ observer.observe();
}
void systemReady() {
@@ -711,6 +733,9 @@
&& (!(old != null
&& (notification.flags & Notification.FLAG_ONLY_ALERT_ONCE) != 0 ))
&& mSystemReady) {
+
+ final AudioManager audioManager = (AudioManager) mContext
+ .getSystemService(Context.AUDIO_SERVICE);
// sound
final boolean useDefaultSound =
(notification.defaults & Notification.DEFAULT_SOUND) != 0;
@@ -729,18 +754,20 @@
audioStreamType = DEFAULT_STREAM_TYPE;
}
mSoundNotification = r;
- long identity = Binder.clearCallingIdentity();
- try {
- mSound.play(mContext, uri, looping, audioStreamType);
- }
- finally {
- Binder.restoreCallingIdentity(identity);
+ // do not play notifications if stream volume is 0
+ // (typically because ringer mode is silent).
+ if (audioManager.getStreamVolume(audioStreamType) != 0) {
+ long identity = Binder.clearCallingIdentity();
+ try {
+ mSound.play(mContext, uri, looping, audioStreamType);
+ }
+ finally {
+ Binder.restoreCallingIdentity(identity);
+ }
}
}
// vibrate
- final AudioManager audioManager = (AudioManager) mContext
- .getSystemService(Context.AUDIO_SERVICE);
final boolean useDefaultVibrate =
(notification.defaults & Notification.DEFAULT_VIBRATE) != 0;
if ((useDefaultVibrate || notification.vibrate != null)
@@ -1000,7 +1027,9 @@
mLedNotification = mLights.get(n-1);
}
}
- if (mLedNotification == null) {
+
+ // we only flash if screen is off and persistent pulsing is enabled
+ if (mLedNotification == null || mScreenOn || !mNotificationPulseEnabled) {
mNotificationLight.turnOff();
} else {
mNotificationLight.setFlashing(
@@ -1092,7 +1121,13 @@
}
}
}
-
+
+ private void updateNotificationPulse() {
+ synchronized (mNotificationList) {
+ updateLightsLocked();
+ }
+ }
+
// ======================================================================
@Override
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
diff --git a/services/java/com/android/server/PackageManagerService.java b/services/java/com/android/server/PackageManagerService.java
index 5ed2d35..9382146 100644
--- a/services/java/com/android/server/PackageManagerService.java
+++ b/services/java/com/android/server/PackageManagerService.java
@@ -2966,12 +2966,6 @@
TAG, "Removing package " + pkg.applicationInfo.packageName );
synchronized (mPackages) {
- if (pkg.mPreferredOrder > 0) {
- mSettings.mPreferredPackages.remove(pkg);
- pkg.mPreferredOrder = 0;
- updatePreferredIndicesLP();
- }
-
clearPackagePreferredActivitiesLP(pkg.packageName);
mPackages.remove(pkg.applicationInfo.packageName);
@@ -4938,62 +4932,17 @@
public void addPackageToPreferred(String packageName) {
mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
-
- synchronized (mPackages) {
- PackageParser.Package p = mPackages.get(packageName);
- if (p == null) {
- return;
- }
- PackageSetting ps = (PackageSetting)p.mExtras;
- if (ps != null) {
- mSettings.mPreferredPackages.remove(ps);
- mSettings.mPreferredPackages.add(0, ps);
- updatePreferredIndicesLP();
- mSettings.writeLP();
- }
- }
+ Log.w(TAG, "addPackageToPreferred: no longer implemented");
}
public void removePackageFromPreferred(String packageName) {
mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
-
- synchronized (mPackages) {
- PackageParser.Package p = mPackages.get(packageName);
- if (p == null) {
- return;
- }
- if (p.mPreferredOrder > 0) {
- PackageSetting ps = (PackageSetting)p.mExtras;
- if (ps != null) {
- mSettings.mPreferredPackages.remove(ps);
- p.mPreferredOrder = 0;
- updatePreferredIndicesLP();
- mSettings.writeLP();
- }
- }
- }
- }
-
- private void updatePreferredIndicesLP() {
- final ArrayList<PackageSetting> pkgs
- = mSettings.mPreferredPackages;
- final int N = pkgs.size();
- for (int i=0; i<N; i++) {
- pkgs.get(i).pkg.mPreferredOrder = N - i;
- }
+ Log.w(TAG, "removePackageFromPreferred: no longer implemented");
}
public List<PackageInfo> getPreferredPackages(int flags) {
- synchronized (mPackages) {
- final ArrayList<PackageInfo> res = new ArrayList<PackageInfo>();
- final ArrayList<PackageSetting> pref = mSettings.mPreferredPackages;
- final int N = pref.size();
- for (int i=0; i<N; i++) {
- res.add(generatePackageInfo(pref.get(i).pkg, flags));
- }
- return res;
- }
+ return new ArrayList<PackageInfo>();
}
public void addPreferredActivity(IntentFilter filter, int match,
@@ -5307,13 +5256,6 @@
pw.println("Preferred Activities:");
mSettings.mPreferredActivities.dump(pw, " ");
pw.println(" ");
- pw.println("Preferred Packages:");
- {
- for (PackageSetting ps : mSettings.mPreferredPackages) {
- pw.print(" "); pw.println(ps.name);
- }
- }
- pw.println(" ");
pw.println("Permissions:");
{
for (BasePermission p : mSettings.mPermissions.values()) {
@@ -6064,10 +6006,6 @@
private final File mBackupSettingsFilename;
private final HashMap<String, PackageSetting> mPackages =
new HashMap<String, PackageSetting>();
- // The user's preferred packages/applications, in order of preference.
- // First is the most preferred.
- private final ArrayList<PackageSetting> mPreferredPackages =
- new ArrayList<PackageSetting>();
// List of replaced system applications
final HashMap<String, PackageSetting> mDisabledSysPackages =
new HashMap<String, PackageSetting>();
@@ -6112,9 +6050,6 @@
final HashMap<String, BasePermission> mPermissionTrees =
new HashMap<String, BasePermission>();
- private final ArrayList<String> mPendingPreferredPackages
- = new ArrayList<String>();
-
private final StringBuilder mReadMessages = new StringBuilder();
private static final class PendingPackage extends PackageSettingBase {
@@ -6598,16 +6533,6 @@
writeDisabledSysPackage(serializer, pkg);
}
- serializer.startTag(null, "preferred-packages");
- int N = mPreferredPackages.size();
- for (int i=0; i<N; i++) {
- PackageSetting pkg = mPreferredPackages.get(i);
- serializer.startTag(null, "item");
- serializer.attribute(null, "name", pkg.name);
- serializer.endTag(null, "item");
- }
- serializer.endTag(null, "preferred-packages");
-
serializer.startTag(null, "preferred-activities");
for (PreferredActivity pa : mPreferredActivities.filterSet()) {
serializer.startTag(null, "item");
@@ -6885,7 +6810,7 @@
} else if (tagName.equals("shared-user")) {
readSharedUserLP(parser);
} else if (tagName.equals("preferred-packages")) {
- readPreferredPackagesLP(parser);
+ // no longer used.
} else if (tagName.equals("preferred-activities")) {
readPreferredActivitiesLP(parser);
} else if(tagName.equals("updated-package")) {
@@ -6939,19 +6864,6 @@
}
mPendingPackages.clear();
- N = mPendingPreferredPackages.size();
- mPreferredPackages.clear();
- for (int i=0; i<N; i++) {
- final String name = mPendingPreferredPackages.get(i);
- final PackageSetting p = mPackages.get(name);
- if (p != null) {
- mPreferredPackages.add(p);
- } else {
- Log.w(TAG, "Unknown preferred package: " + name);
- }
- }
- mPendingPreferredPackages.clear();
-
mReadMessages.append("Read completed successfully: "
+ mPackages.size() + " packages, "
+ mSharedUsers.size() + " shared uids\n");
@@ -7410,37 +7322,6 @@
}
}
- private void readPreferredPackagesLP(XmlPullParser parser)
- throws XmlPullParserException, IOException {
- int outerDepth = parser.getDepth();
- int type;
- while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
- && (type != XmlPullParser.END_TAG
- || parser.getDepth() > outerDepth)) {
- if (type == XmlPullParser.END_TAG
- || type == XmlPullParser.TEXT) {
- continue;
- }
-
- String tagName = parser.getName();
- if (tagName.equals("item")) {
- String name = parser.getAttributeValue(null, "name");
- if (name != null) {
- mPendingPreferredPackages.add(name);
- } else {
- reportSettingsProblem(Log.WARN,
- "Error in package manager settings: <preferred-package> has no name at "
- + parser.getPositionDescription());
- }
- } else {
- reportSettingsProblem(Log.WARN,
- "Unknown element under <preferred-packages>: "
- + parser.getName());
- }
- XmlUtils.skipCurrentTag(parser);
- }
- }
-
private void readPreferredActivitiesLP(XmlPullParser parser)
throws XmlPullParserException, IOException {
int outerDepth = parser.getDepth();
diff --git a/services/java/com/android/server/WindowManagerService.java b/services/java/com/android/server/WindowManagerService.java
index 538d60e..05d340e 100644
--- a/services/java/com/android/server/WindowManagerService.java
+++ b/services/java/com/android/server/WindowManagerService.java
@@ -6397,7 +6397,9 @@
// Ignore
}
- if (eventType != TOUCH_EVENT
+ if (ev.classType == RawInputEvent.CLASS_CONFIGURATION_CHANGED) {
+ // do not wake screen in this case
+ } else if (eventType != TOUCH_EVENT
&& eventType != LONG_TOUCH_EVENT
&& eventType != CHEEK_EVENT) {
mPowerManager.userActivity(curTime, false,
diff --git a/telephony/java/android/telephony/NeighboringCellInfo.java b/telephony/java/android/telephony/NeighboringCellInfo.java
index 1d69761..ad7dfc9 100644
--- a/telephony/java/android/telephony/NeighboringCellInfo.java
+++ b/telephony/java/android/telephony/NeighboringCellInfo.java
@@ -68,12 +68,13 @@
private int mNetworkType;
/**
- * @deprecated
* Empty constructor. Initializes the RSSI and CID.
*
* NeighboringCellInfo is one time shot for the neighboring cells based on
* the radio network type at that moment. Its constructor needs radio network
* type.
+ *
+ * @deprecated by {@link #NeighboringCellInfo(int, String, int)}
*/
@Deprecated
public NeighboringCellInfo() {
@@ -85,12 +86,13 @@
}
/**
- * @deprecated
* Initialize the object from rssi and cid.
*
* NeighboringCellInfo is one time shot for the neighboring cells based on
* the radio network type at that moment. Its constructor needs radio network
* type.
+ *
+ * @deprecated by {@link #NeighboringCellInfo(int, String, int)}
*/
@Deprecated
public NeighboringCellInfo(int rssi, int cid) {
@@ -99,7 +101,6 @@
}
/**
- * @hide
* Initialize the object from rssi, location string, and radioType
* radioType is one of following
* {@link TelephonyManager#NETWORK_TYPE_GPRS TelephonyManager.NETWORK_TYPE_GPRS},
@@ -223,12 +224,14 @@
return mNetworkType;
}
/**
- * @deprecated
* Set the cell id.
*
* NeighboringCellInfo is a one time shot for the neighboring cells based on
* the radio network type at that moment. It shouldn't be changed after
* creation.
+ *
+ * @deprecated cid value passed as in location parameter passed to constructor
+ * {@link #NeighboringCellInfo(int, String, int)}
*/
@Deprecated
public void setCid(int cid) {
@@ -236,12 +239,14 @@
}
/**
- * @deprecated
* Set the signal strength of the cell.
*
* NeighboringCellInfo is a one time shot for the neighboring cells based on
* the radio network type at that moment. It shouldn't be changed after
* creation.
+ *
+ * @deprecated initial rssi value passed as parameter to constructor
+ * {@link #NeighboringCellInfo(int, String, int)}
*/
@Deprecated
public void setRssi(int rssi) {
diff --git a/telephony/java/android/telephony/PhoneStateListener.java b/telephony/java/android/telephony/PhoneStateListener.java
index ea6593e..9bfd900 100644
--- a/telephony/java/android/telephony/PhoneStateListener.java
+++ b/telephony/java/android/telephony/PhoneStateListener.java
@@ -49,8 +49,9 @@
*
* @see #onSignalStrengthChanged
*
- * TODO: @deprecated to be deprecated by LISTEN_SIGNAL_STRENGTHS, @see #onSignalStrengthsChanged
+ * @deprecated by {@link #LISTEN_SIGNAL_STRENGTHS}
*/
+ @Deprecated
public static final int LISTEN_SIGNAL_STRENGTH = 0x00000002;
/**
@@ -127,8 +128,6 @@
* icon.
*
* @see #onSignalStrengthsChanged
- *
- * @hide
*/
public static final int LISTEN_SIGNAL_STRENGTHS = 0x00000100;
@@ -206,7 +205,6 @@
}
/**
- * @hide
* same as above, but with the network type. Both called.
*/
public void onDataConnectionStateChanged(int state, int networkType) {
@@ -232,8 +230,6 @@
* @see ServiceState#STATE_IN_SERVICE
* @see ServiceState#STATE_OUT_OF_SERVICE
* @see ServiceState#STATE_POWER_OFF
- *
- * @hide
*/
public void onSignalStrengthsChanged(SignalStrength signalStrength) {
// default implementation empty
diff --git a/telephony/java/android/telephony/SignalStrength.java b/telephony/java/android/telephony/SignalStrength.java
index 8ed0065..c9e304a 100644
--- a/telephony/java/android/telephony/SignalStrength.java
+++ b/telephony/java/android/telephony/SignalStrength.java
@@ -24,8 +24,6 @@
/**
* Contains phone signal strength related information.
- *
- * @hide
*/
public class SignalStrength implements Parcelable {
@@ -50,6 +48,7 @@
* @param m Bundle from intent notifier
* @return newly created SignalStrength
*
+ * @hide
*/
public static SignalStrength newFromBundle(Bundle m) {
SignalStrength ret;
@@ -61,6 +60,7 @@
/**
* Empty constructor
*
+ * @hide
*/
public SignalStrength() {
mGsmSignalStrength = 99;
@@ -76,6 +76,7 @@
/**
* Constructor
*
+ * @hide
*/
public SignalStrength(int gsmSignalStrength, int gsmBitErrorRate,
int cdmaDbm, int cdmaEcio,
@@ -94,6 +95,8 @@
* Copy constructors
*
* @param s Source SignalStrength
+ *
+ * @hide
*/
public SignalStrength(SignalStrength s) {
copyFrom(s);
@@ -115,6 +118,8 @@
/**
* Construct a SignalStrength object from the given parcel.
+ *
+ * @hide
*/
public SignalStrength(Parcel in) {
mGsmSignalStrength = in.readInt();
@@ -127,6 +132,9 @@
isGsm = (in.readInt() != 0);
}
+ /**
+ * {@link Parcelable#writeToParcel}
+ */
public void writeToParcel(Parcel out, int flags) {
out.writeInt(mGsmSignalStrength);
out.writeInt(mGsmBitErrorRate);
@@ -138,10 +146,18 @@
out.writeInt(isGsm ? 1 : 0);
}
+ /**
+ * {@link Parcelable#describeContents}
+ */
public int describeContents() {
return 0;
}
+ /**
+ * {@link Parcelable.Creator}
+ *
+ * @hide
+ */
public static final Parcelable.Creator<SignalStrength> CREATOR = new Parcelable.Creator() {
public SignalStrength createFromParcel(Parcel in) {
return new SignalStrength(in);
@@ -202,14 +218,14 @@
}
/**
- * @hide
+ * @return true if this is for GSM
*/
public boolean isGsm() {
return this.isGsm;
}
/**
- * @hide
+ * @return hash code
*/
@Override
public int hashCode() {
@@ -221,7 +237,7 @@
}
/**
- * @hide
+ * @return true if the signal strengths are the same
*/
@Override
public boolean equals (Object o) {
@@ -248,7 +264,7 @@
}
/**
- * @hide
+ * @return string representation.
*/
@Override
public String toString() {
diff --git a/telephony/java/com/android/internal/telephony/MccTable.java b/telephony/java/com/android/internal/telephony/MccTable.java
index c4877cb..e25eb7b 100644
--- a/telephony/java/com/android/internal/telephony/MccTable.java
+++ b/telephony/java/com/android/internal/telephony/MccTable.java
@@ -24,6 +24,7 @@
import android.os.RemoteException;
import android.os.SystemProperties;
import android.provider.Settings;
+import android.text.TextUtils;
import android.util.Log;
import java.util.Arrays;
@@ -573,34 +574,36 @@
* @param mccmnc truncated imsi with just the MCC and MNC - MNC assumed to be from 4th to end
*/
public static void updateMccMncConfiguration(PhoneBase phone, String mccmnc) {
- int mcc, mnc;
+ if (!TextUtils.isEmpty(mccmnc)) {
+ int mcc, mnc;
- try {
- mcc = Integer.parseInt(mccmnc.substring(0,3));
- mnc = Integer.parseInt(mccmnc.substring(3));
- } catch (NumberFormatException e) {
- Log.e(LOG_TAG, "Error parsing IMSI");
- return;
- }
+ try {
+ mcc = Integer.parseInt(mccmnc.substring(0,3));
+ mnc = Integer.parseInt(mccmnc.substring(3));
+ } catch (NumberFormatException e) {
+ Log.e(LOG_TAG, "Error parsing IMSI");
+ return;
+ }
- Log.d(LOG_TAG, "updateMccMncConfiguration: mcc=" + mcc + ", mnc=" + mnc);
+ Log.d(LOG_TAG, "updateMccMncConfiguration: mcc=" + mcc + ", mnc=" + mnc);
- if (mcc != 0) {
- setTimezoneFromMccIfNeeded(phone, mcc);
- setLocaleFromMccIfNeeded(phone, mcc);
- setWifiChannelsFromMccIfNeeded(phone, mcc);
- }
- try {
- Configuration config = ActivityManagerNative.getDefault().getConfiguration();
if (mcc != 0) {
- config.mcc = mcc;
+ setTimezoneFromMccIfNeeded(phone, mcc);
+ setLocaleFromMccIfNeeded(phone, mcc);
+ setWifiChannelsFromMccIfNeeded(phone, mcc);
}
- if (mnc != 0) {
- config.mnc = mnc;
+ try {
+ Configuration config = ActivityManagerNative.getDefault().getConfiguration();
+ if (mcc != 0) {
+ config.mcc = mcc;
+ }
+ if (mnc != 0) {
+ config.mnc = mnc;
+ }
+ ActivityManagerNative.getDefault().updateConfiguration(config);
+ } catch (RemoteException e) {
+ Log.e(LOG_TAG, "Can't update configuration", e);
}
- ActivityManagerNative.getDefault().updateConfiguration(config);
- } catch (RemoteException e) {
- Log.e(LOG_TAG, "Can't update configuration", e);
}
}
diff --git a/telephony/java/com/android/internal/telephony/RIL.java b/telephony/java/com/android/internal/telephony/RIL.java
index e47f799..279f57f 100644
--- a/telephony/java/com/android/internal/telephony/RIL.java
+++ b/telephony/java/com/android/internal/telephony/RIL.java
@@ -2191,6 +2191,7 @@
case RIL_REQUEST_SET_SMSC_ADDRESS: ret = responseVoid(p); break;
case RIL_REQUEST_EXIT_EMERGENCY_CALLBACK_MODE: ret = responseVoid(p); break;
case RIL_REQUEST_REPORT_SMS_MEMORY_STATUS: ret = responseVoid(p); break;
+ case RIL_REQUEST_REPORT_STK_SERVICE_IS_RUNNING: ret = responseVoid(p); break;
default:
throw new RuntimeException("Unrecognized solicited response: " + rr.mRequest);
//break;
diff --git a/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java b/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java
index 04a03b2..422cc19 100755
--- a/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java
@@ -202,10 +202,6 @@
// Sets current entry in the telephony carrier table
updateCurrentCarrierInProvider(operatorNumeric);
- // Updates MCC MNC device configuration information
- MccTable.updateMccMncConfiguration(this, operatorNumeric);
-
-
// Notify voicemails.
notifier.notifyMessageWaitingChanged(this);
}
@@ -1401,20 +1397,22 @@
}
/**
- * Sets the "current" field in the telephony provider according to the build-time
- * operator numeric property
+ * Sets the "current" field in the telephony provider according to the
+ * build-time operator numeric property
*
* @return true for success; false otherwise.
*/
- // TODO(Moto): move this method into PhoneBase, since it looks identical to
- // the one in GsmPhone
- private boolean updateCurrentCarrierInProvider(String operatorNumeric) {
+ boolean updateCurrentCarrierInProvider(String operatorNumeric) {
if (!TextUtils.isEmpty(operatorNumeric)) {
try {
Uri uri = Uri.withAppendedPath(Telephony.Carriers.CONTENT_URI, "current");
ContentValues map = new ContentValues();
map.put(Telephony.Carriers.NUMERIC, operatorNumeric);
getContext().getContentResolver().insert(uri, map);
+
+ // Updates MCC MNC device configuration information
+ MccTable.updateMccMncConfiguration(this, operatorNumeric);
+
return true;
} catch (SQLException e) {
Log.e(LOG_TAG, "Can't store current operator", e);
diff --git a/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java b/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java
index ebd60a9..d627baf 100644
--- a/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java
+++ b/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java
@@ -280,6 +280,7 @@
// send it as a UCS-2 encoded message
try {
userData = encodeUCS2(message, header);
+ encoding = ENCODING_16BIT;
} catch(UnsupportedEncodingException uex) {
Log.e(LOG_TAG,
"Implausible UnsupportedEncodingException ",