Merge "DO NOT MERGE Adjust action bar home/up sizing/padding for smaller tablets." into honeycomb-mr2
diff --git a/media/libstagefright/AwesomePlayer.cpp b/media/libstagefright/AwesomePlayer.cpp
index 2aa53a9..a8e0a4d 100644
--- a/media/libstagefright/AwesomePlayer.cpp
+++ b/media/libstagefright/AwesomePlayer.cpp
@@ -24,10 +24,12 @@
#include "include/ARTSPController.h"
#include "include/AwesomePlayer.h"
+#include "include/DRMExtractor.h"
#include "include/SoftwareRenderer.h"
#include "include/NuCachedSource2.h"
#include "include/ThrottledSource.h"
#include "include/MPEG2TSExtractor.h"
+#include "include/WVMExtractor.h"
#include <binder/IPCThreadState.h>
#include <binder/IServiceManager.h>
@@ -447,6 +449,7 @@
cancelPlayerEvents();
+ mWVMExtractor.clear();
mCachedSource.clear();
mAudioTrack.clear();
mVideoTrack.clear();
@@ -554,6 +557,11 @@
*durationUs = cachedDataRemaining * 8000000ll / bitrate;
*eos = (finalStatus != OK);
return true;
+ } else if (mWVMExtractor != NULL) {
+ status_t finalStatus;
+ *durationUs = mWVMExtractor->getCachedDurationUs(&finalStatus);
+ *eos = (finalStatus != OK);
+ return true;
}
return false;
@@ -646,6 +654,30 @@
}
}
}
+ } else if (mWVMExtractor != NULL) {
+ status_t finalStatus;
+
+ int64_t cachedDurationUs
+ = mWVMExtractor->getCachedDurationUs(&finalStatus);
+
+ bool eos = (finalStatus != OK);
+
+ if (eos) {
+ if (finalStatus == ERROR_END_OF_STREAM) {
+ notifyListener_l(MEDIA_BUFFERING_UPDATE, 100);
+ }
+ if (mFlags & PREPARING) {
+ LOGV("cache has reached EOS, prepare is done.");
+ finishAsyncPrepare_l();
+ }
+ } else {
+ int percentage = 100.0 * (double)cachedDurationUs / mDurationUs;
+ if (percentage > 100) {
+ percentage = 100;
+ }
+
+ notifyListener_l(MEDIA_BUFFERING_UPDATE, percentage);
+ }
}
int64_t cachedDurationUs;
@@ -1320,7 +1352,7 @@
mVideoBuffer = NULL;
}
- if (mSeeking == SEEK && mCachedSource != NULL && mAudioSource != NULL
+ if (mSeeking == SEEK && isStreamingHTTP() && mAudioSource != NULL
&& !(mFlags & SEEK_PREVIEW)) {
// We're going to seek the video source first, followed by
// the audio source.
@@ -1654,8 +1686,19 @@
status_t AwesomePlayer::finishSetDataSource_l() {
sp<DataSource> dataSource;
+ bool isWidevineStreaming = false;
+ if (!strncasecmp("widevine://", mUri.string(), 11)) {
+ isWidevineStreaming = true;
+
+ String8 newURI = String8("http://");
+ newURI.append(mUri.string() + 11);
+
+ mUri = newURI;
+ }
+
if (!strncasecmp("http://", mUri.string(), 7)
- || !strncasecmp("https://", mUri.string(), 8)) {
+ || !strncasecmp("https://", mUri.string(), 8)
+ || isWidevineStreaming) {
mConnectingDataSource = new NuHTTPDataSource(
(mFlags & INCOGNITO) ? NuHTTPDataSource::kFlagIncognito : 0);
@@ -1670,39 +1713,48 @@
return err;
}
+ if (!isWidevineStreaming) {
+ // The widevine extractor does its own caching.
+
#if 0
- mCachedSource = new NuCachedSource2(
- new ThrottledSource(
- mConnectingDataSource, 50 * 1024 /* bytes/sec */));
+ mCachedSource = new NuCachedSource2(
+ new ThrottledSource(
+ mConnectingDataSource, 50 * 1024 /* bytes/sec */));
#else
- mCachedSource = new NuCachedSource2(mConnectingDataSource);
+ mCachedSource = new NuCachedSource2(mConnectingDataSource);
#endif
- mConnectingDataSource.clear();
- dataSource = mCachedSource;
-
- // We're going to prefill the cache before trying to instantiate
- // the extractor below, as the latter is an operation that otherwise
- // could block on the datasource for a significant amount of time.
- // During that time we'd be unable to abort the preparation phase
- // without this prefill.
-
- mLock.unlock();
-
- for (;;) {
- status_t finalStatus;
- size_t cachedDataRemaining =
- mCachedSource->approxDataRemaining(&finalStatus);
-
- if (finalStatus != OK || cachedDataRemaining >= kHighWaterMarkBytes
- || (mFlags & PREPARE_CANCELLED)) {
- break;
- }
-
- usleep(200000);
+ dataSource = mCachedSource;
+ } else {
+ dataSource = mConnectingDataSource;
}
- mLock.lock();
+ mConnectingDataSource.clear();
+
+ if (mCachedSource != NULL) {
+ // We're going to prefill the cache before trying to instantiate
+ // the extractor below, as the latter is an operation that otherwise
+ // could block on the datasource for a significant amount of time.
+ // During that time we'd be unable to abort the preparation phase
+ // without this prefill.
+
+ mLock.unlock();
+
+ for (;;) {
+ status_t finalStatus;
+ size_t cachedDataRemaining =
+ mCachedSource->approxDataRemaining(&finalStatus);
+
+ if (finalStatus != OK || cachedDataRemaining >= kHighWaterMarkBytes
+ || (mFlags & PREPARE_CANCELLED)) {
+ break;
+ }
+
+ usleep(200000);
+ }
+
+ mLock.lock();
+ }
if (mFlags & PREPARE_CANCELLED) {
LOGI("Prepare cancelled while waiting for initial cache fill.");
@@ -1740,10 +1792,29 @@
return UNKNOWN_ERROR;
}
- sp<MediaExtractor> extractor = MediaExtractor::Create(dataSource);
+ sp<MediaExtractor> extractor;
- if (extractor == NULL) {
- return UNKNOWN_ERROR;
+ if (isWidevineStreaming) {
+ String8 mimeType;
+ float confidence;
+ sp<AMessage> dummy;
+ bool success = SniffDRM(dataSource, &mimeType, &confidence, &dummy);
+
+ if (!success
+ || strcasecmp(
+ mimeType.string(), MEDIA_MIMETYPE_CONTAINER_WVM)) {
+ return ERROR_UNSUPPORTED;
+ }
+
+ mWVMExtractor = new WVMExtractor(dataSource);
+ mWVMExtractor->setAdaptiveStreamingMode(true);
+ extractor = mWVMExtractor;
+ } else {
+ extractor = MediaExtractor::Create(dataSource);
+
+ if (extractor == NULL) {
+ return UNKNOWN_ERROR;
+ }
}
dataSource->getDrmInfo(&mDecryptHandle, &mDrmManagerClient);
@@ -1754,7 +1825,15 @@
}
}
- return setDataSource_l(extractor);
+ status_t err = setDataSource_l(extractor);
+
+ if (err != OK) {
+ mWVMExtractor.clear();
+
+ return err;
+ }
+
+ return OK;
}
void AwesomePlayer::abortPrepare(status_t err) {
@@ -1815,7 +1894,7 @@
mFlags |= PREPARING_CONNECTED;
- if (mCachedSource != NULL || mRTSPController != NULL) {
+ if (isStreamingHTTP() || mRTSPController != NULL) {
postBufferingEvent_l();
} else {
finishAsyncPrepare_l();
@@ -1852,4 +1931,8 @@
postCheckAudioStatusEvent_l();
}
+bool AwesomePlayer::isStreamingHTTP() const {
+ return mCachedSource != NULL || mWVMExtractor != NULL;
+}
+
} // namespace android
diff --git a/media/libstagefright/WVMExtractor.cpp b/media/libstagefright/WVMExtractor.cpp
index 7c72852..83a1eaa 100644
--- a/media/libstagefright/WVMExtractor.cpp
+++ b/media/libstagefright/WVMExtractor.cpp
@@ -45,7 +45,8 @@
static Mutex gWVMutex;
WVMExtractor::WVMExtractor(const sp<DataSource> &source)
- : mDataSource(source) {
+ : mDataSource(source),
+ mUseAdaptiveStreaming(false) {
{
Mutex::Autolock autoLock(gWVMutex);
if (gVendorLibHandle == NULL) {
@@ -100,5 +101,21 @@
return mImpl->getMetaData();
}
+int64_t WVMExtractor::getCachedDurationUs(status_t *finalStatus) {
+ // TODO: Fill this with life.
+
+ *finalStatus = OK;
+
+ return 0;
+}
+
+void WVMExtractor::setAdaptiveStreamingMode(bool adaptive) {
+ mUseAdaptiveStreaming = adaptive;
+}
+
+bool WVMExtractor::getAdaptiveStreamingMode() const {
+ return mUseAdaptiveStreaming;
+}
+
} //namespace android
diff --git a/media/libstagefright/include/AwesomePlayer.h b/media/libstagefright/include/AwesomePlayer.h
index 4e6f75c..3a21f25 100644
--- a/media/libstagefright/include/AwesomePlayer.h
+++ b/media/libstagefright/include/AwesomePlayer.h
@@ -44,6 +44,8 @@
class DrmManagerClinet;
class DecryptHandle;
+struct WVMExtractor;
+
struct AwesomeRenderer : public RefBase {
AwesomeRenderer() {}
@@ -219,6 +221,8 @@
DrmManagerClient *mDrmManagerClient;
DecryptHandle *mDecryptHandle;
+ sp<WVMExtractor> mWVMExtractor;
+
status_t setDataSource_l(
const char *uri,
const KeyedVector<String8, String8> *headers = NULL);
@@ -268,6 +272,8 @@
status_t startAudioPlayer_l();
+ bool isStreamingHTTP() const;
+
AwesomePlayer(const AwesomePlayer &);
AwesomePlayer &operator=(const AwesomePlayer &);
};
diff --git a/media/libstagefright/include/WVMExtractor.h b/media/libstagefright/include/WVMExtractor.h
index 0da45a8..62e5aa5 100644
--- a/media/libstagefright/include/WVMExtractor.h
+++ b/media/libstagefright/include/WVMExtractor.h
@@ -19,6 +19,7 @@
#define WVM_EXTRACTOR_H_
#include <media/stagefright/MediaExtractor.h>
+#include <utils/Errors.h>
namespace android {
@@ -33,12 +34,31 @@
virtual sp<MetaData> getTrackMetaData(size_t index, uint32_t flags);
virtual sp<MetaData> getMetaData();
+ // Return the amount of data cached from the current
+ // playback positiion (in us).
+ // While more data is still being fetched *finalStatus == OK,
+ // Once fetching is completed (no more data available), *finalStatus != OK
+ // If fetching completed normally (i.e. reached EOS instead of IO error)
+ // *finalStatus == ERROR_END_OF_STREAM
+ int64_t getCachedDurationUs(status_t *finalStatus);
+
+ // Set to use adaptive streaming mode by the WV component.
+ // If adaptive == true, adaptive streaming mode will be used.
+ // Default mode is non-adaptive streaming mode.
+ // Should set to use adaptive streaming mode only if widevine:// protocol
+ // is used.
+ void setAdaptiveStreamingMode(bool adaptive);
+
+ // Retrieve the adaptive streaming mode used by the WV component.
+ bool getAdaptiveStreamingMode() const;
+
protected:
virtual ~WVMExtractor();
private:
sp<DataSource> mDataSource;
sp<MediaExtractor> mImpl;
+ bool mUseAdaptiveStreaming;
WVMExtractor(const WVMExtractor &);
WVMExtractor &operator=(const WVMExtractor &);
diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java
index 26d89cd..607c60a 100644
--- a/services/java/com/android/server/wm/WindowManagerService.java
+++ b/services/java/com/android/server/wm/WindowManagerService.java
@@ -6498,8 +6498,22 @@
}
if (mBaseDisplayWidth < mInitialDisplayWidth
|| mBaseDisplayHeight < mInitialDisplayHeight) {
- Rect outer = new Rect(0, 0, mInitialDisplayWidth, mInitialDisplayHeight);
- Rect inner = new Rect(0, 0, mBaseDisplayWidth, mBaseDisplayHeight);
+ int initW, initH, baseW, baseH;
+ final boolean rotated = (mRotation == Surface.ROTATION_90
+ || mRotation == Surface.ROTATION_270);
+ if (rotated) {
+ initW = mInitialDisplayHeight;
+ initH = mInitialDisplayWidth;
+ baseW = mBaseDisplayHeight;
+ baseH = mBaseDisplayWidth;
+ } else {
+ initW = mInitialDisplayWidth;
+ initH = mInitialDisplayHeight;
+ baseW = mBaseDisplayWidth;
+ baseH = mBaseDisplayHeight;
+ }
+ Rect outer = new Rect(0, 0, initW, initH);
+ Rect inner = new Rect(0, 0, baseW, baseH);
try {
mBlackFrame = new BlackFrame(mFxSession, outer, inner, MASK_LAYER);
} catch (Surface.OutOfResourcesException e) {
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java
index 3c0c9a4..144ec42 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java
@@ -201,7 +201,8 @@
Capability.VIEW_MANIPULATION,
Capability.PLAY_ANIMATION,
Capability.ANIMATED_VIEW_MANIPULATION,
- Capability.ADAPTER_BINDING);
+ Capability.ADAPTER_BINDING,
+ Capability.EXTENDED_VIEWINFO);
BridgeAssetManager.initSystem();
@@ -399,15 +400,6 @@
throw new IllegalArgumentException("viewObject is not a View");
}
- @Override
- public int getViewBaseline(Object viewObject) {
- if (viewObject instanceof View) {
- return ((View) viewObject).getBaseline();
- }
-
- throw new IllegalArgumentException("viewObject is not a View");
- }
-
/**
* Returns the lock for the bridge
*/
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/MockView.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/MockView.java
index 1ca3182..3d50b2a 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/MockView.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/MockView.java
@@ -19,21 +19,23 @@
import android.content.Context;
import android.graphics.Canvas;
import android.util.AttributeSet;
+import android.view.Gravity;
import android.widget.TextView;
/**
* Base class for mocked views.
- *
+ *
* TODO: implement onDraw and draw a rectangle in a random color with the name of the class
* (or better the id of the view).
*/
public class MockView extends TextView {
-
+
public MockView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
-
+
setText(this.getClass().getSimpleName());
setTextColor(0xFF000000);
+ setGravity(Gravity.CENTER);
}
@Override
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java
index c53cb23..b800519 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java
@@ -74,6 +74,7 @@
import android.view.View.AttachInfo;
import android.view.View.MeasureSpec;
import android.view.ViewGroup.LayoutParams;
+import android.view.ViewGroup.MarginLayoutParams;
import android.widget.AbsListView;
import android.widget.AbsSpinner;
import android.widget.AdapterView;
@@ -513,7 +514,7 @@
mViewRoot.draw(mCanvas);
}
- mViewInfoList = startVisitingViews(mViewRoot, 0);
+ mViewInfoList = startVisitingViews(mViewRoot, 0, params.getExtendedViewInfoMode());
// success!
return SUCCESS.createResult();
@@ -1255,7 +1256,7 @@
}
}
- private List<ViewInfo> startVisitingViews(View view, int offset) {
+ private List<ViewInfo> startVisitingViews(View view, int offset, boolean setExtendedInfo) {
if (view == null) {
return null;
}
@@ -1264,7 +1265,7 @@
offset += view.getTop();
if (view == mContentRoot) {
- return visitAllChildren(mContentRoot, offset);
+ return visitAllChildren(mContentRoot, offset, setExtendedInfo);
}
// otherwise, look for mContentRoot in the children
@@ -1272,7 +1273,8 @@
ViewGroup group = ((ViewGroup) view);
for (int i = 0; i < group.getChildCount(); i++) {
- List<ViewInfo> list = startVisitingViews(group.getChildAt(i), offset);
+ List<ViewInfo> list = startVisitingViews(group.getChildAt(i), offset,
+ setExtendedInfo);
if (list != null) {
return list;
}
@@ -1287,8 +1289,9 @@
* bounds of all the views.
* @param view the root View
* @param offset an offset for the view bounds.
+ * @param setExtendedInfo whether to set the extended view info in the {@link ViewInfo} object.
*/
- private ViewInfo visit(View view, int offset) {
+ private ViewInfo visit(View view, int offset, boolean setExtendedInfo) {
if (view == null) {
return null;
}
@@ -1298,9 +1301,22 @@
view.getLeft(), view.getTop() + offset, view.getRight(), view.getBottom() + offset,
view, view.getLayoutParams());
+ if (setExtendedInfo) {
+ MarginLayoutParams marginParams = null;
+ LayoutParams params = view.getLayoutParams();
+ if (params instanceof MarginLayoutParams) {
+ marginParams = (MarginLayoutParams) params;
+ }
+ result.setExtendedInfo(view.getBaseline(),
+ marginParams != null ? marginParams.leftMargin : 0,
+ marginParams != null ? marginParams.topMargin : 0,
+ marginParams != null ? marginParams.rightMargin : 0,
+ marginParams != null ? marginParams.bottomMargin : 0);
+ }
+
if (view instanceof ViewGroup) {
ViewGroup group = ((ViewGroup) view);
- result.setChildren(visitAllChildren(group, 0 /*offset*/));
+ result.setChildren(visitAllChildren(group, 0 /*offset*/, setExtendedInfo));
}
return result;
@@ -1311,15 +1327,17 @@
* containing the bounds of all the views.
* @param view the root View
* @param offset an offset for the view bounds.
+ * @param setExtendedInfo whether to set the extended view info in the {@link ViewInfo} object.
*/
- private List<ViewInfo> visitAllChildren(ViewGroup viewGroup, int offset) {
+ private List<ViewInfo> visitAllChildren(ViewGroup viewGroup, int offset,
+ boolean setExtendedInfo) {
if (viewGroup == null) {
return null;
}
List<ViewInfo> children = new ArrayList<ViewInfo>();
for (int i = 0; i < viewGroup.getChildCount(); i++) {
- children.add(visit(viewGroup.getChildAt(i), offset));
+ children.add(visit(viewGroup.getChildAt(i), offset, setExtendedInfo));
}
return children;
}