Merge "Create logic for applying padding only to custom preference layouts"
diff --git a/api/current.xml b/api/current.xml
index e6ac507..04d7a1d 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -18994,7 +18994,7 @@
visibility="public"
>
<method name="after"
- return="void"
+ return="android.animation.AnimatorSet.Builder"
abstract="false"
native="false"
synchronized="false"
@@ -19007,7 +19007,7 @@
</parameter>
</method>
<method name="after"
- return="void"
+ return="android.animation.AnimatorSet.Builder"
abstract="false"
native="false"
synchronized="false"
@@ -19020,7 +19020,7 @@
</parameter>
</method>
<method name="before"
- return="void"
+ return="android.animation.AnimatorSet.Builder"
abstract="false"
native="false"
synchronized="false"
@@ -19033,7 +19033,7 @@
</parameter>
</method>
<method name="with"
- return="void"
+ return="android.animation.AnimatorSet.Builder"
abstract="false"
native="false"
synchronized="false"
@@ -221206,7 +221206,7 @@
>
</method>
<method name="getShortcutInputMethodsAndSubtypes"
- return="java.util.List<android.util.Pair<android.view.inputmethod.InputMethodInfo, android.view.inputmethod.InputMethodSubtype>>"
+ return="java.util.Map<android.view.inputmethod.InputMethodInfo, java.util.List<android.view.inputmethod.InputMethodSubtype>>"
abstract="false"
native="false"
synchronized="false"
diff --git a/core/java/android/animation/AnimatorSet.java b/core/java/android/animation/AnimatorSet.java
index 9ba9388..f5420d1 100644
--- a/core/java/android/animation/AnimatorSet.java
+++ b/core/java/android/animation/AnimatorSet.java
@@ -341,6 +341,20 @@
return this;
}
+ @Override
+ public void setupStartValues() {
+ for (Node node : mNodes) {
+ node.animation.setupStartValues();
+ }
+ }
+
+ @Override
+ public void setupEndValues() {
+ for (Node node : mNodes) {
+ node.animation.setupEndValues();
+ }
+ }
+
/**
* {@inheritDoc}
*
@@ -401,6 +415,7 @@
}
}
});
+ delayAnim.start();
}
if (mListeners != null) {
ArrayList<AnimatorListener> tmpListeners =
@@ -408,6 +423,11 @@
int numListeners = tmpListeners.size();
for (int i = 0; i < numListeners; ++i) {
tmpListeners.get(i).onAnimationStart(this);
+ if (mNodes.size() == 0) {
+ // Handle unusual case where empty AnimatorSet is started - should send out
+ // end event immediately since the event will not be sent out at all otherwise
+ tmpListeners.get(i).onAnimationEnd(this);
+ }
}
}
}
@@ -894,7 +914,7 @@
* @param anim The animation that will play when the animation supplied to the
* {@link AnimatorSet#play(Animator)} method starts.
*/
- public void with(Animator anim) {
+ public Builder with(Animator anim) {
Node node = mNodeMap.get(anim);
if (node == null) {
node = new Node(anim);
@@ -903,6 +923,7 @@
}
Dependency dependency = new Dependency(mCurrentNode, Dependency.WITH);
node.addDependency(dependency);
+ return this;
}
/**
@@ -913,7 +934,7 @@
* @param anim The animation that will play when the animation supplied to the
* {@link AnimatorSet#play(Animator)} method ends.
*/
- public void before(Animator anim) {
+ public Builder before(Animator anim) {
Node node = mNodeMap.get(anim);
if (node == null) {
node = new Node(anim);
@@ -922,6 +943,7 @@
}
Dependency dependency = new Dependency(mCurrentNode, Dependency.AFTER);
node.addDependency(dependency);
+ return this;
}
/**
@@ -932,7 +954,7 @@
* @param anim The animation whose end will cause the animation supplied to the
* {@link AnimatorSet#play(Animator)} method to play.
*/
- public void after(Animator anim) {
+ public Builder after(Animator anim) {
Node node = mNodeMap.get(anim);
if (node == null) {
node = new Node(anim);
@@ -941,6 +963,7 @@
}
Dependency dependency = new Dependency(node, Dependency.AFTER);
mCurrentNode.addDependency(dependency);
+ return this;
}
/**
@@ -951,11 +974,12 @@
* @param delay The number of milliseconds that should elapse before the
* animation starts.
*/
- public void after(long delay) {
+ public Builder after(long delay) {
// setup dummy ValueAnimator just to run the clock
ValueAnimator anim = ValueAnimator.ofFloat(0f, 1f);
anim.setDuration(delay);
after(anim);
+ return this;
}
}
diff --git a/core/java/android/animation/ValueAnimator.java b/core/java/android/animation/ValueAnimator.java
index b021e75..e192067 100755
--- a/core/java/android/animation/ValueAnimator.java
+++ b/core/java/android/animation/ValueAnimator.java
@@ -19,6 +19,7 @@
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
+import android.util.AndroidRuntimeException;
import android.view.animation.AccelerateDecelerateInterpolator;
import android.view.animation.AnimationUtils;
@@ -860,21 +861,22 @@
/**
* Start the animation playing. This version of start() takes a boolean flag that indicates
* whether the animation should play in reverse. The flag is usually false, but may be set
- * to true if called from the reverse() method/
+ * to true if called from the reverse() method.
+ *
+ * <p>The animation started by calling this method will be run on the thread that called
+ * this method. This thread should have a Looper on it (a runtime exception will be thrown if
+ * this is not the case). Also, if the animation will animate
+ * properties of objects in the view hierarchy, then the calling thread should be the UI
+ * thread for that view hierarchy.</p>
*
* @param playBackwards Whether the ValueAnimator should start playing in reverse.
*/
private void start(boolean playBackwards) {
- mPlayingBackwards = playBackwards;
- Looper looper = Looper.getMainLooper();
- final boolean isUiThread;
- if (looper != null) {
- isUiThread = Thread.currentThread() == looper.getThread();
- } else {
- // ignore check if we don't have a Looper (this isn't an Activity)
- isUiThread = true;
+ if (Looper.myLooper() == null) {
+ throw new AndroidRuntimeException("Animators may only be run on Looper threads");
}
- if ((mStartDelay == 0) && isUiThread) {
+ mPlayingBackwards = playBackwards;
+ if (mStartDelay == 0) {
if (mListeners != null) {
ArrayList<AnimatorListener> tmpListeners =
(ArrayList<AnimatorListener>) mListeners.clone();
@@ -912,9 +914,14 @@
listener.onAnimationCancel(this);
}
}
- // Just set the CANCELED flag - this causes the animation to end the next time a frame
- // is processed.
- mPlayingState = CANCELED;
+ // Only cancel if the animation is actually running or has been started and is about
+ // to run
+ if (mPlayingState != STOPPED || sPendingAnimations.get().contains(this) ||
+ sDelayedAnims.get().contains(this)) {
+ // Just set the CANCELED flag - this causes the animation to end the next time a frame
+ // is processed.
+ mPlayingState = CANCELED;
+ }
}
@Override
diff --git a/core/java/android/os/Debug.java b/core/java/android/os/Debug.java
index 2b4f39a..1c295a7 100644
--- a/core/java/android/os/Debug.java
+++ b/core/java/android/os/Debug.java
@@ -513,21 +513,27 @@
}
/**
- * Count the number and aggregate size of memory allocations between
- * two points.
+ * Start counting the number and aggregate size of memory allocations.
*
- * The "start" function resets the counts and enables counting. The
- * "stop" function disables the counting so that the analysis code
- * doesn't cause additional allocations. The "get" function returns
- * the specified value.
+ * <p>The {@link #startAllocCounting() start} function resets the counts and enables counting.
+ * The {@link #stopAllocCounting() stop} function disables the counting so that the analysis
+ * code doesn't cause additional allocations. The various <code>get</code> functions return
+ * the specified value. And the various <code>reset</code> functions reset the specified
+ * count.</p>
*
- * Counts are kept for the system as a whole and for each thread.
+ * <p>Counts are kept for the system as a whole and for each thread.
* The per-thread counts for threads other than the current thread
- * are not cleared by the "reset" or "start" calls.
+ * are not cleared by the "reset" or "start" calls.</p>
*/
public static void startAllocCounting() {
VMDebug.startAllocCounting();
}
+
+ /**
+ * Stop counting the number and aggregate size of memory allocations.
+ *
+ * @see #startAllocCounting()
+ */
public static void stopAllocCounting() {
VMDebug.stopAllocCounting();
}
@@ -671,11 +677,11 @@
* for catching regressions in code that is expected to operate
* without causing any allocations.
*
- * Pass in the maximum number of allowed allocations. Use -1 to disable
- * the limit. Returns the previous limit.
+ * <p>Pass in the maximum number of allowed allocations. Use -1 to disable
+ * the limit. Returns the previous limit.</p>
*
- * The preferred way to use this is:
- *
+ * <p>The preferred way to use this is:
+ * <pre>
* int prevLimit = -1;
* try {
* prevLimit = Debug.setAllocationLimit(0);
@@ -683,16 +689,16 @@
* } finally {
* Debug.setAllocationLimit(prevLimit);
* }
- *
+ * </pre>
* This allows limits to be nested. The try/finally ensures that the
- * limit is reset if something fails.
+ * limit is reset if something fails.</p>
*
- * Exceeding the limit causes a dalvik.system.AllocationLimitError to
+ * <p>Exceeding the limit causes a dalvik.system.AllocationLimitError to
* be thrown from a memory allocation call. The limit is reset to -1
- * when this happens.
+ * when this happens.</p>
*
- * The feature may be disabled in the VM configuration. If so, this
- * call has no effect, and always returns -1.
+ * <p>The feature may be disabled in the VM configuration. If so, this
+ * call has no effect, and always returns -1.</p>
*/
public static int setAllocationLimit(int limit) {
return VMDebug.setAllocationLimit(limit);
@@ -846,6 +852,7 @@
* API for gathering and querying instruction counts.
*
* Example usage:
+ * <pre>
* Debug.InstructionCount icount = new Debug.InstructionCount();
* icount.resetAndStart();
* [... do lots of stuff ...]
@@ -855,6 +862,7 @@
* System.out.println("Method invocations: "
* + icount.globalMethodInvocations());
* }
+ * </pre>
*/
public static class InstructionCount {
private static final int NUM_INSTR = 256;
diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java
index a5f3ade..621a908 100644
--- a/core/java/android/view/inputmethod/InputMethodManager.java
+++ b/core/java/android/view/inputmethod/InputMethodManager.java
@@ -23,7 +23,6 @@
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
-import android.os.Parcelable;
import android.os.RemoteException;
import android.os.ResultReceiver;
import android.os.ServiceManager;
@@ -49,7 +48,9 @@
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
@@ -1454,30 +1455,29 @@
}
}
- public List<Pair<InputMethodInfo, InputMethodSubtype>> getShortcutInputMethodsAndSubtypes() {
+ public Map<InputMethodInfo, List<InputMethodSubtype>> getShortcutInputMethodsAndSubtypes() {
synchronized (mH) {
- List<Pair<InputMethodInfo, InputMethodSubtype>> ret =
- new ArrayList<Pair<InputMethodInfo, InputMethodSubtype>>();
+ HashMap<InputMethodInfo, List<InputMethodSubtype>> ret =
+ new HashMap<InputMethodInfo, List<InputMethodSubtype>>();
try {
// TODO: We should change the return type from List<Object> to List<Parcelable>
List<Object> info = mService.getShortcutInputMethodsAndSubtypes();
- // "info" has imi1, subtype1, imi2, subtype2, imi3, subtype3,..... in the list
- Object imi;
- Object subtype;
- if (info != null && info.size() > 0) {
- final int N = info.size();
- if (N % 2 == 0) {
- for (int i = 0; i < N;) {
- if ((imi = info.get(i++)) instanceof InputMethodInfo) {
- subtype = info.get(i++);
- ret.add(new Pair<InputMethodInfo, InputMethodSubtype> (
- (InputMethodInfo)imi,
- (subtype instanceof InputMethodSubtype) ?
- (InputMethodSubtype)subtype : null));
+ // "info" has imi1, subtype1, subtype2, imi2, subtype2, imi3, subtype3..in the list
+ ArrayList<InputMethodSubtype> subtypes = null;
+ final int N = info.size();
+ if (info != null && N > 0) {
+ for (int i = 0; i < N; ++i) {
+ Object o = info.get(i);
+ if (o instanceof InputMethodInfo) {
+ if (ret.containsKey(o)) {
+ Log.e(TAG, "IMI list already contains the same InputMethod.");
+ break;
}
+ subtypes = new ArrayList<InputMethodSubtype>();
+ ret.put((InputMethodInfo)o, subtypes);
+ } else if (subtypes != null && o instanceof InputMethodSubtype) {
+ subtypes.add((InputMethodSubtype)o);
}
- } else {
- Log.w(TAG, "The size of list was illegal.");
}
}
} catch (RemoteException e) {
@@ -1486,6 +1486,7 @@
return ret;
}
}
+
public boolean switchToLastInputMethod(IBinder imeToken) {
synchronized (mH) {
try {
diff --git a/core/java/android/widget/ScrollView.java b/core/java/android/widget/ScrollView.java
index 3faec55..900c9ec 100644
--- a/core/java/android/widget/ScrollView.java
+++ b/core/java/android/widget/ScrollView.java
@@ -24,6 +24,7 @@
import android.graphics.Canvas;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
+import android.os.StrictMode;
import android.util.AttributeSet;
import android.view.FocusFinder;
import android.view.KeyEvent;
@@ -128,7 +129,16 @@
* drags/flings if multiple pointers are used.
*/
private int mActivePointerId = INVALID_POINTER;
-
+
+ /**
+ * The StrictMode "critical time span" objects to catch animation
+ * stutters. Non-null when a time-sensitive animation is
+ * in-flight. Must call finish() on them when done animating.
+ * These are no-ops on user builds.
+ */
+ private StrictMode.Span mScrollStrictSpan = null; // aka "drag"
+ private StrictMode.Span mFlingStrictSpan = null;
+
/**
* Sentinel value for no current active pointer.
* Used by {@link #mActivePointerId}.
@@ -437,6 +447,9 @@
if (yDiff > mTouchSlop) {
mIsBeingDragged = true;
mLastMotionY = y;
+ if (mScrollStrictSpan == null) {
+ mScrollStrictSpan = StrictMode.enterCriticalSpan("ScrollView-scroll");
+ }
}
break;
}
@@ -461,6 +474,9 @@
* being flinged.
*/
mIsBeingDragged = !mScroller.isFinished();
+ if (mIsBeingDragged && mScrollStrictSpan == null) {
+ mScrollStrictSpan = StrictMode.enterCriticalSpan("ScrollView-scroll");
+ }
break;
}
@@ -512,6 +528,10 @@
*/
if (!mScroller.isFinished()) {
mScroller.abortAnimation();
+ if (mFlingStrictSpan != null) {
+ mFlingStrictSpan.finish();
+ mFlingStrictSpan = null;
+ }
}
// Remember where the motion event started
@@ -577,16 +597,7 @@
}
mActivePointerId = INVALID_POINTER;
- mIsBeingDragged = false;
-
- if (mVelocityTracker != null) {
- mVelocityTracker.recycle();
- mVelocityTracker = null;
- }
- if (mEdgeGlowTop != null) {
- mEdgeGlowTop.onRelease();
- mEdgeGlowBottom.onRelease();
- }
+ endDrag();
}
break;
case MotionEvent.ACTION_CANCEL:
@@ -595,15 +606,7 @@
invalidate();
}
mActivePointerId = INVALID_POINTER;
- mIsBeingDragged = false;
- if (mVelocityTracker != null) {
- mVelocityTracker.recycle();
- mVelocityTracker = null;
- }
- if (mEdgeGlowTop != null) {
- mEdgeGlowTop.onRelease();
- mEdgeGlowBottom.onRelease();
- }
+ endDrag();
}
break;
case MotionEvent.ACTION_POINTER_UP:
@@ -1004,6 +1007,10 @@
} else {
if (!mScroller.isFinished()) {
mScroller.abortAnimation();
+ if (mFlingStrictSpan != null) {
+ mFlingStrictSpan.finish();
+ mFlingStrictSpan = null;
+ }
}
scrollBy(dx, dy);
}
@@ -1122,6 +1129,11 @@
// Keep on drawing until the animation has finished.
postInvalidate();
+ } else {
+ if (mFlingStrictSpan != null) {
+ mFlingStrictSpan.finish();
+ mFlingStrictSpan = null;
+ }
}
}
@@ -1296,6 +1308,20 @@
}
@Override
+ protected void onDetachedFromWindow() {
+ super.onDetachedFromWindow();
+
+ if (mScrollStrictSpan != null) {
+ mScrollStrictSpan.finish();
+ mScrollStrictSpan = null;
+ }
+ if (mFlingStrictSpan != null) {
+ mFlingStrictSpan.finish();
+ mFlingStrictSpan = null;
+ }
+ }
+
+ @Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
super.onLayout(changed, l, t, r, b);
mIsLayoutDirty = false;
@@ -1368,11 +1394,34 @@
mScrollViewMovedFocus = true;
mScrollViewMovedFocus = false;
}
-
+
+ if (mFlingStrictSpan == null) {
+ mFlingStrictSpan = StrictMode.enterCriticalSpan("ScrollView-fling");
+ }
+
invalidate();
}
}
+ private void endDrag() {
+ mIsBeingDragged = false;
+
+ if (mVelocityTracker != null) {
+ mVelocityTracker.recycle();
+ mVelocityTracker = null;
+ }
+
+ if (mEdgeGlowTop != null) {
+ mEdgeGlowTop.onRelease();
+ mEdgeGlowBottom.onRelease();
+ }
+
+ if (mScrollStrictSpan != null) {
+ mScrollStrictSpan.finish();
+ mScrollStrictSpan = null;
+ }
+ }
+
/**
* {@inheritDoc}
*
diff --git a/docs/html/guide/topics/fragments/index.jd b/docs/html/guide/topics/fragments/index.jd
index ce10ef7..766146e 100644
--- a/docs/html/guide/topics/fragments/index.jd
+++ b/docs/html/guide/topics/fragments/index.jd
@@ -399,7 +399,7 @@
Fragment newFragment = new MyFragment();
FragmentTransaction ft = openFragmentTransaction();
// Replace and add to back stack
-ft.replace(newFragment, R.id.myfragment);
+ft.replace(R.id.myfragment, newFragment);
ft.addToBackStack(null);
// Apply changes
ft.commit();
diff --git a/graphics/java/android/graphics/ComposeShader.java b/graphics/java/android/graphics/ComposeShader.java
index 8d5c913..241ab17 100644
--- a/graphics/java/android/graphics/ComposeShader.java
+++ b/graphics/java/android/graphics/ComposeShader.java
@@ -30,7 +30,7 @@
/** Create a new compose shader, given shaders A, B, and a combining mode.
When the mode is applied, it will be given the result from shader A as its
- "dst", and the result of from shader B as its "src".
+ "dst", and the result from shader B as its "src".
@param shaderA The colors from this shader are seen as the "dst" by the mode
@param shaderB The colors from this shader are seen as the "src" by the mode
@param mode The mode that combines the colors from the two shaders. If mode
@@ -53,7 +53,7 @@
/** Create a new compose shader, given shaders A, B, and a combining PorterDuff mode.
When the mode is applied, it will be given the result from shader A as its
- "dst", and the result of from shader B as its "src".
+ "dst", and the result from shader B as its "src".
@param shaderA The colors from this shader are seen as the "dst" by the mode
@param shaderB The colors from this shader are seen as the "src" by the mode
@param mode The PorterDuff mode that combines the colors from the two shaders.
diff --git a/media/libstagefright/OMXCodec.cpp b/media/libstagefright/OMXCodec.cpp
index 3f32f2f..3108e4e 100644
--- a/media/libstagefright/OMXCodec.cpp
+++ b/media/libstagefright/OMXCodec.cpp
@@ -3898,32 +3898,34 @@
mOutputFormat->setInt32(kKeyHeight, video_def->nFrameHeight);
mOutputFormat->setInt32(kKeyColorFormat, video_def->eColorFormat);
- OMX_CONFIG_RECTTYPE rect;
- status_t err =
- mOMX->getConfig(
- mNode, OMX_IndexConfigCommonOutputCrop,
- &rect, sizeof(rect));
+ if (!mIsEncoder) {
+ OMX_CONFIG_RECTTYPE rect;
+ status_t err =
+ mOMX->getConfig(
+ mNode, OMX_IndexConfigCommonOutputCrop,
+ &rect, sizeof(rect));
- if (err == OK) {
- CHECK_GE(rect.nLeft, 0);
- CHECK_GE(rect.nTop, 0);
- CHECK_GE(rect.nWidth, 0u);
- CHECK_GE(rect.nHeight, 0u);
- CHECK_LE(rect.nLeft + rect.nWidth - 1, video_def->nFrameWidth);
- CHECK_LE(rect.nTop + rect.nHeight - 1, video_def->nFrameHeight);
+ if (err == OK) {
+ CHECK_GE(rect.nLeft, 0);
+ CHECK_GE(rect.nTop, 0);
+ CHECK_GE(rect.nWidth, 0u);
+ CHECK_GE(rect.nHeight, 0u);
+ CHECK_LE(rect.nLeft + rect.nWidth - 1, video_def->nFrameWidth);
+ CHECK_LE(rect.nTop + rect.nHeight - 1, video_def->nFrameHeight);
- mOutputFormat->setRect(
- kKeyCropRect,
- rect.nLeft,
- rect.nTop,
- rect.nLeft + rect.nWidth - 1,
- rect.nTop + rect.nHeight - 1);
- } else {
- mOutputFormat->setRect(
- kKeyCropRect,
- 0, 0,
- video_def->nFrameWidth - 1,
- video_def->nFrameHeight - 1);
+ mOutputFormat->setRect(
+ kKeyCropRect,
+ rect.nLeft,
+ rect.nTop,
+ rect.nLeft + rect.nWidth - 1,
+ rect.nTop + rect.nHeight - 1);
+ } else {
+ mOutputFormat->setRect(
+ kKeyCropRect,
+ 0, 0,
+ video_def->nFrameWidth - 1,
+ video_def->nFrameHeight - 1);
+ }
}
break;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
index 4ff2429..cd2679a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
@@ -116,7 +116,6 @@
IntentFilter filter = new IntentFilter();
filter.addAction(WifiManager.RSSI_CHANGED_ACTION);
filter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
- filter.addAction(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION);
filter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
filter.addAction(TelephonyIntents.ACTION_SIM_STATE_CHANGED);
context.registerReceiver(this, filter);
@@ -141,7 +140,6 @@
final String action = intent.getAction();
if (action.equals(WifiManager.RSSI_CHANGED_ACTION)
|| action.equals(WifiManager.WIFI_STATE_CHANGED_ACTION)
- || action.equals(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION)
|| action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) {
updateWifiState(intent);
refreshViews();
@@ -489,8 +487,7 @@
mWifiEnabled = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE,
WifiManager.WIFI_STATE_UNKNOWN) == WifiManager.WIFI_STATE_ENABLED;
- } else if (action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)
- || action.equals(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION)) {
+ } else if (action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) {
final NetworkInfo networkInfo = (NetworkInfo)
intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);
boolean wasConnected = mWifiConnected;
diff --git a/services/java/com/android/server/InputMethodManagerService.java b/services/java/com/android/server/InputMethodManagerService.java
index b2cc6bd..eca37b7 100644
--- a/services/java/com/android/server/InputMethodManagerService.java
+++ b/services/java/com/android/server/InputMethodManagerService.java
@@ -240,10 +240,9 @@
private InputMethodSubtype mCurrentSubtype;
// This list contains the pairs of InputMethodInfo and InputMethodSubtype.
- private List<Pair<InputMethodInfo, InputMethodSubtype>> mShortcutInputMethodsAndSubtypes;
- // This list is used for returning the pairs of InputMethodInfo and InputMethodSubtype through
- // aidl. This list has imi1, subtype1 imi2, subtype2...
- private List mShortcutInputMethodsAndSubtypesObjectList;
+ private final HashMap<InputMethodInfo, ArrayList<InputMethodSubtype>>
+ mShortcutInputMethodsAndSubtypes =
+ new HashMap<InputMethodInfo, ArrayList<InputMethodSubtype>>();
/**
* Set to true if our ServiceConnection is currently actively bound to
@@ -992,7 +991,7 @@
mCurMethodId = null;
unbindCurrentMethodLocked(true);
}
- mShortcutInputMethodsAndSubtypes = null;
+ mShortcutInputMethodsAndSubtypes.clear();
} else {
// There is no longer an input method set, so stop any current one.
mCurMethodId = null;
@@ -2022,7 +2021,6 @@
+ mostApplicableIMI.getId() + "," + mostApplicableSubtypeId);
}
if (mostApplicableIMI != null && mostApplicableSubtypeId != NOT_A_SUBTYPE_ID) {
- ArrayList<Parcelable> ret = new ArrayList<Parcelable>(2);
return new Pair<InputMethodInfo, InputMethodSubtype> (mostApplicableIMI,
mostApplicableIMI.getSubtypes().get(mostApplicableSubtypeId));
} else {
@@ -2067,25 +2065,37 @@
}
}
+ private void addShortcutInputMethodAndSubtypes(InputMethodInfo imi,
+ InputMethodSubtype subtype) {
+ if (mShortcutInputMethodsAndSubtypes.containsKey(imi)) {
+ mShortcutInputMethodsAndSubtypes.get(imi).add(subtype);
+ } else {
+ ArrayList<InputMethodSubtype> subtypes = new ArrayList<InputMethodSubtype>();
+ subtypes.add(subtype);
+ mShortcutInputMethodsAndSubtypes.put(imi, subtypes);
+ }
+ }
+
// TODO: We should change the return type from List to List<Parcelable>
public List getShortcutInputMethodsAndSubtypes() {
synchronized (mMethodMap) {
- if (mShortcutInputMethodsAndSubtypesObjectList != null) {
+ if (mShortcutInputMethodsAndSubtypes.size() == 0) {
// If there are no selected shortcut subtypes, the framework will try to find
// the most applicable subtype from all subtypes whose mode is
// SUBTYPE_MODE_VOICE. This is an exceptional case, so we will hardcode the mode.
- mShortcutInputMethodsAndSubtypes =
- new ArrayList<Pair<InputMethodInfo, InputMethodSubtype>>();
- mShortcutInputMethodsAndSubtypes.add(
- findLastResortApplicableShortcutInputMethodAndSubtypeLocked(
- SUBTYPE_MODE_VOICE));
- mShortcutInputMethodsAndSubtypesObjectList = new ArrayList<Parcelable>();
- for (Pair ime: mShortcutInputMethodsAndSubtypes) {
- mShortcutInputMethodsAndSubtypesObjectList.add(ime.first);
- mShortcutInputMethodsAndSubtypesObjectList.add(ime.second);
+ Pair<InputMethodInfo, InputMethodSubtype> info =
+ findLastResortApplicableShortcutInputMethodAndSubtypeLocked(
+ SUBTYPE_MODE_VOICE);
+ addShortcutInputMethodAndSubtypes(info.first, info.second);
+ }
+ ArrayList ret = new ArrayList<Object>();
+ for (InputMethodInfo imi: mShortcutInputMethodsAndSubtypes.keySet()) {
+ ret.add(imi);
+ for (InputMethodSubtype subtype: mShortcutInputMethodsAndSubtypes.get(imi)) {
+ ret.add(subtype);
}
}
- return mShortcutInputMethodsAndSubtypesObjectList;
+ return ret;
}
}
diff --git a/tools/layoutlib/bridge/src/android/graphics/BitmapFactory.java b/tools/layoutlib/bridge/src/android/graphics/BitmapFactory.java
index 6fd59c4..212223c 100644
--- a/tools/layoutlib/bridge/src/android/graphics/BitmapFactory.java
+++ b/tools/layoutlib/bridge/src/android/graphics/BitmapFactory.java
@@ -456,7 +456,11 @@
// into is.read(...) This number is not related to the value passed
// to mark(...) above.
try {
- bm = Bitmap_Delegate.createBitmap(is, Density.MEDIUM);
+ Density density = Density.MEDIUM;
+ if (opts != null) {
+ density = Density.getEnum(opts.inDensity);
+ }
+ bm = Bitmap_Delegate.createBitmap(is, true, density);
} catch (IOException e) {
return null;
}
diff --git a/tools/layoutlib/bridge/src/android/graphics/Bitmap_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Bitmap_Delegate.java
index 0920497..b4c51b2 100644
--- a/tools/layoutlib/bridge/src/android/graphics/Bitmap_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/Bitmap_Delegate.java
@@ -75,32 +75,56 @@
/**
* Creates and returns a {@link Bitmap} initialized with the given file content.
+ *
+ * @param input the file from which to read the bitmap content
+ * @param isMutable whether the bitmap is mutable
+ * @param density the density associated with the bitmap
+ *
+ * @see Bitmap#isMutable()
+ * @see Bitmap#getDensity()
*/
- public static Bitmap createBitmap(File input, Density density) throws IOException {
+ public static Bitmap createBitmap(File input, boolean isMutable, Density density)
+ throws IOException {
// create a delegate with the content of the file.
Bitmap_Delegate delegate = new Bitmap_Delegate(ImageIO.read(input));
- return createBitmap(delegate, density.getValue());
+ return createBitmap(delegate, isMutable, density.getValue());
}
/**
* Creates and returns a {@link Bitmap} initialized with the given stream content.
+ *
+ * @param input the stream from which to read the bitmap content
+ * @param isMutable whether the bitmap is mutable
+ * @param density the density associated with the bitmap
+ *
+ * @see Bitmap#isMutable()
+ * @see Bitmap#getDensity()
*/
- public static Bitmap createBitmap(InputStream input, Density density) throws IOException {
+ public static Bitmap createBitmap(InputStream input, boolean isMutable, Density density)
+ throws IOException {
// create a delegate with the content of the stream.
Bitmap_Delegate delegate = new Bitmap_Delegate(ImageIO.read(input));
- return createBitmap(delegate, density.getValue());
+ return createBitmap(delegate, isMutable, density.getValue());
}
/**
* Creates and returns a {@link Bitmap} initialized with the given {@link BufferedImage}
+ *
+ * @param image the bitmap content
+ * @param isMutable whether the bitmap is mutable
+ * @param density the density associated with the bitmap
+ *
+ * @see Bitmap#isMutable()
+ * @see Bitmap#getDensity()
*/
- public static Bitmap createBitmap(BufferedImage image, Density density) throws IOException {
+ public static Bitmap createBitmap(BufferedImage image, boolean isMutable, Density density)
+ throws IOException {
// create a delegate with the given image.
Bitmap_Delegate delegate = new Bitmap_Delegate(image);
- return createBitmap(delegate, density.getValue());
+ return createBitmap(delegate, isMutable, density.getValue());
}
/**
@@ -153,7 +177,7 @@
// create a delegate with the content of the stream.
Bitmap_Delegate delegate = new Bitmap_Delegate(image);
- return createBitmap(delegate, Bitmap.getDefaultDensity());
+ return createBitmap(delegate, mutable, Bitmap.getDefaultDensity());
}
/*package*/ static Bitmap nativeCopy(int srcBitmap, int nativeConfig, boolean isMutable) {
@@ -166,8 +190,7 @@
}
/*package*/ static void nativeRecycle(int nativeBitmap) {
- // FIXME implement native delegate
- throw new UnsupportedOperationException("Native delegate needed for Bitmap");
+ sManager.removeDelegate(nativeBitmap);
}
/*package*/ static boolean nativeCompress(int nativeBitmap, int format, int quality,
@@ -336,11 +359,11 @@
mImage = image;
}
- private static Bitmap createBitmap(Bitmap_Delegate delegate, int density) {
+ private static Bitmap createBitmap(Bitmap_Delegate delegate, boolean isMutable, int density) {
// get its native_int
int nativeInt = sManager.addDelegate(delegate);
// and create/return a new Bitmap with it
- return new Bitmap(nativeInt, true /*isMutable*/, null /*ninePatchChunk*/, density);
+ return new Bitmap(nativeInt, isMutable, null /*ninePatchChunk*/, density);
}
}
diff --git a/tools/layoutlib/bridge/src/android/graphics/Canvas_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Canvas_Delegate.java
index cea07af..08f3c7a 100644
--- a/tools/layoutlib/bridge/src/android/graphics/Canvas_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/Canvas_Delegate.java
@@ -960,7 +960,7 @@
* Creates a new {@link Graphics2D} based on the {@link Paint} parameters.
* <p/>The object must be disposed ({@link Graphics2D#dispose()}) after being used.
*/
- private Graphics2D getCustomGraphics(Paint_Delegate paint) {
+ /*package*/ Graphics2D getCustomGraphics(Paint_Delegate paint) {
// make new one
Graphics2D g = getGraphics2d();
g = (Graphics2D)g.create();
diff --git a/tools/layoutlib/bridge/src/android/graphics/NinePatch_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/NinePatch_Delegate.java
new file mode 100644
index 0000000..3d26e47
--- /dev/null
+++ b/tools/layoutlib/bridge/src/android/graphics/NinePatch_Delegate.java
@@ -0,0 +1,225 @@
+/*
+ * Copyright (C) 2010 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.graphics;
+
+import com.android.layoutlib.bridge.impl.DelegateManager;
+import com.android.ninepatch.NinePatchChunk;
+
+import android.graphics.drawable.NinePatchDrawable;
+
+import java.awt.Graphics2D;
+import java.awt.image.BufferedImage;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.lang.ref.SoftReference;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Delegate implementing the native methods of android.graphics.NinePatch
+ *
+ * Through the layoutlib_create tool, the original native methods of NinePatch have been replaced
+ * by calls to methods of the same name in this delegate class.
+ *
+ * Because it's a stateless class to start with, there's no need to keep a {@link DelegateManager}
+ * around to map int to instance of the delegate.
+ *
+ */
+public class NinePatch_Delegate {
+
+ /**
+ * Cache map for {@link NinePatchChunk}.
+ * When the chunks are created they are serialized into a byte[], and both are put
+ * in the cache, using a {@link SoftReference} for the chunk. The default Java classes
+ * for {@link NinePatch} and {@link NinePatchDrawable} only reference to the byte[] data, and
+ * provide this for drawing.
+ * Using the cache map allows us to not have to deserialize the byte[] back into a
+ * {@link NinePatchChunk} every time a rendering is done.
+ */
+ private final static Map<byte[], SoftReference<NinePatchChunk>> sChunkCache =
+ new HashMap<byte[], SoftReference<NinePatchChunk>>();
+
+ // ---- Public Helper methods ----
+
+ /**
+ * Serializes the given chunk.
+ *
+ * @return the serialized data for the chunk.
+ */
+ public static byte[] serialize(NinePatchChunk chunk) {
+ // serialize the chunk to get a byte[]
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ ObjectOutputStream oos = null;
+ try {
+ oos = new ObjectOutputStream(baos);
+ oos.writeObject(chunk);
+ } catch (IOException e) {
+ //FIXME log this.
+ return null;
+ } finally {
+ if (oos != null) {
+ try {
+ oos.close();
+ } catch (IOException e) {
+ }
+ }
+ }
+
+ // get the array and add it to the cache
+ byte[] array = baos.toByteArray();
+ sChunkCache.put(array, new SoftReference<NinePatchChunk>(chunk));
+ return array;
+ }
+
+ // ---- native methods ----
+
+ /*package*/ static boolean isNinePatchChunk(byte[] chunk) {
+ NinePatchChunk chunkObject = getChunk(chunk);
+ if (chunkObject != null) {
+ return true;
+ }
+
+ return false;
+ }
+
+ /*package*/ static void validateNinePatchChunk(int bitmap, byte[] chunk) {
+ // the default JNI implementation only checks that the byte[] has the same
+ // size as the C struct it represent. Since we cannot do the same check (serialization
+ // will return different size depending on content), we do nothing.
+ }
+
+ /*package*/ static void nativeDraw(int canvas_instance, RectF loc, int bitmap_instance,
+ byte[] c, int paint_instance_or_null, int destDensity, int srcDensity) {
+ draw(canvas_instance,
+ (int) loc.left, (int) loc.top, (int) loc.width(), (int) loc.height(),
+ bitmap_instance, c, paint_instance_or_null,
+ destDensity, srcDensity);
+ }
+
+ /*package*/ static void nativeDraw(int canvas_instance, Rect loc, int bitmap_instance,
+ byte[] c, int paint_instance_or_null, int destDensity, int srcDensity) {
+ draw(canvas_instance,
+ loc.left, loc.top, loc.width(), loc.height(),
+ bitmap_instance, c, paint_instance_or_null,
+ destDensity, srcDensity);
+ }
+
+ private static void draw(int canvas_instance,
+ int left, int top, int right, int bottom,
+ int bitmap_instance, byte[] c, int paint_instance_or_null,
+ int destDensity, int srcDensity) {
+ // get the delegate from the native int.
+ Bitmap_Delegate bitmap_delegate = Bitmap_Delegate.getDelegate(bitmap_instance);
+ if (bitmap_delegate == null) {
+ assert false;
+ return;
+ }
+
+ if (c == null) {
+ // not a 9-patch?
+ BufferedImage image = bitmap_delegate.getImage();
+ Canvas_Delegate.native_drawBitmap(canvas_instance, bitmap_instance,
+ new Rect(0, 0, image.getWidth(), image.getHeight()),
+ new Rect(left, top, right, bottom),
+ paint_instance_or_null, destDensity, srcDensity);
+ return;
+ }
+
+ NinePatchChunk chunkObject = getChunk(c);
+ assert chunkObject != null;
+ if (chunkObject == null) {
+ return;
+ }
+
+ Canvas_Delegate canvas_delegate = Canvas_Delegate.getDelegate(canvas_instance);
+ if (canvas_delegate == null) {
+ assert false;
+ return;
+ }
+
+ // this one can be null
+ Paint_Delegate paint_delegate = Paint_Delegate.getDelegate(paint_instance_or_null);
+
+ Graphics2D graphics;
+ if (paint_delegate != null) {
+ graphics = canvas_delegate.getCustomGraphics(paint_delegate);
+ } else {
+ graphics = canvas_delegate.getGraphics2d();
+ }
+
+ try {
+ chunkObject.draw(bitmap_delegate.getImage(), graphics,
+ left, top, right - left, bottom - top);
+ } finally {
+ if (paint_delegate != null) {
+ graphics.dispose();
+ }
+ }
+
+ }
+
+ /*package*/ static int nativeGetTransparentRegion(int bitmap, byte[] chunk, Rect location) {
+ return 0;
+ }
+
+ // ---- Private Helper methods ----
+
+ /**
+ * Returns a {@link NinePatchChunk} object for the given serialized representation.
+ *
+ * If the chunk is present in the cache then the object from the cache is returned, otherwise
+ * the array is deserialized into a {@link NinePatchChunk} object.
+ *
+ * @param array the serialized representation of the chunk.
+ * @return the NinePatchChunk or null if deserialization failed.
+ */
+ private static NinePatchChunk getChunk(byte[] array) {
+ SoftReference<NinePatchChunk> chunkRef = sChunkCache.get(array);
+ NinePatchChunk chunk = chunkRef.get();
+ if (chunk == null) {
+ ByteArrayInputStream bais = new ByteArrayInputStream(array);
+ ObjectInputStream ois = null;
+ try {
+ ois = new ObjectInputStream(bais);
+ chunk = (NinePatchChunk) ois.readObject();
+
+ // put back the chunk in the cache
+ if (chunk != null) {
+ sChunkCache.put(array, new SoftReference<NinePatchChunk>(chunk));
+ }
+ } catch (IOException e) {
+ // FIXME: log this
+ return null;
+ } catch (ClassNotFoundException e) {
+ // FIXME: log this
+ return null;
+ } finally {
+ if (ois != null) {
+ try {
+ ois.close();
+ } catch (IOException e) {
+ }
+ }
+ }
+ }
+
+ return chunk;
+ }
+}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java
index e691fdf..35ba73d 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java
@@ -26,7 +26,7 @@
import com.android.layoutlib.bridge.android.BridgeAssetManager;
import com.android.layoutlib.bridge.impl.FontLoader;
import com.android.layoutlib.bridge.impl.LayoutSceneImpl;
-import com.android.ninepatch.NinePatch;
+import com.android.ninepatch.NinePatchChunk;
import com.android.tools.layoutlib.create.MethodAdapter;
import com.android.tools.layoutlib.create.OverrideMethod;
@@ -73,13 +73,13 @@
private final static Map<Object, Map<String, SoftReference<Bitmap>>> sProjectBitmapCache =
new HashMap<Object, Map<String, SoftReference<Bitmap>>>();
- private final static Map<Object, Map<String, SoftReference<NinePatch>>> sProject9PatchCache =
- new HashMap<Object, Map<String, SoftReference<NinePatch>>>();
+ private final static Map<Object, Map<String, SoftReference<NinePatchChunk>>> sProject9PatchCache =
+ new HashMap<Object, Map<String, SoftReference<NinePatchChunk>>>();
private final static Map<String, SoftReference<Bitmap>> sFrameworkBitmapCache =
new HashMap<String, SoftReference<Bitmap>>();
- private final static Map<String, SoftReference<NinePatch>> sFramework9PatchCache =
- new HashMap<String, SoftReference<NinePatch>>();
+ private final static Map<String, SoftReference<NinePatchChunk>> sFramework9PatchCache =
+ new HashMap<String, SoftReference<NinePatchChunk>>();
private static Map<String, Map<String, Integer>> sEnumValueMap;
@@ -252,23 +252,23 @@
}
/**
- * Sets a 9 patch in a project cache or in the framework cache.
+ * Sets a 9 patch chunk in a project cache or in the framework cache.
* @param value the path of the 9 patch
* @param ninePatch the 9 patch object
* @param projectKey the key of the project, or null to put the bitmap in the framework cache.
*/
- public static void setCached9Patch(String value, NinePatch ninePatch, Object projectKey) {
+ public static void setCached9Patch(String value, NinePatchChunk ninePatch, Object projectKey) {
if (projectKey != null) {
- Map<String, SoftReference<NinePatch>> map = sProject9PatchCache.get(projectKey);
+ Map<String, SoftReference<NinePatchChunk>> map = sProject9PatchCache.get(projectKey);
if (map == null) {
- map = new HashMap<String, SoftReference<NinePatch>>();
+ map = new HashMap<String, SoftReference<NinePatchChunk>>();
sProject9PatchCache.put(projectKey, map);
}
- map.put(value, new SoftReference<NinePatch>(ninePatch));
+ map.put(value, new SoftReference<NinePatchChunk>(ninePatch));
} else {
- sFramework9PatchCache.put(value, new SoftReference<NinePatch>(ninePatch));
+ sFramework9PatchCache.put(value, new SoftReference<NinePatchChunk>(ninePatch));
}
}
@@ -436,24 +436,24 @@
}
/**
- * Returns the 9 patch for a specific path, from a specific project cache, or from the
+ * Returns the 9 patch chunk for a specific path, from a specific project cache, or from the
* framework cache.
* @param value the path of the 9 patch
* @param projectKey the key of the project, or null to query the framework cache.
* @return the cached 9 patch or null if not found.
*/
- public static NinePatch getCached9Patch(String value, Object projectKey) {
+ public static NinePatchChunk getCached9Patch(String value, Object projectKey) {
if (projectKey != null) {
- Map<String, SoftReference<NinePatch>> map = sProject9PatchCache.get(projectKey);
+ Map<String, SoftReference<NinePatchChunk>> map = sProject9PatchCache.get(projectKey);
if (map != null) {
- SoftReference<NinePatch> ref = map.get(value);
+ SoftReference<NinePatchChunk> ref = map.get(value);
if (ref != null) {
return ref.get();
}
}
} else {
- SoftReference<NinePatch> ref = sFramework9PatchCache.get(value);
+ SoftReference<NinePatchChunk> ref = sFramework9PatchCache.get(value);
if (ref != null) {
return ref.get();
}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/NinePatchDrawable.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/NinePatchDrawable.java
deleted file mode 100644
index 4efa631..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/NinePatchDrawable.java
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge.android;
-
-import com.android.ninepatch.NinePatch;
-
-import android.graphics.Canvas;
-import android.graphics.Canvas_Delegate;
-import android.graphics.ColorFilter;
-import android.graphics.Rect;
-import android.graphics.drawable.Drawable;
-
-public class NinePatchDrawable extends Drawable {
-
- private NinePatch m9Patch;
-
- public NinePatchDrawable(NinePatch ninePatch) {
- m9Patch = ninePatch;
- }
-
- @Override
- public int getMinimumWidth() {
- return m9Patch.getWidth();
- }
-
- @Override
- public int getMinimumHeight() {
- return m9Patch.getHeight();
- }
-
- /**
- * Return the intrinsic width of the underlying drawable object. Returns
- * -1 if it has no intrinsic width, such as with a solid color.
- */
- @Override
- public int getIntrinsicWidth() {
- return m9Patch.getWidth();
- }
-
- /**
- * Return the intrinsic height of the underlying drawable object. Returns
- * -1 if it has no intrinsic height, such as with a solid color.
- */
- @Override
- public int getIntrinsicHeight() {
- return m9Patch.getHeight();
- }
-
- /**
- * Return in padding the insets suggested by this Drawable for placing
- * content inside the drawable's bounds. Positive values move toward the
- * center of the Drawable (set Rect.inset). Returns true if this drawable
- * actually has a padding, else false. When false is returned, the padding
- * is always set to 0.
- */
- @Override
- public boolean getPadding(Rect padding) {
- int[] padd = new int[4];
- m9Patch.getPadding(padd);
- padding.left = padd[0];
- padding.top = padd[1];
- padding.right = padd[2];
- padding.bottom = padd[3];
- return true;
- }
-
- @Override
- public void draw(Canvas canvas) {
- Rect r = getBounds();
- Canvas_Delegate canvasDelegate = Canvas_Delegate.getDelegate(canvas);
- m9Patch.draw(canvasDelegate.getGraphics2d(), r.left, r.top, r.width(), r.height());
-
- return;
- }
-
-
- // ----------- Not implemented methods ---------------
-
-
- @Override
- public int getOpacity() {
- // FIXME
- return 0xFF;
- }
-
- @Override
- public void setAlpha(int arg0) {
- // FIXME !
- }
-
- @Override
- public void setColorFilter(ColorFilter arg0) {
- // FIXME
- }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/LayoutSceneImpl.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/LayoutSceneImpl.java
index 2e3f9a8..f7d249e 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/LayoutSceneImpl.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/LayoutSceneImpl.java
@@ -313,10 +313,12 @@
// create an Android bitmap around the BufferedImage
Bitmap bitmap = Bitmap_Delegate.createBitmap(mImage,
+ true /*isMutable*/,
Density.getEnum(mParams.getDensity()));
// create a Canvas around the Android bitmap
Canvas canvas = new Canvas(bitmap);
+ canvas.setDensity(mParams.getDensity());
// to set the logger, get the native delegate
Canvas_Delegate canvasDelegate = Canvas_Delegate.getDelegate(canvas);
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/ResourceHelper.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/ResourceHelper.java
index 3e506b8..ceb8a0d 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/ResourceHelper.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/ResourceHelper.java
@@ -22,8 +22,8 @@
import com.android.layoutlib.bridge.Bridge;
import com.android.layoutlib.bridge.android.BridgeContext;
import com.android.layoutlib.bridge.android.BridgeXmlBlockParser;
-import com.android.layoutlib.bridge.android.NinePatchDrawable;
import com.android.ninepatch.NinePatch;
+import com.android.ninepatch.NinePatchChunk;
import org.kxml2.io.KXmlParser;
import org.xmlpull.v1.XmlPullParser;
@@ -31,9 +31,12 @@
import android.graphics.Bitmap;
import android.graphics.Bitmap_Delegate;
+import android.graphics.NinePatch_Delegate;
+import android.graphics.Rect;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
+import android.graphics.drawable.NinePatchDrawable;
import android.util.TypedValue;
import java.io.File;
@@ -121,15 +124,38 @@
if (lowerCaseValue.endsWith(NinePatch.EXTENSION_9PATCH)) {
File file = new File(stringValue);
if (file.isFile()) {
- NinePatch ninePatch = Bridge.getCached9Patch(stringValue,
+ // see if we still have both the chunk and the bitmap in the caches
+ NinePatchChunk chunk = Bridge.getCached9Patch(stringValue,
+ isFramework ? null : context.getProjectKey());
+ Bitmap bitmap = Bridge.getCachedBitmap(stringValue,
isFramework ? null : context.getProjectKey());
- if (ninePatch == null) {
+ // if either chunk or bitmap is null, then we reload the 9-patch file.
+ if (chunk == null || bitmap == null) {
try {
- ninePatch = NinePatch.load(file.toURL(), false /* convert */);
+ NinePatch ninePatch = NinePatch.load(file.toURL(), false /* convert */);
+ if (ninePatch != null) {
+ if (chunk == null) {
+ chunk = ninePatch.getChunk();
- Bridge.setCached9Patch(stringValue, ninePatch,
- isFramework ? null : context.getProjectKey());
+ Bridge.setCached9Patch(stringValue, chunk,
+ isFramework ? null : context.getProjectKey());
+ }
+
+ if (bitmap == null) {
+ Density density = Density.MEDIUM;
+ if (value instanceof IDensityBasedResourceValue) {
+ density = ((IDensityBasedResourceValue)value).getDensity();
+ }
+
+ bitmap = Bitmap_Delegate.createBitmap(ninePatch.getImage(),
+ false /*isMutable*/,
+ density);
+
+ Bridge.setCachedBitmap(stringValue, bitmap,
+ isFramework ? null : context.getProjectKey());
+ }
+ }
} catch (MalformedURLException e) {
// URL is wrong, we'll return null below
} catch (IOException e) {
@@ -137,8 +163,13 @@
}
}
- if (ninePatch != null) {
- return new NinePatchDrawable(ninePatch);
+ if (chunk != null && bitmap != null) {
+ int[] padding = chunk.getPadding();
+ Rect paddingRect = new Rect(padding[0], padding[1], padding[2], padding[3]);
+
+ return new NinePatchDrawable(context.getResources(), bitmap,
+ NinePatch_Delegate.serialize(chunk),
+ paddingRect, null);
}
}
@@ -174,29 +205,17 @@
isFramework ? null : context.getProjectKey());
if (bitmap == null) {
- // always create the cache copy in the original density.
- bitmap = Bitmap_Delegate.createBitmap(bmpFile, Density.MEDIUM);
+ Density density = Density.MEDIUM;
+ if (value instanceof IDensityBasedResourceValue) {
+ density = ((IDensityBasedResourceValue)value).getDensity();
+ }
+
+ bitmap = Bitmap_Delegate.createBitmap(bmpFile, false /*isMutable*/,
+ density);
Bridge.setCachedBitmap(stringValue, bitmap,
isFramework ? null : context.getProjectKey());
}
- try {
- if (value instanceof IDensityBasedResourceValue) {
- Density density = ((IDensityBasedResourceValue)value).getDensity();
- if (density != Density.MEDIUM) {
- // create a copy of the bitmap
- bitmap = Bitmap.createBitmap(bitmap);
-
- // apply the density
- bitmap.setDensity(density.getValue());
- }
- }
- } catch (NoClassDefFoundError error) {
- // look like we're running in an older version of ADT that doesn't include
- // the new layoutlib_api. Let's just ignore this, the drawing will just be
- // wrong.
- }
-
return new BitmapDrawable(context.getResources(), bitmap);
} catch (IOException e) {
// we'll return null below
diff --git a/tools/layoutlib/bridge/tests/com/android/layoutlib/bridge/NinePatchTest.java b/tools/layoutlib/bridge/tests/com/android/layoutlib/bridge/NinePatchTest.java
index 23351ab..a3219e7 100644
--- a/tools/layoutlib/bridge/tests/com/android/layoutlib/bridge/NinePatchTest.java
+++ b/tools/layoutlib/bridge/tests/com/android/layoutlib/bridge/NinePatchTest.java
@@ -48,5 +48,4 @@
assertEquals(36, mPatch.getWidth());
assertEquals(25, mPatch.getHeight());
}
-
}
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java
index b9c71133..bb2e6b3 100644
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java
+++ b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java
@@ -109,6 +109,7 @@
"android.graphics.DashPathEffect",
"android.graphics.LinearGradient",
"android.graphics.Matrix",
+ "android.graphics.NinePatch",
"android.graphics.Paint",
"android.graphics.PathEffect",
"android.graphics.PorterDuffXfermode",
diff --git a/wifi/java/android/net/wifi/WifiStateMachine.java b/wifi/java/android/net/wifi/WifiStateMachine.java
index 90abd02..7e3df1a 100644
--- a/wifi/java/android/net/wifi/WifiStateMachine.java
+++ b/wifi/java/android/net/wifi/WifiStateMachine.java
@@ -1529,7 +1529,7 @@
}
void setNetworkAvailable(boolean available) {
- sendMessage(CMD_SET_NETWORK_AVAILABLE, available ? 1 : 0);
+ sendMessage(obtainMessage(CMD_SET_NETWORK_AVAILABLE, available ? 1 : 0, 0));
}
/********************************************************