Merge "Fix issue #9913990: Background processes are being added to..."
diff --git a/Android.mk b/Android.mk
index d81e581..98bd88d 100644
--- a/Android.mk
+++ b/Android.mk
@@ -26,7 +26,10 @@
# TODO: find a more appropriate way to do this.
framework_res_source_path := APPS/framework-res_intermediates/src
-# the library
+# Build the master framework library.
+# The framework contains too many method references (>64K) for poor old DEX.
+# So we first build the framework as a monolithic static library then split it
+# up into smaller pieces.
# ============================================================
include $(CLEAR_VARS)
@@ -39,14 +42,6 @@
core/java/android/speech/tts/EventLogTags.logtags \
core/java/android/webkit/EventLogTags.logtags \
-# The following filters out code we are temporarily not including at all.
-# TODO: Move AWT and beans (and associated harmony code) back into libcore.
-# TODO: Maybe remove javax.microedition entirely?
-# TODO: Move SyncML (org.mobilecontrol.*) into its own library.
-LOCAL_SRC_FILES := $(filter-out \
- org/mobilecontrol/% \
- ,$(LOCAL_SRC_FILES))
-
## READ ME: ########################################################
##
## When updating this list of aidl files, consider if that aidl is
@@ -258,8 +253,6 @@
telephony/java/com/android/internal/telephony/IWapPushManager.aidl \
wifi/java/android/net/wifi/IWifiManager.aidl \
wifi/java/android/net/wifi/p2p/IWifiP2pManager.aidl
-#
-
# FRAMEWORKS_BASE_JAVA_SRC_DIRS comes from build/core/pathmap.mk
LOCAL_AIDL_INCLUDES += $(FRAMEWORKS_BASE_JAVA_SRC_DIRS)
@@ -272,17 +265,11 @@
LOCAL_NO_STANDARD_LIBRARIES := true
LOCAL_JAVA_LIBRARIES := bouncycastle conscrypt core core-junit ext okhttp
-LOCAL_MODULE := framework
-LOCAL_MODULE_CLASS := JAVA_LIBRARIES
+LOCAL_MODULE := framework-base
-# List of classes and interfaces which should be loaded by the Zygote.
-LOCAL_JAVA_RESOURCE_FILES += $(LOCAL_PATH)/preloaded-classes
+LOCAL_JAR_EXCLUDE_FILES := none
-#LOCAL_JARJAR_RULES := $(LOCAL_PATH)/jarjar-rules.txt
-
-LOCAL_DX_FLAGS := --core-library
-
-include $(BUILD_JAVA_LIBRARY)
+include $(BUILD_STATIC_JAVA_LIBRARY)
# Make sure that R.java and Manifest.java are built before we build
# the source for this library.
@@ -290,14 +277,53 @@
$(call intermediates-dir-for,APPS,framework-res,,COMMON)/src/R.stamp
$(full_classes_compiled_jar): $(framework_res_R_stamp)
-# Make sure that framework-res is installed when framework is.
-$(LOCAL_INSTALLED_MODULE): | $(dir $(LOCAL_INSTALLED_MODULE))framework-res.apk
-
-framework_built := $(call java-lib-deps,framework)
-
-# AIDL files to be preprocessed and included in the SDK,
-# relative to the root of the build tree.
+# Build part 1 of the framework library.
# ============================================================
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := framework
+LOCAL_MODULE_CLASS := JAVA_LIBRARIES
+LOCAL_NO_STANDARD_LIBRARIES := true
+LOCAL_STATIC_JAVA_LIBRARIES := framework-base
+LOCAL_DX_FLAGS := --core-library
+
+# Packages to include, use \* wildcard to include descendants.
+LOCAL_JAR_PACKAGES := android\*
+
+# List of classes and interfaces which should be loaded by the Zygote.
+LOCAL_JAVA_RESOURCE_FILES += $(LOCAL_PATH)/preloaded-classes
+
+include $(BUILD_JAVA_LIBRARY)
+framework_module := $(LOCAL_INSTALLED_MODULE)
+
+# Build part 2 of the framework library.
+# ============================================================
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := framework2
+LOCAL_MODULE_CLASS := JAVA_LIBRARIES
+LOCAL_NO_STANDARD_LIBRARIES := true
+LOCAL_STATIC_JAVA_LIBRARIES := framework-base
+LOCAL_DX_FLAGS := --core-library
+
+# Packages to include, use \* wildcard to include descendants.
+LOCAL_JAR_PACKAGES := com\* javax\*
+
+include $(BUILD_JAVA_LIBRARY)
+framework2_module := $(LOCAL_INSTALLED_MODULE)
+
+# Make sure that all framework modules are installed when framework is.
+# ============================================================
+$(framework_module): | $(dir $(framework_module))framework-res.apk
+$(framework_module): | $(dir $(framework_module))framework2.jar
+
+framework_built := $(call java-lib-deps,framework framework2)
+
+# Copy AIDL files to be preprocessed and included in the SDK,
+# specified relative to the root of the build tree.
+# ============================================================
+include $(CLEAR_VARS)
+
aidl_files := \
frameworks/base/core/java/android/accounts/IAccountManager.aidl \
frameworks/base/core/java/android/accounts/IAccountManagerResponse.aidl \
@@ -443,6 +469,7 @@
okhttp \
ext \
framework \
+ framework2 \
mms-common \
telephony-common \
voip-common
@@ -479,7 +506,7 @@
-overview $(LOCAL_PATH)/core/java/overview.html
framework_docs_LOCAL_API_CHECK_ADDITIONAL_JAVA_DIR:= \
- $(call intermediates-dir-for,JAVA_LIBRARIES,framework,,COMMON)
+ $(call intermediates-dir-for,JAVA_LIBRARIES,framework-base,,COMMON)
framework_docs_LOCAL_ADDITIONAL_JAVA_DIR:= \
$(framework_docs_LOCAL_API_CHECK_ADDITIONAL_JAVA_DIR) \
@@ -761,7 +788,7 @@
LOCAL_SRC_FILES:=$(framework_docs_LOCAL_SRC_FILES)
LOCAL_INTERMEDIATE_SOURCES:=$(framework_docs_LOCAL_INTERMEDIATE_SOURCES)
-LOCAL_JAVA_LIBRARIES:=$(framework_docs_LOCAL_JAVA_LIBRARIES) framework
+LOCAL_JAVA_LIBRARIES:=$(framework_docs_LOCAL_JAVA_LIBRARIES)
LOCAL_MODULE_CLASS:=$(framework_docs_LOCAL_MODULE_CLASS)
LOCAL_DROIDDOC_SOURCE_PATH:=$(framework_docs_LOCAL_DROIDDOC_SOURCE_PATH)
LOCAL_DROIDDOC_HTML_DIR:=$(framework_docs_LOCAL_DROIDDOC_HTML_DIR)
diff --git a/api/current.txt b/api/current.txt
index e0fc76c..494a6ec 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -8742,13 +8742,17 @@
method public final boolean isPremultiplied();
method public final boolean isRecycled();
method public void prepareToDraw();
+ method public void reconfigure(int, int, android.graphics.Bitmap.Config);
method public void recycle();
method public boolean sameAs(android.graphics.Bitmap);
+ method public void setConfig(android.graphics.Bitmap.Config);
method public void setDensity(int);
method public void setHasAlpha(boolean);
method public final void setHasMipMap(boolean);
+ method public void setHeight(int);
method public void setPixel(int, int, int);
method public void setPixels(int[], int, int, int, int, int, int);
+ method public void setWidth(int);
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator CREATOR;
field public static final int DENSITY_NONE = 0; // 0x0
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index 52433a5..19e3905 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -6500,58 +6500,67 @@
}
/**
- * Put a view into the ScrapViews list. These views are unordered.
+ * Puts a view into the list of scrap views.
+ * <p>
+ * If the list data hasn't changed or the adapter has stable IDs, views
+ * with transient state will be preserved for later retrieval.
*
* @param scrap The view to add
+ * @param position The view's position within its parent
*/
void addScrapView(View scrap, int position) {
- AbsListView.LayoutParams lp = (AbsListView.LayoutParams) scrap.getLayoutParams();
+ final AbsListView.LayoutParams lp = (AbsListView.LayoutParams) scrap.getLayoutParams();
if (lp == null) {
return;
}
lp.scrappedFromPosition = position;
- // Don't put header or footer views or views that should be ignored
- // into the scrap heap
- int viewType = lp.viewType;
+ // Don't scrap header or footer views, or views that should
+ // otherwise not be recycled.
+ final int viewType = lp.viewType;
+ if (!shouldRecycleViewType(viewType)) {
+ return;
+ }
+
+ scrap.dispatchStartTemporaryDetach();
+
+ // Don't scrap views that have transient state.
final boolean scrapHasTransientState = scrap.hasTransientState();
- if (!shouldRecycleViewType(viewType) || scrapHasTransientState) {
- if (viewType != ITEM_VIEW_TYPE_HEADER_OR_FOOTER && scrapHasTransientState) {
+ if (scrapHasTransientState) {
+ if (mAdapter != null && mAdapterHasStableIds) {
+ // If the adapter has stable IDs, we can reuse the view for
+ // the same data.
+ if (mTransientStateViewsById == null) {
+ mTransientStateViewsById = new LongSparseArray<View>();
+ }
+ mTransientStateViewsById.put(lp.itemId, scrap);
+ } else if (!mDataChanged) {
+ // If the data hasn't changed, we can reuse the views at
+ // their old positions.
+ if (mTransientStateViews == null) {
+ mTransientStateViews = new SparseArray<View>();
+ }
+ mTransientStateViews.put(position, scrap);
+ } else {
+ // Otherwise, we'll have to remove the view and start over.
if (mSkippedScrap == null) {
mSkippedScrap = new ArrayList<View>();
}
mSkippedScrap.add(scrap);
}
- if (scrapHasTransientState) {
- scrap.dispatchStartTemporaryDetach();
- if (mAdapter != null && mAdapterHasStableIds) {
- if (mTransientStateViewsById == null) {
- mTransientStateViewsById = new LongSparseArray<View>();
- }
- mTransientStateViewsById.put(lp.itemId, scrap);
- } else if (!mDataChanged) {
- // avoid putting views on transient state list during a data change;
- // the layout positions may be out of sync with the adapter positions
- if (mTransientStateViews == null) {
- mTransientStateViews = new SparseArray<View>();
- }
- mTransientStateViews.put(position, scrap);
- }
- }
- return;
- }
-
- scrap.dispatchStartTemporaryDetach();
- if (mViewTypeCount == 1) {
- mCurrentScrap.add(scrap);
} else {
- mScrapViews[viewType].add(scrap);
- }
+ if (mViewTypeCount == 1) {
+ mCurrentScrap.add(scrap);
+ } else {
+ mScrapViews[viewType].add(scrap);
+ }
- scrap.setAccessibilityDelegate(null);
- if (mRecyclerListener != null) {
- mRecyclerListener.onMovedToScrapHeap(scrap);
+ scrap.setAccessibilityDelegate(null);
+
+ if (mRecyclerListener != null) {
+ mRecyclerListener.onMovedToScrapHeap(scrap);
+ }
}
}
diff --git a/core/java/android/widget/ListView.java b/core/java/android/widget/ListView.java
index c44ac32..2f42ae3 100644
--- a/core/java/android/widget/ListView.java
+++ b/core/java/android/widget/ListView.java
@@ -1478,12 +1478,12 @@
@Override
protected void layoutChildren() {
final boolean blockLayoutRequests = mBlockLayoutRequests;
- if (!blockLayoutRequests) {
- mBlockLayoutRequests = true;
- } else {
+ if (blockLayoutRequests) {
return;
}
+ mBlockLayoutRequests = true;
+
try {
super.layoutChildren();
@@ -1495,10 +1495,10 @@
return;
}
- int childrenTop = mListPadding.top;
- int childrenBottom = mBottom - mTop - mListPadding.bottom;
+ final int childrenTop = mListPadding.top;
+ final int childrenBottom = mBottom - mTop - mListPadding.bottom;
+ final int childCount = getChildCount();
- int childCount = getChildCount();
int index = 0;
int delta = 0;
@@ -1507,8 +1507,6 @@
View oldFirst = null;
View newSel = null;
- View focusLayoutRestoreView = null;
-
AccessibilityNodeInfo accessibilityFocusLayoutRestoreNode = null;
View accessibilityFocusLayoutRestoreView = null;
int accessibilityFocusPosition = INVALID_POSITION;
@@ -1570,6 +1568,7 @@
// Remember which child, if any, had accessibility focus. This must
// occur before recycling any views, since that will clear
// accessibility focus.
+ // TODO: This should rely on transient state.
final ViewRootImpl viewRootImpl = getViewRootImpl();
if (viewRootImpl != null) {
final View accessFocusedView = viewRootImpl.getAccessibilityFocusedHost();
@@ -1593,16 +1592,18 @@
}
}
+ // Ensure the child containing focus, if any, has transient state.
+ // If the list data hasn't changed, or if the adapter has stable
+ // IDs, this will maintain focus.
+ final View focusedChild = getFocusedChild();
+ if (focusedChild != null) {
+ focusedChild.setHasTransientState(true);
+ }
+
// Pull all children into the RecycleBin.
// These views will be reused if possible
final int firstPosition = mFirstPosition;
final RecycleBin recycleBin = mRecycler;
-
- // reset the focus restoration
- View focusLayoutRestoreDirectChild = null;
-
- // Don't put header or footer views into the Recycler. Those are
- // already cached in mHeaderViews;
if (dataChanged) {
for (int i = 0; i < childCount; i++) {
recycleBin.addScrapView(getChildAt(i), firstPosition+i);
@@ -1611,28 +1612,6 @@
recycleBin.fillActiveViews(childCount, firstPosition);
}
- // take focus back to us temporarily to avoid the eventual
- // call to clear focus when removing the focused child below
- // from messing things up when ViewAncestor assigns focus back
- // to someone else
- final View focusedChild = getFocusedChild();
- if (focusedChild != null) {
- // TODO: in some cases focusedChild.getParent() == null
-
- // we can remember the focused view to restore after relayout if the
- // data hasn't changed, or if the focused position is a header or footer
- if (!dataChanged || isDirectChildHeaderOrFooter(focusedChild)) {
- focusLayoutRestoreDirectChild = focusedChild;
- // remember the specific view that had focus
- focusLayoutRestoreView = findFocus();
- if (focusLayoutRestoreView != null) {
- // tell it we are going to mess with it
- focusLayoutRestoreView.onStartTemporaryDetach();
- }
- }
- requestFocus();
- }
-
// Clear out old views
detachAllViewsFromParent();
recycleBin.removeSkippedScrap();
@@ -1692,43 +1671,37 @@
recycleBin.scrapActiveViews();
if (sel != null) {
- // the current selected item should get focus if items
- // are focusable
- if (mItemsCanFocus && hasFocus() && !sel.hasFocus()) {
- final boolean focusWasTaken = (sel == focusLayoutRestoreDirectChild &&
- focusLayoutRestoreView != null &&
- focusLayoutRestoreView.requestFocus()) || sel.requestFocus();
- if (!focusWasTaken) {
- // selected item didn't take focus, fine, but still want
- // to make sure something else outside of the selected view
- // has focus
+ final boolean shouldPlaceFocus = mItemsCanFocus && hasFocus();
+ final boolean maintainedFocus = focusedChild != null && focusedChild.hasFocus();
+ if (shouldPlaceFocus && !maintainedFocus && !sel.hasFocus()) {
+ if (sel.requestFocus()) {
+ // Successfully placed focus, clear selection.
+ sel.setSelected(false);
+ mSelectorRect.setEmpty();
+ } else {
+ // Failed to place focus, clear current (invalid) focus.
final View focused = getFocusedChild();
if (focused != null) {
focused.clearFocus();
}
positionSelector(INVALID_POSITION, sel);
- } else {
- sel.setSelected(false);
- mSelectorRect.setEmpty();
}
} else {
positionSelector(INVALID_POSITION, sel);
}
mSelectedTop = sel.getTop();
} else {
- if (mTouchMode > TOUCH_MODE_DOWN && mTouchMode < TOUCH_MODE_SCROLL) {
- View child = getChildAt(mMotionPosition - mFirstPosition);
- if (child != null) positionSelector(mMotionPosition, child);
+ // If the user's finger is down, select the motion position.
+ // Otherwise, clear selection.
+ if (mTouchMode == TOUCH_MODE_TAP || mTouchMode == TOUCH_MODE_DONE_WAITING) {
+ final View child = getChildAt(mMotionPosition - mFirstPosition);
+ if (child != null) {
+ positionSelector(mMotionPosition, child);
+ }
} else {
mSelectedTop = 0;
mSelectorRect.setEmpty();
}
-
- // even if there is not selected position, we may need to restore
- // focus (i.e. something focusable in touch mode)
- if (hasFocus() && focusLayoutRestoreView != null) {
- focusLayoutRestoreView.requestFocus();
- }
}
// Attempt to restore accessibility focus.
@@ -1753,11 +1726,8 @@
}
}
- // tell focus view we are done mucking with it, if it is still in
- // our view hierarchy.
- if (focusLayoutRestoreView != null
- && focusLayoutRestoreView.getWindowToken() != null) {
- focusLayoutRestoreView.onFinishTemporaryDetach();
+ if (focusedChild != null) {
+ focusedChild.setHasTransientState(false);
}
mLayoutMode = LAYOUT_NORMAL;
diff --git a/core/jni/android/graphics/Bitmap.cpp b/core/jni/android/graphics/Bitmap.cpp
index 63683b4..b03d12a 100644
--- a/core/jni/android/graphics/Bitmap.cpp
+++ b/core/jni/android/graphics/Bitmap.cpp
@@ -271,6 +271,26 @@
return true;
}
+static void Bitmap_reconfigure(JNIEnv* env, jobject clazz, jint bitmapInt,
+ int width, int height, SkBitmap::Config config, int allocSize) {
+ if (width * height * SkBitmap::ComputeBytesPerPixel(config) > allocSize) {
+ // done in native as there's no way to get BytesPerPixel in Java
+ doThrowIAE(env, "Bitmap not large enough to support new configuration");
+ return;
+ }
+ SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapInt);
+ SkPixelRef* ref = bitmap->pixelRef();
+ SkSafeRef(ref);
+ bitmap->setConfig(config, width, height);
+ bitmap->setPixelRef(ref);
+
+ // notifyPixelsChanged will increment the generation ID even though the actual pixel data
+ // hasn't been touched. This signals the renderer that the bitmap (including width, height,
+ // and config) has changed.
+ ref->notifyPixelsChanged();
+ SkSafeUnref(ref);
+}
+
// These must match the int values in Bitmap.java
enum JavaEncodeFormat {
kJPEG_JavaEncodeFormat = 0,
@@ -666,6 +686,7 @@
(void*)Bitmap_copy },
{ "nativeDestructor", "(I)V", (void*)Bitmap_destructor },
{ "nativeRecycle", "(I)Z", (void*)Bitmap_recycle },
+ { "nativeReconfigure", "(IIIII)V", (void*)Bitmap_reconfigure },
{ "nativeCompress", "(IIILjava/io/OutputStream;[B)Z",
(void*)Bitmap_compress },
{ "nativeErase", "(II)V", (void*)Bitmap_erase },
diff --git a/data/etc/platform.xml b/data/etc/platform.xml
index 1289971..ec8e7ea 100644
--- a/data/etc/platform.xml
+++ b/data/etc/platform.xml
@@ -54,10 +54,6 @@
<group gid="inet" />
</permission>
- <permission name="android.permission.CAMERA" >
- <group gid="camera" />
- </permission>
-
<permission name="android.permission.READ_LOGS" >
<group gid="log" />
</permission>
diff --git a/graphics/java/android/graphics/Bitmap.java b/graphics/java/android/graphics/Bitmap.java
index 50231da..ad5bfc8 100644
--- a/graphics/java/android/graphics/Bitmap.java
+++ b/graphics/java/android/graphics/Bitmap.java
@@ -170,7 +170,98 @@
public void setDensity(int density) {
mDensity = density;
}
-
+
+ /**
+ * <p>Modifies the bitmap to have a specified width, height, and {@link
+ * Config}, without affecting the underlying allocation backing the bitmap.
+ * Bitmap pixel data is not re-initialized for the new configuration.</p>
+ *
+ * <p>This method can be used to avoid allocating a new bitmap, instead
+ * reusing an existing bitmap's allocation for a new configuration of equal
+ * or lesser size. If the Bitmap's allocation isn't large enough to support
+ * the new configuration, an IllegalArgumentException will be thrown and the
+ * bitmap will not be modified.</p>
+ *
+ * <p>The result of {@link #getByteCount()} will reflect the new configuration,
+ * while {@link #getAllocationByteCount()} will reflect that of the initial
+ * configuration.</p>
+ *
+ * <p>WARNING: This method should NOT be called on a bitmap currently used
+ * by the view system. It does not make guarantees about how the underlying
+ * pixel buffer is remapped to the new config, just that the allocation is
+ * reused. Additionally, the view system does not account for bitmap
+ * properties being modifying during use, e.g. while attached to
+ * drawables.</p>
+ *
+ * @see #setWidth(int)
+ * @see #setHeight(int)
+ * @see #setConfig(Config)
+ */
+ public void reconfigure(int width, int height, Config config) {
+ checkRecycled("Can't call reconfigure() on a recycled bitmap");
+ if (width <= 0 || height <= 0) {
+ throw new IllegalArgumentException("width and height must be > 0");
+ }
+ if (!isMutable()) {
+ throw new IllegalArgumentException("only mutable bitmaps may be reconfigured");
+ }
+ if (mBuffer == null) {
+ throw new IllegalArgumentException("only non-inPurgeable bitmaps may be reconfigured");
+ }
+
+ nativeReconfigure(mNativeBitmap, width, height, config.nativeInt, mBuffer.length);
+ mWidth = width;
+ mHeight = height;
+ }
+
+ /**
+ * <p>Convenience method for calling {@link #reconfigure(int, int, Config)}
+ * with the current height and config.</p>
+ *
+ * <p>WARNING: this method should not be used on bitmaps currently used by
+ * the view system, see {@link #reconfigure(int, int, Config)} for more
+ * details.</p>
+ *
+ * @see #reconfigure(int, int, Config)
+ * @see #setHeight(int)
+ * @see #setConfig(Config)
+ */
+ public void setWidth(int width) {
+ reconfigure(width, getHeight(), getConfig());
+ }
+
+ /**
+ * <p>Convenience method for calling {@link #reconfigure(int, int, Config)}
+ * with the current width and config.</p>
+ *
+ * <p>WARNING: this method should not be used on bitmaps currently used by
+ * the view system, see {@link #reconfigure(int, int, Config)} for more
+ * details.</p>
+ *
+ * @see #reconfigure(int, int, Config)
+ * @see #setWidth(int)
+ * @see #setConfig(Config)
+ */
+ public void setHeight(int height) {
+ reconfigure(getWidth(), height, getConfig());
+ }
+
+ /**
+ * <p>Convenience method for calling {@link #reconfigure(int, int, Config)}
+ * with the current height and width.</p>
+ *
+ * <p>WARNING: this method should not be used on bitmaps currently used by
+ * the view system, see {@link #reconfigure(int, int, Config)} for more
+ * details.</p>
+ *
+ * @see #reconfigure(int, int, Config)
+ * @see #setWidth(int)
+ * @see #setHeight(int)
+ */
+ public void setConfig(Config config) {
+ reconfigure(getWidth(), getHeight(), config);
+ }
+
/**
* Sets the nine patch chunk.
*
@@ -1010,7 +1101,7 @@
*
* <p>As of {@link android.os.Build.VERSION_CODES#KEY_LIME_PIE}, the result of this method can
* no longer be used to determine memory usage of a bitmap. See {@link
- * #getAllocationByteCount()}.
+ * #getAllocationByteCount()}.</p>
*/
public final int getByteCount() {
// int result permits bitmaps up to 46,340 x 46,340
@@ -1021,11 +1112,15 @@
* Returns the size of the allocated memory used to store this bitmap's pixels.
*
* <p>This can be larger than the result of {@link #getByteCount()} if a bitmap is reused to
- * decode other bitmaps of smaller size. See {@link BitmapFactory.Options#inBitmap inBitmap in
- * BitmapFactory.Options}. If a bitmap is not reused in this way, this value will be the same as
- * that returned by {@link #getByteCount()}.
+ * decode other bitmaps of smaller size, or by manual reconfiguration. See {@link
+ * #reconfigure(int, int, Config)}, {@link #setWidth(int)}, {@link #setHeight(int)}, {@link
+ * #setConfig(Bitmap.Config)}, and {@link BitmapFactory.Options#inBitmap
+ * BitmapFactory.Options.inBitmap}. If a bitmap is not modified in this way, this value will be
+ * the same as that returned by {@link #getByteCount()}.</p>
*
- * <p>This value will not change over the lifetime of a Bitmap.
+ * <p>This value will not change over the lifetime of a Bitmap.</p>
+ *
+ * @see #reconfigure(int, int, Config)
*/
public final int getAllocationByteCount() {
return mBuffer.length;
@@ -1423,11 +1518,13 @@
private static native Bitmap nativeCreate(int[] colors, int offset,
int stride, int width, int height,
- int nativeConfig, boolean mutable);
+ int nativeConfig, boolean mutable);
private static native Bitmap nativeCopy(int srcBitmap, int nativeConfig,
boolean isMutable);
private static native void nativeDestructor(int nativeBitmap);
private static native boolean nativeRecycle(int nativeBitmap);
+ private static native void nativeReconfigure(int nativeBitmap, int width, int height,
+ int config, int allocSize);
private static native boolean nativeCompress(int nativeBitmap, int format,
int quality, OutputStream stream,
diff --git a/graphics/java/android/graphics/BitmapFactory.java b/graphics/java/android/graphics/BitmapFactory.java
index aff4cd8..a4124bf 100644
--- a/graphics/java/android/graphics/BitmapFactory.java
+++ b/graphics/java/android/graphics/BitmapFactory.java
@@ -48,34 +48,40 @@
/**
* If set, decode methods that take the Options object will attempt to
- * reuse this bitmap when loading content. If the decode operation cannot
- * use this bitmap, the decode method will return <code>null</code> and
- * will throw an IllegalArgumentException. The current implementation
- * necessitates that the reused bitmap be mutable, and the resulting
- * reused bitmap will continue to remain mutable even when decoding a
- * resource which would normally result in an immutable bitmap.
+ * reuse this bitmap when loading content. If the decode operation
+ * cannot use this bitmap, the decode method will return
+ * <code>null</code> and will throw an IllegalArgumentException. The
+ * current implementation necessitates that the reused bitmap be
+ * mutable, and the resulting reused bitmap will continue to remain
+ * mutable even when decoding a resource which would normally result in
+ * an immutable bitmap.</p>
*
- * <p>As of {@link android.os.Build.VERSION_CODES#KEY_LIME_PIE}, any mutable
- * bitmap can be reused to decode any other bitmaps as long as the resulting
- * {@link Bitmap#getByteCount() byte count} of the decoded bitmap is less
- * than or equal to the {@link Bitmap#getAllocationByteCount() allocated byte count}
- * of the reused bitmap. This can be because the intrinsic size is smaller,
- * or the size after density / sampled size scaling is smaller.
+ * <p>As of {@link android.os.Build.VERSION_CODES#KEY_LIME_PIE}, any
+ * mutable bitmap can be reused to decode any other bitmaps as long as
+ * the resulting {@link Bitmap#getByteCount() byte count} of the decoded
+ * bitmap is less than or equal to the {@link
+ * Bitmap#getAllocationByteCount() allocated byte count} of the reused
+ * bitmap. This can be because the intrinsic size is smaller, or its
+ * size post scaling (for density / sample size) is smaller.</p>
*
- * <p>Prior to {@link android.os.Build.VERSION_CODES#KEY_LIME_PIE} additional
- * constraints apply: The image being decoded (whether as a resource or
- * as a stream) must be in jpeg or png format. Only equal sized bitmaps
- * are supported, with {@link #inSampleSize} set to 1. Additionally, the
- * {@link android.graphics.Bitmap.Config configuration} of the reused
- * bitmap will override the setting of {@link #inPreferredConfig}, if set.
+ * <p>Prior to {@link android.os.Build.VERSION_CODES#KEY_LIME_PIE}
+ * additional constraints apply: The image being decoded (whether as a
+ * resource or as a stream) must be in jpeg or png format. Only equal
+ * sized bitmaps are supported, with {@link #inSampleSize} set to 1.
+ * Additionally, the {@link android.graphics.Bitmap.Config
+ * configuration} of the reused bitmap will override the setting of
+ * {@link #inPreferredConfig}, if set.</p>
*
* <p>You should still always use the returned Bitmap of the decode
* method and not assume that reusing the bitmap worked, due to the
* constraints outlined above and failure situations that can occur.
* Checking whether the return value matches the value of the inBitmap
* set in the Options structure will indicate if the bitmap was reused,
- * but in all cases you should use the Bitmap returned by the decoding function to ensure
- * that you are using the bitmap that was used as the decode destination.</p>
+ * but in all cases you should use the Bitmap returned by the decoding
+ * function to ensure that you are using the bitmap that was used as the
+ * decode destination.</p>
+ *
+ * @see Bitmap#reconfigure(int,int,Config)
*/
public Bitmap inBitmap;