summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--api/current.txt8
-rw-r--r--core/java/android/app/ActivityManagerNative.java32
-rw-r--r--core/java/android/app/ActivityThread.java3
-rw-r--r--core/java/android/app/ActivityView.java163
-rw-r--r--core/java/android/app/IActivityContainer.aidl3
-rw-r--r--core/java/android/content/ContentProviderNative.java13
-rw-r--r--core/java/android/os/Parcel.java24
-rw-r--r--core/java/android/preference/PreferenceActivity.java8
-rw-r--r--core/java/android/widget/ActionMenuPresenter.java36
-rw-r--r--data/keyboards/AVRCP.kl4
-rw-r--r--graphics/java/android/graphics/drawable/DrawableContainer.java30
-rw-r--r--graphics/java/android/graphics/drawable/LayerDrawable.java1
-rw-r--r--media/jni/Android.mk7
-rw-r--r--media/jni/android_mtp_MtpDatabase.cpp76
-rw-r--r--policy/src/com/android/internal/policy/impl/PhoneLayoutInflater.java3
-rw-r--r--rs/java/android/renderscript/BaseObj.java32
-rw-r--r--rs/java/android/renderscript/RenderScript.java23
-rw-r--r--rs/jni/android_renderscript_RenderScript.cpp8
-rw-r--r--services/Android.mk3
-rw-r--r--services/core/java/com/android/server/am/ActivityStack.java4
-rw-r--r--services/core/java/com/android/server/am/ActivityStackSupervisor.java91
-rw-r--r--services/core/java/com/android/server/display/DisplayManagerService.java4
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerService.java18
23 files changed, 475 insertions, 119 deletions
diff --git a/api/current.txt b/api/current.txt
index 520d05aae66e..b734c677fee0 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -3161,6 +3161,14 @@ package android.app {
method public void update(android.app.ActivityOptions);
}
+ public class ActivityView extends android.view.ViewGroup {
+ ctor public ActivityView(android.content.Context);
+ ctor public ActivityView(android.content.Context, android.util.AttributeSet);
+ ctor public ActivityView(android.content.Context, android.util.AttributeSet, int);
+ method protected void onLayout(boolean, int, int, int, int);
+ method public void startActivity(android.content.Intent);
+ }
+
public class AlarmManager {
method public void cancel(android.app.PendingIntent);
method public void set(int, long, android.app.PendingIntent);
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index 3bc2ee60c10a..7b81713c0fcc 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -2027,7 +2027,12 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM
IActivityContainer activityContainer =
createActivityContainer(parentActivityToken, callback);
reply.writeNoException();
- reply.writeStrongBinder(activityContainer.asBinder());
+ if (activityContainer != null) {
+ reply.writeInt(1);
+ reply.writeStrongBinder(activityContainer.asBinder());
+ } else {
+ reply.writeInt(0);
+ }
return true;
}
@@ -2036,7 +2041,12 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM
IBinder activityToken = data.readStrongBinder();
IActivityContainer activityContainer = getEnclosingActivityContainer(activityToken);
reply.writeNoException();
- reply.writeStrongBinder(activityContainer.asBinder());
+ if (activityContainer != null) {
+ reply.writeInt(1);
+ reply.writeStrongBinder(activityContainer.asBinder());
+ } else {
+ reply.writeInt(0);
+ }
return true;
}
@@ -4670,8 +4680,13 @@ class ActivityManagerProxy implements IActivityManager
data.writeStrongBinder((IBinder)callback);
mRemote.transact(CREATE_ACTIVITY_CONTAINER_TRANSACTION, data, reply, 0);
reply.readException();
- IActivityContainer res =
- IActivityContainer.Stub.asInterface(reply.readStrongBinder());
+ final int result = reply.readInt();
+ final IActivityContainer res;
+ if (result == 1) {
+ res = IActivityContainer.Stub.asInterface(reply.readStrongBinder());
+ } else {
+ res = null;
+ }
data.recycle();
reply.recycle();
return res;
@@ -4685,8 +4700,13 @@ class ActivityManagerProxy implements IActivityManager
data.writeStrongBinder(activityToken);
mRemote.transact(GET_ACTIVITY_CONTAINER_TRANSACTION, data, reply, 0);
reply.readException();
- IActivityContainer res =
- IActivityContainer.Stub.asInterface(reply.readStrongBinder());
+ final int result = reply.readInt();
+ final IActivityContainer res;
+ if (result == 1) {
+ res = IActivityContainer.Stub.asInterface(reply.readStrongBinder());
+ } else {
+ res = null;
+ }
data.recycle();
reply.recycle();
return res;
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 94ebff97d496..5239cc6d3af4 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -2235,7 +2235,8 @@ public final class ActivityThread {
try {
IActivityContainer container =
ActivityManagerNative.getDefault().getEnclosingActivityContainer(r.token);
- final int displayId = container.getDisplayId();
+ final int displayId =
+ container == null ? Display.DEFAULT_DISPLAY : container.getDisplayId();
if (displayId > Display.DEFAULT_DISPLAY) {
Display display = dm.getRealDisplay(displayId, r.token);
baseContext = appContext.createDisplayContext(display);
diff --git a/core/java/android/app/ActivityView.java b/core/java/android/app/ActivityView.java
new file mode 100644
index 000000000000..fef4597e4e4e
--- /dev/null
+++ b/core/java/android/app/ActivityView.java
@@ -0,0 +1,163 @@
+/*
+ * Copyright (C) 2013 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 android.app;
+
+import android.content.Context;
+import android.content.ContextWrapper;
+import android.content.Intent;
+import android.graphics.SurfaceTexture;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.util.AttributeSet;
+import android.util.DisplayMetrics;
+import android.view.Surface;
+import android.view.TextureView;
+import android.view.TextureView.SurfaceTextureListener;
+import android.view.ViewGroup;
+import android.view.WindowManager;
+
+public class ActivityView extends ViewGroup {
+ private final TextureView mTextureView;
+ private IActivityContainer mActivityContainer;
+ private Activity mActivity;
+ private boolean mAttached;
+ private int mWidth;
+ private int mHeight;
+
+ public ActivityView(Context context) {
+ this(context, null);
+ }
+
+ public ActivityView(Context context, AttributeSet attrs) {
+ this(context, attrs, 0);
+ }
+
+ public ActivityView(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+
+ while (context instanceof ContextWrapper) {
+ if (context instanceof Activity) {
+ mActivity = (Activity)context;
+ break;
+ }
+ context = ((ContextWrapper)context).getBaseContext();
+ }
+ if (mActivity == null) {
+ throw new IllegalStateException("The ActivityView's Context is not an Activity.");
+ }
+
+ mTextureView = new TextureView(context);
+ mTextureView.setSurfaceTextureListener(new ActivityViewSurfaceTextureListener());
+ addView(mTextureView);
+ }
+
+ @Override
+ protected void onLayout(boolean changed, int l, int t, int r, int b) {
+ mTextureView.layout(l, t, r, b);
+ }
+
+ @Override
+ protected void onAttachedToWindow() {
+ try {
+ final IBinder token = mActivity.getActivityToken();
+ mActivityContainer =
+ ActivityManagerNative.getDefault().createActivityContainer(token, null);
+ } catch (RemoteException e) {
+ throw new IllegalStateException("ActivityView: Unable to create ActivityContainer. "
+ + e);
+ }
+
+ final SurfaceTexture surfaceTexture = mTextureView.getSurfaceTexture();
+ if (surfaceTexture != null) {
+ createActivityView(surfaceTexture);
+ }
+ }
+
+ @Override
+ protected void onDetachedFromWindow() {
+ if (mActivityContainer != null) {
+ try {
+ mActivityContainer.deleteActivityView();
+ } catch (RemoteException e) {
+ }
+ mActivityContainer = null;
+ }
+ mAttached = false;
+ }
+
+ public void startActivity(Intent intent) {
+ if (mActivityContainer != null && mAttached) {
+ try {
+ mActivityContainer.startActivity(intent);
+ } catch (RemoteException e) {
+ throw new IllegalStateException("ActivityView: Unable to startActivity. " + e);
+ }
+ }
+ }
+
+ /** Call when both mActivityContainer and mTextureView's SurfaceTexture are not null */
+ private void createActivityView(SurfaceTexture surfaceTexture) {
+ WindowManager wm = (WindowManager)mActivity.getSystemService(Context.WINDOW_SERVICE);
+ DisplayMetrics metrics = new DisplayMetrics();
+ wm.getDefaultDisplay().getMetrics(metrics);
+
+ try {
+ mActivityContainer.createActivityView(new Surface(surfaceTexture), mWidth, mHeight,
+ metrics.densityDpi);
+ } catch (RemoteException e) {
+ mActivityContainer = null;
+ throw new IllegalStateException(
+ "ActivityView: Unable to create ActivityContainer. " + e);
+ }
+ mAttached = true;
+ }
+
+ private class ActivityViewSurfaceTextureListener implements SurfaceTextureListener {
+ @Override
+ public void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture, int width,
+ int height) {
+ mWidth = width;
+ mHeight = height;
+ if (mActivityContainer != null) {
+ createActivityView(surfaceTexture);
+ }
+ }
+
+ @Override
+ public void onSurfaceTextureSizeChanged(SurfaceTexture surfaceTexture, int width,
+ int height) {
+ }
+
+ @Override
+ public boolean onSurfaceTextureDestroyed(SurfaceTexture surfaceTexture) {
+ try {
+ mActivityContainer.deleteActivityView();
+ // TODO: Add binderDied to handle this nullification.
+ mActivityContainer = null;
+ } catch (RemoteException r) {
+ }
+ mAttached = false;
+ return false;
+ }
+
+ @Override
+ public void onSurfaceTextureUpdated(SurfaceTexture surfaceTexture) {
+
+ }
+
+ }
+}
diff --git a/core/java/android/app/IActivityContainer.aidl b/core/java/android/app/IActivityContainer.aidl
index 2d8d18f0c328..b03a459a95a4 100644
--- a/core/java/android/app/IActivityContainer.aidl
+++ b/core/java/android/app/IActivityContainer.aidl
@@ -19,6 +19,7 @@ package android.app;
import android.app.IActivityContainerCallback;
import android.content.Intent;
import android.os.IBinder;
+import android.view.Surface;
/** @hide */
interface IActivityContainer {
@@ -26,4 +27,6 @@ interface IActivityContainer {
int getDisplayId();
void detachFromDisplay();
int startActivity(in Intent intent);
+ void createActivityView(in Surface surface, int width, int height, int density);
+ void deleteActivityView();
}
diff --git a/core/java/android/content/ContentProviderNative.java b/core/java/android/content/ContentProviderNative.java
index bcf0b637a213..39286d6ea9b6 100644
--- a/core/java/android/content/ContentProviderNative.java
+++ b/core/java/android/content/ContentProviderNative.java
@@ -112,17 +112,24 @@ abstract public class ContentProviderNative extends Binder implements IContentPr
Cursor cursor = query(callingPkg, url, projection, selection, selectionArgs,
sortOrder, cancellationSignal);
if (cursor != null) {
+ CursorToBulkCursorAdaptor adaptor = null;
+
try {
- CursorToBulkCursorAdaptor adaptor = new CursorToBulkCursorAdaptor(
- cursor, observer, getProviderName());
- BulkCursorDescriptor d = adaptor.getBulkCursorDescriptor();
+ adaptor = new CursorToBulkCursorAdaptor(cursor, observer,
+ getProviderName());
cursor = null;
+ BulkCursorDescriptor d = adaptor.getBulkCursorDescriptor();
+ adaptor = null;
+
reply.writeNoException();
reply.writeInt(1);
d.writeToParcel(reply, Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
} finally {
// Close cursor if an exception was thrown while constructing the adaptor.
+ if (adaptor != null) {
+ adaptor.close();
+ }
if (cursor != null) {
cursor.close();
}
diff --git a/core/java/android/os/Parcel.java b/core/java/android/os/Parcel.java
index 94b961793e26..b13262752bfa 100644
--- a/core/java/android/os/Parcel.java
+++ b/core/java/android/os/Parcel.java
@@ -29,6 +29,7 @@ import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
+import java.io.ObjectStreamClass;
import java.io.Serializable;
import java.lang.reflect.Field;
import java.util.ArrayList;
@@ -2061,7 +2062,7 @@ public final class Parcel {
return readByte();
case VAL_SERIALIZABLE:
- return readSerializable();
+ return readSerializable(loader);
case VAL_PARCELABLEARRAY:
return readParcelableArray(loader);
@@ -2198,6 +2199,10 @@ public final class Parcel {
* wasn't found in the parcel.
*/
public final Serializable readSerializable() {
+ return readSerializable(null);
+ }
+
+ private final Serializable readSerializable(final ClassLoader loader) {
String name = readString();
if (name == null) {
// For some reason we were unable to read the name of the Serializable (either there
@@ -2209,14 +2214,27 @@ public final class Parcel {
byte[] serializedData = createByteArray();
ByteArrayInputStream bais = new ByteArrayInputStream(serializedData);
try {
- ObjectInputStream ois = new ObjectInputStream(bais);
+ ObjectInputStream ois = new ObjectInputStream(bais) {
+ @Override
+ protected Class<?> resolveClass(ObjectStreamClass osClass)
+ throws IOException, ClassNotFoundException {
+ // try the custom classloader if provided
+ if (loader != null) {
+ Class<?> c = Class.forName(osClass.getName(), false, loader);
+ if (c != null) {
+ return c;
+ }
+ }
+ return super.resolveClass(osClass);
+ }
+ };
return (Serializable) ois.readObject();
} catch (IOException ioe) {
throw new RuntimeException("Parcelable encountered " +
"IOException reading a Serializable object (name = " + name +
")", ioe);
} catch (ClassNotFoundException cnfe) {
- throw new RuntimeException("Parcelable encountered" +
+ throw new RuntimeException("Parcelable encountered " +
"ClassNotFoundException reading a Serializable object (name = "
+ name + ")", cnfe);
}
diff --git a/core/java/android/preference/PreferenceActivity.java b/core/java/android/preference/PreferenceActivity.java
index 0d14a9e29f69..04180491f137 100644
--- a/core/java/android/preference/PreferenceActivity.java
+++ b/core/java/android/preference/PreferenceActivity.java
@@ -33,7 +33,6 @@ import android.os.Parcel;
import android.os.Parcelable;
import android.text.TextUtils;
import android.util.AttributeSet;
-import android.util.Log;
import android.util.TypedValue;
import android.util.Xml;
import android.view.LayoutInflater;
@@ -1173,7 +1172,7 @@ public abstract class PreferenceActivity extends ListActivity implements
}
}
- private void switchToHeaderInner(String fragmentName, Bundle args, int direction) {
+ private void switchToHeaderInner(String fragmentName, Bundle args) {
getFragmentManager().popBackStack(BACK_STACK_PREFS,
FragmentManager.POP_BACK_STACK_INCLUSIVE);
if (!isValidFragment(fragmentName)) {
@@ -1196,7 +1195,7 @@ public abstract class PreferenceActivity extends ListActivity implements
*/
public void switchToHeader(String fragmentName, Bundle args) {
setSelectedHeader(null);
- switchToHeaderInner(fragmentName, args, 0);
+ switchToHeaderInner(fragmentName, args);
}
/**
@@ -1215,8 +1214,7 @@ public abstract class PreferenceActivity extends ListActivity implements
if (header.fragment == null) {
throw new IllegalStateException("can't switch to header that has no fragment");
}
- int direction = mHeaders.indexOf(header) - mHeaders.indexOf(mCurHeader);
- switchToHeaderInner(header.fragment, header.fragmentArguments, direction);
+ switchToHeaderInner(header.fragment, header.fragmentArguments);
setSelectedHeader(header);
}
}
diff --git a/core/java/android/widget/ActionMenuPresenter.java b/core/java/android/widget/ActionMenuPresenter.java
index b75d12fbacab..01abf2ceb09b 100644
--- a/core/java/android/widget/ActionMenuPresenter.java
+++ b/core/java/android/widget/ActionMenuPresenter.java
@@ -168,8 +168,24 @@ public class ActionMenuPresenter extends BaseMenuPresenter
}
actionView.setVisibility(item.isActionViewExpanded() ? View.GONE : View.VISIBLE);
+ final ActionMenuView menuParent = (ActionMenuView) parent;
+ final ViewGroup.LayoutParams lp = actionView.getLayoutParams();
+ if (!menuParent.checkLayoutParams(lp)) {
+ actionView.setLayoutParams(menuParent.generateLayoutParams(lp));
+ }
+ return actionView;
+ }
+
+ @Override
+ public void bindItemView(final MenuItemImpl item, MenuView.ItemView itemView) {
+ itemView.initialize(item, 0);
+
+ final ActionMenuView menuView = (ActionMenuView) mMenuView;
+ final ActionMenuItemView actionItemView = (ActionMenuItemView) itemView;
+ actionItemView.setItemInvoker(menuView);
+
if (item.hasSubMenu()) {
- actionView.setOnTouchListener(new ForwardingListener(actionView) {
+ actionItemView.setOnTouchListener(new ForwardingListener(actionItemView) {
@Override
public ListPopupWindow getPopup() {
return mActionButtonPopup != null ? mActionButtonPopup.getPopup() : null;
@@ -186,24 +202,8 @@ public class ActionMenuPresenter extends BaseMenuPresenter
}
});
} else {
- actionView.setOnTouchListener(null);
+ actionItemView.setOnTouchListener(null);
}
-
- final ActionMenuView menuParent = (ActionMenuView) parent;
- final ViewGroup.LayoutParams lp = actionView.getLayoutParams();
- if (!menuParent.checkLayoutParams(lp)) {
- actionView.setLayoutParams(menuParent.generateLayoutParams(lp));
- }
- return actionView;
- }
-
- @Override
- public void bindItemView(MenuItemImpl item, MenuView.ItemView itemView) {
- itemView.initialize(item, 0);
-
- final ActionMenuView menuView = (ActionMenuView) mMenuView;
- ActionMenuItemView actionItemView = (ActionMenuItemView) itemView;
- actionItemView.setItemInvoker(menuView);
}
@Override
diff --git a/data/keyboards/AVRCP.kl b/data/keyboards/AVRCP.kl
index 4c91ece3b5ef..736b43c80c4d 100644
--- a/data/keyboards/AVRCP.kl
+++ b/data/keyboards/AVRCP.kl
@@ -14,8 +14,8 @@
# Key layout used for Bluetooth AVRCP support.
-key 200 MEDIA_PLAY_PAUSE WAKE
-key 201 MEDIA_PLAY_PAUSE WAKE
+key 200 MEDIA_PLAY WAKE
+key 201 MEDIA_PAUSE WAKE
key 166 MEDIA_STOP WAKE
key 163 MEDIA_NEXT WAKE
key 165 MEDIA_PREVIOUS WAKE
diff --git a/graphics/java/android/graphics/drawable/DrawableContainer.java b/graphics/java/android/graphics/drawable/DrawableContainer.java
index a1e0772856ce..a98b84f20c61 100644
--- a/graphics/java/android/graphics/drawable/DrawableContainer.java
+++ b/graphics/java/android/graphics/drawable/DrawableContainer.java
@@ -50,6 +50,9 @@ public class DrawableContainer extends Drawable implements Drawable.Callback {
private Drawable mCurrDrawable;
private int mAlpha = 0xFF;
+ /** Whether setAlpha() has been called at least once. */
+ private boolean mHasAlpha;
+
private int mCurIndex = -1;
private boolean mMutated;
@@ -117,6 +120,8 @@ public class DrawableContainer extends Drawable implements Drawable.Callback {
@Override
public void setAlpha(int alpha) {
+ mHasAlpha = true;
+
if (mAlpha != alpha) {
mAlpha = alpha;
if (mCurrDrawable != null) {
@@ -146,8 +151,11 @@ public class DrawableContainer extends Drawable implements Drawable.Callback {
@Override
public void setColorFilter(ColorFilter cf) {
+ mDrawableContainerState.mHasColorFilter = true;
+
if (mDrawableContainerState.mColorFilter != cf) {
mDrawableContainerState.mColorFilter = cf;
+
if (mCurrDrawable != null) {
mCurrDrawable.mutate().setColorFilter(cf);
}
@@ -189,9 +197,11 @@ public class DrawableContainer extends Drawable implements Drawable.Callback {
@Override
public void setAutoMirrored(boolean mirrored) {
- mDrawableContainerState.mAutoMirrored = mirrored;
- if (mCurrDrawable != null) {
- mCurrDrawable.mutate().setAutoMirrored(mDrawableContainerState.mAutoMirrored);
+ if (mDrawableContainerState.mAutoMirrored != mirrored) {
+ mDrawableContainerState.mAutoMirrored = mirrored;
+ if (mCurrDrawable != null) {
+ mCurrDrawable.mutate().setAutoMirrored(mDrawableContainerState.mAutoMirrored);
+ }
}
}
@@ -210,7 +220,9 @@ public class DrawableContainer extends Drawable implements Drawable.Callback {
}
if (mCurrDrawable != null) {
mCurrDrawable.jumpToCurrentState();
- mCurrDrawable.mutate().setAlpha(mAlpha);
+ if (mHasAlpha) {
+ mCurrDrawable.mutate().setAlpha(mAlpha);
+ }
}
if (mExitAnimationEnd != 0) {
mExitAnimationEnd = 0;
@@ -353,12 +365,14 @@ public class DrawableContainer extends Drawable implements Drawable.Callback {
d.mutate();
if (mDrawableContainerState.mEnterFadeDuration > 0) {
mEnterAnimationEnd = now + mDrawableContainerState.mEnterFadeDuration;
- } else {
+ } else if (mHasAlpha) {
d.setAlpha(mAlpha);
}
+ if (mDrawableContainerState.mHasColorFilter) {
+ d.setColorFilter(mDrawableContainerState.mColorFilter);
+ }
d.setVisible(isVisible(), true);
d.setDither(mDrawableContainerState.mDither);
- d.setColorFilter(mDrawableContainerState.mColorFilter);
d.setState(getState());
d.setLevel(getLevel());
d.setBounds(getBounds());
@@ -394,6 +408,8 @@ public class DrawableContainer extends Drawable implements Drawable.Callback {
}
void animate(boolean schedule) {
+ mHasAlpha = true;
+
final long now = SystemClock.uptimeMillis();
boolean animating = false;
if (mCurrDrawable != null) {
@@ -507,6 +523,7 @@ public class DrawableContainer extends Drawable implements Drawable.Callback {
boolean mAutoMirrored;
ColorFilter mColorFilter;
+ boolean mHasColorFilter;
DrawableContainerState(DrawableContainerState orig, DrawableContainer owner,
Resources res) {
@@ -529,6 +546,7 @@ public class DrawableContainer extends Drawable implements Drawable.Callback {
mExitFadeDuration = orig.mExitFadeDuration;
mAutoMirrored = orig.mAutoMirrored;
mColorFilter = orig.mColorFilter;
+ mHasColorFilter = orig.mHasColorFilter;
// Cloning the following values may require creating futures.
mConstantPadding = orig.getConstantPadding();
diff --git a/graphics/java/android/graphics/drawable/LayerDrawable.java b/graphics/java/android/graphics/drawable/LayerDrawable.java
index f2e9988f4c0c..51c183f582be 100644
--- a/graphics/java/android/graphics/drawable/LayerDrawable.java
+++ b/graphics/java/android/graphics/drawable/LayerDrawable.java
@@ -342,6 +342,7 @@ public class LayerDrawable extends Drawable implements Drawable.Callback {
childDrawable.mInsetT = t;
childDrawable.mInsetR = r;
childDrawable.mInsetB = b;
+ invalidatePadding();
}
/**
diff --git a/media/jni/Android.mk b/media/jni/Android.mk
index 685bbcc784af..a45051c93df3 100644
--- a/media/jni/Android.mk
+++ b/media/jni/Android.mk
@@ -37,17 +37,14 @@ LOCAL_SHARED_LIBRARIES := \
libcamera_client \
libmtp \
libusbhost \
- libjhead \
+ libexif \
libstagefright_amrnb_common \
-LOCAL_REQUIRED_MODULES := \
- libjhead_jni
-
LOCAL_STATIC_LIBRARIES := \
libstagefright_amrnbenc
LOCAL_C_INCLUDES += \
- external/jhead \
+ external/libexif/ \
external/tremor/Tremor \
frameworks/base/core/jni \
frameworks/av/media/libmedia \
diff --git a/media/jni/android_mtp_MtpDatabase.cpp b/media/jni/android_mtp_MtpDatabase.cpp
index 72ce3cce0325..4fbc55a3fa87 100644
--- a/media/jni/android_mtp_MtpDatabase.cpp
+++ b/media/jni/android_mtp_MtpDatabase.cpp
@@ -37,7 +37,10 @@
#include "mtp.h"
extern "C" {
-#include "jhead.h"
+#include "libexif/exif-content.h"
+#include "libexif/exif-data.h"
+#include "libexif/exif-tag.h"
+#include "libexif/exif-utils.h"
}
using namespace android;
@@ -750,6 +753,22 @@ MtpResponseCode MyMtpDatabase::getObjectPropertyList(MtpObjectHandle handle,
return result;
}
+static void foreachentry(ExifEntry *entry, void *user) {
+ char buf[1024];
+ ALOGI("entry %x, format %d, size %d: %s",
+ entry->tag, entry->format, entry->size, exif_entry_get_value(entry, buf, sizeof(buf)));
+}
+
+static void foreachcontent(ExifContent *content, void *user) {
+ ALOGI("content %d", exif_content_get_ifd(content));
+ exif_content_foreach_entry(content, foreachentry, user);
+}
+
+static long getLongFromExifEntry(ExifEntry *e) {
+ ExifByteOrder o = exif_data_get_byte_order(e->parent->parent);
+ return exif_get_long(e->data, o);
+}
+
MtpResponseCode MyMtpDatabase::getObjectInfo(MtpObjectHandle handle,
MtpObjectInfo& info) {
char date[20];
@@ -792,23 +811,22 @@ MtpResponseCode MyMtpDatabase::getObjectInfo(MtpObjectHandle handle,
// read EXIF data for thumbnail information
if (info.mFormat == MTP_FORMAT_EXIF_JPEG || info.mFormat == MTP_FORMAT_JFIF) {
- ResetJpgfile();
- // Start with an empty image information structure.
- memset(&ImageInfo, 0, sizeof(ImageInfo));
- ImageInfo.FlashUsed = -1;
- ImageInfo.MeteringMode = -1;
- ImageInfo.Whitebalance = -1;
- strncpy(ImageInfo.FileName, (const char *)path, PATH_MAX);
- if (ReadJpegFile((const char*)path, READ_METADATA)) {
- Section_t* section = FindSection(M_EXIF);
- if (section) {
- info.mThumbCompressedSize = ImageInfo.ThumbnailSize;
- info.mThumbFormat = MTP_FORMAT_EXIF_JPEG;
- info.mImagePixWidth = ImageInfo.Width;
- info.mImagePixHeight = ImageInfo.Height;
- }
+
+ ExifData *exifdata = exif_data_new_from_file(path);
+ if (exifdata) {
+ //exif_data_foreach_content(exifdata, foreachcontent, NULL);
+
+ // XXX get this from exif, or parse jpeg header instead?
+ ExifEntry *w = exif_content_get_entry(
+ exifdata->ifd[EXIF_IFD_EXIF], EXIF_TAG_PIXEL_X_DIMENSION);
+ ExifEntry *h = exif_content_get_entry(
+ exifdata->ifd[EXIF_IFD_EXIF], EXIF_TAG_PIXEL_Y_DIMENSION);
+ info.mThumbCompressedSize = exifdata->data ? exifdata->size : 0;
+ info.mThumbFormat = MTP_FORMAT_EXIF_JPEG;
+ info.mImagePixWidth = getLongFromExifEntry(w);
+ info.mImagePixHeight = getLongFromExifEntry(h);
+ exif_data_unref(exifdata);
}
- DiscardData();
}
checkAndClearExceptionFromCallback(env, __FUNCTION__);
@@ -824,22 +842,16 @@ void* MyMtpDatabase::getThumbnail(MtpObjectHandle handle, size_t& outThumbSize)
if (getObjectFilePath(handle, path, length, format) == MTP_RESPONSE_OK
&& (format == MTP_FORMAT_EXIF_JPEG || format == MTP_FORMAT_JFIF)) {
- ResetJpgfile();
- // Start with an empty image information structure.
- memset(&ImageInfo, 0, sizeof(ImageInfo));
- ImageInfo.FlashUsed = -1;
- ImageInfo.MeteringMode = -1;
- ImageInfo.Whitebalance = -1;
- strncpy(ImageInfo.FileName, (const char *)path, PATH_MAX);
- if (ReadJpegFile((const char*)path, READ_METADATA)) {
- Section_t* section = FindSection(M_EXIF);
- if (section) {
- outThumbSize = ImageInfo.ThumbnailSize;
- result = malloc(outThumbSize);
- if (result)
- memcpy(result, section->Data + ImageInfo.ThumbnailOffset + 8, outThumbSize);
+
+ ExifData *exifdata = exif_data_new_from_file(path);
+ if (exifdata) {
+ if (exifdata->data) {
+ result = malloc(exifdata->size);
+ if (result) {
+ memcpy(result, exifdata->data, exifdata->size);
+ }
}
- DiscardData();
+ exif_data_unref(exifdata);
}
}
diff --git a/policy/src/com/android/internal/policy/impl/PhoneLayoutInflater.java b/policy/src/com/android/internal/policy/impl/PhoneLayoutInflater.java
index 5d8d0d17e9c3..df6fca4c7bc9 100644
--- a/policy/src/com/android/internal/policy/impl/PhoneLayoutInflater.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneLayoutInflater.java
@@ -24,7 +24,8 @@ import android.view.LayoutInflater;
public class PhoneLayoutInflater extends LayoutInflater {
private static final String[] sClassPrefixList = {
"android.widget.",
- "android.webkit."
+ "android.webkit.",
+ "android.app."
};
/**
diff --git a/rs/java/android/renderscript/BaseObj.java b/rs/java/android/renderscript/BaseObj.java
index 1a15ce6f2fa4..eee4936a96e3 100644
--- a/rs/java/android/renderscript/BaseObj.java
+++ b/rs/java/android/renderscript/BaseObj.java
@@ -16,6 +16,8 @@
package android.renderscript;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+
/**
* BaseObj is the base class for all RenderScript objects owned by a RS context.
* It is responsible for lifetime management and resource tracking. This class
@@ -107,17 +109,30 @@ public class BaseObj {
return mName;
}
- protected void finalize() throws Throwable {
- if (!mDestroyed) {
- if(mID != 0 && mRS.isAlive()) {
+ private void helpDestroy() {
+ boolean shouldDestroy = false;
+ synchronized(this) {
+ if (!mDestroyed) {
+ shouldDestroy = true;
+ mDestroyed = true;
+ }
+ }
+
+ if (shouldDestroy) {
+ // must include nObjDestroy in the critical section
+ ReentrantReadWriteLock.ReadLock rlock = mRS.mRWLock.readLock();
+ rlock.lock();
+ if(mRS.isAlive()) {
mRS.nObjDestroy(mID);
}
+ rlock.unlock();
mRS = null;
mID = 0;
- mDestroyed = true;
- //Log.v(RenderScript.LOG_TAG, getClass() +
- // " auto finalizing object without having released the RS reference.");
}
+ }
+
+ protected void finalize() throws Throwable {
+ helpDestroy();
super.finalize();
}
@@ -126,12 +141,11 @@ public class BaseObj {
* primary use is to force immediate cleanup of resources when it is
* believed the GC will not respond quickly enough.
*/
- synchronized public void destroy() {
+ public void destroy() {
if(mDestroyed) {
throw new RSInvalidStateException("Object already destroyed.");
}
- mDestroyed = true;
- mRS.nObjDestroy(mID);
+ helpDestroy();
}
/**
diff --git a/rs/java/android/renderscript/RenderScript.java b/rs/java/android/renderscript/RenderScript.java
index d2c74564db80..b0ef156e0934 100644
--- a/rs/java/android/renderscript/RenderScript.java
+++ b/rs/java/android/renderscript/RenderScript.java
@@ -18,6 +18,7 @@ package android.renderscript;
import java.io.File;
import java.lang.reflect.Method;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
import android.content.Context;
import android.content.res.AssetManager;
@@ -147,6 +148,7 @@ public class RenderScript {
}
ContextType mContextType;
+ ReentrantReadWriteLock mRWLock;
// Methods below are wrapped to protect the non-threadsafe
// lockless fifo.
@@ -174,7 +176,18 @@ public class RenderScript {
native void rsnContextDestroy(long con);
synchronized void nContextDestroy() {
validate();
- rsnContextDestroy(mContext);
+
+ // take teardown lock
+ // teardown lock can only be taken when no objects are being destroyed
+ ReentrantReadWriteLock.WriteLock wlock = mRWLock.writeLock();
+ wlock.lock();
+
+ long curCon = mContext;
+ // context is considered dead as of this point
+ mContext = 0;
+
+ wlock.unlock();
+ rsnContextDestroy(curCon);
}
native void rsnContextSetSurface(long con, int w, int h, Surface sur);
synchronized void nContextSetSurface(int w, int h, Surface sur) {
@@ -259,8 +272,10 @@ public class RenderScript {
validate();
return rsnGetName(mContext, obj);
}
+
+ // nObjDestroy is explicitly _not_ synchronous to prevent crashes in finalizers
native void rsnObjDestroy(long con, long id);
- synchronized void nObjDestroy(long id) {
+ void nObjDestroy(long id) {
// There is a race condition here. The calling code may be run
// by the gc while teardown is occuring. This protects againts
// deleting dead objects.
@@ -1092,6 +1107,7 @@ public class RenderScript {
if (ctx != null) {
mApplicationContext = ctx.getApplicationContext();
}
+ mRWLock = new ReentrantReadWriteLock();
}
/**
@@ -1186,6 +1202,8 @@ public class RenderScript {
*/
public void destroy() {
validate();
+ nContextFinish();
+
nContextDeinitToClient(mContext);
mMessageThread.mRun = false;
try {
@@ -1194,7 +1212,6 @@ public class RenderScript {
}
nContextDestroy();
- mContext = 0;
nDeviceDestroy(mDev);
mDev = 0;
diff --git a/rs/jni/android_renderscript_RenderScript.cpp b/rs/jni/android_renderscript_RenderScript.cpp
index 84d9a22443bf..5cf3a83b19c6 100644
--- a/rs/jni/android_renderscript_RenderScript.cpp
+++ b/rs/jni/android_renderscript_RenderScript.cpp
@@ -224,28 +224,28 @@ nDeviceCreate(JNIEnv *_env, jobject _this)
}
static void
-nDeviceDestroy(JNIEnv *_env, jobject _this, jint dev)
+nDeviceDestroy(JNIEnv *_env, jobject _this, jlong dev)
{
LOG_API("nDeviceDestroy");
return rsDeviceDestroy((RsDevice)dev);
}
static void
-nDeviceSetConfig(JNIEnv *_env, jobject _this, jint dev, jint p, jint value)
+nDeviceSetConfig(JNIEnv *_env, jobject _this, jlong dev, jint p, jint value)
{
LOG_API("nDeviceSetConfig dev(%p), param(%i), value(%i)", (void *)dev, p, value);
return rsDeviceSetConfig((RsDevice)dev, (RsDeviceParam)p, value);
}
static jlong
-nContextCreate(JNIEnv *_env, jobject _this, jint dev, jint ver, jint sdkVer, jint ct)
+nContextCreate(JNIEnv *_env, jobject _this, jlong dev, jint ver, jint sdkVer, jint ct)
{
LOG_API("nContextCreate");
return (jint)rsContextCreate((RsDevice)dev, ver, sdkVer, (RsContextType)ct, 0);
}
static jlong
-nContextCreateGL(JNIEnv *_env, jobject _this, jint dev, jint ver, jint sdkVer,
+nContextCreateGL(JNIEnv *_env, jobject _this, jlong dev, jint ver, jint sdkVer,
int colorMin, int colorPref,
int alphaMin, int alphaPref,
int depthMin, int depthPref,
diff --git a/services/Android.mk b/services/Android.mk
index 553159289b8f..80fd35a0e345 100644
--- a/services/Android.mk
+++ b/services/Android.mk
@@ -43,4 +43,7 @@ LOCAL_MODULE:= libandroid_servers
include $(BUILD_SHARED_LIBRARY)
+ifeq (,$(ONE_SHOT_MAKEFILE))
include $(call all-makefiles-under, $(LOCAL_PATH))
+endif
+
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index 125621a20a9c..6078611f6983 100644
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -458,11 +458,11 @@ final class ActivityStack {
final void moveToFront() {
if (isAttached()) {
- mStacks.remove(this);
- mStacks.add(this);
if (isOnHomeDisplay()) {
mStackSupervisor.moveHomeStack(isHomeStack());
}
+ mStacks.remove(this);
+ mStacks.add(this);
}
}
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index 1e0be233ee19..5e8c52c18edd 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -59,6 +59,8 @@ import android.content.res.Configuration;
import android.graphics.Point;
import android.hardware.display.DisplayManager;
import android.hardware.display.DisplayManager.DisplayListener;
+import android.hardware.display.DisplayManagerGlobal;
+import android.hardware.display.VirtualDisplay;
import android.os.Binder;
import android.os.Bundle;
import android.os.Debug;
@@ -79,6 +81,7 @@ import android.util.SparseArray;
import android.util.SparseIntArray;
import android.view.Display;
import android.view.DisplayInfo;
+import android.view.Surface;
import com.android.internal.app.HeavyWeightSwitcherActivity;
import com.android.internal.os.TransferPipe;
import com.android.server.am.ActivityManagerService.PendingActivityLaunch;
@@ -88,6 +91,7 @@ import com.android.server.wm.WindowManagerService;
import java.io.FileDescriptor;
import java.io.IOException;
import java.io.PrintWriter;
+import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.List;
@@ -119,6 +123,7 @@ public final class ActivityStackSupervisor implements DisplayListener {
static final int HANDLE_DISPLAY_CHANGED = FIRST_SUPERVISOR_STACK_MSG + 6;
static final int HANDLE_DISPLAY_REMOVED = FIRST_SUPERVISOR_STACK_MSG + 7;
+ private final static String VIRTUAL_DISPLAY_BASE_NAME = "ActivityViewVirtualDisplay";
// For debugging to make sure the caller when acquiring/releasing our
// wake lock is the system process.
@@ -212,11 +217,13 @@ public final class ActivityStackSupervisor implements DisplayListener {
/** Stack id of the front stack when user switched, indexed by userId. */
SparseIntArray mUserStackInFront = new SparseIntArray(2);
+ // TODO: Add listener for removal of references.
/** Mapping from (ActivityStack/TaskStack).mStackId to their current state */
- SparseArray<ActivityContainer> mActivityContainers = new SparseArray<ActivityContainer>();
+ SparseArray<WeakReference<ActivityContainer>> mActivityContainers =
+ new SparseArray<WeakReference<ActivityContainer>>();
/** Mapping from displayId to display current state */
- SparseArray<ActivityDisplay> mActivityDisplays = new SparseArray<ActivityDisplay>();
+ private SparseArray<ActivityDisplay> mActivityDisplays = new SparseArray<ActivityDisplay>();
public ActivityStackSupervisor(ActivityManagerService service) {
mService = service;
@@ -2099,9 +2106,14 @@ public final class ActivityStackSupervisor implements DisplayListener {
}
ActivityStack getStack(int stackId) {
- ActivityContainer activityContainer = mActivityContainers.get(stackId);
- if (activityContainer != null) {
- return activityContainer.mStack;
+ WeakReference<ActivityContainer> weakReference = mActivityContainers.get(stackId);
+ if (weakReference != null) {
+ ActivityContainer activityContainer = weakReference.get();
+ if (activityContainer != null) {
+ return activityContainer.mStack;
+ } else {
+ mActivityContainers.remove(stackId);
+ }
}
return null;
}
@@ -2135,7 +2147,7 @@ public final class ActivityStackSupervisor implements DisplayListener {
IActivityContainerCallback callback) {
ActivityContainer activityContainer = new ActivityContainer(parentActivity, stackId,
callback);
- mActivityContainers.put(stackId, activityContainer);
+ mActivityContainers.put(stackId, new WeakReference<ActivityContainer>(activityContainer));
if (parentActivity != null) {
parentActivity.mChildContainers.add(activityContainer.mStack);
}
@@ -2729,11 +2741,17 @@ public final class ActivityStackSupervisor implements DisplayListener {
}
public void handleDisplayAddedLocked(int displayId) {
+ boolean newDisplay;
synchronized (mService) {
- ActivityDisplay activityDisplay = new ActivityDisplay(displayId);
- mActivityDisplays.put(displayId, activityDisplay);
+ newDisplay = mActivityDisplays.get(displayId) == null;
+ if (newDisplay) {
+ ActivityDisplay activityDisplay = new ActivityDisplay(displayId);
+ mActivityDisplays.put(displayId, activityDisplay);
+ }
+ }
+ if (newDisplay) {
+ mWindowManager.onDisplayAdded(displayId);
}
- mWindowManager.onDisplayAdded(displayId);
}
public void handleDisplayRemovedLocked(int displayId) {
@@ -2961,6 +2979,49 @@ public final class ActivityStackSupervisor implements DisplayListener {
return this;
}
+ @Override
+ public void createActivityView(Surface surface, int width, int height, int density) {
+ DisplayManagerGlobal dm = DisplayManagerGlobal.getInstance();
+ VirtualDisplay virtualDisplay;
+ long ident = Binder.clearCallingIdentity();
+ try {
+ virtualDisplay = dm.createVirtualDisplay(mService.mContext,
+ VIRTUAL_DISPLAY_BASE_NAME, width, height, density, surface,
+ // TODO: Add VIRTUAL_DISPLAY_FLAG_DISABLE_MIRRORING when it is available.
+ DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC);
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+
+ final Display display = virtualDisplay.getDisplay();
+ final int displayId = display.getDisplayId();
+
+ // Do WindowManager operation first so that it is ahead of CREATE_STACK in the H queue.
+ mWindowManager.onDisplayAdded(displayId);
+
+ synchronized (mService) {
+ ActivityDisplay activityDisplay = new ActivityDisplay(display);
+ mActivityDisplays.put(displayId, activityDisplay);
+ attachToDisplayLocked(activityDisplay);
+ activityDisplay.mVirtualDisplay = virtualDisplay;
+ }
+ }
+
+ @Override
+ public void deleteActivityView() {
+ synchronized (mService) {
+ if (!isAttached()) {
+ return;
+ }
+ VirtualDisplay virtualDisplay = mActivityDisplay.mVirtualDisplay;
+ if (virtualDisplay != null) {
+ virtualDisplay.release();
+ mActivityDisplay.mVirtualDisplay = null;
+ }
+ detachLocked();
+ }
+ }
+
ActivityStackSupervisor getOuter() {
return ActivityStackSupervisor.this;
}
@@ -2990,9 +3051,17 @@ public final class ActivityStackSupervisor implements DisplayListener {
* stacks, bottommost behind. Accessed directly by ActivityManager package classes */
final ArrayList<ActivityStack> mStacks = new ArrayList<ActivityStack>();
+ /** If this display is for an ActivityView then the VirtualDisplay created for it is stored
+ * here. */
+ VirtualDisplay mVirtualDisplay;
+
ActivityDisplay(int displayId) {
- mDisplayId = displayId;
- mDisplay = mDisplayManager.getDisplay(displayId);
+ this(mDisplayManager.getDisplay(displayId));
+ }
+
+ ActivityDisplay(Display display) {
+ mDisplay = display;
+ mDisplayId = display.getDisplayId();
mDisplay.getDisplayInfo(mDisplayInfo);
}
diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java
index 073e24a30518..12ef65ae6eba 100644
--- a/services/core/java/com/android/server/display/DisplayManagerService.java
+++ b/services/core/java/com/android/server/display/DisplayManagerService.java
@@ -31,6 +31,7 @@ import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
+import android.os.Process;
import android.os.RemoteException;
import android.os.SystemClock;
import android.os.SystemProperties;
@@ -675,7 +676,8 @@ public final class DisplayManagerService extends IDisplayManager.Stub {
if (surface == null) {
throw new IllegalArgumentException("surface must not be null");
}
- if ((flags & DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC) != 0) {
+ if (callingUid != Process.SYSTEM_UID &&
+ (flags & DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC) != 0) {
if (mContext.checkCallingPermission(android.Manifest.permission.CAPTURE_VIDEO_OUTPUT)
!= PackageManager.PERMISSION_GRANTED
&& mContext.checkCallingPermission(
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index b71fc1996e26..ca8ff1edd688 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -4816,21 +4816,23 @@ public class WindowManagerService extends IWindowManager.Stub
}
/**
- * Create a new TaskStack and place it next to an existing stack.
+ * Create a new TaskStack and place it on a DisplayContent.
* @param stackId The unique identifier of the new stack.
+ * @param displayId The unique identifier of the DisplayContent.
*/
public void createStack(int stackId, int displayId) {
- synchronized (mWindowMap) {
- final int numDisplays = mDisplayContents.size();
- for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
- final DisplayContent displayContent = mDisplayContents.valueAt(displayNdx);
- if (displayContent.getDisplayId() == displayId) {
+ final long origId = Binder.clearCallingIdentity();
+ try {
+ synchronized (mWindowMap) {
+ final DisplayContent displayContent = mDisplayContents.get(displayId);
+ if (displayContent != null) {
TaskStack stack = displayContent.createStack(stackId);
mStackIdToStack.put(stackId, stack);
performLayoutAndPlaceSurfacesLocked();
- return;
}
}
+ } finally {
+ Binder.restoreCallingIdentity(origId);
}
}
@@ -7040,6 +7042,8 @@ public class WindowManagerService extends IWindowManager.Stub
public static final int TAP_OUTSIDE_STACK = 31;
public static final int NOTIFY_ACTIVITY_DRAWN = 32;
+ public static final int REMOVE_STARTING_TIMEOUT = 33;
+
@Override
public void handleMessage(Message msg) {
if (DEBUG_WINDOW_TRACE) {