summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--api/current.xml2
-rw-r--r--core/java/android/appwidget/AppWidgetProviderInfo.java12
-rw-r--r--core/java/android/os/Parcel.java9
-rw-r--r--core/java/android/view/Display.java10
-rw-r--r--core/java/android/view/ScaleGestureDetector.java13
-rw-r--r--core/java/android/webkit/ZoomManager.java38
-rw-r--r--core/java/android/widget/AbsListView.java1
-rw-r--r--core/java/android/widget/NumberPicker.java5
-rw-r--r--core/java/android/widget/TabWidget.java2
-rw-r--r--core/java/android/widget/TextView.java5
-rw-r--r--core/jni/android_util_Binder.cpp206
-rw-r--r--core/jni/android_view_Display.cpp50
-rw-r--r--core/jni/android_view_Surface.cpp2
-rw-r--r--include/binder/IBinder.h2
-rw-r--r--include/utils/StrongPointer.h6
-rw-r--r--libs/surfaceflinger_client/Surface.cpp2
-rw-r--r--libs/utils/RefBase.cpp34
-rw-r--r--media/java/android/media/videoeditor/MediaArtistNativeHelper.java4
-rwxr-xr-xmedia/java/android/media/videoeditor/MediaProperties.java4
-rwxr-xr-xmedia/java/android/media/videoeditor/VideoEditorImpl.java2
-rw-r--r--media/libstagefright/colorconversion/ColorConverter.cpp2
-rwxr-xr-xmedia/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaFrameworkPerfTestRunner.java38
-rwxr-xr-xmedia/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaTestUtil.java45
-rw-r--r--media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaRecorderTest.java167
-rw-r--r--media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/performance/MediaPlayerPerformance.java15
-rw-r--r--packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_ime_default.pngbin1914 -> 3746 bytes
-rw-r--r--packages/SystemUI/res/drawable-xlarge-mdpi/recents_thumbnail_bg.pngbin1564 -> 3981 bytes
-rw-r--r--packages/SystemUI/res/drawable-xlarge-mdpi/recents_thumbnail_bg_press.pngbin0 -> 2327 bytes
-rw-r--r--packages/SystemUI/res/layout-xlarge/status_bar_recent_item.xml8
-rw-r--r--packages/SystemUI/res/layout-xlarge/status_bar_recent_panel.xml33
-rw-r--r--packages/SystemUI/res/layout-xlarge/status_bar_recent_panel_footer.xml25
-rw-r--r--packages/SystemUI/res/values/dimens.xml29
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/tablet/RecentAppsPanel.java186
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java11
-rw-r--r--services/java/com/android/server/AppWidgetService.java2
-rw-r--r--services/java/com/android/server/wm/WindowManagerService.java3
-rw-r--r--test-runner/src/android/test/SingleLaunchActivityTestCase.java2
37 files changed, 583 insertions, 392 deletions
diff --git a/api/current.xml b/api/current.xml
index 6adf8aa2c861..2c9789222b8b 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -39947,7 +39947,7 @@
visibility="public"
>
</field>
-<field name="resizableMode"
+<field name="resizeMode"
type="int"
transient="false"
volatile="false"
diff --git a/core/java/android/appwidget/AppWidgetProviderInfo.java b/core/java/android/appwidget/AppWidgetProviderInfo.java
index 32c239755040..b46802e94e7a 100644
--- a/core/java/android/appwidget/AppWidgetProviderInfo.java
+++ b/core/java/android/appwidget/AppWidgetProviderInfo.java
@@ -130,6 +130,9 @@ public class AppWidgetProviderInfo implements Parcelable {
/**
* The view id of the AppWidget subview which should be auto-advanced by the widget's host.
+ *
+ * <p>This field corresponds to the <code>android:autoAdvanceViewId</code> attribute in
+ * the AppWidget meta-data file.
*/
public int autoAdvanceViewId;
@@ -146,8 +149,11 @@ public class AppWidgetProviderInfo implements Parcelable {
* The rules by which a widget can be resized. See {@link #RESIZE_NONE},
* {@link #RESIZE_NONE}, {@link #RESIZE_HORIZONTAL},
* {@link #RESIZE_VERTICAL}, {@link #RESIZE_BOTH}.
+ *
+ * <p>This field corresponds to the <code>android:resizeMode</code> attribute in
+ * the AppWidget meta-data file.
*/
- public int resizableMode;
+ public int resizeMode;
public AppWidgetProviderInfo() {
}
@@ -170,7 +176,7 @@ public class AppWidgetProviderInfo implements Parcelable {
this.icon = in.readInt();
this.previewImage = in.readInt();
this.autoAdvanceViewId = in.readInt();
- this.resizableMode = in.readInt();
+ this.resizeMode = in.readInt();
}
public void writeToParcel(android.os.Parcel out, int flags) {
@@ -194,7 +200,7 @@ public class AppWidgetProviderInfo implements Parcelable {
out.writeInt(this.icon);
out.writeInt(this.previewImage);
out.writeInt(this.autoAdvanceViewId);
- out.writeInt(this.resizableMode);
+ out.writeInt(this.resizeMode);
}
public int describeContents() {
diff --git a/core/java/android/os/Parcel.java b/core/java/android/os/Parcel.java
index 31f87198878a..8944f12e6e80 100644
--- a/core/java/android/os/Parcel.java
+++ b/core/java/android/os/Parcel.java
@@ -31,6 +31,7 @@ import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.lang.reflect.Field;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -356,7 +357,7 @@ public final class Parcel {
public final native void enforceInterface(String interfaceName);
/**
- * Write a byte array into the parcel at the current {#link #dataPosition},
+ * Write a byte array into the parcel at the current {@link #dataPosition},
* growing {@link #dataCapacity} if needed.
* @param b Bytes to place into the parcel.
*/
@@ -365,7 +366,7 @@ public final class Parcel {
}
/**
- * Write an byte array into the parcel at the current {#link #dataPosition},
+ * Write an byte array into the parcel at the current {@link #dataPosition},
* growing {@link #dataCapacity} if needed.
* @param b Bytes to place into the parcel.
* @param offset Index of first byte to be written.
@@ -376,9 +377,7 @@ public final class Parcel {
writeInt(-1);
return;
}
- if (b.length < offset + len || len < 0 || offset < 0) {
- throw new ArrayIndexOutOfBoundsException();
- }
+ Arrays.checkOffsetAndCount(b.length, offset, len);
writeNative(b, offset, len);
}
diff --git a/core/java/android/view/Display.java b/core/java/android/view/Display.java
index b74806486bf9..126f409d1dab 100644
--- a/core/java/android/view/Display.java
+++ b/core/java/android/view/Display.java
@@ -79,6 +79,11 @@ public class Display
*/
native public int getHeight();
+ /** @hide special for when we are faking the screen size. */
+ native public int getRealWidth();
+ /** @hide special for when we are faking the screen size. */
+ native public int getRealHeight();
+
/**
* Returns the rotation of the screen from its "natural" orientation.
* The returned value may be {@link Surface#ROTATION_0 Surface.ROTATION_0}
@@ -136,11 +141,6 @@ public class Display
outMetrics.ydpi = mDpiY;
}
- /**
- * @hide Helper for our fake display size hack.
- */
- native public static int unmapDisplaySize(int newSize);
-
/*
* We use a class initializer to allow the native code to cache some
* field offsets.
diff --git a/core/java/android/view/ScaleGestureDetector.java b/core/java/android/view/ScaleGestureDetector.java
index 218ee4f9885a..0124151b5ddc 100644
--- a/core/java/android/view/ScaleGestureDetector.java
+++ b/core/java/android/view/ScaleGestureDetector.java
@@ -245,6 +245,7 @@ public class ScaleGestureDetector {
final float bottomSlop = mBottomSlopEdge;
int index0 = event.findPointerIndex(mActiveId0);
int index1 = event.findPointerIndex(mActiveId1);
+
float x0 = getRawX(event, index0);
float y0 = getRawY(event, index0);
float x1 = getRawX(event, index1);
@@ -353,14 +354,24 @@ public class ScaleGestureDetector {
if (actionId == mActiveId0) {
final int newIndex = findNewActiveIndex(event, mActiveId1, actionIndex);
if (newIndex >= 0) {
+ mListener.onScaleEnd(this);
mActiveId0 = event.getPointerId(newIndex);
+ mActive0MostRecent = true;
+ mPrevEvent = MotionEvent.obtain(event);
+ setContext(event);
+ mGestureInProgress = mListener.onScaleBegin(this);
} else {
gestureEnded = true;
}
} else if (actionId == mActiveId1) {
final int newIndex = findNewActiveIndex(event, mActiveId0, actionIndex);
if (newIndex >= 0) {
+ mListener.onScaleEnd(this);
mActiveId1 = event.getPointerId(newIndex);
+ mActive0MostRecent = false;
+ mPrevEvent = MotionEvent.obtain(event);
+ setContext(event);
+ mGestureInProgress = mListener.onScaleBegin(this);
} else {
gestureEnded = true;
}
@@ -449,6 +460,7 @@ public class ScaleGestureDetector {
* MotionEvent has no getRawX(int) method; simulate it pending future API approval.
*/
private static float getRawX(MotionEvent event, int pointerIndex) {
+ if (pointerIndex < 0) return Float.MIN_VALUE;
if (pointerIndex == 0) return event.getRawX();
float offset = event.getRawX() - event.getX();
return event.getX(pointerIndex) + offset;
@@ -458,6 +470,7 @@ public class ScaleGestureDetector {
* MotionEvent has no getRawY(int) method; simulate it pending future API approval.
*/
private static float getRawY(MotionEvent event, int pointerIndex) {
+ if (pointerIndex < 0) return Float.MIN_VALUE;
if (pointerIndex == 0) return event.getRawY();
float offset = event.getRawY() - event.getY();
return event.getY(pointerIndex) + offset;
diff --git a/core/java/android/webkit/ZoomManager.java b/core/java/android/webkit/ZoomManager.java
index 5e0de27bb173..63038503b238 100644
--- a/core/java/android/webkit/ZoomManager.java
+++ b/core/java/android/webkit/ZoomManager.java
@@ -227,10 +227,13 @@ class ZoomManager {
assert density > 0;
if (Math.abs(density - mDefaultScale) > MINIMUM_SCALE_INCREMENT) {
+ // Remember the current zoom density before it gets changed.
+ final float originalDefault = mDefaultScale;
// set the new default density
setDefaultZoomScale(density);
+ float scaleChange = (originalDefault > 0.0) ? density / originalDefault: 1.0f;
// adjust the scale if it falls outside the new zoom bounds
- setZoomScale(mActualScale, true);
+ setZoomScale(mActualScale * scaleChange, true);
}
}
@@ -721,10 +724,7 @@ class ZoomManager {
}
public boolean onScale(ScaleGestureDetector detector) {
- // Prevent scaling beyond overview scale.
- float scale = Math.max(
- computeScaleWithLimits(detector.getScaleFactor() * mActualScale),
- getZoomOverviewScale());
+ float scale = computeScaleWithLimits(detector.getScaleFactor() * mActualScale);
if (mPinchToZoomAnimating || willScaleTriggerZoom(scale)) {
mPinchToZoomAnimating = true;
// limit the scale change per step
@@ -780,13 +780,6 @@ class ZoomManager {
// update mMinZoomScale if the minimum zoom scale is not fixed
if (!mMinZoomScaleFixed) {
- // when change from narrow screen to wide screen, the new viewWidth
- // can be wider than the old content width. We limit the minimum
- // scale to 1.0f. The proper minimum scale will be calculated when
- // the new picture shows up.
- mMinZoomScale = Math.min(1.0f, (float) mWebView.getViewWidth()
- / (mWebView.drawHistory() ? mWebView.getHistoryPictureWidth()
- : mZoomOverviewWidth));
// limit the minZoomScale to the initialScale if it is set
if (mInitialScale > 0 && mInitialScale < mMinZoomScale) {
mMinZoomScale = mInitialScale;
@@ -823,7 +816,7 @@ class ZoomManager {
// Keep overview mode unchanged when rotating.
final float zoomOverviewScale = getZoomOverviewScale();
final float newScale = (mInZoomOverviewBeforeSizeChange) ?
- zoomOverviewScale : Math.max(mActualScale, zoomOverviewScale);
+ zoomOverviewScale : mActualScale;
setZoomScale(newScale, mUpdateTextWrap, true);
// update the zoom buttons as the scale can be changed
updateZoomPicker();
@@ -879,21 +872,15 @@ class ZoomManager {
}
}
- if (!mMinZoomScaleFixed) {
- mMinZoomScale = newZoomOverviewScale;
- }
// fit the content width to the current view for the first new picture
// after first layout.
boolean scaleHasDiff = exceedsMinScaleIncrement(newZoomOverviewScale, mActualScale);
- // Make sure the actual scale is no less than zoom overview scale.
- boolean scaleLessThanOverview =
- (newZoomOverviewScale - mActualScale) >= MINIMUM_SCALE_INCREMENT;
// Make sure mobile sites are correctly handled since mobile site will
// change content width after rotating.
boolean mobileSiteInOverview = mInZoomOverview &&
!exceedsMinScaleIncrement(newZoomOverviewScale, 1.0f);
if (!mWebView.drawHistory() &&
- (mInitialZoomOverview || scaleLessThanOverview || mobileSiteInOverview) &&
+ (mInitialZoomOverview || mobileSiteInOverview) &&
scaleHasDiff && zoomOverviewWidthChanged) {
mInitialZoomOverview = false;
setZoomScale(newZoomOverviewScale, !willScaleTriggerZoom(mTextWrapScale) &&
@@ -967,10 +954,11 @@ class ZoomManager {
mTextWrapScale = viewState.mTextWrapScale;
scale = viewState.mViewScale;
} else {
- scale = overviewScale;
- if (!settings.getUseWideViewPort()
- || !settings.getLoadWithOverviewMode()) {
- scale = Math.max(viewState.mTextWrapScale, scale);
+ scale = mDefaultScale;
+ mTextWrapScale = mDefaultScale;
+ if (settings.getUseWideViewPort()
+ && settings.getLoadWithOverviewMode()) {
+ scale = Math.max(overviewScale, scale);
}
if (settings.isNarrowColumnLayout() &&
settings.getUseFixedViewport()) {
@@ -981,7 +969,7 @@ class ZoomManager {
}
boolean reflowText = false;
if (!viewState.mIsRestored) {
- if (settings.getUseFixedViewport()) {
+ if (settings.getUseFixedViewport() && settings.getLoadWithOverviewMode()) {
// Override the scale only in case of fixed viewport.
scale = Math.max(scale, overviewScale);
mTextWrapScale = Math.max(mTextWrapScale, overviewScale);
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index c2c8d16a928a..1d05d0bf59f3 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -3529,6 +3529,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
post(this);
} else {
mTouchMode = TOUCH_MODE_REST;
+ reportScrollStateChange(OnScrollListener.SCROLL_STATE_IDLE);
}
}
diff --git a/core/java/android/widget/NumberPicker.java b/core/java/android/widget/NumberPicker.java
index 7a591782564f..2947ebeb1d4b 100644
--- a/core/java/android/widget/NumberPicker.java
+++ b/core/java/android/widget/NumberPicker.java
@@ -608,7 +608,7 @@ public class NumberPicker extends LinearLayout {
case MotionEvent.ACTION_DOWN:
mLastMotionEventY = mLastDownEventY = event.getY();
removeAllCallbacks();
- hideInputControls();
+ mShowInputControlsAnimator.cancel();
mBeginEditOnUpEvent = false;
mAdjustScrollerOnUpEvent = true;
if (mDrawSelectorWheel) {
@@ -621,6 +621,7 @@ public class NumberPicker extends LinearLayout {
}
mBeginEditOnUpEvent = scrollersFinished;
mAdjustScrollerOnUpEvent = true;
+ hideInputControls();
return true;
}
if (isEventInViewHitRect(event, mInputText)
@@ -630,6 +631,7 @@ public class NumberPicker extends LinearLayout {
&& isEventInViewHitRect(event, mDecrementButton))) {
mAdjustScrollerOnUpEvent = false;
setDrawSelectorWheel(true);
+ hideInputControls();
return true;
}
break;
@@ -640,6 +642,7 @@ public class NumberPicker extends LinearLayout {
mBeginEditOnUpEvent = false;
onScrollStateChange(OnScrollListener.SCROLL_STATE_TOUCH_SCROLL);
setDrawSelectorWheel(true);
+ hideInputControls();
return true;
}
break;
diff --git a/core/java/android/widget/TabWidget.java b/core/java/android/widget/TabWidget.java
index 22f6f4ed93d8..d74ef245e5f7 100644
--- a/core/java/android/widget/TabWidget.java
+++ b/core/java/android/widget/TabWidget.java
@@ -174,8 +174,8 @@ public class TabWidget extends LinearLayout implements OnFocusChangeListener {
void measureHorizontal(int widthMeasureSpec, int heightMeasureSpec) {
// First, measure with no constraint
final int unspecifiedWidth = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
- super.measureHorizontal(unspecifiedWidth, heightMeasureSpec);
mImposedTabsHeight = -1;
+ super.measureHorizontal(unspecifiedWidth, heightMeasureSpec);
int extraWidth = getMeasuredWidth() - MeasureSpec.getSize(widthMeasureSpec);
if (extraWidth > 0) {
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 33d1225e5181..09c1ac5e916a 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -7091,6 +7091,11 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
// Only track when onStartTemporaryDetach() is called directly,
// usually because this instance is an editable field in a list
if (!mDispatchTemporaryDetach) mTemporaryDetach = true;
+
+ // Because of View recycling in ListView, there is no easy way to know when a TextView with
+ // selection becomes visible again. Until a better solution is found, stop text selection
+ // mode (if any) as soon as this TextView is recycled.
+ stopSelectionActionMode();
}
@Override
diff --git a/core/jni/android_util_Binder.cpp b/core/jni/android_util_Binder.cpp
index 7a53874c6983..7226e31ec39f 100644
--- a/core/jni/android_util_Binder.cpp
+++ b/core/jni/android_util_Binder.cpp
@@ -31,6 +31,8 @@
#include <binder/IPCThreadState.h>
#include <utils/Log.h>
#include <utils/SystemClock.h>
+#include <utils/List.h>
+#include <utils/KeyedVector.h>
#include <cutils/logger.h>
#include <binder/Parcel.h>
#include <binder/ProcessState.h>
@@ -322,25 +324,15 @@ private:
class JavaBBinderHolder : public RefBase
{
public:
- JavaBBinderHolder(JNIEnv* env, jobject object)
- : mObject(object)
- {
- LOGV("Creating JavaBBinderHolder for Object %p\n", object);
- }
- ~JavaBBinderHolder()
- {
- LOGV("Destroying JavaBBinderHolder for Object %p\n", mObject);
- }
-
- sp<JavaBBinder> get(JNIEnv* env)
+ sp<JavaBBinder> get(JNIEnv* env, jobject obj)
{
AutoMutex _l(mLock);
sp<JavaBBinder> b = mBinder.promote();
if (b == NULL) {
- b = new JavaBBinder(env, mObject);
+ b = new JavaBBinder(env, obj);
mBinder = b;
LOGV("Creating JavaBinder %p (refs %p) for Object %p, weakCount=%d\n",
- b.get(), b->getWeakRefs(), mObject, b->getWeakRefs()->getWeakCount());
+ b.get(), b->getWeakRefs(), obj, b->getWeakRefs()->getWeakCount());
}
return b;
@@ -354,20 +346,41 @@ public:
private:
Mutex mLock;
- jobject mObject;
wp<JavaBBinder> mBinder;
};
// ----------------------------------------------------------------------------
+// Per-IBinder death recipient bookkeeping. This is how we reconcile local jobject
+// death recipient references passed in through JNI with the permanent corresponding
+// JavaDeathRecipient objects.
+
+class JavaDeathRecipient;
+
+class DeathRecipientList : public RefBase {
+ List< sp<JavaDeathRecipient> > mList;
+ Mutex mLock;
+
+public:
+ ~DeathRecipientList();
+
+ void add(const sp<JavaDeathRecipient>& recipient);
+ void remove(const sp<JavaDeathRecipient>& recipient);
+ sp<JavaDeathRecipient> find(jobject recipient);
+};
+
+// ----------------------------------------------------------------------------
+
class JavaDeathRecipient : public IBinder::DeathRecipient
{
public:
- JavaDeathRecipient(JNIEnv* env, jobject object)
- : mVM(jnienv_to_javavm(env)), mObject(env->NewGlobalRef(object)),
- mHoldsRef(true)
+ JavaDeathRecipient(JNIEnv* env, jobject object, sp<DeathRecipientList>& list)
+ : mVM(jnienv_to_javavm(env)), mObject(env->NewGlobalRef(object)), mList(list)
{
- incStrong(this);
+ // These objects manage their own lifetimes so are responsible for final bookkeeping.
+ // The list holds a strong reference to this object.
+ mList->add(this);
+
android_atomic_inc(&gNumDeathRefs);
incRefsCreated(env);
}
@@ -391,16 +404,12 @@ public:
void clearReference()
{
- bool release = false;
- mLock.lock();
- if (mHoldsRef) {
- mHoldsRef = false;
- release = true;
- }
- mLock.unlock();
- if (release) {
- decStrong(this);
- }
+ mList->remove(this);
+ }
+
+ bool matches(jobject obj) {
+ JNIEnv* env = javavm_to_jnienv(mVM);
+ return env->IsSameObject(obj, mObject);
}
protected:
@@ -415,12 +424,57 @@ protected:
private:
JavaVM* const mVM;
jobject const mObject;
- Mutex mLock;
- bool mHoldsRef;
+ sp<DeathRecipientList> mList;
};
// ----------------------------------------------------------------------------
+DeathRecipientList::~DeathRecipientList() {
+ AutoMutex _l(mLock);
+
+ // Should never happen -- the JavaDeathRecipient objects that have added themselves
+ // to the list are holding references on the list object. Only when they are torn
+ // down can the list header be destroyed.
+ if (mList.size() > 0) {
+ LOGE("Retiring binder %p with extant death recipients\n", this);
+ }
+}
+
+void DeathRecipientList::add(const sp<JavaDeathRecipient>& recipient) {
+ AutoMutex _l(mLock);
+
+ mList.push_back(recipient);
+}
+
+void DeathRecipientList::remove(const sp<JavaDeathRecipient>& recipient) {
+ AutoMutex _l(mLock);
+
+ List< sp<JavaDeathRecipient> >::iterator iter;
+ for (iter = mList.begin(); iter != mList.end(); iter++) {
+ if (*iter == recipient) {
+ mList.erase(iter);
+ return;
+ }
+ }
+}
+
+sp<JavaDeathRecipient> DeathRecipientList::find(jobject recipient) {
+ AutoMutex _l(mLock);
+
+ List< sp<JavaDeathRecipient> >::iterator iter;
+ for (iter = mList.begin(); iter != mList.end(); iter++) {
+ if ((*iter)->matches(recipient)) {
+ return *iter;
+ }
+ }
+ return NULL;
+}
+
+static KeyedVector<IBinder*, sp<DeathRecipientList> > gDeathRecipientsByIBinder;
+static Mutex gDeathRecipientMapLock;
+
+// ----------------------------------------------------------------------------
+
namespace android {
static void proxy_cleanup(const void* id, void* obj, void* cleanupCookie)
@@ -490,7 +544,7 @@ sp<IBinder> ibinderForJavaObject(JNIEnv* env, jobject obj)
if (env->IsInstanceOf(obj, gBinderOffsets.mClass)) {
JavaBBinderHolder* jbh = (JavaBBinderHolder*)
env->GetIntField(obj, gBinderOffsets.mObject);
- return jbh != NULL ? jbh->get(env) : NULL;
+ return jbh != NULL ? jbh->get(env, obj) : NULL;
}
if (env->IsInstanceOf(obj, gBinderProxyOffsets.mClass)) {
@@ -621,26 +675,26 @@ static void android_os_Binder_flushPendingCommands(JNIEnv* env, jobject clazz)
IPCThreadState::self()->flushCommands();
}
-static void android_os_Binder_init(JNIEnv* env, jobject clazz)
+static void android_os_Binder_init(JNIEnv* env, jobject obj)
{
- JavaBBinderHolder* jbh = new JavaBBinderHolder(env, clazz);
+ JavaBBinderHolder* jbh = new JavaBBinderHolder();
if (jbh == NULL) {
jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
return;
}
- LOGV("Java Binder %p: acquiring first ref on holder %p", clazz, jbh);
- jbh->incStrong(clazz);
- env->SetIntField(clazz, gBinderOffsets.mObject, (int)jbh);
+ LOGV("Java Binder %p: acquiring first ref on holder %p", obj, jbh);
+ jbh->incStrong((void*)android_os_Binder_init);
+ env->SetIntField(obj, gBinderOffsets.mObject, (int)jbh);
}
-static void android_os_Binder_destroy(JNIEnv* env, jobject clazz)
+static void android_os_Binder_destroy(JNIEnv* env, jobject obj)
{
JavaBBinderHolder* jbh = (JavaBBinderHolder*)
- env->GetIntField(clazz, gBinderOffsets.mObject);
+ env->GetIntField(obj, gBinderOffsets.mObject);
if (jbh != NULL) {
- env->SetIntField(clazz, gBinderOffsets.mObject, 0);
- LOGV("Java Binder %p: removing ref on holder %p", clazz, jbh);
- jbh->decStrong(clazz);
+ env->SetIntField(obj, gBinderOffsets.mObject, 0);
+ LOGV("Java Binder %p: removing ref on holder %p", obj, jbh);
+ jbh->decStrong((void*)android_os_Binder_init);
} else {
// Encountering an uninitialized binder is harmless. All it means is that
// the Binder was only partially initialized when its finalizer ran and called
@@ -648,7 +702,7 @@ static void android_os_Binder_destroy(JNIEnv* env, jobject clazz)
// For example, a Binder subclass constructor might have thrown an exception before
// it could delegate to its superclass's constructor. Consequently init() would
// not have been called and the holder pointer would remain NULL.
- LOGV("Java Binder %p: ignoring uninitialized binder", clazz);
+ LOGV("Java Binder %p: ignoring uninitialized binder", obj);
}
}
@@ -973,8 +1027,25 @@ static void android_os_BinderProxy_linkToDeath(JNIEnv* env, jobject obj,
LOGV("linkToDeath: binder=%p recipient=%p\n", target, recipient);
if (!target->localBinder()) {
- sp<JavaDeathRecipient> jdr = new JavaDeathRecipient(env, recipient);
- status_t err = target->linkToDeath(jdr, recipient, flags);
+ sp<JavaDeathRecipient> jdr;
+
+ {
+ sp<DeathRecipientList> list;
+ AutoMutex _maplocker(gDeathRecipientMapLock);
+
+ ssize_t listIndex = gDeathRecipientsByIBinder.indexOfKey(target);
+ if (listIndex < 0) {
+ // Set up the death notice bookkeeping for this binder lazily
+ list = new DeathRecipientList;
+ gDeathRecipientsByIBinder.add(target, list);
+ } else {
+ list = gDeathRecipientsByIBinder.valueAt(listIndex);
+ }
+
+ jdr = new JavaDeathRecipient(env, recipient, list);
+ }
+
+ status_t err = target->linkToDeath(jdr, NULL, flags);
if (err != NO_ERROR) {
// Failure adding the death recipient, so clear its reference
// now.
@@ -1003,15 +1074,33 @@ static jboolean android_os_BinderProxy_unlinkToDeath(JNIEnv* env, jobject obj,
LOGV("unlinkToDeath: binder=%p recipient=%p\n", target, recipient);
if (!target->localBinder()) {
- wp<IBinder::DeathRecipient> dr;
- status_t err = target->unlinkToDeath(NULL, recipient, flags, &dr);
- if (err == NO_ERROR && dr != NULL) {
- sp<IBinder::DeathRecipient> sdr = dr.promote();
- JavaDeathRecipient* jdr = static_cast<JavaDeathRecipient*>(sdr.get());
- if (jdr != NULL) {
- jdr->clearReference();
+ status_t err = NAME_NOT_FOUND;
+ sp<JavaDeathRecipient> origJDR;
+ {
+ AutoMutex _maplocker(gDeathRecipientMapLock);
+ ssize_t listIndex = gDeathRecipientsByIBinder.indexOfKey(target);
+ if (listIndex >= 0) {
+ sp<DeathRecipientList> list = gDeathRecipientsByIBinder.valueAt(listIndex);
+ origJDR = list->find(recipient);
+ } else {
+ // If there is no DeathRecipientList for this binder, it means the binder
+ // is dead and in the process of being cleaned up.
+ err = DEAD_OBJECT;
+ }
+ }
+ // If we found the matching recipient, proceed to unlink using that
+ if (origJDR != NULL) {
+ wp<IBinder::DeathRecipient> dr;
+ err = target->unlinkToDeath(origJDR, NULL, flags, &dr);
+ if (err == NO_ERROR && dr != NULL) {
+ sp<IBinder::DeathRecipient> sdr = dr.promote();
+ JavaDeathRecipient* jdr = static_cast<JavaDeathRecipient*>(sdr.get());
+ if (jdr != NULL) {
+ jdr->clearReference();
+ }
}
}
+
if (err == NO_ERROR || err == DEAD_OBJECT) {
res = JNI_TRUE;
} else {
@@ -1031,6 +1120,15 @@ static void android_os_BinderProxy_destroy(JNIEnv* env, jobject obj)
env->SetIntField(obj, gBinderProxyOffsets.mObject, 0);
b->decStrong(obj);
IPCThreadState::self()->flushCommands();
+
+ // tear down the death recipient bookkeeping
+ {
+ AutoMutex _maplocker(gDeathRecipientMapLock);
+ ssize_t listIndex = gDeathRecipientsByIBinder.indexOfKey(b);
+ if (listIndex >= 0) {
+ gDeathRecipientsByIBinder.removeItemsAt((size_t)listIndex);
+ }
+ }
}
// ----------------------------------------------------------------------------
@@ -1152,15 +1250,13 @@ static void android_os_Parcel_writeNative(JNIEnv* env, jobject clazz,
if (parcel == NULL) {
return;
}
- void *dest;
const status_t err = parcel->writeInt32(length);
if (err != NO_ERROR) {
jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
}
- dest = parcel->writeInplace(length);
-
+ void* dest = parcel->writeInplace(length);
if (dest == NULL) {
jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
return;
@@ -1168,7 +1264,7 @@ static void android_os_Parcel_writeNative(JNIEnv* env, jobject clazz,
jbyte* ar = (jbyte*)env->GetPrimitiveArrayCritical((jarray)data, 0);
if (ar) {
- memcpy(dest, ar, length);
+ memcpy(dest, ar + offset, length);
env->ReleasePrimitiveArrayCritical((jarray)data, ar, 0);
}
}
diff --git a/core/jni/android_view_Display.cpp b/core/jni/android_view_Display.cpp
index ac8835a60be7..160d654b658f 100644
--- a/core/jni/android_view_Display.cpp
+++ b/core/jni/android_view_Display.cpp
@@ -44,6 +44,8 @@ struct offsets_t {
};
static offsets_t offsets;
+static int gShortSize = -1;
+static int gLongSize = -1;
static int gOldSize = -1;
static int gNewSize = -1;
@@ -76,6 +78,10 @@ static jint android_view_Display_getWidth(
{
DisplayID dpy = env->GetIntField(clazz, offsets.display);
jint w = SurfaceComposerClient::getDisplayWidth(dpy);
+ if (gShortSize > 0) {
+ jint h = SurfaceComposerClient::getDisplayHeight(dpy);
+ return w < h ? gShortSize : gLongSize;
+ }
return w == gOldSize ? gNewSize : w;
}
@@ -84,9 +90,27 @@ static jint android_view_Display_getHeight(
{
DisplayID dpy = env->GetIntField(clazz, offsets.display);
int h = SurfaceComposerClient::getDisplayHeight(dpy);
+ if (gShortSize > 0) {
+ jint w = SurfaceComposerClient::getDisplayWidth(dpy);
+ return h < w ? gShortSize : gLongSize;
+ }
return h == gOldSize ? gNewSize : h;
}
+static jint android_view_Display_getRealWidth(
+ JNIEnv* env, jobject clazz)
+{
+ DisplayID dpy = env->GetIntField(clazz, offsets.display);
+ return SurfaceComposerClient::getDisplayWidth(dpy);
+}
+
+static jint android_view_Display_getRealHeight(
+ JNIEnv* env, jobject clazz)
+{
+ DisplayID dpy = env->GetIntField(clazz, offsets.display);
+ return SurfaceComposerClient::getDisplayHeight(dpy);
+}
+
static jint android_view_Display_getOrientation(
JNIEnv* env, jobject clazz)
{
@@ -100,13 +124,6 @@ static jint android_view_Display_getDisplayCount(
return SurfaceComposerClient::getNumberOfDisplays();
}
-static jint android_view_Display_unmapDisplaySize(
- JNIEnv* env, jclass clazz, jint newSize)
-{
- if (newSize == gNewSize) return gOldSize;
- return newSize;
-}
-
// ----------------------------------------------------------------------------
const char* const kClassPathName = "android/view/Display";
@@ -124,10 +141,12 @@ static JNINativeMethod gMethods[] = {
(void*)android_view_Display_getWidth },
{ "getHeight", "()I",
(void*)android_view_Display_getHeight },
+ { "getRealWidth", "()I",
+ (void*)android_view_Display_getRealWidth },
+ { "getRealHeight", "()I",
+ (void*)android_view_Display_getRealHeight },
{ "getOrientation", "()I",
- (void*)android_view_Display_getOrientation },
- { "unmapDisplaySize", "(I)I",
- (void*)android_view_Display_unmapDisplaySize }
+ (void*)android_view_Display_getOrientation }
};
void nativeClassInit(JNIEnv* env, jclass clazz)
@@ -146,7 +165,15 @@ int register_android_view_Display(JNIEnv* env)
int len = property_get("persist.demo.screensizehack", buf, "");
if (len > 0) {
int temp1, temp2;
- if (sscanf(buf, "%d=%d", &temp1, &temp2) == 2) {
+ if (sscanf(buf, "%dx%d", &temp1, &temp2) == 2) {
+ if (temp1 < temp2) {
+ gShortSize = temp1;
+ gLongSize = temp2;
+ } else {
+ gShortSize = temp2;
+ gLongSize = temp1;
+ }
+ } else if (sscanf(buf, "%d=%d", &temp1, &temp2) == 2) {
gOldSize = temp1;
gNewSize = temp2;
}
@@ -157,4 +184,3 @@ int register_android_view_Display(JNIEnv* env)
}
};
-
diff --git a/core/jni/android_view_Surface.cpp b/core/jni/android_view_Surface.cpp
index be66e9c4d5e9..bd2e6694f3f5 100644
--- a/core/jni/android_view_Surface.cpp
+++ b/core/jni/android_view_Surface.cpp
@@ -177,7 +177,7 @@ static sp<Surface> getSurface(JNIEnv* env, jobject clazz)
sp<ANativeWindow> android_Surface_getNativeWindow(
JNIEnv* env, jobject clazz) {
- return getSurface(env, clazz).get();
+ return getSurface(env, clazz);
}
static void setSurface(JNIEnv* env, jobject clazz, const sp<Surface>& surface)
diff --git a/include/binder/IBinder.h b/include/binder/IBinder.h
index 749a977b83b5..81b56c2b2b3b 100644
--- a/include/binder/IBinder.h
+++ b/include/binder/IBinder.h
@@ -98,7 +98,7 @@ public:
* Register the @a recipient for a notification if this binder
* goes away. If this binder object unexpectedly goes away
* (typically because its hosting process has been killed),
- * then DeathRecipient::binderDied() will be called with a referene
+ * then DeathRecipient::binderDied() will be called with a reference
* to this.
*
* The @a cookie is optional -- if non-NULL, it should be a
diff --git a/include/utils/StrongPointer.h b/include/utils/StrongPointer.h
index a8c989749b60..49fa3a8d6f62 100644
--- a/include/utils/StrongPointer.h
+++ b/include/utils/StrongPointer.h
@@ -133,7 +133,7 @@ sp<T>::sp(const sp<T>& other)
template<typename T> template<typename U>
sp<T>::sp(U* other) : m_ptr(other)
{
- if (other) other->incStrong(this);
+ if (other) ((T*)other)->incStrong(this);
}
template<typename T> template<typename U>
@@ -170,7 +170,7 @@ sp<T>& sp<T>::operator = (T* other)
template<typename T> template<typename U>
sp<T>& sp<T>::operator = (const sp<U>& other)
{
- U* otherPtr(other.m_ptr);
+ T* otherPtr(other.m_ptr);
if (otherPtr) otherPtr->incStrong(this);
if (m_ptr) m_ptr->decStrong(this);
m_ptr = otherPtr;
@@ -180,7 +180,7 @@ sp<T>& sp<T>::operator = (const sp<U>& other)
template<typename T> template<typename U>
sp<T>& sp<T>::operator = (U* other)
{
- if (other) other->incStrong(this);
+ if (other) ((T*)other)->incStrong(this);
if (m_ptr) m_ptr->decStrong(this);
m_ptr = other;
return *this;
diff --git a/libs/surfaceflinger_client/Surface.cpp b/libs/surfaceflinger_client/Surface.cpp
index 1e9bd744f51c..68611d6a37e4 100644
--- a/libs/surfaceflinger_client/Surface.cpp
+++ b/libs/surfaceflinger_client/Surface.cpp
@@ -1040,7 +1040,7 @@ int Surface::getBufferIndex(const sp<GraphicBuffer>& buffer) const
// e.g. if GraphicBuffer is used to wrap an android_native_buffer_t that
// was dequeued from an ANativeWindow.
for (size_t i = 0; i < mBuffers.size(); i++) {
- if (buffer->handle == mBuffers[i]->handle) {
+ if (mBuffers[i] != 0 && buffer->handle == mBuffers[i]->handle) {
idx = mBuffers[i]->getIndex();
break;
}
diff --git a/libs/utils/RefBase.cpp b/libs/utils/RefBase.cpp
index 0fd404d66c1e..bb6c1255f38a 100644
--- a/libs/utils/RefBase.cpp
+++ b/libs/utils/RefBase.cpp
@@ -99,20 +99,38 @@ public:
#if DEBUG_REFS_FATAL_SANITY_CHECKS
LOG_ALWAYS_FATAL("Strong references remain!");
#else
- LOGE("Strong references remain!");
+ LOGE("Strong references remain:");
#endif
+ ref_entry* refs = mStrongRefs;
+ while (refs) {
+ char inc = refs->ref >= 0 ? '+' : '-';
+ LOGD("\t%c ID %p (ref %d):", inc, refs->id, refs->ref);
+#if DEBUG_REFS_CALLSTACK_ENABLED
+ refs->stack.dump();
+#endif;
+ refs = refs->next;
+ }
}
if (!mRetain && mWeakRefs != NULL) {
dumpStack = true;
#if DEBUG_REFS_FATAL_SANITY_CHECKS
- LOG_ALWAYS_FATAL("Weak references remain!");
+ LOG_ALWAYS_FATAL("Weak references remain:");
#else
LOGE("Weak references remain!");
#endif
+ ref_entry* refs = mWeakRefs;
+ while (refs) {
+ char inc = refs->ref >= 0 ? '+' : '-';
+ LOGD("\t%c ID %p (ref %d):", inc, refs->id, refs->ref);
+#if DEBUG_REFS_CALLSTACK_ENABLED
+ refs->stack.dump();
+#endif;
+ refs = refs->next;
+ }
}
-
if (dumpStack) {
+ LOGE("above errors at:");
CallStack stack;
stack.update();
stack.dump();
@@ -228,7 +246,8 @@ private:
if (mTrackEnabled) {
AutoMutex _l(mMutex);
- ref_entry* ref = *refs;
+ ref_entry* const head = *refs;
+ ref_entry* ref = head;
while (ref != NULL) {
if (ref->id == id) {
*refs = ref->next;
@@ -249,6 +268,13 @@ private:
"(weakref_type %p) that doesn't exist!",
id, mBase, this);
+ ref = head;
+ while (ref) {
+ char inc = ref->ref >= 0 ? '+' : '-';
+ LOGD("\t%c ID %p (ref %d):", inc, ref->id, ref->ref);
+ ref = ref->next;
+ }
+
CallStack stack;
stack.update();
stack.dump();
diff --git a/media/java/android/media/videoeditor/MediaArtistNativeHelper.java b/media/java/android/media/videoeditor/MediaArtistNativeHelper.java
index e0df257eca55..53bbb0ff5531 100644
--- a/media/java/android/media/videoeditor/MediaArtistNativeHelper.java
+++ b/media/java/android/media/videoeditor/MediaArtistNativeHelper.java
@@ -3556,7 +3556,7 @@ class MediaArtistNativeHelper {
case MediaProperties.ASPECT_RATIO_4_3:
if (height == MediaProperties.HEIGHT_480)
retValue = VideoFrameSize.VGA;
- if (height == MediaProperties.HEIGHT_720)
+ else if (height == MediaProperties.HEIGHT_720)
retValue = VideoFrameSize.S720p;
break;
case MediaProperties.ASPECT_RATIO_5_3:
@@ -3566,6 +3566,8 @@ class MediaArtistNativeHelper {
case MediaProperties.ASPECT_RATIO_11_9:
if (height == MediaProperties.HEIGHT_144)
retValue = VideoFrameSize.QCIF;
+ else if (height == MediaProperties.HEIGHT_288)
+ retValue = VideoFrameSize.CIF;
break;
}
if (retValue == VideoFrameSize.SIZE_UNDEFINED) {
diff --git a/media/java/android/media/videoeditor/MediaProperties.java b/media/java/android/media/videoeditor/MediaProperties.java
index 0b7ec081cca3..022580779c37 100755
--- a/media/java/android/media/videoeditor/MediaProperties.java
+++ b/media/java/android/media/videoeditor/MediaProperties.java
@@ -29,6 +29,7 @@ public class MediaProperties {
* Supported heights
*/
public static final int HEIGHT_144 = 144;
+ public static final int HEIGHT_288 = 288;
public static final int HEIGHT_360 = 360;
public static final int HEIGHT_480 = 480;
public static final int HEIGHT_720 = 720;
@@ -82,7 +83,8 @@ public class MediaProperties {
@SuppressWarnings({"unchecked"})
private static final Pair<Integer, Integer>[] ASPECT_RATIO_11_9_RESOLUTIONS =
new Pair[] {
- new Pair<Integer, Integer>(176, HEIGHT_144)
+ new Pair<Integer, Integer>(176, HEIGHT_144),
+ new Pair<Integer, Integer>(352, HEIGHT_288)
};
@SuppressWarnings({"unchecked"})
diff --git a/media/java/android/media/videoeditor/VideoEditorImpl.java b/media/java/android/media/videoeditor/VideoEditorImpl.java
index 1fb8c615465d..7e1f73aa88fc 100755
--- a/media/java/android/media/videoeditor/VideoEditorImpl.java
+++ b/media/java/android/media/videoeditor/VideoEditorImpl.java
@@ -389,6 +389,8 @@ public class VideoEditorImpl implements VideoEditor {
switch (height) {
case MediaProperties.HEIGHT_144:
break;
+ case MediaProperties.HEIGHT_288:
+ break;
case MediaProperties.HEIGHT_360:
break;
case MediaProperties.HEIGHT_480:
diff --git a/media/libstagefright/colorconversion/ColorConverter.cpp b/media/libstagefright/colorconversion/ColorConverter.cpp
index d518c9768384..3b92e5d0072e 100644
--- a/media/libstagefright/colorconversion/ColorConverter.cpp
+++ b/media/libstagefright/colorconversion/ColorConverter.cpp
@@ -187,7 +187,7 @@ status_t ColorConverter::convertCbYCrY(
status_t ColorConverter::convertYUV420Planar(
const BitmapParams &src, const BitmapParams &dst) {
- if (!((dst.mWidth & 3) == 0
+ if (!((dst.mWidth & 1) == 0
&& (src.mCropLeft & 1) == 0
&& src.cropWidth() == dst.cropWidth()
&& src.cropHeight() == dst.cropHeight())) {
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaFrameworkPerfTestRunner.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaFrameworkPerfTestRunner.java
index 988b229474b6..a6cf3551ed40 100755
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaFrameworkPerfTestRunner.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaFrameworkPerfTestRunner.java
@@ -21,9 +21,10 @@ import com.android.mediaframeworktest.performance.MediaPlayerPerformance;
import com.android.mediaframeworktest.performance.VideoEditorPerformance;
import junit.framework.TestSuite;
+import android.os.Bundle;
import android.test.InstrumentationTestRunner;
import android.test.InstrumentationTestSuite;
-
+import android.util.Log;
/**
* Instrumentation Test Runner for all MediaPlayer tests.
@@ -36,19 +37,30 @@ import android.test.InstrumentationTestSuite;
public class MediaFrameworkPerfTestRunner extends InstrumentationTestRunner {
+ public static boolean mGetNativeHeapDump = false;
+
+
+ @Override
+ public TestSuite getAllTests() {
+ TestSuite suite = new InstrumentationTestSuite(this);
+ suite.addTestSuite(MediaPlayerPerformance.class);
+ /* Video Editor performance Test cases */
+ suite.addTestSuite(VideoEditorPerformance.class);
+ return suite;
+ }
- @Override
- public TestSuite getAllTests() {
- TestSuite suite = new InstrumentationTestSuite(this);
- suite.addTestSuite(MediaPlayerPerformance.class);
- /*Video Editor performance Test cases*/
- suite.addTestSuite(VideoEditorPerformance.class);
- return suite;
- }
+ @Override
+ public ClassLoader getLoader() {
+ return MediaFrameworkTestRunner.class.getClassLoader();
+ }
- @Override
- public ClassLoader getLoader() {
- return MediaFrameworkTestRunner.class.getClassLoader();
- }
+ @Override
+ public void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+ String get_heap_dump = (String) icicle.get("get_heap_dump");
+ if (get_heap_dump != null) {
+ mGetNativeHeapDump = true;
+ }
+ }
}
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaTestUtil.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaTestUtil.java
new file mode 100755
index 000000000000..0183b5df8d59
--- /dev/null
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaTestUtil.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.mediaframeworktest;
+
+import java.io.FileOutputStream;
+
+import android.os.Debug;
+import android.os.Environment;
+
+/**
+ *
+ * Utilities for media framework test.
+ *
+ */
+public class MediaTestUtil {
+ private MediaTestUtil(){
+ }
+
+ private static final String STORAGE_PATH =
+ Environment.getExternalStorageDirectory().toString();
+
+ //Catpure the heapdump for memory leaksage analysis\
+ public static void getNativeHeapDump (String name) throws Exception {
+ System.gc();
+ System.runFinalization();
+ Thread.sleep(1000);
+ FileOutputStream o = new FileOutputStream(STORAGE_PATH + '/' +name + ".dump");
+ Debug.dumpNativeHeap(o.getFD());
+ o.close();
+ }
+} \ No newline at end of file
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaRecorderTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaRecorderTest.java
index ce6db68aab43..82df6690c571 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaRecorderTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaRecorderTest.java
@@ -28,7 +28,7 @@ import android.media.MediaRecorder;
import android.media.EncoderCapabilities;
import android.media.EncoderCapabilities.VideoEncoderCap;
import android.media.EncoderCapabilities.AudioEncoderCap;
-import android.test.ActivityInstrumentationTestCase;
+import android.test.ActivityInstrumentationTestCase2;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
@@ -42,7 +42,7 @@ import java.util.List;
/**
* Junit / Instrumentation test case for the media recorder api
*/
-public class MediaRecorderTest extends ActivityInstrumentationTestCase<MediaFrameworkTest> {
+public class MediaRecorderTest extends ActivityInstrumentationTestCase2<MediaFrameworkTest> {
private String TAG = "MediaRecorderTest";
private int mOutputDuration =0;
private int mOutputVideoWidth = 0;
@@ -62,9 +62,9 @@ public class MediaRecorderTest extends ActivityInstrumentationTestCase<MediaFram
}
protected void setUp() throws Exception {
- super.setUp();
- Log.v(TAG,"create the media recorder");
+ getActivity();
mRecorder = new MediaRecorder();
+ super.setUp();
}
private void recordVideo(int frameRate, int width, int height,
@@ -199,8 +199,6 @@ public class MediaRecorderTest extends ActivityInstrumentationTestCase<MediaFram
return false;
}
-
-
private void getOutputVideoProperty(String outputFilePath) {
MediaPlayer mediaPlayer = new MediaPlayer();
try {
@@ -215,8 +213,6 @@ public class MediaRecorderTest extends ActivityInstrumentationTestCase<MediaFram
Thread.sleep(1000);
mOutputVideoHeight = mediaPlayer.getVideoHeight();
mOutputVideoWidth = mediaPlayer.getVideoWidth();
- //mOutputVideoHeight = CodecTest.videoHeight(outputFilePath);
- //mOutputVideoWidth = CodecTest.videoWidth(outputFilePath);
mediaPlayer.release();
} catch (Exception e) {
Log.v(TAG, e.toString());
@@ -224,11 +220,6 @@ public class MediaRecorderTest extends ActivityInstrumentationTestCase<MediaFram
}
}
- private void removeFile(String filePath) {
- File fileRemove = new File(filePath);
- fileRemove.delete();
- }
-
private boolean validateVideo(String filePath, int width, int height) {
boolean validVideo = false;
getOutputVideoProperty(filePath);
@@ -237,72 +228,9 @@ public class MediaRecorderTest extends ActivityInstrumentationTestCase<MediaFram
validVideo = true;
}
Log.v(TAG, "width = " + mOutputVideoWidth + " height = " + mOutputVideoHeight + " Duration = " + mOutputDuration);
- //removeFile(filePath);
return validVideo;
}
-
-
- //Format: HVGA h263
- @Suppress
- public void testHVGAH263() throws Exception {
- boolean videoRecordedResult = false;
- recordVideo(15, 480, 320, MediaRecorder.VideoEncoder.H263,
- MediaRecorder.OutputFormat.THREE_GPP, MediaNames.RECORDED_HVGA_H263, false);
- videoRecordedResult = validateVideo(MediaNames.RECORDED_HVGA_H263, 480, 320);
- assertTrue("HVGAH263", videoRecordedResult);
- }
-
- //Format: QVGA h263
- @Suppress
- public void testQVGAH263() throws Exception {
- boolean videoRecordedResult = false;
- recordVideo(15, 320, 240, MediaRecorder.VideoEncoder.H263,
- MediaRecorder.OutputFormat.THREE_GPP, MediaNames.RECORDED_QVGA_H263, false);
- videoRecordedResult = validateVideo(MediaNames.RECORDED_QVGA_H263, 320, 240);
- assertTrue("QVGAH263", videoRecordedResult);
- }
-
- //Format: SQVGA h263
- @Suppress
- public void testSQVGAH263() throws Exception {
- boolean videoRecordedResult = false;
- recordVideo(15, 240, 160, MediaRecorder.VideoEncoder.H263,
- MediaRecorder.OutputFormat.THREE_GPP, MediaNames.RECORDED_SQVGA_H263, false);
- videoRecordedResult = validateVideo(MediaNames.RECORDED_SQVGA_H263, 240, 160);
- assertTrue("SQVGAH263", videoRecordedResult);
- }
-
- //Format: QCIF h263
- @LargeTest
- public void testQCIFH263() throws Exception {
- boolean videoRecordedResult = false;
- recordVideo(15, 176, 144, MediaRecorder.VideoEncoder.H263,
- MediaRecorder.OutputFormat.THREE_GPP, MediaNames.RECORDED_QCIF_H263, false);
- videoRecordedResult = validateVideo(MediaNames.RECORDED_QCIF_H263, 176, 144);
- assertTrue("QCIFH263", videoRecordedResult);
- }
-
- //Format: CIF h263
- @LargeTest
- public void testCIFH263() throws Exception {
- boolean videoRecordedResult = false;
- recordVideo(15, 352, 288, MediaRecorder.VideoEncoder.H263,
- MediaRecorder.OutputFormat.THREE_GPP, MediaNames.RECORDED_CIF_H263, false);
- videoRecordedResult = validateVideo(MediaNames.RECORDED_CIF_H263, 352, 288);
- assertTrue("CIFH263", videoRecordedResult);
- }
-
-
-
- @LargeTest
- public void testVideoOnly() throws Exception {
- boolean videoRecordedResult = false;
- recordVideo(15, 176, 144, MediaRecorder.VideoEncoder.H263,
- MediaRecorder.OutputFormat.MPEG_4, MediaNames.RECORDED_VIDEO_3GP, true);
- videoRecordedResult = validateVideo(MediaNames.RECORDED_VIDEO_3GP, 176, 144);
- assertTrue("QCIFH263 Video Only", videoRecordedResult);
- }
-
+
@LargeTest
/*
* This test case set the camera in portrait mode.
@@ -332,74 +260,6 @@ public class MediaRecorderTest extends ActivityInstrumentationTestCase<MediaFram
assertTrue("PortraitH263", videoRecordedResult);
}
- @Suppress
- public void testHVGAMP4() throws Exception {
- boolean videoRecordedResult = false;
- recordVideo(15, 480, 320, MediaRecorder.VideoEncoder.MPEG_4_SP,
- MediaRecorder.OutputFormat.MPEG_4, MediaNames.RECORDED_HVGA_MP4, false);
- videoRecordedResult = validateVideo(MediaNames.RECORDED_HVGA_MP4, 480, 320);
- assertTrue("HVGAMP4", videoRecordedResult);
- }
-
- @Suppress
- public void testQVGAMP4() throws Exception {
- boolean videoRecordedResult = false;
- recordVideo(15, 320, 240, MediaRecorder.VideoEncoder.MPEG_4_SP,
- MediaRecorder.OutputFormat.MPEG_4, MediaNames.RECORDED_QVGA_MP4, false);
- videoRecordedResult = validateVideo(MediaNames.RECORDED_QVGA_MP4, 320, 240);
- assertTrue("QVGAMP4", videoRecordedResult);
- }
-
- @Suppress
- public void testSQVGAMP4() throws Exception {
- boolean videoRecordedResult = false;
- recordVideo(15, 240, 160, MediaRecorder.VideoEncoder.MPEG_4_SP,
- MediaRecorder.OutputFormat.MPEG_4, MediaNames.RECORDED_SQVGA_MP4, false);
- videoRecordedResult = validateVideo(MediaNames.RECORDED_SQVGA_MP4, 240, 160);
- assertTrue("SQVGAMP4", videoRecordedResult);
- }
-
- //Format: QCIF MP4
- @LargeTest
- public void testQCIFMP4() throws Exception {
- boolean videoRecordedResult = false;
- recordVideo(15, 176, 144, MediaRecorder.VideoEncoder.MPEG_4_SP,
- MediaRecorder.OutputFormat.MPEG_4, MediaNames.RECORDED_QCIF_MP4, false);
- videoRecordedResult = validateVideo(MediaNames.RECORDED_QCIF_MP4, 176, 144);
- assertTrue("QCIFMP4", videoRecordedResult);
- }
-
-
- //Format: CIF MP4
- @LargeTest
- public void testCIFMP4() throws Exception {
- boolean videoRecordedResult = false;
- recordVideo(15, 352, 288, MediaRecorder.VideoEncoder.MPEG_4_SP,
- MediaRecorder.OutputFormat.MPEG_4, MediaNames.RECORDED_CIF_MP4, false);
- videoRecordedResult = validateVideo(MediaNames.RECORDED_CIF_MP4, 352, 288);
- assertTrue("CIFMP4", videoRecordedResult);
- }
-
-
- //Format: CIF MP4 output format 3gpp
- @LargeTest
- public void testCIFMP43GPP() throws Exception {
- boolean videoRecordedResult = false;
- recordVideo(15, 352, 288, MediaRecorder.VideoEncoder.MPEG_4_SP,
- MediaRecorder.OutputFormat.THREE_GPP, MediaNames.RECORDED_VIDEO_3GP, false);
- videoRecordedResult = validateVideo(MediaNames.RECORDED_VIDEO_3GP, 352, 288);
- assertTrue("CIFMP4 3GPP", videoRecordedResult);
- }
-
- @LargeTest
- public void testQCIFH2633GPP() throws Exception {
- boolean videoRecordedResult = false;
- recordVideo(15, 176, 144, MediaRecorder.VideoEncoder.H263,
- MediaRecorder.OutputFormat.THREE_GPP, MediaNames.RECORDED_VIDEO_3GP, false);
- videoRecordedResult = validateVideo(MediaNames.RECORDED_VIDEO_3GP, 176, 144);
- assertTrue("QCIFH263 3GPP", videoRecordedResult);
- }
-
@LargeTest
public void testInvalidVideoPath() throws Exception {
boolean isTestInvalidVideoPathSuccessful = false;
@@ -408,23 +268,6 @@ public class MediaRecorderTest extends ActivityInstrumentationTestCase<MediaFram
assertTrue("Invalid outputFile Path", isTestInvalidVideoPathSuccessful);
}
- @Suppress
- public void testInvalidVideoSize() throws Exception {
- boolean isTestInvalidVideoSizeSuccessful = false;
- isTestInvalidVideoSizeSuccessful = invalidRecordSetting(15, 800, 600, MediaRecorder.VideoEncoder.H263,
- MediaRecorder.OutputFormat.THREE_GPP, MediaNames.RECORDED_VIDEO_3GP, false);
- assertTrue("Invalid video Size", isTestInvalidVideoSizeSuccessful);
- }
-
- @Suppress
- @LargeTest
- public void testInvalidFrameRate() throws Exception {
- boolean isTestInvalidFrameRateSuccessful = false;
- isTestInvalidFrameRateSuccessful = invalidRecordSetting(50, 176, 144, MediaRecorder.VideoEncoder.H263,
- MediaRecorder.OutputFormat.THREE_GPP, MediaNames.RECORDED_VIDEO_3GP, false);
- assertTrue("Invalid FrameRate", isTestInvalidFrameRateSuccessful);
- }
-
@LargeTest
//test cases for the new codec
public void testDeviceSpecificCodec() throws Exception {
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/performance/MediaPlayerPerformance.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/performance/MediaPlayerPerformance.java
index 0e3029bbb3d7..34affa7b1cb7 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/performance/MediaPlayerPerformance.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/performance/MediaPlayerPerformance.java
@@ -17,7 +17,9 @@
package com.android.mediaframeworktest.performance;
import com.android.mediaframeworktest.MediaFrameworkTest;
+import com.android.mediaframeworktest.MediaFrameworkPerfTestRunner;
import com.android.mediaframeworktest.MediaNames;
+import com.android.mediaframeworktest.MediaTestUtil;
import android.database.sqlite.SQLiteDatabase;
import android.hardware.Camera;
@@ -27,7 +29,7 @@ import android.media.MediaRecorder;
import android.os.ConditionVariable;
import android.os.Looper;
import android.os.SystemClock;
-import android.test.ActivityInstrumentationTestCase;
+import android.test.ActivityInstrumentationTestCase2;
import android.test.suitebuilder.annotation.LargeTest;
import android.test.suitebuilder.annotation.Suppress;
import android.util.Log;
@@ -52,7 +54,7 @@ import android.hardware.Camera.PreviewCallback;
* Junit / Instrumentation - performance measurement for media player and
* recorder
*/
-public class MediaPlayerPerformance extends ActivityInstrumentationTestCase<MediaFrameworkTest> {
+public class MediaPlayerPerformance extends ActivityInstrumentationTestCase2<MediaFrameworkTest> {
private String TAG = "MediaPlayerPerformance";
@@ -87,6 +89,15 @@ public class MediaPlayerPerformance extends ActivityInstrumentationTestCase<Medi
protected void setUp() throws Exception {
super.setUp();
+ getActivity();
+ if (MediaFrameworkPerfTestRunner.mGetNativeHeapDump)
+ MediaTestUtil.getNativeHeapDump(this.getName() + "_before");
+ }
+
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ if (MediaFrameworkPerfTestRunner.mGetNativeHeapDump)
+ MediaTestUtil.getNativeHeapDump(this.getName() + "_after");
}
public void createDB() {
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_ime_default.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_ime_default.png
index e4d5a328bdb3..7b54daff94c7 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_ime_default.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_ime_default.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xlarge-mdpi/recents_thumbnail_bg.png b/packages/SystemUI/res/drawable-xlarge-mdpi/recents_thumbnail_bg.png
index 9f72549353c6..87a67c9cf474 100644
--- a/packages/SystemUI/res/drawable-xlarge-mdpi/recents_thumbnail_bg.png
+++ b/packages/SystemUI/res/drawable-xlarge-mdpi/recents_thumbnail_bg.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xlarge-mdpi/recents_thumbnail_bg_press.png b/packages/SystemUI/res/drawable-xlarge-mdpi/recents_thumbnail_bg_press.png
new file mode 100644
index 000000000000..7f86fb35f5e0
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xlarge-mdpi/recents_thumbnail_bg_press.png
Binary files differ
diff --git a/packages/SystemUI/res/layout-xlarge/status_bar_recent_item.xml b/packages/SystemUI/res/layout-xlarge/status_bar_recent_item.xml
index d7e16337d47f..bfa6c36a096e 100644
--- a/packages/SystemUI/res/layout-xlarge/status_bar_recent_item.xml
+++ b/packages/SystemUI/res/layout-xlarge/status_bar_recent_item.xml
@@ -22,14 +22,14 @@
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="wrap_content"
- android:layout_width="156dip">
+ android:layout_width="@dimen/status_bar_recents_thumbnail_view_width">
<ImageView android:id="@+id/app_thumbnail"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
- android:layout_marginLeft="105dip"
+ android:layout_marginLeft="@dimen/status_bar_recents_thumbnail_left_margin"
android:scaleType="center"
/>
@@ -40,8 +40,8 @@
android:layout_alignParentTop="true"
android:layout_marginLeft="123dip"
android:layout_marginTop="16dip"
- android:maxWidth="64dip"
- android:maxHeight="64dip"
+ android:maxWidth="@dimen/status_bar_recents_thumbnail_max_width"
+ android:maxHeight="@dimen/status_bar_recents_thumbnail_max_height"
android:adjustViewBounds="true"
/>
diff --git a/packages/SystemUI/res/layout-xlarge/status_bar_recent_panel.xml b/packages/SystemUI/res/layout-xlarge/status_bar_recent_panel.xml
index ecd2b6f225c7..4be57a20c2ca 100644
--- a/packages/SystemUI/res/layout-xlarge/status_bar_recent_panel.xml
+++ b/packages/SystemUI/res/layout-xlarge/status_bar_recent_panel.xml
@@ -36,36 +36,35 @@
<LinearLayout android:id="@+id/recents_glow"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:orientation="horizontal"
- android:layout_marginBottom="-28dip"
+ android:layout_marginBottom="-52dip"
android:layout_gravity="bottom"
- android:background="@drawable/recents_blue_glow">
+ android:background="@drawable/recents_blue_glow"
+ android:orientation="horizontal"
+ >
- <LinearLayout android:id="@+id/recents_container"
- android:layout_width="356dip"
+ <ListView android:id="@+id/recents_container"
+ android:layout_width="@dimen/status_bar_recents_width"
android:layout_height="wrap_content"
- android:orientation="vertical"
android:layout_marginRight="100dip"
+ android:divider="@null"
+ android:scrollingCache="true"
+ android:stackFromBottom="true"
+ android:fadingEdge="vertical"
+ android:scrollbars="none"
+ android:fadingEdgeLength="30dip"
+ android:listSelector="@drawable/recents_thumbnail_bg_press"
/>
</LinearLayout>
</FrameLayout>
- <!-- The outer FrameLayout is just used as an opaque background for the dismiss icon -->
- <FrameLayout
+ <View android:id="@+id/recents_dismiss_button"
android:layout_width="80px"
android:layout_height="@*android:dimen/status_bar_height"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
- android:background="#ff000000">
-
- <View android:id="@+id/recents_dismiss_button"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:background="@drawable/ic_sysbar_back_ime"
- />
-
- </FrameLayout>
+ android:background="@drawable/ic_sysbar_back_ime"
+ />
</com.android.systemui.statusbar.tablet.RecentAppsPanel>
diff --git a/packages/SystemUI/res/layout-xlarge/status_bar_recent_panel_footer.xml b/packages/SystemUI/res/layout-xlarge/status_bar_recent_panel_footer.xml
new file mode 100644
index 000000000000..4d14d1fb9fe2
--- /dev/null
+++ b/packages/SystemUI/res/layout-xlarge/status_bar_recent_panel_footer.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/* apps/common/assets/default/default/skins/StatusBar.xml
+**
+** Copyright 2011, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/listview_footer_padding"
+ android:layout_height="24dip"
+ android:layout_width="match_parent">
+</FrameLayout>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 93cf3778bc9c..88cd43c74da0 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -2,21 +2,34 @@
<!--
* Copyright (c) 2006, The Android Open Source Project
*
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * http://www.apache.org/licenses/LICENSE-2.0
*
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
* limitations under the License.
*/
-->
<resources>
<!-- Margin at the edge of the screen to ignore touch events for in the windowshade. -->
<dimen name="status_bar_edge_ignore">5dp</dimen>
+
+ <!-- Recent Applications parameters -->
+ <!-- Width of a recent app view, including all content -->
+ <dimen name="status_bar_recents_thumbnail_view_width">156dp</dimen>
+ <!-- How far the thumbnail for a recent app appears from left edge -->
+ <dimen name="status_bar_recents_thumbnail_left_margin">110dp</dimen>
+ <!-- Upper width limit for application icon -->
+ <dimen name="status_bar_recents_thumbnail_max_width">64dp</dimen>
+ <!-- Upper height limit for application icon -->
+ <dimen name="status_bar_recents_thumbnail_max_height">64dp</dimen>
+ <!-- Width of scrollable area in recents -->
+ <dimen name="status_bar_recents_width">356dp</dimen>
+
</resources>
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/RecentAppsPanel.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/RecentAppsPanel.java
index e0d558f2580d..ebe1a7c9c622 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/RecentAppsPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/RecentAppsPanel.java
@@ -40,37 +40,43 @@ import android.graphics.RectF;
import android.graphics.Shader.TileMode;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
+import android.os.Parcelable;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.Log;
import android.util.Slog;
+import android.view.LayoutInflater;
import android.view.View;
-import android.view.View.OnClickListener;
-import android.view.animation.DecelerateInterpolator;
+import android.view.ViewGroup;
+import android.widget.AdapterView;
+import android.widget.AdapterView.OnItemClickListener;
+import android.widget.BaseAdapter;
import android.widget.ImageView;
-import android.widget.LinearLayout;
+import android.widget.ListView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import com.android.systemui.R;
-public class RecentAppsPanel extends RelativeLayout implements StatusBarPanel, OnClickListener {
+public class RecentAppsPanel extends RelativeLayout implements StatusBarPanel, OnItemClickListener {
private static final int GLOW_PADDING = 15;
private static final String TAG = "RecentAppsPanel";
private static final boolean DEBUG = TabletStatusBar.DEBUG;
- private static final int DISPLAY_TASKS_PORTRAIT = 7; // Limited by max binder transaction size
- private static final int DISPLAY_TASKS_LANDSCAPE = 5; // number of recent tasks to display
- private static final int MAX_TASKS = DISPLAY_TASKS_PORTRAIT + 1; // allow extra for non-apps
+ private static final int DISPLAY_TASKS = 20;
+ private static final int MAX_TASKS = DISPLAY_TASKS + 1; // allow extra for non-apps
+ private static final int BOTTOM_OFFSET = 28; // TODO: Get from dimens.xml
private TabletStatusBar mBar;
private ArrayList<ActivityDescription> mActivityDescriptions;
private int mIconDpi;
private View mRecentsScrim;
private View mRecentsGlowView;
- private LinearLayout mRecentsContainer;
+ private ListView mRecentsContainer;
private Bitmap mGlowBitmap;
private boolean mShowing;
private Choreographer mChoreo;
private View mRecentsDismissButton;
+ private ActvityDescriptionAdapter mListAdapter;
+ protected int mLastVisibleItem;
static class ActivityDescription {
int id;
@@ -98,6 +104,63 @@ public class RecentAppsPanel extends RelativeLayout implements StatusBarPanel, O
}
};
+ private static class ViewHolder {
+ private ImageView thumbnailView;
+ private ImageView iconView;
+ private TextView labelView;
+ private TextView descriptionView;
+ private ActivityDescription activityDescription;
+ }
+
+ private class ActvityDescriptionAdapter extends BaseAdapter {
+ private LayoutInflater mInflater;
+
+ public ActvityDescriptionAdapter(Context context) {
+ mInflater = LayoutInflater.from(context);
+ }
+
+ public int getCount() {
+ return mActivityDescriptions != null ? mActivityDescriptions.size() : 0;
+ }
+
+ public Object getItem(int position) {
+ return position; // we only need the index
+ }
+
+ public long getItemId(int position) {
+ return position; // we just need something unique for this position
+ }
+
+ public View getView(int position, View convertView, ViewGroup parent) {
+ ViewHolder holder;
+ if (convertView == null) {
+ convertView = mInflater.inflate(R.layout.status_bar_recent_item, null);
+ holder = new ViewHolder();
+ holder.thumbnailView = (ImageView) convertView.findViewById(R.id.app_thumbnail);
+ holder.iconView = (ImageView) convertView.findViewById(R.id.app_icon);
+ holder.labelView = (TextView) convertView.findViewById(R.id.app_label);
+ holder.descriptionView = (TextView) convertView.findViewById(R.id.app_description);
+ convertView.setTag(holder);
+ } else {
+ holder = (ViewHolder) convertView.getTag();
+ }
+
+ // activityId is reverse since most recent appears at the bottom...
+ final int activityId = mActivityDescriptions.size() - position - 1;
+
+ final ActivityDescription activityDescription = mActivityDescriptions.get(activityId);
+ final Bitmap thumb = activityDescription.thumbnail;
+ holder.thumbnailView.setImageBitmap(compositeBitmap(mGlowBitmap, thumb));
+ holder.iconView.setImageDrawable(activityDescription.icon);
+ holder.labelView.setText(activityDescription.label);
+ holder.descriptionView.setText(activityDescription.description);
+ holder.thumbnailView.setTag(activityDescription);
+ holder.activityDescription = activityDescription;
+
+ return convertView;
+ }
+ }
+
public boolean isInContentArea(int x, int y) {
// use mRecentsContainer's exact bounds to determine horizontal position
final int l = mRecentsContainer.getLeft();
@@ -267,9 +330,41 @@ public class RecentAppsPanel extends RelativeLayout implements StatusBarPanel, O
}
@Override
+ protected void onSizeChanged(int w, int h, int oldw, int oldh) {
+ super.onSizeChanged(w, h, oldw, oldh);
+ // Keep track of the last visible item in the list so we can restore it
+ // to the bottom when the orientation changes.
+ int childCount = mRecentsContainer.getChildCount();
+ if (childCount > 0) {
+ mLastVisibleItem = mRecentsContainer.getFirstVisiblePosition() + childCount - 1;
+ View view = mRecentsContainer.getChildAt(childCount - 1);
+ final int distanceFromBottom = mRecentsContainer.getHeight() - view.getTop();
+ //final int distanceFromBottom = view.getHeight() + BOTTOM_OFFSET;
+
+ // This has to happen post-layout, so run it "in the future"
+ post(new Runnable() {
+ public void run() {
+ mRecentsContainer.setSelectionFromTop(mLastVisibleItem,
+ mRecentsContainer.getHeight() - distanceFromBottom);
+ }
+ });
+ }
+ }
+
+ @Override
protected void onFinishInflate() {
super.onFinishInflate();
- mRecentsContainer = (LinearLayout) findViewById(R.id.recents_container);
+ LayoutInflater inflater = (LayoutInflater)
+ mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+
+ mRecentsContainer = (ListView) findViewById(R.id.recents_container);
+ View footer = inflater.inflate(R.layout.status_bar_recent_panel_footer,
+ mRecentsContainer, false);
+ mRecentsContainer.setScrollbarFadingEnabled(true);
+ mRecentsContainer.addFooterView(footer);
+ mRecentsContainer.setAdapter(mListAdapter = new ActvityDescriptionAdapter(mContext));
+ mRecentsContainer.setOnItemClickListener(this);
+
mRecentsGlowView = findViewById(R.id.recents_glow);
mRecentsScrim = (View) findViewById(R.id.recents_bg_protect);
mChoreo = new Choreographer(this, mRecentsScrim, mRecentsGlowView);
@@ -287,20 +382,16 @@ public class RecentAppsPanel extends RelativeLayout implements StatusBarPanel, O
}
@Override
- protected void onConfigurationChanged(Configuration newConfig) {
- super.onConfigurationChanged(newConfig);
- // we show more in portrait mode, so update UI if orientation changes
- updateUiElements(newConfig, false);
- }
-
- @Override
protected void onVisibilityChanged(View changedView, int visibility) {
super.onVisibilityChanged(changedView, visibility);
if (DEBUG) Log.v(TAG, "onVisibilityChanged(" + changedView + ", " + visibility + ")");
if (visibility == View.VISIBLE && changedView == this) {
refreshApplicationList();
- mRecentsContainer.setScrollbarFadingEnabled(true);
- mRecentsContainer.scrollTo(0, 0);
+ post(new Runnable() {
+ public void run() {
+ mRecentsContainer.setSelection(mActivityDescriptions.size() - 1);
+ }
+ });
}
}
@@ -402,11 +493,12 @@ public class RecentAppsPanel extends RelativeLayout implements StatusBarPanel, O
private void refreshApplicationList() {
mActivityDescriptions = getRecentTasks();
+ mListAdapter.notifyDataSetInvalidated();
if (mActivityDescriptions.size() > 0) {
- updateUiElements(getResources().getConfiguration(), true);
+ mLastVisibleItem = mActivityDescriptions.size() - 1; // scroll to bottom after reloading
+ updateUiElements(getResources().getConfiguration());
} else {
// Immediately hide this panel
- mShowing = false;
hide(false);
}
}
@@ -426,44 +518,29 @@ public class RecentAppsPanel extends RelativeLayout implements StatusBarPanel, O
canvas.drawBitmap(thumbnail,
new Rect(0, 0, srcWidth-1, srcHeight-1),
new RectF(GLOW_PADDING,
- GLOW_PADDING - 4.0f,
- outBitmap.getWidth() - GLOW_PADDING + 2.0f,
- outBitmap.getHeight() - GLOW_PADDING + 3.0f), paint);
+ GLOW_PADDING - 7.0f,
+ outBitmap.getWidth() - GLOW_PADDING + 3.0f,
+ outBitmap.getHeight() - GLOW_PADDING + 7.0f), paint);
}
return outBitmap;
}
- private void updateUiElements(Configuration config, boolean animate) {
- mRecentsContainer.removeAllViews();
-
- final int first = 0;
- final boolean isPortrait = config.orientation == Configuration.ORIENTATION_PORTRAIT;
- final int taskCount = isPortrait ? DISPLAY_TASKS_PORTRAIT : DISPLAY_TASKS_LANDSCAPE;
- final int last = Math.min(mActivityDescriptions.size(), taskCount) - 1;
- for (int i = last; i >= first; i--) {
- ActivityDescription activityDescription = mActivityDescriptions.get(i);
- View view = View.inflate(mContext, R.layout.status_bar_recent_item, null);
- ImageView appThumbnail = (ImageView) view.findViewById(R.id.app_thumbnail);
- ImageView appIcon = (ImageView) view.findViewById(R.id.app_icon);
- TextView appLabel = (TextView) view.findViewById(R.id.app_label);
- TextView appDesc = (TextView) view.findViewById(R.id.app_description);
- final Bitmap thumb = activityDescription.thumbnail;
- appThumbnail.setImageBitmap(compositeBitmap(mGlowBitmap, thumb));
- appIcon.setImageDrawable(activityDescription.icon);
- appLabel.setText(activityDescription.label);
- appDesc.setText(activityDescription.description);
- appThumbnail.setOnClickListener(this);
- appThumbnail.setTag(activityDescription);
- mRecentsContainer.addView(view);
- }
+ private void updateUiElements(Configuration config) {
+ final int items = mActivityDescriptions.size();
+
+ mRecentsContainer.setVisibility(items > 0 ? View.VISIBLE : View.GONE);
+ mRecentsGlowView.setVisibility(items > 0 ? View.VISIBLE : View.GONE);
+ }
- int views = mRecentsContainer.getChildCount();
- mRecentsContainer.setVisibility(views > 0 ? View.VISIBLE : View.GONE);
- mRecentsGlowView.setVisibility(views > 0 ? View.VISIBLE : View.GONE);
+ private void hide(boolean animate) {
+ if (!animate) {
+ setVisibility(View.GONE);
+ }
+ mBar.animateCollapse();
}
- public void onClick(View v) {
- ActivityDescription ad = (ActivityDescription)v.getTag();
+ public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
+ ActivityDescription ad = ((ViewHolder) view.getTag()).activityDescription;
final ActivityManager am = (ActivityManager)
getContext().getSystemService(Context.ACTIVITY_SERVICE);
if (ad.id >= 0) {
@@ -478,11 +555,4 @@ public class RecentAppsPanel extends RelativeLayout implements StatusBarPanel, O
}
hide(true);
}
-
- private void hide(boolean animate) {
- setVisibility(View.GONE);
- if (animate) {
- mBar.animateCollapse();
- }
- }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
index 233d601b6fda..f0408a28a00f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
@@ -267,6 +267,8 @@ public class TabletStatusBar extends StatusBar implements
lp.gravity = Gravity.BOTTOM | Gravity.LEFT;
lp.setTitle("RecentsPanel");
lp.windowAnimations = R.style.Animation_RecentPanel;
+ lp.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_STATE_UNCHANGED
+ | WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING;
WindowManagerImpl.getDefault().addView(mRecentsPanel, lp);
mRecentsPanel.setBar(this);
@@ -509,7 +511,7 @@ public class TabletStatusBar extends StatusBar implements
final int peekIndex = m.arg1;
if (peekIndex < N) {
//Slog.d(TAG, "loading peek: " + peekIndex);
- NotificationData.Entry entry =
+ NotificationData.Entry entry =
mNotificationDNDMode
? mNotificationDNDDummyEntry
: mNotificationData.get(N-1-peekIndex);
@@ -555,7 +557,7 @@ public class TabletStatusBar extends StatusBar implements
final int N = mNotificationData.size();
if (mNotificationPeekIndex >= 0 && mNotificationPeekIndex < N) {
- NotificationData.Entry entry =
+ NotificationData.Entry entry =
mNotificationDNDMode
? mNotificationDNDDummyEntry
: mNotificationData.get(N-1-mNotificationPeekIndex);
@@ -584,6 +586,8 @@ public class TabletStatusBar extends StatusBar implements
case MSG_OPEN_RECENTS_PANEL:
if (DEBUG) Slog.d(TAG, "opening recents panel");
if (mRecentsPanel != null) {
+ disable(StatusBarManager.DISABLE_NAVIGATION
+ | StatusBarManager.DISABLE_BACK);
mRecentsPanel.setVisibility(View.VISIBLE);
mRecentsPanel.show(true, true);
}
@@ -591,6 +595,7 @@ public class TabletStatusBar extends StatusBar implements
case MSG_CLOSE_RECENTS_PANEL:
if (DEBUG) Slog.d(TAG, "closing recents panel");
if (mRecentsPanel != null && mRecentsPanel.isShowing()) {
+ disable(StatusBarManager.DISABLE_NONE);
mRecentsPanel.show(false, true);
}
break;
@@ -701,7 +706,7 @@ public class TabletStatusBar extends StatusBar implements
&& oldContentView.getLayoutId() == contentView.getLayoutId();
ViewGroup rowParent = (ViewGroup) oldEntry.row.getParent();
boolean orderUnchanged = notification.notification.when==oldNotification.notification.when
- && notification.priority == oldNotification.priority;
+ && notification.priority == oldNotification.priority;
// priority now encompasses isOngoing()
boolean isLastAnyway = rowParent.indexOfChild(oldEntry.row) == rowParent.getChildCount()-1;
if (contentsUnchanged && (orderUnchanged || isLastAnyway)) {
diff --git a/services/java/com/android/server/AppWidgetService.java b/services/java/com/android/server/AppWidgetService.java
index afa8d69c3596..f28e2b12ce55 100644
--- a/services/java/com/android/server/AppWidgetService.java
+++ b/services/java/com/android/server/AppWidgetService.java
@@ -1029,7 +1029,7 @@ class AppWidgetService extends IAppWidgetService.Stub
com.android.internal.R.styleable.AppWidgetProviderInfo_previewImage, 0);
info.autoAdvanceViewId = sa.getResourceId(
com.android.internal.R.styleable.AppWidgetProviderInfo_autoAdvanceViewId, -1);
- info.resizableMode = sa.getInt(
+ info.resizeMode = sa.getInt(
com.android.internal.R.styleable.AppWidgetProviderInfo_resizeMode,
AppWidgetProviderInfo.RESIZE_NONE);
diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java
index b7cc3243255a..e3218c852b17 100644
--- a/services/java/com/android/server/wm/WindowManagerService.java
+++ b/services/java/com/android/server/wm/WindowManagerService.java
@@ -5812,8 +5812,7 @@ public class WindowManagerService extends IWindowManager.Stub
mDisplay = wm.getDefaultDisplay();
mInitialDisplayWidth = mDisplay.getWidth();
mInitialDisplayHeight = mDisplay.getHeight();
- mInputManager.setDisplaySize(0, Display.unmapDisplaySize(mInitialDisplayWidth),
- Display.unmapDisplaySize(mInitialDisplayHeight));
+ mInputManager.setDisplaySize(0, mDisplay.getRealWidth(), mDisplay.getRealHeight());
}
try {
diff --git a/test-runner/src/android/test/SingleLaunchActivityTestCase.java b/test-runner/src/android/test/SingleLaunchActivityTestCase.java
index b63b3ce19759..79c554a46391 100644
--- a/test-runner/src/android/test/SingleLaunchActivityTestCase.java
+++ b/test-runner/src/android/test/SingleLaunchActivityTestCase.java
@@ -75,7 +75,7 @@ public abstract class SingleLaunchActivityTestCase<T extends Activity>
protected void tearDown() throws Exception {
// If it is the last test case, call finish on the activity.
sTestCaseCounter --;
- if (sTestCaseCounter == 1) {
+ if (sTestCaseCounter == 0) {
sActivity.finish();
}
super.tearDown();