summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/app/SearchDialog.java4
-rw-r--r--core/java/android/app/SuggestionsAdapter.java34
-rwxr-xr-xcore/java/android/appwidget/AppWidgetProvider.java8
-rw-r--r--core/java/android/content/res/CompatibilityInfo.java9
-rw-r--r--core/java/android/view/SurfaceView.java16
-rw-r--r--core/java/android/view/ViewRoot.java9
-rw-r--r--core/java/android/view/WindowManager.java3
-rw-r--r--core/jni/android/graphics/Bitmap.cpp6
-rw-r--r--core/jni/android/graphics/BitmapFactory.cpp10
-rw-r--r--core/jni/android/graphics/Graphics.cpp56
-rw-r--r--core/jni/android/graphics/GraphicsJNI.h6
-rw-r--r--core/jni/android_media_AudioRecord.cpp6
-rw-r--r--graphics/java/android/graphics/BitmapFactory.java13
-rw-r--r--keystore/java/android/security/CertTool.java50
-rw-r--r--keystore/jni/cert.c114
-rw-r--r--keystore/jni/cert.h15
-rw-r--r--keystore/jni/certtool.c97
-rw-r--r--packages/TtsService/jni/android_tts_SynthProxy.cpp1
-rw-r--r--services/java/com/android/server/WindowManagerService.java45
-rw-r--r--tests/DumpRenderTree/src/com/android/dumprendertree/LoadTestsAutoTest.java4
20 files changed, 413 insertions, 93 deletions
diff --git a/core/java/android/app/SearchDialog.java b/core/java/android/app/SearchDialog.java
index 359cdac4560c..906361c3bcb5 100644
--- a/core/java/android/app/SearchDialog.java
+++ b/core/java/android/app/SearchDialog.java
@@ -139,8 +139,8 @@ public class SearchDialog extends Dialog implements OnItemClickListener, OnItemS
// A weak map of drawables we've gotten from other packages, so we don't load them
// more than once.
- private final WeakHashMap<String, Drawable> mOutsideDrawablesCache =
- new WeakHashMap<String, Drawable>();
+ private final WeakHashMap<String, Drawable.ConstantState> mOutsideDrawablesCache =
+ new WeakHashMap<String, Drawable.ConstantState>();
// Last known IME options value for the search edit text.
private int mSearchAutoCompleteImeOptions;
diff --git a/core/java/android/app/SuggestionsAdapter.java b/core/java/android/app/SuggestionsAdapter.java
index f2325d020772..593b7b736cfa 100644
--- a/core/java/android/app/SuggestionsAdapter.java
+++ b/core/java/android/app/SuggestionsAdapter.java
@@ -61,8 +61,8 @@ class SuggestionsAdapter extends ResourceCursorAdapter {
private SearchDialog mSearchDialog;
private SearchableInfo mSearchable;
private Context mProviderContext;
- private WeakHashMap<String, Drawable> mOutsideDrawablesCache;
- private SparseArray<Drawable> mBackgroundsCache;
+ private WeakHashMap<String, Drawable.ConstantState> mOutsideDrawablesCache;
+ private SparseArray<Drawable.ConstantState> mBackgroundsCache;
private boolean mGlobalSearchMode;
// Cached column indexes, updated when the cursor changes.
@@ -97,8 +97,10 @@ class SuggestionsAdapter extends ResourceCursorAdapter {
*/
private static final long DELETE_KEY_POST_DELAY = 500L;
- public SuggestionsAdapter(Context context, SearchDialog searchDialog, SearchableInfo searchable,
- WeakHashMap<String, Drawable> outsideDrawablesCache, boolean globalSearchMode) {
+ public SuggestionsAdapter(Context context, SearchDialog searchDialog,
+ SearchableInfo searchable,
+ WeakHashMap<String, Drawable.ConstantState> outsideDrawablesCache,
+ boolean globalSearchMode) {
super(context,
com.android.internal.R.layout.search_dropdown_item_icons_2line,
null, // no initial cursor
@@ -112,7 +114,7 @@ class SuggestionsAdapter extends ResourceCursorAdapter {
mProviderContext = mSearchable.getProviderContext(mContext, activityContext);
mOutsideDrawablesCache = outsideDrawablesCache;
- mBackgroundsCache = new SparseArray<Drawable>();
+ mBackgroundsCache = new SparseArray<Drawable.ConstantState>();
mGlobalSearchMode = globalSearchMode;
mStartSpinnerRunnable = new Runnable() {
@@ -345,11 +347,10 @@ class SuggestionsAdapter extends ResourceCursorAdapter {
if (backgroundColor == 0) {
return null;
} else {
- Drawable cachedBg = mBackgroundsCache.get(backgroundColor);
+ Drawable.ConstantState cachedBg = mBackgroundsCache.get(backgroundColor);
if (cachedBg != null) {
if (DBG) Log.d(LOG_TAG, "Background cache hit for color " + backgroundColor);
- // copy the drawable so that they don't share states
- return cachedBg.getConstantState().newDrawable();
+ return cachedBg.newDrawable();
}
if (DBG) Log.d(LOG_TAG, "Creating new background for color " + backgroundColor);
ColorDrawable transparent = new ColorDrawable(0);
@@ -358,7 +359,7 @@ class SuggestionsAdapter extends ResourceCursorAdapter {
newBg.addState(new int[]{android.R.attr.state_selected}, transparent);
newBg.addState(new int[]{android.R.attr.state_pressed}, transparent);
newBg.addState(new int[]{}, background);
- mBackgroundsCache.put(backgroundColor, newBg);
+ mBackgroundsCache.put(backgroundColor, newBg.getConstantState());
return newBg;
}
}
@@ -523,12 +524,13 @@ class SuggestionsAdapter extends ResourceCursorAdapter {
}
// First, check the cache.
- Drawable drawable = mOutsideDrawablesCache.get(drawableId);
- if (drawable != null) {
+ Drawable.ConstantState cached = mOutsideDrawablesCache.get(drawableId);
+ if (cached != null) {
if (DBG) Log.d(LOG_TAG, "Found icon in cache: " + drawableId);
- return drawable;
+ return cached.newDrawable();
}
+ Drawable drawable = null;
try {
// Not cached, try using it as a plain resource ID in the provider's context.
int resourceId = Integer.parseInt(drawableId);
@@ -560,7 +562,7 @@ class SuggestionsAdapter extends ResourceCursorAdapter {
// If we got a drawable for this resource id, then stick it in the
// map so we don't do this lookup again.
if (drawable != null) {
- mOutsideDrawablesCache.put(drawableId, drawable);
+ mOutsideDrawablesCache.put(drawableId, drawable.getConstantState());
}
} catch (Resources.NotFoundException nfe) {
if (DBG) Log.d(LOG_TAG, "Icon resource not found: " + drawableId);
@@ -615,12 +617,14 @@ class SuggestionsAdapter extends ResourceCursorAdapter {
String componentIconKey = component.flattenToShortString();
// Using containsKey() since we also store null values.
if (mOutsideDrawablesCache.containsKey(componentIconKey)) {
- return mOutsideDrawablesCache.get(componentIconKey);
+ Drawable.ConstantState cached = mOutsideDrawablesCache.get(componentIconKey);
+ return cached == null ? null : cached.newDrawable();
}
// Then try the activity or application icon
Drawable drawable = getActivityIcon(component);
// Stick it in the cache so we don't do this lookup again.
- mOutsideDrawablesCache.put(componentIconKey, drawable);
+ Drawable.ConstantState toCache = drawable == null ? null : drawable.getConstantState();
+ mOutsideDrawablesCache.put(componentIconKey, toCache);
return drawable;
}
diff --git a/core/java/android/appwidget/AppWidgetProvider.java b/core/java/android/appwidget/AppWidgetProvider.java
index 26712a10f0ce..f1bbedef9024 100755
--- a/core/java/android/appwidget/AppWidgetProvider.java
+++ b/core/java/android/appwidget/AppWidgetProvider.java
@@ -64,11 +64,9 @@ public class AppWidgetProvider extends BroadcastReceiver {
}
else if (AppWidgetManager.ACTION_APPWIDGET_DELETED.equals(action)) {
Bundle extras = intent.getExtras();
- if (extras != null) {
- int[] appWidgetIds = extras.getIntArray(AppWidgetManager.EXTRA_APPWIDGET_IDS);
- if (appWidgetIds != null && appWidgetIds.length > 0) {
- this.onDeleted(context, appWidgetIds);
- }
+ if (extras != null && extras.containsKey(AppWidgetManager.EXTRA_APPWIDGET_ID)) {
+ final int appWidgetId = extras.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID);
+ this.onDeleted(context, new int[] { appWidgetId });
}
}
else if (AppWidgetManager.ACTION_APPWIDGET_ENABLED.equals(action)) {
diff --git a/core/java/android/content/res/CompatibilityInfo.java b/core/java/android/content/res/CompatibilityInfo.java
index ebe556e3cd65..08e3a40e66a0 100644
--- a/core/java/android/content/res/CompatibilityInfo.java
+++ b/core/java/android/content/res/CompatibilityInfo.java
@@ -38,7 +38,12 @@ public class CompatibilityInfo {
private static final String TAG = "CompatibilityInfo";
/** default compatibility info object for compatible applications */
- public static final CompatibilityInfo DEFAULT_COMPATIBILITY_INFO = new CompatibilityInfo();
+ public static final CompatibilityInfo DEFAULT_COMPATIBILITY_INFO = new CompatibilityInfo() {
+ @Override
+ public void setExpandable(boolean expandable) {
+ throw new UnsupportedOperationException("trying to change default compatibility info");
+ }
+ };
/**
* The default width of the screen in portrait mode.
@@ -191,7 +196,7 @@ public class CompatibilityInfo {
@Override
public String toString() {
return "CompatibilityInfo{scale=" + applicationScale +
- ", compatibility flag=" + mCompatibilityFlags + "}";
+ ", supports screen=" + supportsScreen() + "}";
}
/**
diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java
index ff1eb532dff0..28c1fe1fefb5 100644
--- a/core/java/android/view/SurfaceView.java
+++ b/core/java/android/view/SurfaceView.java
@@ -17,7 +17,6 @@
package android.view;
import android.content.Context;
-import android.content.res.CompatibilityInfo;
import android.content.res.CompatibilityInfo.Translator;
import android.graphics.Canvas;
import android.graphics.PixelFormat;
@@ -256,7 +255,7 @@ public class SurfaceView extends View {
public boolean dispatchTouchEvent(MotionEvent event) {
// SurfaceView uses pre-scaled size unless fixed size is requested. This hook
// scales the event back to the pre-scaled coordinates for such surface.
- if (mRequestedWidth < 0 && mTranslator != null) {
+ if (mScaled) {
MotionEvent scaledBack = MotionEvent.obtain(event);
scaledBack.scale(mTranslator.applicationScale);
try {
@@ -290,6 +289,8 @@ public class SurfaceView extends View {
public void setWindowType(int type) {
mWindowType = type;
}
+
+ boolean mScaled = false;
private void updateWindow(boolean force) {
if (!mHaveFrame) {
@@ -309,6 +310,9 @@ public class SurfaceView extends View {
if (mRequestedWidth <= 0 && mTranslator != null) {
myWidth *= appScale;
myHeight *= appScale;
+ mScaled = true;
+ } else {
+ mScaled = false;
}
getLocationInWindow(mLocation);
@@ -533,6 +537,7 @@ public class SurfaceView extends View {
private SurfaceHolder mSurfaceHolder = new SurfaceHolder() {
private static final String LOG_TAG = "SurfaceHolder";
+ private int mSaveCount;
public boolean isCreating() {
return mIsCreating;
@@ -627,6 +632,10 @@ public class SurfaceView extends View {
if (localLOGV) Log.i(TAG, "Returned canvas: " + c);
if (c != null) {
mLastLockTime = SystemClock.uptimeMillis();
+ if (mScaled) {
+ mSaveCount = c.save();
+ mTranslator.translateCanvas(c);
+ }
return c;
}
@@ -649,6 +658,9 @@ public class SurfaceView extends View {
}
public void unlockCanvasAndPost(Canvas canvas) {
+ if (mScaled) {
+ canvas.restoreToCount(mSaveCount);
+ }
mSurface.unlockCanvasAndPost(canvas);
mSurfaceLock.unlock();
}
diff --git a/core/java/android/view/ViewRoot.java b/core/java/android/view/ViewRoot.java
index eab3799a9059..301d604bac76 100644
--- a/core/java/android/view/ViewRoot.java
+++ b/core/java/android/view/ViewRoot.java
@@ -497,8 +497,12 @@ public final class ViewRoot extends Handler implements ViewParent,
void setLayoutParams(WindowManager.LayoutParams attrs, boolean newView) {
synchronized (this) {
int oldSoftInputMode = mWindowAttributes.softInputMode;
+ // preserve compatible window flag if exists.
+ int compatibleWindowFlag =
+ mWindowAttributes.flags & WindowManager.LayoutParams.FLAG_COMPATIBLE_WINDOW;
mWindowAttributes.copyFrom(attrs);
-
+ mWindowAttributes.flags |= compatibleWindowFlag;
+
if (newView) {
mSoftInputMode = attrs.softInputMode;
requestLayout();
@@ -1301,7 +1305,8 @@ public final class ViewRoot extends Handler implements ViewParent,
if (DEBUG_DRAW) {
Context cxt = mView.getContext();
Log.i(TAG, "Drawing: package:" + cxt.getPackageName() +
- ", metrics=" + mView.getContext().getResources().getDisplayMetrics());
+ ", metrics=" + cxt.getResources().getDisplayMetrics() +
+ ", compatibilityInfo=" + cxt.getResources().getCompatibilityInfo());
}
int saveCount = canvas.save(Canvas.MATRIX_SAVE_FLAG);
try {
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index e96a15ba05f2..ba3bfa76f5c2 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -986,6 +986,9 @@ public interface WindowManager extends ViewManager {
sb.append(" or=");
sb.append(screenOrientation);
}
+ if ((flags & FLAG_COMPATIBLE_WINDOW) != 0) {
+ sb.append(" compatible=true");
+ }
sb.append('}');
return sb.toString();
}
diff --git a/core/jni/android/graphics/Bitmap.cpp b/core/jni/android/graphics/Bitmap.cpp
index af8ecf5cccc3..3fb07a74a6f6 100644
--- a/core/jni/android/graphics/Bitmap.cpp
+++ b/core/jni/android/graphics/Bitmap.cpp
@@ -224,7 +224,7 @@ static jobject Bitmap_creator(JNIEnv* env, jobject, jintArray jColors,
SkBitmap bitmap;
bitmap.setConfig(config, width, height);
- if (!GraphicsJNI::setJavaPixelRef(env, &bitmap, NULL)) {
+ if (!GraphicsJNI::setJavaPixelRef(env, &bitmap, NULL, true)) {
return NULL;
}
@@ -240,7 +240,7 @@ static jobject Bitmap_creator(JNIEnv* env, jobject, jintArray jColors,
static jobject Bitmap_copy(JNIEnv* env, jobject, const SkBitmap* src,
SkBitmap::Config dstConfig, jboolean isMutable) {
SkBitmap result;
- JavaPixelAllocator allocator(env);
+ JavaPixelAllocator allocator(env, true);
if (!src->copyTo(&result, dstConfig, &allocator)) {
return NULL;
@@ -356,7 +356,7 @@ static jobject Bitmap_createFromParcel(JNIEnv* env, jobject, jobject parcel) {
}
}
- if (!GraphicsJNI::setJavaPixelRef(env, bitmap, ctable)) {
+ if (!GraphicsJNI::setJavaPixelRef(env, bitmap, ctable, true)) {
ctable->safeUnref();
delete bitmap;
return NULL;
diff --git a/core/jni/android/graphics/BitmapFactory.cpp b/core/jni/android/graphics/BitmapFactory.cpp
index 137707fa93bf..0c842650962f 100644
--- a/core/jni/android/graphics/BitmapFactory.cpp
+++ b/core/jni/android/graphics/BitmapFactory.cpp
@@ -23,6 +23,7 @@ static jfieldID gOptions_configFieldID;
static jfieldID gOptions_ditherFieldID;
static jfieldID gOptions_purgeableFieldID;
static jfieldID gOptions_shareableFieldID;
+static jfieldID gOptions_nativeAllocFieldID;
static jfieldID gOptions_widthFieldID;
static jfieldID gOptions_heightFieldID;
static jfieldID gOptions_mimeFieldID;
@@ -300,6 +301,11 @@ static bool optionsShareable(JNIEnv* env, jobject options) {
env->GetBooleanField(options, gOptions_shareableFieldID);
}
+static bool optionsReportSizeToVM(JNIEnv* env, jobject options) {
+ return NULL == options ||
+ !env->GetBooleanField(options, gOptions_nativeAllocFieldID);
+}
+
static jobject nullObjectReturn(const char msg[]) {
if (msg) {
SkDebugf("--- %s\n", msg);
@@ -330,6 +336,7 @@ static jobject doDecode(JNIEnv* env, SkStream* stream, jobject padding,
SkBitmap::Config prefConfig = SkBitmap::kNo_Config;
bool doDither = true;
bool isPurgeable = allowPurgeable && optionsPurgeable(env, options);
+ bool reportSizeToVM = optionsReportSizeToVM(env, options);
if (NULL != options) {
sampleSize = env->GetIntField(options, gOptions_sampleSizeFieldID);
@@ -355,7 +362,7 @@ static jobject doDecode(JNIEnv* env, SkStream* stream, jobject padding,
decoder->setDitherImage(doDither);
NinePatchPeeker peeker;
- JavaPixelAllocator javaAllocator(env);
+ JavaPixelAllocator javaAllocator(env, reportSizeToVM);
SkBitmap* bitmap = new SkBitmap;
Res_png_9patch dummy9Patch;
@@ -699,6 +706,7 @@ int register_android_graphics_BitmapFactory(JNIEnv* env) {
gOptions_ditherFieldID = getFieldIDCheck(env, gOptions_class, "inDither", "Z");
gOptions_purgeableFieldID = getFieldIDCheck(env, gOptions_class, "inPurgeable", "Z");
gOptions_shareableFieldID = getFieldIDCheck(env, gOptions_class, "inInputShareable", "Z");
+ gOptions_nativeAllocFieldID = getFieldIDCheck(env, gOptions_class, "inNativeAlloc", "Z");
gOptions_widthFieldID = getFieldIDCheck(env, gOptions_class, "outWidth", "I");
gOptions_heightFieldID = getFieldIDCheck(env, gOptions_class, "outHeight", "I");
gOptions_mimeFieldID = getFieldIDCheck(env, gOptions_class, "outMimeType", "Ljava/lang/String;");
diff --git a/core/jni/android/graphics/Graphics.cpp b/core/jni/android/graphics/Graphics.cpp
index 6eebbdcfb563..6e159a8853d5 100644
--- a/core/jni/android/graphics/Graphics.cpp
+++ b/core/jni/android/graphics/Graphics.cpp
@@ -5,6 +5,7 @@
#include "SkRegion.h"
#include <android_runtime/AndroidRuntime.h>
+//#define REPORT_SIZE_TO_JVM
//#define TRACK_LOCK_COUNT
void doThrow(JNIEnv* env, const char* exc, const char* msg) {
@@ -444,7 +445,7 @@ private:
};
bool GraphicsJNI::setJavaPixelRef(JNIEnv* env, SkBitmap* bitmap,
- SkColorTable* ctable) {
+ SkColorTable* ctable, bool reportSizeToVM) {
Sk64 size64 = bitmap->getSize64();
if (size64.isNeg() || !size64.is32()) {
doThrow(env, "java/lang/IllegalArgumentException",
@@ -453,35 +454,41 @@ bool GraphicsJNI::setJavaPixelRef(JNIEnv* env, SkBitmap* bitmap,
}
size_t size = size64.get32();
- // SkDebugf("-------------- inform VM we've allocated %d bytes\n", size);
jlong jsize = size; // the VM wants longs for the size
- bool r = env->CallBooleanMethod(gVMRuntime_singleton,
- gVMRuntime_trackExternalAllocationMethodID,
- jsize);
- if (GraphicsJNI::hasException(env)) {
- return false;
- }
- if (!r) {
- LOGE("VM won't let us allocate %zd bytes\n", size);
- doThrowOOME(env, "bitmap size exceeds VM budget");
- return false;
+ if (reportSizeToVM) {
+ // SkDebugf("-------------- inform VM we've allocated %d bytes\n", size);
+ bool r = env->CallBooleanMethod(gVMRuntime_singleton,
+ gVMRuntime_trackExternalAllocationMethodID,
+ jsize);
+ if (GraphicsJNI::hasException(env)) {
+ return false;
+ }
+ if (!r) {
+ LOGE("VM won't let us allocate %zd bytes\n", size);
+ doThrowOOME(env, "bitmap size exceeds VM budget");
+ return false;
+ }
}
-
// call the version of malloc that returns null on failure
void* addr = sk_malloc_flags(size, 0);
if (NULL == addr) {
- // SkDebugf("-------------- inform VM we're releasing %d bytes which we couldn't allocate\n", size);
- // we didn't actually allocate it, so inform the VM
- env->CallVoidMethod(gVMRuntime_singleton,
- gVMRuntime_trackExternalFreeMethodID,
- jsize);
- if (!GraphicsJNI::hasException(env)) {
- doThrowOOME(env, "bitmap size too large for malloc");
+ if (reportSizeToVM) {
+ // SkDebugf("-------------- inform VM we're releasing %d bytes which we couldn't allocate\n", size);
+ // we didn't actually allocate it, so inform the VM
+ env->CallVoidMethod(gVMRuntime_singleton,
+ gVMRuntime_trackExternalFreeMethodID,
+ jsize);
+ if (!GraphicsJNI::hasException(env)) {
+ doThrowOOME(env, "bitmap size too large for malloc");
+ }
}
return false;
}
- bitmap->setPixelRef(new AndroidPixelRef(env, addr, size, ctable))->unref();
+ SkPixelRef* pr = reportSizeToVM ?
+ new AndroidPixelRef(env, addr, size, ctable) :
+ new SkMallocPixelRef(addr, size, ctable);
+ bitmap->setPixelRef(pr)->unref();
// since we're already allocated, we lockPixels right away
// HeapAllocator behaves this way too
bitmap->lockPixels();
@@ -490,12 +497,11 @@ bool GraphicsJNI::setJavaPixelRef(JNIEnv* env, SkBitmap* bitmap,
///////////////////////////////////////////////////////////////////////////////
-JavaPixelAllocator::JavaPixelAllocator(JNIEnv* env) : fEnv(env)
-{
-}
+JavaPixelAllocator::JavaPixelAllocator(JNIEnv* env, bool reportSizeToVM)
+ : fEnv(env), fReportSizeToVM(reportSizeToVM) {}
bool JavaPixelAllocator::allocPixelRef(SkBitmap* bitmap, SkColorTable* ctable) {
- return GraphicsJNI::setJavaPixelRef(fEnv, bitmap, ctable);
+ return GraphicsJNI::setJavaPixelRef(fEnv, bitmap, ctable, fReportSizeToVM);
}
////////////////////////////////////////////////////////////////////////////////
diff --git a/core/jni/android/graphics/GraphicsJNI.h b/core/jni/android/graphics/GraphicsJNI.h
index e2dc9acf1beb..16925e41ab4f 100644
--- a/core/jni/android/graphics/GraphicsJNI.h
+++ b/core/jni/android/graphics/GraphicsJNI.h
@@ -59,7 +59,8 @@ public:
Returns true on success. If it returns false, then it failed, and the
appropriate exception will have been raised.
*/
- static bool setJavaPixelRef(JNIEnv*, SkBitmap*, SkColorTable* ctable);
+ static bool setJavaPixelRef(JNIEnv*, SkBitmap*, SkColorTable* ctable,
+ bool reportSizeToVM);
/** Copy the colors in colors[] to the bitmap, convert to the correct
format along the way.
@@ -71,12 +72,13 @@ public:
class JavaPixelAllocator : public SkBitmap::Allocator {
public:
- JavaPixelAllocator(JNIEnv* env);
+ JavaPixelAllocator(JNIEnv* env, bool reportSizeToVM);
// overrides
virtual bool allocPixelRef(SkBitmap* bitmap, SkColorTable* ctable);
private:
JNIEnv* fEnv;
+ bool fReportSizeToVM;
};
class AutoJavaFloatArray {
diff --git a/core/jni/android_media_AudioRecord.cpp b/core/jni/android_media_AudioRecord.cpp
index e71e3481862e..44a9e8cbcc58 100644
--- a/core/jni/android_media_AudioRecord.cpp
+++ b/core/jni/android_media_AudioRecord.cpp
@@ -212,8 +212,10 @@ android_media_AudioRecord_setup(JNIEnv *env, jobject thiz, jobject weak_this,
// failure:
native_init_failure:
+ env->DeleteGlobalRef(lpCallbackData->audioRecord_class);
+ env->DeleteGlobalRef(lpCallbackData->audioRecord_ref);
delete lpCallbackData;
-
+
native_track_failure:
delete lpRecorder;
@@ -274,6 +276,8 @@ static void android_media_AudioRecord_finalize(JNIEnv *env, jobject thiz) {
thiz, javaAudioRecordFields.nativeCallbackCookie);
if (lpCookie) {
LOGV("deleting lpCookie: %x\n", (int)lpCookie);
+ env->DeleteGlobalRef(lpCookie->audioRecord_class);
+ env->DeleteGlobalRef(lpCookie->audioRecord_ref);
delete lpCookie;
}
diff --git a/graphics/java/android/graphics/BitmapFactory.java b/graphics/java/android/graphics/BitmapFactory.java
index e5a9aab7ad63..082e0c069c0e 100644
--- a/graphics/java/android/graphics/BitmapFactory.java
+++ b/graphics/java/android/graphics/BitmapFactory.java
@@ -129,6 +129,19 @@ public class BitmapFactory {
public boolean inInputShareable;
/**
+ * Normally bitmap allocations count against the dalvik heap, which
+ * means they help trigger GCs when a lot have been allocated. However,
+ * in rare cases, the caller may want to allocate the bitmap outside of
+ * that heap. To request that, set inNativeAlloc to true. In these
+ * rare instances, it is solely up to the caller to ensure that OOM is
+ * managed explicitly by calling bitmap.recycle() as soon as such a
+ * bitmap is no longer needed.
+ *
+ * @hide pending API council approval
+ */
+ public boolean inNativeAlloc;
+
+ /**
* The resulting width of the bitmap, set independent of the state of
* inJustDecodeBounds. However, if there is an error trying to decode,
* outWidth will be set to -1.
diff --git a/keystore/java/android/security/CertTool.java b/keystore/java/android/security/CertTool.java
index 26d22aec57fb..c96cd4f4d907 100644
--- a/keystore/java/android/security/CertTool.java
+++ b/keystore/java/android/security/CertTool.java
@@ -16,11 +16,19 @@
package android.security;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateException;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.UnrecoverableKeyException;
+
import android.content.Context;
import android.content.Intent;
import android.security.Keystore;
import android.text.TextUtils;
-
+import android.util.Log;
/**
* The CertTool class provides the functions to list the certs/keys,
@@ -41,12 +49,12 @@ public class CertTool {
public static final String KEY_NAMESPACE = "namespace";
public static final String KEY_DESCRIPTION = "description";
- private static final String TAG = "CertTool";
+ public static final String TITLE_CA_CERT = "CA Certificate";
+ public static final String TITLE_USER_CERT = "User Certificate";
+ public static final String TITLE_PKCS12_KEYSTORE = "PKCS12 Keystore";
+ public static final String TITLE_PRIVATE_KEY = "Private Key";
- private static final String TITLE_CA_CERT = "CA Certificate";
- private static final String TITLE_USER_CERT = "User Certificate";
- private static final String TITLE_PKCS12_KEYSTORE = "PKCS12 Keystore";
- private static final String TITLE_PRIVATE_KEY = "Private Key";
+ private static final String TAG = "CertTool";
private static final String UNKNOWN = "Unknown";
private static final String ISSUER_NAME = "Issuer Name:";
private static final String DISTINCT_NAME = "Distinct Name:";
@@ -58,6 +66,11 @@ public class CertTool {
private static final String KEYNAME_DELIMITER = "_";
private static final Keystore sKeystore = Keystore.getInstance();
+ private native int getPkcs12Handle(byte[] data, String password);
+ private native String getPkcs12Certificate(int handle);
+ private native String getPkcs12PrivateKey(int handle);
+ private native String popPkcs12CertificateStack(int handle);
+ private native void freePkcs12Handle(int handle);
private native String generateCertificateRequest(int bits, String subject);
private native boolean isPkcs12Keystore(byte[] data);
private native int generateX509Certificate(byte[] data);
@@ -130,10 +143,35 @@ public class CertTool {
intent.putExtra(KEY_NAMESPACE + "1", namespace);
}
+ public int addPkcs12Keystore(byte[] p12Data, String password,
+ String keyname) {
+ int handle, i = 0;
+ String pemData;
+ Log.i("CertTool", "addPkcs12Keystore()");
+
+ if ((handle = getPkcs12Handle(p12Data, password)) == 0) return -1;
+ if ((pemData = getPkcs12Certificate(handle)) != null) {
+ sKeystore.put(USER_CERTIFICATE, keyname, pemData);
+ }
+ if ((pemData = getPkcs12PrivateKey(handle)) != null) {
+ sKeystore.put(USER_KEY, keyname, pemData);
+ }
+ while ((pemData = this.popPkcs12CertificateStack(handle)) != null) {
+ if (i++ > 0) {
+ sKeystore.put(CA_CERTIFICATE, keyname + i, pemData);
+ } else {
+ sKeystore.put(CA_CERTIFICATE, keyname, pemData);
+ }
+ }
+ freePkcs12Handle(handle);
+ return 0;
+ }
+
public synchronized void addCertificate(byte[] data, Context context) {
int handle;
Intent intent = null;
+ Log.i("CertTool", "addCertificate()");
if (isPkcs12Keystore(data)) {
intent = prepareIntent(TITLE_PKCS12_KEYSTORE, data, USER_KEY,
UNKNOWN, UNKNOWN);
diff --git a/keystore/jni/cert.c b/keystore/jni/cert.c
index cc36b84e99a3..0db28fd0e822 100644
--- a/keystore/jni/cert.c
+++ b/keystore/jni/cert.c
@@ -136,30 +136,126 @@ err:
return ret_code;
}
-int is_pkcs12(const char *buf, int bufLen)
+PKCS12 *get_p12_handle(const char *buf, int bufLen)
{
- int ret = 0;
BIO *bp = NULL;
PKCS12 *p12 = NULL;
- if (!buf || bufLen < 1) goto err;
+ if (!buf || (bufLen < 1) || (buf[0] != 48)) goto err;
bp = BIO_new(BIO_s_mem());
if (!bp) goto err;
- if (buf[0] != 48) goto err; // it is not DER.
-
if (!BIO_write(bp, buf, bufLen)) goto err;
- if ((p12 = d2i_PKCS12_bio(bp, NULL)) != NULL) {
- PKCS12_free(p12);
- ret = 1;
- }
+ p12 = d2i_PKCS12_bio(bp, NULL);
+
err:
if (bp) BIO_free(bp);
+ return p12;
+}
+
+PKCS12_KEYSTORE *get_pkcs12_keystore_handle(const char *buf, int bufLen,
+ const char *passwd)
+{
+ PKCS12_KEYSTORE *p12store = NULL;
+ EVP_PKEY *pkey = NULL;
+ X509 *cert = NULL;
+ STACK_OF(X509) *certs = NULL;
+ PKCS12 *p12 = get_p12_handle(buf, bufLen);
+
+ if (p12 == NULL) return NULL;
+ if (!PKCS12_parse(p12, passwd, &pkey, &cert, &certs)) {
+ LOGE("Can not parse PKCS12 content");
+ PKCS12_free(p12);
+ return NULL;
+ }
+ if ((p12store = malloc(sizeof(PKCS12_KEYSTORE))) == NULL) {
+ if (cert) X509_free(cert);
+ if (pkey) EVP_PKEY_free(pkey);
+ if (certs) sk_X509_free(certs);
+ }
+ p12store->p12 = p12;
+ p12store->pkey = pkey;
+ p12store->cert = cert;
+ p12store->certs = certs;
+ return p12store;
+}
+
+void free_pkcs12_keystore(PKCS12_KEYSTORE *p12store)
+{
+ if (p12store != NULL) {
+ if (p12store->cert) X509_free(p12store->cert);
+ if (p12store->pkey) EVP_PKEY_free(p12store->pkey);
+ if (p12store->certs) sk_X509_free(p12store->certs);
+ free(p12store);
+ }
+}
+
+int is_pkcs12(const char *buf, int bufLen)
+{
+ int ret = 0;
+ PKCS12 *p12 = get_p12_handle(buf, bufLen);
+ if (p12 != NULL) ret = 1;
+ PKCS12_free(p12);
return ret;
}
+static int convert_to_pem(void *data, int is_cert, char *buf, int size)
+{
+ int len = 0;
+ BIO *bio = NULL;
+
+ if (data == NULL) return -1;
+
+ if ((bio = BIO_new(BIO_s_mem())) == NULL) goto err;
+ if (is_cert) {
+ if ((len = PEM_write_bio_X509(bio, (X509*)data)) == 0) {
+ goto err;
+ }
+ } else {
+ if ((len = PEM_write_bio_PrivateKey(bio, (EVP_PKEY *)data, NULL,
+ NULL, 0, NULL, NULL)) == 0) {
+ goto err;
+ }
+ }
+ if (len < size && (len = BIO_read(bio, buf, size - 1)) > 0) {
+ buf[len] = 0;
+ }
+err:
+ if (bio) BIO_free(bio);
+ return (len == 0) ? -1 : 0;
+}
+
+int get_pkcs12_certificate(PKCS12_KEYSTORE *p12store, char *buf, int size)
+{
+ if ((p12store != NULL) && (p12store->cert != NULL)) {
+ return convert_to_pem((void*)p12store->cert, 1, buf, size);
+ }
+ return -1;
+}
+
+int get_pkcs12_private_key(PKCS12_KEYSTORE *p12store, char *buf, int size)
+{
+ if ((p12store != NULL) && (p12store->pkey != NULL)) {
+ return convert_to_pem((void*)p12store->pkey, 0, buf, size);
+ }
+ return -1;
+}
+
+int pop_pkcs12_certs_stack(PKCS12_KEYSTORE *p12store, char *buf, int size)
+{
+ X509 *cert = NULL;
+
+ if ((p12store != NULL) && (p12store->certs != NULL) &&
+ ((cert = sk_X509_pop(p12store->certs)) != NULL)) {
+ int ret = convert_to_pem((void*)cert, 1, buf, size);
+ X509_free(cert);
+ return ret;
+ }
+ return -1;
+}
+
X509* parse_cert(const char *buf, int bufLen)
{
X509 *cert = NULL;
diff --git a/keystore/jni/cert.h b/keystore/jni/cert.h
index a9807b1b20f0..aaa7602d8126 100644
--- a/keystore/jni/cert.h
+++ b/keystore/jni/cert.h
@@ -41,6 +41,13 @@ typedef struct {
int key_len;
} PKEY_STORE;
+typedef struct {
+ PKCS12 *p12;
+ EVP_PKEY *pkey;
+ X509 *cert;
+ STACK_OF(X509) *certs;
+} PKCS12_KEYSTORE;
+
#define PKEY_STORE_free(x) { \
if(x.pkey) EVP_PKEY_free(x.pkey); \
if(x.public_key) free(x.public_key); \
@@ -49,8 +56,14 @@ typedef struct {
#define nelem(x) (sizeof (x) / sizeof *(x))
int gen_csr(int bits, const char *organizations, char reply[REPLY_MAX]);
+PKCS12_KEYSTORE *get_pkcs12_keystore_handle(const char *buf, int bufLen,
+ const char *passwd);
+int get_pkcs12_certificate(PKCS12_KEYSTORE *p12store, char *buf, int size);
+int get_pkcs12_private_key(PKCS12_KEYSTORE *p12store, char *buf, int size);
+int pop_pkcs12_certs_stack(PKCS12_KEYSTORE *p12store, char *buf, int size);
+void free_pkcs12_keystore(PKCS12_KEYSTORE *p12store);
int is_pkcs12(const char *buf, int bufLen);
-X509* parse_cert(const char *buf, int bufLen);
+X509 *parse_cert(const char *buf, int bufLen);
int get_cert_name(X509 *cert, char *buf, int size);
int get_issuer_name(X509 *cert, char *buf, int size);
int is_ca_cert(X509 *cert);
diff --git a/keystore/jni/certtool.c b/keystore/jni/certtool.c
index fabf5cdf3fb7..1ae8dab4281f 100644
--- a/keystore/jni/certtool.c
+++ b/keystore/jni/certtool.c
@@ -19,10 +19,13 @@
#include <string.h>
#include <jni.h>
#include <cutils/log.h>
+#include <openssl/pkcs12.h>
#include <openssl/x509v3.h>
#include "cert.h"
+typedef int PKCS12_KEYSTORE_FUNC(PKCS12_KEYSTORE *store, char *buf, int size);
+
jstring
android_security_CertTool_generateCertificateRequest(JNIEnv* env,
jobject thiz,
@@ -42,12 +45,88 @@ android_security_CertTool_isPkcs12Keystore(JNIEnv* env,
jobject thiz,
jbyteArray data)
{
- char buf[REPLY_MAX];
int len = (*env)->GetArrayLength(env, data);
- if (len > REPLY_MAX) return 0;
- (*env)->GetByteArrayRegion(env, data, 0, len, (jbyte*)buf);
- return (jboolean) is_pkcs12(buf, len);
+ if (len > 0) {
+ PKCS12 *handle = NULL;
+ char buf[len];
+
+ (*env)->GetByteArrayRegion(env, data, 0, len, (jbyte*)buf);
+ return (jboolean)is_pkcs12(buf, len);
+ } else {
+ return 0;
+ }
+}
+
+jint
+android_security_CertTool_getPkcs12Handle(JNIEnv* env,
+ jobject thiz,
+ jbyteArray data,
+ jstring jPassword)
+{
+ jboolean bIsCopy;
+ int len = (*env)->GetArrayLength(env, data);
+ const char* passwd = (*env)->GetStringUTFChars(env, jPassword , &bIsCopy);
+
+ if (len > 0) {
+ PKCS12_KEYSTORE *handle = NULL;
+ char buf[len];
+
+ (*env)->GetByteArrayRegion(env, data, 0, len, (jbyte*)buf);
+ handle = get_pkcs12_keystore_handle(buf, len, passwd);
+ (*env)->ReleaseStringUTFChars(env, jPassword, passwd);
+ return (jint)handle;
+ } else {
+ return 0;
+ }
+}
+
+jstring call_pkcs12_ks_func(PKCS12_KEYSTORE_FUNC *func,
+ JNIEnv* env,
+ jobject thiz,
+ jint phandle)
+{
+ char buf[REPLY_MAX];
+
+ if (phandle == 0) return NULL;
+ if (func((PKCS12_KEYSTORE*)phandle, buf, sizeof(buf)) == 0) {
+ return (*env)->NewStringUTF(env, buf);
+ }
+ return NULL;
+}
+
+jstring
+android_security_CertTool_getPkcs12Certificate(JNIEnv* env,
+ jobject thiz,
+ jint phandle)
+{
+ return call_pkcs12_ks_func((PKCS12_KEYSTORE_FUNC *)get_pkcs12_certificate,
+ env, thiz, phandle);
+}
+
+jstring
+android_security_CertTool_getPkcs12PrivateKey(JNIEnv* env,
+ jobject thiz,
+ jint phandle)
+{
+ return call_pkcs12_ks_func((PKCS12_KEYSTORE_FUNC *)get_pkcs12_private_key,
+ env, thiz, phandle);
+}
+
+jstring
+android_security_CertTool_popPkcs12CertificateStack(JNIEnv* env,
+ jobject thiz,
+ jint phandle)
+{
+ return call_pkcs12_ks_func((PKCS12_KEYSTORE_FUNC *)pop_pkcs12_certs_stack,
+ env, thiz, phandle);
+}
+
+void android_security_CertTool_freePkcs12Handle(JNIEnv* env,
+ jobject thiz,
+ jint handle)
+{
+ if (handle != 0) free_pkcs12_keystore((PKCS12_KEYSTORE*)handle);
}
jint
@@ -117,6 +196,16 @@ static JNINativeMethod gCertToolMethods[] = {
(void*)android_security_CertTool_generateCertificateRequest},
{"isPkcs12Keystore", "([B)Z",
(void*)android_security_CertTool_isPkcs12Keystore},
+ {"getPkcs12Handle", "([BLjava/lang/String;)I",
+ (void*)android_security_CertTool_getPkcs12Handle},
+ {"getPkcs12Certificate", "(I)Ljava/lang/String;",
+ (void*)android_security_CertTool_getPkcs12Certificate},
+ {"getPkcs12PrivateKey", "(I)Ljava/lang/String;",
+ (void*)android_security_CertTool_getPkcs12PrivateKey},
+ {"popPkcs12CertificateStack", "(I)Ljava/lang/String;",
+ (void*)android_security_CertTool_popPkcs12CertificateStack},
+ {"freePkcs12Handle", "(I)V",
+ (void*)android_security_CertTool_freePkcs12Handle},
{"generateX509Certificate", "([B)I",
(void*)android_security_CertTool_generateX509Certificate},
{"isCaCertificate", "(I)Z",
diff --git a/packages/TtsService/jni/android_tts_SynthProxy.cpp b/packages/TtsService/jni/android_tts_SynthProxy.cpp
index 64cdb5b80160..099c4d148f80 100644
--- a/packages/TtsService/jni/android_tts_SynthProxy.cpp
+++ b/packages/TtsService/jni/android_tts_SynthProxy.cpp
@@ -286,6 +286,7 @@ android_tts_SynthProxy_native_finalize(JNIEnv *env, jobject thiz, jint jniData)
{
if (jniData) {
SynthProxyJniStorage* pSynthData = (SynthProxyJniStorage*)jniData;
+ env->DeleteGlobalRef(pSynthData->tts_ref);
delete pSynthData;
}
}
diff --git a/services/java/com/android/server/WindowManagerService.java b/services/java/com/android/server/WindowManagerService.java
index 4baf202869c1..5425709fa994 100644
--- a/services/java/com/android/server/WindowManagerService.java
+++ b/services/java/com/android/server/WindowManagerService.java
@@ -1891,7 +1891,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
break;
case WindowManagerPolicy.TRANSIT_TASK_TO_BACK:
animAttr = enter
- ? com.android.internal.R.styleable.WindowAnimation_taskToBackEnterAnimation
+ ? com.android.internal.R.styleable.WindowAnimation_taskToBackEnterAnimation
: com.android.internal.R.styleable.WindowAnimation_taskToBackExitAnimation;
break;
}
@@ -7232,17 +7232,27 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
public static WindowManager.LayoutParams findAnimations(
ArrayList<AppWindowToken> order,
- ArrayList<AppWindowToken> tokenList1,
- ArrayList<AppWindowToken> tokenList2) {
+ ArrayList<AppWindowToken> openingTokenList1,
+ ArrayList<AppWindowToken> closingTokenList2) {
// We need to figure out which animation to use...
+
+ // First, check if there is a compatible window in opening/closing
+ // apps, and use it if exists.
WindowManager.LayoutParams animParams = null;
int animSrc = 0;
-
+ animParams = findCompatibleWindowParams(openingTokenList1);
+ if (animParams == null) {
+ animParams = findCompatibleWindowParams(closingTokenList2);
+ }
+ if (animParams != null) {
+ return animParams;
+ }
+
//Log.i(TAG, "Looking for animations...");
for (int i=order.size()-1; i>=0; i--) {
AppWindowToken wtoken = order.get(i);
//Log.i(TAG, "Token " + wtoken + " with " + wtoken.windows.size() + " windows");
- if (tokenList1.contains(wtoken) || tokenList2.contains(wtoken)) {
+ if (openingTokenList1.contains(wtoken) || closingTokenList2.contains(wtoken)) {
int j = wtoken.windows.size();
while (j > 0) {
j--;
@@ -7270,6 +7280,21 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
return animParams;
}
+ private static LayoutParams findCompatibleWindowParams(ArrayList<AppWindowToken> tokenList) {
+ for (int appCount = tokenList.size() - 1; appCount >= 0; appCount--) {
+ AppWindowToken wtoken = tokenList.get(appCount);
+ // Just checking one window is sufficient as all windows have the compatible flag
+ // if the application is in compatibility mode.
+ if (wtoken.windows.size() > 0) {
+ WindowManager.LayoutParams params = wtoken.windows.get(0).mAttrs;
+ if ((params.flags & FLAG_COMPATIBLE_WINDOW) != 0) {
+ return params;
+ }
+ }
+ }
+ return null;
+ }
+
// -------------------------------------------------------------
// DummyAnimation
// -------------------------------------------------------------
@@ -9277,16 +9302,10 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
// width is the screen width {@see AppWindowToken#stepAnimatinoLocked}
mWidth = width;
}
-
- @Override
- public boolean willChangeTransformationMatrix() {
- return true;
- }
@Override
- public boolean willChangeBounds() {
- return true;
+ public int getZAdjustment() {
+ return Animation.ZORDER_TOP;
}
}
}
-
diff --git a/tests/DumpRenderTree/src/com/android/dumprendertree/LoadTestsAutoTest.java b/tests/DumpRenderTree/src/com/android/dumprendertree/LoadTestsAutoTest.java
index 39bbf16b73b2..ba461973fbfb 100644
--- a/tests/DumpRenderTree/src/com/android/dumprendertree/LoadTestsAutoTest.java
+++ b/tests/DumpRenderTree/src/com/android/dumprendertree/LoadTestsAutoTest.java
@@ -73,6 +73,10 @@ public class LoadTestsAutoTest extends ActivityInstrumentationTestCase2<TestShel
runTestAndWaitUntilDone(activity, runner.mTestPath, runner.mTimeoutInMillis);
activity.clearCache();
+ try {
+ Thread.sleep(5000);
+ } catch (InterruptedException e) {
+ }
dumpMemoryInfo();
// Kill activity