Merge "add Base64OutputStream to android-common"
diff --git a/core/java/android/content/SyncManager.java b/core/java/android/content/SyncManager.java
index ebb95e87..9ff2e25 100644
--- a/core/java/android/content/SyncManager.java
+++ b/core/java/android/content/SyncManager.java
@@ -1041,7 +1041,7 @@
continue;
}
- SyncStorageEngine.AuthorityInfo settings = mSyncStorageEngine.getAuthority(
+ SyncStorageEngine.AuthorityInfo settings = mSyncStorageEngine.getOrCreateAuthority(
account, syncAdapterType.type.authority);
SyncStatusInfo status = mSyncStorageEngine.getOrCreateSyncStatus(settings);
pw.print(" "); pw.print(settings.authority);
diff --git a/core/java/android/content/SyncStorageEngine.java b/core/java/android/content/SyncStorageEngine.java
index 07a1f46..fcb910d 100644
--- a/core/java/android/content/SyncStorageEngine.java
+++ b/core/java/android/content/SyncStorageEngine.java
@@ -632,9 +632,11 @@
}
}
- public AuthorityInfo getAuthority(Account account, String authority) {
+ public AuthorityInfo getOrCreateAuthority(Account account, String authority) {
synchronized (mAuthorities) {
- return getAuthorityLocked(account, authority, null);
+ return getOrCreateAuthorityLocked(account, authority,
+ -1 /* assign a new identifier if creating a new authority */,
+ true /* write to storage if this results in a change */);
}
}
diff --git a/core/java/android/view/animation/Animation.java b/core/java/android/view/animation/Animation.java
index 337fe58..349b7e5 100644
--- a/core/java/android/view/animation/Animation.java
+++ b/core/java/android/view/animation/Animation.java
@@ -281,8 +281,8 @@
*/
public void detach() {
if (mStarted && !mEnded) {
- if (mListener != null) mListener.onAnimationEnd(this);
mEnded = true;
+ if (mListener != null) mListener.onAnimationEnd(this);
}
}
@@ -776,10 +776,10 @@
if (expired) {
if (mRepeatCount == mRepeated) {
if (!mEnded) {
+ mEnded = true;
if (mListener != null) {
mListener.onAnimationEnd(this);
}
- mEnded = true;
}
} else {
if (mRepeatCount > 0) {
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 713e7258..a57c71b 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -1249,11 +1249,7 @@
android:theme="@style/Theme.Dialog.Alert"
android:excludeFromRecents="true">
</activity>
- <activity android:name="com.android.internal.app.UsbStorageActivity"
- android:excludeFromRecents="true">
- </activity>
- <activity android:name="com.android.internal.app.UsbStorageStopActivity"
- android:theme="@style/Theme.Dialog.Alert"
+ <activity android:name="com.android.server.status.UsbStorageActivity"
android:excludeFromRecents="true">
</activity>
<activity android:name="com.android.internal.app.ExternalMediaFormatActivity"
diff --git a/include/media/MediaPlayerInterface.h b/include/media/MediaPlayerInterface.h
index a5a1bb8..be06e33 100644
--- a/include/media/MediaPlayerInterface.h
+++ b/include/media/MediaPlayerInterface.h
@@ -62,7 +62,8 @@
// AudioSink: abstraction layer for audio output
class AudioSink : public RefBase {
public:
- typedef void (*AudioCallback)(
+ // Callback returns the number of bytes actually written to the buffer.
+ typedef size_t (*AudioCallback)(
AudioSink *audioSink, void *buffer, size_t size, void *cookie);
virtual ~AudioSink() {}
@@ -77,8 +78,7 @@
virtual status_t getPosition(uint32_t *position) = 0;
// If no callback is specified, use the "write" API below to submit
- // audio data. Otherwise return a full buffer of audio data on each
- // callback.
+ // audio data.
virtual status_t open(
uint32_t sampleRate, int channelCount,
int format=AudioSystem::PCM_16_BIT,
diff --git a/include/media/stagefright/AudioPlayer.h b/include/media/stagefright/AudioPlayer.h
index 843e051..8e5f05f 100644
--- a/include/media/stagefright/AudioPlayer.h
+++ b/include/media/stagefright/AudioPlayer.h
@@ -90,11 +90,11 @@
static void AudioCallback(int event, void *user, void *info);
void AudioCallback(int event, void *info);
- static void AudioSinkCallback(
+ static size_t AudioSinkCallback(
MediaPlayerBase::AudioSink *audioSink,
void *data, size_t size, void *me);
- void fillBuffer(void *data, size_t size);
+ size_t fillBuffer(void *data, size_t size);
int64_t getRealTimeUsLocked() const;
diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp
index 8e61011..55b06f4 100644
--- a/media/libmediaplayerservice/MediaPlayerService.cpp
+++ b/media/libmediaplayerservice/MediaPlayerService.cpp
@@ -1597,9 +1597,12 @@
AudioOutput *me = (AudioOutput *)cookie;
AudioTrack::Buffer *buffer = (AudioTrack::Buffer *)info;
- (*me->mCallback)(
+ size_t actualSize = (*me->mCallback)(
me, buffer->raw, buffer->size, me->mCallbackCookie);
- me->snoopWrite(buffer->raw, buffer->size);
+
+ if (actualSize > 0) {
+ me->snoopWrite(buffer->raw, actualSize);
+ }
}
#undef LOG_TAG
@@ -1629,14 +1632,75 @@
return NO_ERROR;
}
+////////////////////////////////////////////////////////////////////////////////
+
+struct CallbackThread : public Thread {
+ CallbackThread(const wp<MediaPlayerBase::AudioSink> &sink,
+ MediaPlayerBase::AudioSink::AudioCallback cb,
+ void *cookie);
+
+protected:
+ virtual ~CallbackThread();
+
+ virtual bool threadLoop();
+
+private:
+ wp<MediaPlayerBase::AudioSink> mSink;
+ MediaPlayerBase::AudioSink::AudioCallback mCallback;
+ void *mCookie;
+ void *mBuffer;
+ size_t mBufferSize;
+
+ CallbackThread(const CallbackThread &);
+ CallbackThread &operator=(const CallbackThread &);
+};
+
+CallbackThread::CallbackThread(
+ const wp<MediaPlayerBase::AudioSink> &sink,
+ MediaPlayerBase::AudioSink::AudioCallback cb,
+ void *cookie)
+ : mSink(sink),
+ mCallback(cb),
+ mCookie(cookie),
+ mBuffer(NULL),
+ mBufferSize(0) {
+}
+
+CallbackThread::~CallbackThread() {
+ if (mBuffer) {
+ free(mBuffer);
+ mBuffer = NULL;
+ }
+}
+
+bool CallbackThread::threadLoop() {
+ sp<MediaPlayerBase::AudioSink> sink = mSink.promote();
+ if (sink == NULL) {
+ return false;
+ }
+
+ if (mBuffer == NULL) {
+ mBufferSize = sink->bufferSize();
+ mBuffer = malloc(mBufferSize);
+ }
+
+ size_t actualSize =
+ (*mCallback)(sink.get(), mBuffer, mBufferSize, mCookie);
+
+ if (actualSize > 0) {
+ sink->write(mBuffer, actualSize);
+ }
+
+ return true;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
status_t MediaPlayerService::AudioCache::open(
uint32_t sampleRate, int channelCount, int format, int bufferCount,
AudioCallback cb, void *cookie)
{
LOGV("open(%u, %d, %d, %d)", sampleRate, channelCount, format, bufferCount);
- if (cb != NULL) {
- return UNKNOWN_ERROR; // TODO: implement this.
- }
if (mHeap->getHeapID() < 0) {
return NO_INIT;
}
@@ -1645,9 +1709,25 @@
mChannelCount = (uint16_t)channelCount;
mFormat = (uint16_t)format;
mMsecsPerFrame = 1.e3 / (float) sampleRate;
+
+ if (cb != NULL) {
+ mCallbackThread = new CallbackThread(this, cb, cookie);
+ }
return NO_ERROR;
}
+void MediaPlayerService::AudioCache::start() {
+ if (mCallbackThread != NULL) {
+ mCallbackThread->run("AudioCache callback");
+ }
+}
+
+void MediaPlayerService::AudioCache::stop() {
+ if (mCallbackThread != NULL) {
+ mCallbackThread->requestExitAndWait();
+ }
+}
+
ssize_t MediaPlayerService::AudioCache::write(const void* buffer, size_t size)
{
LOGV("write(%p, %u)", buffer, size);
diff --git a/media/libmediaplayerservice/MediaPlayerService.h b/media/libmediaplayerservice/MediaPlayerService.h
index ffe1ba0..5c03e47 100644
--- a/media/libmediaplayerservice/MediaPlayerService.h
+++ b/media/libmediaplayerservice/MediaPlayerService.h
@@ -139,9 +139,9 @@
int bufferCount = 1,
AudioCallback cb = NULL, void *cookie = NULL);
- virtual void start() {}
+ virtual void start();
virtual ssize_t write(const void* buffer, size_t size);
- virtual void stop() {}
+ virtual void stop();
virtual void flush() {}
virtual void pause() {}
virtual void close() {}
@@ -171,6 +171,8 @@
uint32_t mSize;
int mError;
bool mCommandComplete;
+
+ sp<Thread> mCallbackThread;
};
public:
diff --git a/media/libstagefright/AudioPlayer.cpp b/media/libstagefright/AudioPlayer.cpp
index 4926920..12d7ee2 100644
--- a/media/libstagefright/AudioPlayer.cpp
+++ b/media/libstagefright/AudioPlayer.cpp
@@ -187,12 +187,12 @@
}
// static
-void AudioPlayer::AudioSinkCallback(
+size_t AudioPlayer::AudioSinkCallback(
MediaPlayerBase::AudioSink *audioSink,
void *buffer, size_t size, void *cookie) {
AudioPlayer *me = (AudioPlayer *)cookie;
- me->fillBuffer(buffer, size);
+ return me->fillBuffer(buffer, size);
}
void AudioPlayer::AudioCallback(int event, void *info) {
@@ -201,17 +201,18 @@
}
AudioTrack::Buffer *buffer = (AudioTrack::Buffer *)info;
- fillBuffer(buffer->raw, buffer->size);
+ size_t numBytesWritten = fillBuffer(buffer->raw, buffer->size);
+
+ buffer->size = numBytesWritten;
}
-void AudioPlayer::fillBuffer(void *data, size_t size) {
+size_t AudioPlayer::fillBuffer(void *data, size_t size) {
if (mNumFramesPlayed == 0) {
LOGV("AudioCallback");
}
if (mReachedEOS) {
- memset(data, 0, size);
- return;
+ return 0;
}
size_t size_done = 0;
@@ -244,7 +245,6 @@
if (err != OK) {
mReachedEOS = true;
- memset((char *)data + size_done, 0, size_remaining);
break;
}
@@ -285,7 +285,9 @@
}
Mutex::Autolock autoLock(mLock);
- mNumFramesPlayed += size / mFrameSize;
+ mNumFramesPlayed += size_done / mFrameSize;
+
+ return size_done;
}
int64_t AudioPlayer::getRealTimeUs() {
diff --git a/media/libstagefright/MPEG4Extractor.cpp b/media/libstagefright/MPEG4Extractor.cpp
index 4458006..1ff38ee 100644
--- a/media/libstagefright/MPEG4Extractor.cpp
+++ b/media/libstagefright/MPEG4Extractor.cpp
@@ -1540,7 +1540,7 @@
if (!memcmp(header, "ftyp3gp", 7) || !memcmp(header, "ftypmp42", 8)
|| !memcmp(header, "ftypisom", 8) || !memcmp(header, "ftypM4V ", 8)
- || !memcmp(header, "ftypM4A ", 8)) {
+ || !memcmp(header, "ftypM4A ", 8) || !memcmp(header, "ftypf4v ", 8)) {
*mimeType = MEDIA_MIMETYPE_CONTAINER_MPEG4;
*confidence = 0.1;
diff --git a/media/libstagefright/OMXCodec.cpp b/media/libstagefright/OMXCodec.cpp
index c6c6f21..75b7b6f 100644
--- a/media/libstagefright/OMXCodec.cpp
+++ b/media/libstagefright/OMXCodec.cpp
@@ -112,7 +112,6 @@
{ MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.TI.Video.Decoder" },
{ MEDIA_MIMETYPE_VIDEO_MPEG4, "M4vH263Decoder" },
{ MEDIA_MIMETYPE_VIDEO_H263, "OMX.qcom.video.decoder.h263" },
- { MEDIA_MIMETYPE_VIDEO_H263, "OMX.TI.Video.Decoder" },
{ MEDIA_MIMETYPE_VIDEO_H263, "M4vH263Decoder" },
{ MEDIA_MIMETYPE_VIDEO_AVC, "OMX.qcom.video.decoder.avc" },
{ MEDIA_MIMETYPE_VIDEO_AVC, "OMX.TI.Video.Decoder" },
diff --git a/media/tests/SoundPoolTest/src/com/android/SoundPoolTest.java b/media/tests/SoundPoolTest/src/com/android/SoundPoolTest.java
index 6b3093f..1434d3f 100644
--- a/media/tests/SoundPoolTest/src/com/android/SoundPoolTest.java
+++ b/media/tests/SoundPoolTest/src/com/android/SoundPoolTest.java
@@ -43,10 +43,9 @@
private TestThread mThread;
private static final int[] mTestFiles = new int[] {
- // FIXME: Restore when Stagefright bug is fixed
R.raw.organ441,
R.raw.sine441,
- //R.raw.test1,
+ R.raw.test1,
R.raw.test2,
R.raw.test3,
R.raw.test4,
diff --git a/services/java/com/android/server/NotificationManagerService.java b/services/java/com/android/server/NotificationManagerService.java
index ad8ab84..3657133 100755
--- a/services/java/com/android/server/NotificationManagerService.java
+++ b/services/java/com/android/server/NotificationManagerService.java
@@ -50,7 +50,6 @@
import android.os.Power;
import android.os.Process;
import android.os.RemoteException;
-import android.os.storage.StorageManager;
import android.os.SystemProperties;
import android.os.Vibrator;
import android.provider.Settings;
@@ -408,9 +407,6 @@
mToastQueue = new ArrayList<ToastRecord>();
mHandler = new WorkerHandler();
- StorageManager sm = (StorageManager) context.getSystemService(Context.STORAGE_SERVICE);
- sm.registerListener(new com.android.internal.app.StorageNotification(context));
-
mStatusBarService = statusBar;
statusBar.setNotificationCallbacks(mNotificationCallbacks);
diff --git a/services/java/com/android/server/status/StatusBarPolicy.java b/services/java/com/android/server/status/StatusBarPolicy.java
index f5aeaf0..20209e4 100644
--- a/services/java/com/android/server/status/StatusBarPolicy.java
+++ b/services/java/com/android/server/status/StatusBarPolicy.java
@@ -37,6 +37,7 @@
import android.os.IBinder;
import android.os.Message;
import android.os.RemoteException;
+import android.os.storage.StorageManager;
import android.provider.Settings;
import android.telephony.PhoneStateListener;
import android.telephony.ServiceState;
@@ -93,6 +94,9 @@
private IBinder mClockIcon;
private IconData mClockData;
+ // storage
+ private StorageManager mStorageManager;
+
// battery
private IBinder mBatteryIcon;
private IconData mBatteryData;
@@ -407,6 +411,11 @@
mClockIcon = service.addIcon(mClockData, null);
updateClock();
+ // storage
+ mStorageManager = (StorageManager) context.getSystemService(Context.STORAGE_SERVICE);
+ mStorageManager.registerListener(
+ new com.android.server.status.StorageNotification(context));
+
// battery
mBatteryData = IconData.makeIcon("battery",
null, com.android.internal.R.drawable.stat_sys_battery_unknown, 0, 0);
diff --git a/core/java/com/android/internal/app/StorageNotification.java b/services/java/com/android/server/status/StorageNotification.java
similarity index 97%
rename from core/java/com/android/internal/app/StorageNotification.java
rename to services/java/com/android/server/status/StorageNotification.java
index 8876612..3b79049 100644
--- a/core/java/com/android/internal/app/StorageNotification.java
+++ b/services/java/com/android/server/status/StorageNotification.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.internal.app;
+package com.android.server.status;
import android.app.Activity;
import android.app.Notification;
@@ -119,7 +119,7 @@
* for stopping UMS.
*/
Intent intent = new Intent();
- intent.setClass(mContext, com.android.internal.app.UsbStorageActivity.class);
+ intent.setClass(mContext, com.android.server.status.UsbStorageActivity.class);
PendingIntent pi = PendingIntent.getActivity(mContext, 0, intent, 0);
setUsbStorageNotification(
com.android.internal.R.string.usb_storage_stop_notification_title,
@@ -237,7 +237,7 @@
if (available) {
Intent intent = new Intent();
- intent.setClass(mContext, com.android.internal.app.UsbStorageActivity.class);
+ intent.setClass(mContext, com.android.server.status.UsbStorageActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
PendingIntent pi = PendingIntent.getActivity(mContext, 0, intent, 0);
setUsbStorageNotification(
@@ -253,8 +253,8 @@
/**
* Sets the USB storage notification.
*/
- private synchronized void setUsbStorageNotification(int titleId, int messageId, int icon, boolean sound, boolean visible,
- PendingIntent pi) {
+ private synchronized void setUsbStorageNotification(int titleId, int messageId, int icon,
+ boolean sound, boolean visible, PendingIntent pi) {
if (!visible && mUsbStorageNotification == null) {
return;
diff --git a/core/java/com/android/internal/app/UsbStorageActivity.java b/services/java/com/android/server/status/UsbStorageActivity.java
similarity index 98%
rename from core/java/com/android/internal/app/UsbStorageActivity.java
rename to services/java/com/android/server/status/UsbStorageActivity.java
index 991f04b..7a2a2d6 100644
--- a/core/java/com/android/internal/app/UsbStorageActivity.java
+++ b/services/java/com/android/server/status/UsbStorageActivity.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.internal.app;
+package com.android.server.status;
import android.app.Activity;
import android.content.BroadcastReceiver;