Merge "Replace hard-coded 3 by FCC_2 to simplify searches"
diff --git a/api/current.txt b/api/current.txt
index 0603a63..6fdd161 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -23119,6 +23119,7 @@
method public void addOnLayoutChangeListener(android.view.View.OnLayoutChangeListener);
method public void addTouchables(java.util.ArrayList<android.view.View>);
method public android.view.ViewPropertyAnimator animate();
+ method public void announceForAccessibility(java.lang.CharSequence);
method protected boolean awakenScrollBars();
method protected boolean awakenScrollBars(int);
method protected boolean awakenScrollBars(int, boolean);
@@ -24343,6 +24344,7 @@
field public static final int INVALID_POSITION = -1; // 0xffffffff
field public static final deprecated int MAX_TEXT_LENGTH = 500; // 0x1f4
field public static final int TYPES_ALL_MASK = -1; // 0xffffffff
+ field public static final int TYPE_ANNOUNCEMENT = 16384; // 0x4000
field public static final int TYPE_NOTIFICATION_STATE_CHANGED = 64; // 0x40
field public static final int TYPE_TOUCH_EXPLORATION_GESTURE_END = 1024; // 0x400
field public static final int TYPE_TOUCH_EXPLORATION_GESTURE_START = 512; // 0x200
@@ -27495,9 +27497,19 @@
ctor public Spinner(android.content.Context, android.util.AttributeSet);
ctor public Spinner(android.content.Context, android.util.AttributeSet, int);
ctor public Spinner(android.content.Context, android.util.AttributeSet, int, int);
+ method public int getDropDownHorizontalOffset();
+ method public int getDropDownVerticalOffset();
+ method public int getDropDownWidth();
+ method public int getGravity();
+ method public android.graphics.drawable.Drawable getPopupBackground();
method public java.lang.CharSequence getPrompt();
method public void onClick(android.content.DialogInterface, int);
+ method public void setDropDownHorizontalOffset(int);
+ method public void setDropDownVerticalOffset(int);
+ method public void setDropDownWidth(int);
method public void setGravity(int);
+ method public void setPopupBackgroundDrawable(android.graphics.drawable.Drawable);
+ method public void setPopupBackgroundResource(int);
method public void setPrompt(java.lang.CharSequence);
method public void setPromptId(int);
field public static final int MODE_DIALOG = 0; // 0x0
@@ -27518,14 +27530,26 @@
ctor public Switch(android.content.Context);
ctor public Switch(android.content.Context, android.util.AttributeSet);
ctor public Switch(android.content.Context, android.util.AttributeSet, int);
+ method public int getSwitchMinWidth();
+ method public int getSwitchPadding();
method public java.lang.CharSequence getTextOff();
method public java.lang.CharSequence getTextOn();
+ method public android.graphics.drawable.Drawable getThumbDrawable();
+ method public int getThumbTextPadding();
+ method public android.graphics.drawable.Drawable getTrackDrawable();
method public void onMeasure(int, int);
+ method public void setSwitchMinWidth(int);
+ method public void setSwitchPadding(int);
method public void setSwitchTextAppearance(android.content.Context, int);
method public void setSwitchTypeface(android.graphics.Typeface, int);
method public void setSwitchTypeface(android.graphics.Typeface);
method public void setTextOff(java.lang.CharSequence);
method public void setTextOn(java.lang.CharSequence);
+ method public void setThumbDrawable(android.graphics.drawable.Drawable);
+ method public void setThumbResource(int);
+ method public void setThumbTextPadding(int);
+ method public void setTrackDrawable(android.graphics.drawable.Drawable);
+ method public void setTrackResource(int);
}
public class TabHost extends android.widget.FrameLayout implements android.view.ViewTreeObserver.OnTouchModeChangeListener {
diff --git a/cmds/stagefright/codec.cpp b/cmds/stagefright/codec.cpp
index 0414b98..fea62cc 100644
--- a/cmds/stagefright/codec.cpp
+++ b/cmds/stagefright/codec.cpp
@@ -49,6 +49,7 @@
size_t mCSDIndex;
Vector<sp<ABuffer> > mInBuffers;
Vector<sp<ABuffer> > mOutBuffers;
+ bool mSignalledInputEOS;
bool mSawOutputEOS;
int64_t mNumBuffersDecoded;
int64_t mNumBytesDecoded;
@@ -127,6 +128,7 @@
}
state->mCSDIndex = 0;
+ state->mSignalledInputEOS = false;
state->mSawOutputEOS = false;
ALOGV("got %d pieces of codec specific data.", state->mCSD.size());
@@ -180,33 +182,7 @@
status_t err = extractor->getSampleTrackIndex(&trackIndex);
if (err != OK) {
- ALOGV("signalling EOS.");
-
- for (size_t i = 0; i < stateByTrack.size(); ++i) {
- CodecState *state = &stateByTrack.editValueAt(i);
-
- for (;;) {
- size_t index;
- err = state->mCodec->dequeueInputBuffer(&index, kTimeout);
-
- if (err == -EAGAIN) {
- continue;
- }
-
- CHECK_EQ(err, (status_t)OK);
-
- err = state->mCodec->queueInputBuffer(
- index,
- 0 /* offset */,
- 0 /* size */,
- 0ll /* timeUs */,
- MediaCodec::BUFFER_FLAG_EOS);
-
- CHECK_EQ(err, (status_t)OK);
- break;
- }
- }
-
+ ALOGV("saw input eos");
sawInputEOS = true;
} else {
CodecState *state = &stateByTrack.editValueFor(trackIndex);
@@ -240,6 +216,33 @@
CHECK_EQ(err, -EAGAIN);
}
}
+ } else {
+ for (size_t i = 0; i < stateByTrack.size(); ++i) {
+ CodecState *state = &stateByTrack.editValueAt(i);
+
+ if (!state->mSignalledInputEOS) {
+ size_t index;
+ status_t err =
+ state->mCodec->dequeueInputBuffer(&index, kTimeout);
+
+ if (err == OK) {
+ ALOGV("signalling input EOS on track %d", i);
+
+ err = state->mCodec->queueInputBuffer(
+ index,
+ 0 /* offset */,
+ 0 /* size */,
+ 0ll /* timeUs */,
+ MediaCodec::BUFFER_FLAG_EOS);
+
+ CHECK_EQ(err, (status_t)OK);
+
+ state->mSignalledInputEOS = true;
+ } else {
+ CHECK_EQ(err, -EAGAIN);
+ }
+ }
+ }
}
bool sawOutputEOSOnAllTracks = true;
diff --git a/core/java/android/animation/ValueAnimator.java b/core/java/android/animation/ValueAnimator.java
index 6fbeee3..954ae66 100755
--- a/core/java/android/animation/ValueAnimator.java
+++ b/core/java/android/animation/ValueAnimator.java
@@ -645,7 +645,7 @@
// onAnimate to process the next frame of the animations.
if (!mAnimationScheduled
&& (!mAnimations.isEmpty() || !mDelayedAnims.isEmpty())) {
- mChoreographer.postAnimationCallback(this);
+ mChoreographer.postAnimationCallback(this, null);
mAnimationScheduled = true;
}
}
diff --git a/core/java/android/os/FileUtils.java b/core/java/android/os/FileUtils.java
index 215e836..6c1445d 100644
--- a/core/java/android/os/FileUtils.java
+++ b/core/java/android/os/FileUtils.java
@@ -28,6 +28,8 @@
import java.util.zip.CRC32;
import java.util.zip.CheckedInputStream;
+import libcore.io.Os;
+import libcore.io.StructStat;
/**
* Tools for managing files. Not for public consumption.
@@ -52,8 +54,10 @@
/**
* File status information. This class maps directly to the POSIX stat structure.
+ * @deprecated use {@link StructStat} instead.
* @hide
*/
+ @Deprecated
public static final class FileStatus {
public int dev;
public int ino;
@@ -77,7 +81,9 @@
* exists.
* @return true if the file exists and false if it does not exist. If you do not have
* permission to stat the file, then this method will return false.
+ * @deprecated use {@link Os#stat(String)} instead.
*/
+ @Deprecated
public static boolean getFileStatus(String path, FileStatus status) {
StrictMode.noteDiskRead();
return getFileStatusNative(path, status);
@@ -90,6 +96,10 @@
public static native int setPermissions(String file, int mode, int uid, int gid);
+ /**
+ * @deprecated use {@link Os#stat(String)} instead.
+ */
+ @Deprecated
public static native int getPermissions(String file, int[] outPermissions);
public static native int setUMask(int mask);
diff --git a/core/java/android/os/Parcel.java b/core/java/android/os/Parcel.java
index 15e3af4..1507387 100644
--- a/core/java/android/os/Parcel.java
+++ b/core/java/android/os/Parcel.java
@@ -180,9 +180,14 @@
private static final String TAG = "Parcel";
@SuppressWarnings({"UnusedDeclaration"})
- private int mObject; // used by native code
- @SuppressWarnings({"UnusedDeclaration"})
- private int mOwnObject; // used by native code
+ private int mNativePtr; // used by native code
+
+ /**
+ * Flag indicating if {@link #mNativePtr} was allocated by this object,
+ * indicating that we're responsible for its lifecycle.
+ */
+ private boolean mOwnsNativeParcelObject;
+
private RuntimeException mStack;
private static final int POOL_SIZE = 6;
@@ -224,6 +229,48 @@
private static final int EX_ILLEGAL_STATE = -5;
private static final int EX_HAS_REPLY_HEADER = -128; // special; see below
+ private static native int nativeDataSize(int nativePtr);
+ private static native int nativeDataAvail(int nativePtr);
+ private static native int nativeDataPosition(int nativePtr);
+ private static native int nativeDataCapacity(int nativePtr);
+ private static native void nativeSetDataSize(int nativePtr, int size);
+ private static native void nativeSetDataPosition(int nativePtr, int pos);
+ private static native void nativeSetDataCapacity(int nativePtr, int size);
+
+ private static native boolean nativePushAllowFds(int nativePtr, boolean allowFds);
+ private static native void nativeRestoreAllowFds(int nativePtr, boolean lastValue);
+
+ private static native void nativeWriteByteArray(int nativePtr, byte[] b, int offset, int len);
+ private static native void nativeWriteInt(int nativePtr, int val);
+ private static native void nativeWriteLong(int nativePtr, long val);
+ private static native void nativeWriteFloat(int nativePtr, float val);
+ private static native void nativeWriteDouble(int nativePtr, double val);
+ private static native void nativeWriteString(int nativePtr, String val);
+ private static native void nativeWriteStrongBinder(int nativePtr, IBinder val);
+ private static native void nativeWriteFileDescriptor(int nativePtr, FileDescriptor val);
+
+ private static native byte[] nativeCreateByteArray(int nativePtr);
+ private static native int nativeReadInt(int nativePtr);
+ private static native long nativeReadLong(int nativePtr);
+ private static native float nativeReadFloat(int nativePtr);
+ private static native double nativeReadDouble(int nativePtr);
+ private static native String nativeReadString(int nativePtr);
+ private static native IBinder nativeReadStrongBinder(int nativePtr);
+ private static native FileDescriptor nativeReadFileDescriptor(int nativePtr);
+
+ private static native int nativeCreate();
+ private static native void nativeFreeBuffer(int nativePtr);
+ private static native void nativeDestroy(int nativePtr);
+
+ private static native byte[] nativeMarshall(int nativePtr);
+ private static native void nativeUnmarshall(
+ int nativePtr, byte[] data, int offest, int length);
+ private static native void nativeAppendFrom(
+ int thisNativePtr, int otherNativePtr, int offset, int length);
+ private static native boolean nativeHasFileDescriptors(int nativePtr);
+ private static native void nativeWriteInterfaceToken(int nativePtr, String interfaceName);
+ private static native void nativeEnforceInterface(int nativePtr, String interfaceName);
+
public final static Parcelable.Creator<String> STRING_CREATOR
= new Parcelable.Creator<String>() {
public String createFromParcel(Parcel source) {
@@ -262,7 +309,15 @@
public final void recycle() {
if (DEBUG_RECYCLE) mStack = null;
freeBuffer();
- final Parcel[] pool = mOwnObject != 0 ? sOwnedPool : sHolderPool;
+
+ final Parcel[] pool;
+ if (mOwnsNativeParcelObject) {
+ pool = sOwnedPool;
+ } else {
+ mNativePtr = 0;
+ pool = sHolderPool;
+ }
+
synchronized (pool) {
for (int i=0; i<POOL_SIZE; i++) {
if (pool[i] == null) {
@@ -276,19 +331,25 @@
/**
* Returns the total amount of data contained in the parcel.
*/
- public final native int dataSize();
+ public final int dataSize() {
+ return nativeDataSize(mNativePtr);
+ }
/**
* Returns the amount of data remaining to be read from the
* parcel. That is, {@link #dataSize}-{@link #dataPosition}.
*/
- public final native int dataAvail();
+ public final int dataAvail() {
+ return nativeDataAvail(mNativePtr);
+ }
/**
* Returns the current position in the parcel data. Never
* more than {@link #dataSize}.
*/
- public final native int dataPosition();
+ public final int dataPosition() {
+ return nativeDataPosition(mNativePtr);
+ }
/**
* Returns the total amount of space in the parcel. This is always
@@ -296,7 +357,9 @@
* amount of room left until the parcel needs to re-allocate its
* data buffer.
*/
- public final native int dataCapacity();
+ public final int dataCapacity() {
+ return nativeDataCapacity(mNativePtr);
+ }
/**
* Change the amount of data in the parcel. Can be either smaller or
@@ -305,14 +368,18 @@
*
* @param size The new number of bytes in the Parcel.
*/
- public final native void setDataSize(int size);
+ public final void setDataSize(int size) {
+ nativeSetDataSize(mNativePtr, size);
+ }
/**
* Move the current read/write position in the parcel.
* @param pos New offset in the parcel; must be between 0 and
* {@link #dataSize}.
*/
- public final native void setDataPosition(int pos);
+ public final void setDataPosition(int pos) {
+ nativeSetDataPosition(mNativePtr, pos);
+ }
/**
* Change the capacity (current available space) of the parcel.
@@ -321,13 +388,19 @@
* less than {@link #dataSize} -- that is, you can not drop existing data
* with this method.
*/
- public final native void setDataCapacity(int size);
+ public final void setDataCapacity(int size) {
+ nativeSetDataCapacity(mNativePtr, size);
+ }
/** @hide */
- public final native boolean pushAllowFds(boolean allowFds);
+ public final boolean pushAllowFds(boolean allowFds) {
+ return nativePushAllowFds(mNativePtr, allowFds);
+ }
/** @hide */
- public final native void restoreAllowFds(boolean lastValue);
+ public final void restoreAllowFds(boolean lastValue) {
+ nativeRestoreAllowFds(mNativePtr, lastValue);
+ }
/**
* Returns the raw bytes of the parcel.
@@ -340,27 +413,40 @@
* such does not attempt to maintain compatibility with data created
* in different versions of the platform.
*/
- public final native byte[] marshall();
+ public final byte[] marshall() {
+ return nativeMarshall(mNativePtr);
+ }
/**
* Set the bytes in data to be the raw bytes of this Parcel.
*/
- public final native void unmarshall(byte[] data, int offest, int length);
+ public final void unmarshall(byte[] data, int offest, int length) {
+ nativeUnmarshall(mNativePtr, data, offest, length);
+ }
- public final native void appendFrom(Parcel parcel, int offset, int length);
+ public final void appendFrom(Parcel parcel, int offset, int length) {
+ nativeAppendFrom(mNativePtr, parcel.mNativePtr, offset, length);
+ }
/**
* Report whether the parcel contains any marshalled file descriptors.
*/
- public final native boolean hasFileDescriptors();
+ public final boolean hasFileDescriptors() {
+ return nativeHasFileDescriptors(mNativePtr);
+ }
/**
* Store or read an IBinder interface token in the parcel at the current
* {@link #dataPosition}. This is used to validate that the marshalled
* transaction is intended for the target interface.
*/
- public final native void writeInterfaceToken(String interfaceName);
- public final native void enforceInterface(String interfaceName);
+ public final void writeInterfaceToken(String interfaceName) {
+ nativeWriteInterfaceToken(mNativePtr, interfaceName);
+ }
+
+ public final void enforceInterface(String interfaceName) {
+ nativeEnforceInterface(mNativePtr, interfaceName);
+ }
/**
* Write a byte array into the parcel at the current {@link #dataPosition},
@@ -384,40 +470,48 @@
return;
}
Arrays.checkOffsetAndCount(b.length, offset, len);
- writeNative(b, offset, len);
+ nativeWriteByteArray(mNativePtr, b, offset, len);
}
- private native void writeNative(byte[] b, int offset, int len);
-
/**
* Write an integer value into the parcel at the current dataPosition(),
* growing dataCapacity() if needed.
*/
- public final native void writeInt(int val);
+ public final void writeInt(int val) {
+ nativeWriteInt(mNativePtr, val);
+ }
/**
* Write a long integer value into the parcel at the current dataPosition(),
* growing dataCapacity() if needed.
*/
- public final native void writeLong(long val);
+ public final void writeLong(long val) {
+ nativeWriteLong(mNativePtr, val);
+ }
/**
* Write a floating point value into the parcel at the current
* dataPosition(), growing dataCapacity() if needed.
*/
- public final native void writeFloat(float val);
+ public final void writeFloat(float val) {
+ nativeWriteFloat(mNativePtr, val);
+ }
/**
* Write a double precision floating point value into the parcel at the
* current dataPosition(), growing dataCapacity() if needed.
*/
- public final native void writeDouble(double val);
+ public final void writeDouble(double val) {
+ nativeWriteDouble(mNativePtr, val);
+ }
/**
* Write a string value into the parcel at the current dataPosition(),
* growing dataCapacity() if needed.
*/
- public final native void writeString(String val);
+ public final void writeString(String val) {
+ nativeWriteString(mNativePtr, val);
+ }
/**
* Write a CharSequence value into the parcel at the current dataPosition(),
@@ -432,7 +526,9 @@
* Write an object into the parcel at the current dataPosition(),
* growing dataCapacity() if needed.
*/
- public final native void writeStrongBinder(IBinder val);
+ public final void writeStrongBinder(IBinder val) {
+ nativeWriteStrongBinder(mNativePtr, val);
+ }
/**
* Write an object into the parcel at the current dataPosition(),
@@ -452,7 +548,9 @@
* accepts contextual flags and will close the original file descriptor
* if {@link Parcelable#PARCELABLE_WRITE_RETURN_VALUE} is set.</p>
*/
- public final native void writeFileDescriptor(FileDescriptor val);
+ public final void writeFileDescriptor(FileDescriptor val) {
+ nativeWriteFileDescriptor(mNativePtr, val);
+ }
/**
* Write an byte value into the parcel at the current dataPosition(),
@@ -1341,29 +1439,39 @@
/**
* Read an integer value from the parcel at the current dataPosition().
*/
- public final native int readInt();
+ public final int readInt() {
+ return nativeReadInt(mNativePtr);
+ }
/**
* Read a long integer value from the parcel at the current dataPosition().
*/
- public final native long readLong();
+ public final long readLong() {
+ return nativeReadLong(mNativePtr);
+ }
/**
* Read a floating point value from the parcel at the current
* dataPosition().
*/
- public final native float readFloat();
+ public final float readFloat() {
+ return nativeReadFloat(mNativePtr);
+ }
/**
* Read a double precision floating point value from the parcel at the
* current dataPosition().
*/
- public final native double readDouble();
+ public final double readDouble() {
+ return nativeReadDouble(mNativePtr);
+ }
/**
* Read a string value from the parcel at the current dataPosition().
*/
- public final native String readString();
+ public final String readString() {
+ return nativeReadString(mNativePtr);
+ }
/**
* Read a CharSequence value from the parcel at the current dataPosition().
@@ -1376,17 +1484,18 @@
/**
* Read an object from the parcel at the current dataPosition().
*/
- public final native IBinder readStrongBinder();
+ public final IBinder readStrongBinder() {
+ return nativeReadStrongBinder(mNativePtr);
+ }
/**
* Read a FileDescriptor from the parcel at the current dataPosition().
*/
public final ParcelFileDescriptor readFileDescriptor() {
- FileDescriptor fd = internalReadFileDescriptor();
+ FileDescriptor fd = nativeReadFileDescriptor(mNativePtr);
return fd != null ? new ParcelFileDescriptor(fd) : null;
}
- private native FileDescriptor internalReadFileDescriptor();
/*package*/ static native FileDescriptor openFileDescriptor(String file,
int mode) throws FileNotFoundException;
/*package*/ static native FileDescriptor dupFileDescriptor(FileDescriptor orig)
@@ -1471,7 +1580,9 @@
/**
* Read and return a byte[] object from the parcel.
*/
- public final native byte[] createByteArray();
+ public final byte[] createByteArray() {
+ return nativeCreateByteArray(mNativePtr);
+ }
/**
* Read a byte[] object from the parcel and copy it into the
@@ -2065,12 +2176,37 @@
return new Parcel(obj);
}
- private Parcel(int obj) {
+ private Parcel(int nativePtr) {
if (DEBUG_RECYCLE) {
mStack = new RuntimeException();
}
//Log.i(TAG, "Initializing obj=0x" + Integer.toHexString(obj), mStack);
- init(obj);
+ init(nativePtr);
+ }
+
+ private void init(int nativePtr) {
+ if (nativePtr != 0) {
+ mNativePtr = nativePtr;
+ mOwnsNativeParcelObject = false;
+ } else {
+ mNativePtr = nativeCreate();
+ mOwnsNativeParcelObject = true;
+ }
+ }
+
+ private void freeBuffer() {
+ if (mOwnsNativeParcelObject) {
+ nativeFreeBuffer(mNativePtr);
+ }
+ }
+
+ private void destroy() {
+ if (mNativePtr != 0) {
+ if (mOwnsNativeParcelObject) {
+ nativeDestroy(mNativePtr);
+ }
+ mNativePtr = 0;
+ }
}
@Override
@@ -2083,10 +2219,6 @@
destroy();
}
- private native void freeBuffer();
- private native void init(int obj);
- private native void destroy();
-
/* package */ void readMapInternal(Map outVal, int N,
ClassLoader loader) {
while (N > 0) {
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index bc6594b..fbb3273 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -3129,6 +3129,14 @@
"wifi_watchdog_arp_interval_ms";
/**
+ * ms delay interval between rssi polling when the signal is known to be weak
+ * @hide
+ */
+ public static final String WIFI_WATCHDOG_RSSI_FETCH_INTERVAL_MS =
+ "wifi_watchdog_rssi_fetch_interval_ms";
+
+
+ /**
* ms delay before rechecking a connect SSID for walled garden with a http download.
* @hide
*/
diff --git a/core/java/android/view/Choreographer.java b/core/java/android/view/Choreographer.java
index f4d7af9..10edc06 100644
--- a/core/java/android/view/Choreographer.java
+++ b/core/java/android/view/Choreographer.java
@@ -81,8 +81,8 @@
private static final int MSG_DO_ANIMATION = 0;
private static final int MSG_DO_DRAW = 1;
private static final int MSG_DO_SCHEDULE_VSYNC = 2;
- private static final int MSG_POST_DELAYED_ANIMATION = 3;
- private static final int MSG_POST_DELAYED_DRAW = 4;
+ private static final int MSG_DO_SCHEDULE_ANIMATION = 3;
+ private static final int MSG_DO_SCHEDULE_DRAW = 4;
private final Object mLock = new Object();
@@ -152,134 +152,158 @@
}
/**
+ * Subtracts typical frame delay time from a delay interval in milliseconds.
+ *
+ * This method can be used to compensate for animation delay times that have baked
+ * in assumptions about the frame delay. For example, it's quite common for code to
+ * assume a 60Hz frame time and bake in a 16ms delay. When we call
+ * {@link #postAnimationCallbackDelayed} we want to know how long to wait before
+ * posting the animation callback but let the animation timer take care of the remaining
+ * frame delay time.
+ *
+ * This method is somewhat conservative about how much of the frame delay it
+ * subtracts. It uses the same value returned by {@link #getFrameDelay} which by
+ * default is 10ms even though many parts of the system assume 16ms. Consequently,
+ * we might still wait 6ms before posting an animation callback that we want to run
+ * on the next frame, but this is much better than waiting a whole 16ms and likely
+ * missing the deadline.
+ *
+ * @param delayMillis The original delay time including an assumed frame delay.
+ * @return The adjusted delay time with the assumed frame delay subtracted out.
+ */
+ public static long subtractFrameDelay(long delayMillis) {
+ final long frameDelay = sFrameDelay;
+ return delayMillis <= frameDelay ? 0 : delayMillis - frameDelay;
+ }
+
+ /**
* Posts a callback to run on the next animation cycle.
* The callback only runs once and then is automatically removed.
*
- * @param runnable The callback to run during the next animation cycle.
+ * @param action The callback action to run during the next animation cycle.
+ * @param token The callback token, or null if none.
*
* @see #removeAnimationCallback
*/
- public void postAnimationCallback(Runnable runnable) {
- if (runnable == null) {
- throw new IllegalArgumentException("runnable must not be null");
- }
- postAnimationCallbackUnchecked(runnable);
- }
-
- private void postAnimationCallbackUnchecked(Runnable runnable) {
- synchronized (mLock) {
- mAnimationCallbacks = addCallbackLocked(mAnimationCallbacks, runnable);
- scheduleAnimationLocked();
- }
+ public void postAnimationCallback(Runnable action, Object token) {
+ postAnimationCallbackDelayed(action, token, 0);
}
/**
* Posts a callback to run on the next animation cycle following the specified delay.
* The callback only runs once and then is automatically removed.
*
- * @param runnable The callback to run during the next animation cycle following
+ * @param action The callback action to run during the next animation cycle after
* the specified delay.
+ * @param token The callback token, or null if none.
* @param delayMillis The delay time in milliseconds.
*
* @see #removeAnimationCallback
*/
- public void postAnimationCallbackDelayed(Runnable runnable, long delayMillis) {
- if (runnable == null) {
- throw new IllegalArgumentException("runnable must not be null");
+ public void postAnimationCallbackDelayed(Runnable action, Object token, long delayMillis) {
+ if (action == null) {
+ throw new IllegalArgumentException("action must not be null");
}
- if (delayMillis <= 0) {
- postAnimationCallbackUnchecked(runnable);
- } else {
- Message msg = mHandler.obtainMessage(MSG_POST_DELAYED_ANIMATION, runnable);
- mHandler.sendMessageDelayed(msg, delayMillis);
+
+ synchronized (mLock) {
+ final long now = SystemClock.uptimeMillis();
+ final long dueTime = now + delayMillis;
+ mAnimationCallbacks = addCallbackLocked(mAnimationCallbacks, dueTime, action, token);
+
+ if (dueTime <= now) {
+ scheduleAnimationLocked(now);
+ } else {
+ Message msg = mHandler.obtainMessage(MSG_DO_SCHEDULE_ANIMATION, action);
+ mHandler.sendMessageAtTime(msg, dueTime);
+ }
}
}
/**
- * Removes animation callbacks for the specified runnable.
- * Does nothing if the specified animation callback has not been posted or has already
- * been removed.
+ * Removes animation callbacks that have the specified action and token.
*
- * @param runnable The animation callback to remove.
+ * @param action The action property of the callbacks to remove, or null to remove
+ * callbacks with any action.
+ * @param token The token property of the callbacks to remove, or null to remove
+ * callbacks with any token.
*
* @see #postAnimationCallback
* @see #postAnimationCallbackDelayed
*/
- public void removeAnimationCallbacks(Runnable runnable) {
- if (runnable == null) {
- throw new IllegalArgumentException("runnable must not be null");
- }
+ public void removeAnimationCallbacks(Runnable action, Object token) {
synchronized (mLock) {
- mAnimationCallbacks = removeCallbacksLocked(mAnimationCallbacks, runnable);
+ mAnimationCallbacks = removeCallbacksLocked(mAnimationCallbacks, action, token);
+ if (action != null && token == null) {
+ mHandler.removeMessages(MSG_DO_SCHEDULE_ANIMATION, action);
+ }
}
- mHandler.removeMessages(MSG_POST_DELAYED_ANIMATION, runnable);
}
/**
* Posts a callback to run on the next draw cycle.
* The callback only runs once and then is automatically removed.
*
- * @param runnable The callback to run during the next draw cycle.
+ * @param action The callback action to run during the next draw cycle.
+ * @param token The callback token, or null if none.
*
* @see #removeDrawCallback
*/
- public void postDrawCallback(Runnable runnable) {
- if (runnable == null) {
- throw new IllegalArgumentException("runnable must not be null");
- }
- postDrawCallbackUnchecked(runnable);
- }
-
- private void postDrawCallbackUnchecked(Runnable runnable) {
- synchronized (mLock) {
- mDrawCallbacks = addCallbackLocked(mDrawCallbacks, runnable);
- scheduleDrawLocked();
- }
+ public void postDrawCallback(Runnable action, Object token) {
+ postDrawCallbackDelayed(action, token, 0);
}
/**
* Posts a callback to run on the next draw cycle following the specified delay.
* The callback only runs once and then is automatically removed.
*
- * @param runnable The callback to run during the next draw cycle following
+ * @param action The callback action to run during the next animation cycle after
* the specified delay.
+ * @param token The callback token, or null if none.
* @param delayMillis The delay time in milliseconds.
*
* @see #removeDrawCallback
*/
- public void postDrawCallbackDelayed(Runnable runnable, long delayMillis) {
- if (runnable == null) {
- throw new IllegalArgumentException("runnable must not be null");
+ public void postDrawCallbackDelayed(Runnable action, Object token, long delayMillis) {
+ if (action == null) {
+ throw new IllegalArgumentException("action must not be null");
}
- if (delayMillis <= 0) {
- postDrawCallbackUnchecked(runnable);
- } else {
- Message msg = mHandler.obtainMessage(MSG_POST_DELAYED_DRAW, runnable);
- mHandler.sendMessageDelayed(msg, delayMillis);
+
+ synchronized (mLock) {
+ final long now = SystemClock.uptimeMillis();
+ final long dueTime = now + delayMillis;
+ mDrawCallbacks = addCallbackLocked(mDrawCallbacks, dueTime, action, token);
+ scheduleDrawLocked(now);
+
+ if (dueTime <= now) {
+ scheduleDrawLocked(now);
+ } else {
+ Message msg = mHandler.obtainMessage(MSG_DO_SCHEDULE_DRAW, action);
+ mHandler.sendMessageAtTime(msg, dueTime);
+ }
}
}
/**
- * Removes draw callbacks for the specified runnable.
- * Does nothing if the specified draw callback has not been posted or has already
- * been removed.
+ * Removes draw callbacks that have the specified action and token.
*
- * @param runnable The draw callback to remove.
+ * @param action The action property of the callbacks to remove, or null to remove
+ * callbacks with any action.
+ * @param token The token property of the callbacks to remove, or null to remove
+ * callbacks with any token.
*
* @see #postDrawCallback
* @see #postDrawCallbackDelayed
*/
- public void removeDrawCallbacks(Runnable runnable) {
- if (runnable == null) {
- throw new IllegalArgumentException("runnable must not be null");
- }
+ public void removeDrawCallbacks(Runnable action, Object token) {
synchronized (mLock) {
- mDrawCallbacks = removeCallbacksLocked(mDrawCallbacks, runnable);
+ mDrawCallbacks = removeCallbacksLocked(mDrawCallbacks, action, token);
+ if (action != null && token == null) {
+ mHandler.removeMessages(MSG_DO_SCHEDULE_DRAW, action);
+ }
}
- mHandler.removeMessages(MSG_POST_DELAYED_DRAW, runnable);
}
- private void scheduleAnimationLocked() {
+ private void scheduleAnimationLocked(long now) {
if (!mAnimationScheduled) {
mAnimationScheduled = true;
if (USE_VSYNC) {
@@ -291,14 +315,13 @@
// otherwise post a message to schedule the vsync from the UI thread
// as soon as possible.
if (isRunningOnLooperThreadLocked()) {
- doScheduleVsyncLocked();
+ scheduleVsyncLocked();
} else {
Message msg = mHandler.obtainMessage(MSG_DO_SCHEDULE_VSYNC);
msg.setAsynchronous(true);
mHandler.sendMessageAtFrontOfQueue(msg);
}
} else {
- final long now = SystemClock.uptimeMillis();
final long nextAnimationTime = Math.max(mLastAnimationTime + sFrameDelay, now);
if (DEBUG) {
Log.d(TAG, "Scheduling animation in " + (nextAnimationTime - now) + " ms.");
@@ -310,18 +333,18 @@
}
}
- private void scheduleDrawLocked() {
+ private void scheduleDrawLocked(long now) {
if (!mDrawScheduled) {
mDrawScheduled = true;
if (USE_ANIMATION_TIMER_FOR_DRAW) {
- scheduleAnimationLocked();
+ scheduleAnimationLocked(now);
} else {
if (DEBUG) {
Log.d(TAG, "Scheduling draw immediately.");
}
Message msg = mHandler.obtainMessage(MSG_DO_DRAW);
msg.setAsynchronous(true);
- mHandler.sendMessage(msg);
+ mHandler.sendMessageAtTime(msg, now);
}
}
}
@@ -336,7 +359,7 @@
void doAnimationInner() {
final long start;
- final Callback callbacks;
+ Callback callbacks;
synchronized (mLock) {
if (!mAnimationScheduled) {
return; // no work to do
@@ -351,7 +374,23 @@
mLastAnimationTime = start;
callbacks = mAnimationCallbacks;
- mAnimationCallbacks = null;
+ if (callbacks != null) {
+ if (callbacks.dueTime > start) {
+ callbacks = null;
+ } else {
+ Callback predecessor = callbacks;
+ Callback successor = predecessor.next;
+ while (successor != null) {
+ if (successor.dueTime > start) {
+ predecessor.next = null;
+ break;
+ }
+ predecessor = successor;
+ successor = successor.next;
+ }
+ mAnimationCallbacks = successor;
+ }
+ }
}
if (callbacks != null) {
@@ -368,7 +407,7 @@
void doDraw() {
final long start;
- final Callback callbacks;
+ Callback callbacks;
synchronized (mLock) {
if (!mDrawScheduled) {
return; // no work to do
@@ -383,7 +422,23 @@
mLastDrawTime = start;
callbacks = mDrawCallbacks;
- mDrawCallbacks = null;
+ if (callbacks != null) {
+ if (callbacks.dueTime > start) {
+ callbacks = null;
+ } else {
+ Callback predecessor = callbacks;
+ Callback successor = predecessor.next;
+ while (successor != null) {
+ if (successor.dueTime > start) {
+ predecessor.next = null;
+ break;
+ }
+ predecessor = successor;
+ successor = successor.next;
+ }
+ mDrawCallbacks = successor;
+ }
+ }
}
if (callbacks != null) {
@@ -400,38 +455,66 @@
void doScheduleVsync() {
synchronized (mLock) {
- doScheduleVsyncLocked();
+ if (mAnimationScheduled) {
+ scheduleVsyncLocked();
+ }
}
}
- private void doScheduleVsyncLocked() {
- if (mAnimationScheduled) {
- mDisplayEventReceiver.scheduleVsync();
+ void doScheduleAnimation() {
+ synchronized (mLock) {
+ final long now = SystemClock.uptimeMillis();
+ if (mAnimationCallbacks != null && mAnimationCallbacks.dueTime <= now) {
+ scheduleAnimationLocked(now);
+ }
}
}
+ void doScheduleDraw() {
+ synchronized (mLock) {
+ final long now = SystemClock.uptimeMillis();
+ if (mDrawCallbacks != null && mDrawCallbacks.dueTime <= now) {
+ scheduleDrawLocked(now);
+ }
+ }
+ }
+
+ private void scheduleVsyncLocked() {
+ mDisplayEventReceiver.scheduleVsync();
+ }
+
private boolean isRunningOnLooperThreadLocked() {
return Looper.myLooper() == mLooper;
}
- private Callback addCallbackLocked(Callback head, Runnable runnable) {
- Callback callback = obtainCallbackLocked(runnable);
+ private Callback addCallbackLocked(Callback head,
+ long dueTime, Runnable action, Object token) {
+ Callback callback = obtainCallbackLocked(dueTime, action, token);
if (head == null) {
return callback;
}
- Callback tail = head;
- while (tail.next != null) {
- tail = tail.next;
+ Callback entry = head;
+ if (dueTime < entry.dueTime) {
+ callback.next = entry;
+ return callback;
}
- tail.next = callback;
+ while (entry.next != null) {
+ if (dueTime < entry.next.dueTime) {
+ callback.next = entry.next;
+ break;
+ }
+ entry = entry.next;
+ }
+ entry.next = callback;
return head;
}
- private Callback removeCallbacksLocked(Callback head, Runnable runnable) {
+ private Callback removeCallbacksLocked(Callback head, Runnable action, Object token) {
Callback predecessor = null;
for (Callback callback = head; callback != null;) {
final Callback next = callback.next;
- if (callback.runnable == runnable) {
+ if ((action == null || callback.action == action)
+ && (token == null || callback.token == token)) {
if (predecessor != null) {
predecessor.next = next;
} else {
@@ -448,7 +531,7 @@
private void runCallbacks(Callback head) {
while (head != null) {
- head.runnable.run();
+ head.action.run();
head = head.next;
}
}
@@ -461,7 +544,7 @@
}
}
- private Callback obtainCallbackLocked(Runnable runnable) {
+ private Callback obtainCallbackLocked(long dueTime, Runnable action, Object token) {
Callback callback = mCallbackPool;
if (callback == null) {
callback = new Callback();
@@ -469,12 +552,15 @@
mCallbackPool = callback.next;
callback.next = null;
}
- callback.runnable = runnable;
+ callback.dueTime = dueTime;
+ callback.action = action;
+ callback.token = token;
return callback;
}
private void recycleCallbackLocked(Callback callback) {
- callback.runnable = null;
+ callback.action = null;
+ callback.token = null;
callback.next = mCallbackPool;
mCallbackPool = callback;
}
@@ -496,11 +582,11 @@
case MSG_DO_SCHEDULE_VSYNC:
doScheduleVsync();
break;
- case MSG_POST_DELAYED_ANIMATION:
- postAnimationCallbackUnchecked((Runnable)msg.obj);
+ case MSG_DO_SCHEDULE_ANIMATION:
+ doScheduleAnimation();
break;
- case MSG_POST_DELAYED_DRAW:
- postDrawCallbackUnchecked((Runnable)msg.obj);
+ case MSG_DO_SCHEDULE_DRAW:
+ doScheduleDraw();
break;
}
}
@@ -519,6 +605,8 @@
private static final class Callback {
public Callback next;
- public Runnable runnable;
+ public long dueTime;
+ public Runnable action;
+ public Object token;
}
}
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index b38ca5b..7ab79ff 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -3952,6 +3952,24 @@
}
/**
+ * Convenience method for sending a {@link AccessibilityEvent#TYPE_ANNOUNCEMENT}
+ * {@link AccessibilityEvent} to make an announcement which is related to some
+ * sort of a context change for which none of the events representing UI transitions
+ * is a good fit. For example, announcing a new page in a book. If accessibility
+ * is not enabled this method does nothing.
+ *
+ * @param text The announcement text.
+ */
+ public void announceForAccessibility(CharSequence text) {
+ if (AccessibilityManager.getInstance(mContext).isEnabled()) {
+ AccessibilityEvent event = AccessibilityEvent.obtain(
+ AccessibilityEvent.TYPE_ANNOUNCEMENT);
+ event.getText().add(text);
+ sendAccessibilityEventUnchecked(event);
+ }
+ }
+
+ /**
* @see #sendAccessibilityEvent(int)
*
* Note: Called from the default {@link AccessibilityDelegate}.
@@ -8793,6 +8811,52 @@
}
/**
+ * <p>Causes the Runnable to execute on the next animation time step.
+ * The runnable will be run on the user interface thread.</p>
+ *
+ * <p>This method can be invoked from outside of the UI thread
+ * only when this View is attached to a window.</p>
+ *
+ * @param action The Runnable that will be executed.
+ *
+ * @hide
+ */
+ public void postOnAnimation(Runnable action) {
+ final AttachInfo attachInfo = mAttachInfo;
+ if (attachInfo != null) {
+ attachInfo.mViewRootImpl.mChoreographer.postAnimationCallback(action, null);
+ } else {
+ // Assume that post will succeed later
+ ViewRootImpl.getRunQueue().post(action);
+ }
+ }
+
+ /**
+ * <p>Causes the Runnable to execute on the next animation time step,
+ * after the specified amount of time elapses.
+ * The runnable will be run on the user interface thread.</p>
+ *
+ * <p>This method can be invoked from outside of the UI thread
+ * only when this View is attached to a window.</p>
+ *
+ * @param action The Runnable that will be executed.
+ * @param delayMillis The delay (in milliseconds) until the Runnable
+ * will be executed.
+ *
+ * @hide
+ */
+ public void postOnAnimationDelayed(Runnable action, long delayMillis) {
+ final AttachInfo attachInfo = mAttachInfo;
+ if (attachInfo != null) {
+ attachInfo.mViewRootImpl.mChoreographer.postAnimationCallbackDelayed(
+ action, null, delayMillis);
+ } else {
+ // Assume that post will succeed later
+ ViewRootImpl.getRunQueue().postDelayed(action, delayMillis);
+ }
+ }
+
+ /**
* <p>Removes the specified Runnable from the message queue.</p>
*
* <p>This method can be invoked from outside of the UI thread
@@ -8809,6 +8873,7 @@
final AttachInfo attachInfo = mAttachInfo;
if (attachInfo != null) {
attachInfo.mHandler.removeCallbacks(action);
+ attachInfo.mViewRootImpl.mChoreographer.removeAnimationCallbacks(action, null);
} else {
// Assume that post will succeed later
ViewRootImpl.getRunQueue().removeCallbacks(action);
@@ -11880,10 +11945,12 @@
*/
public void scheduleDrawable(Drawable who, Runnable what, long when) {
if (verifyDrawable(who) && what != null) {
+ final long delay = when - SystemClock.uptimeMillis();
if (mAttachInfo != null) {
- mAttachInfo.mHandler.postAtTime(what, who, when);
+ mAttachInfo.mViewRootImpl.mChoreographer.postAnimationCallbackDelayed(
+ what, who, Choreographer.subtractFrameDelay(delay));
} else {
- ViewRootImpl.getRunQueue().postDelayed(what, when - SystemClock.uptimeMillis());
+ ViewRootImpl.getRunQueue().postDelayed(what, delay);
}
}
}
@@ -11897,7 +11964,7 @@
public void unscheduleDrawable(Drawable who, Runnable what) {
if (verifyDrawable(who) && what != null) {
if (mAttachInfo != null) {
- mAttachInfo.mHandler.removeCallbacks(what, who);
+ mAttachInfo.mViewRootImpl.mChoreographer.removeAnimationCallbacks(what, who);
} else {
ViewRootImpl.getRunQueue().removeCallbacks(what);
}
@@ -11915,7 +11982,7 @@
*/
public void unscheduleDrawable(Drawable who) {
if (mAttachInfo != null) {
- mAttachInfo.mHandler.removeCallbacksAndMessages(who);
+ mAttachInfo.mViewRootImpl.mChoreographer.removeAnimationCallbacks(null, who);
}
}
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 9cde153..72365c7 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -884,7 +884,7 @@
void scheduleFrame() {
if (!mFrameScheduled) {
mFrameScheduled = true;
- mChoreographer.postDrawCallback(mFrameRunnable);
+ mChoreographer.postDrawCallback(mFrameRunnable, null);
}
}
@@ -893,7 +893,7 @@
if (mFrameScheduled) {
mFrameScheduled = false;
- mChoreographer.removeDrawCallbacks(mFrameRunnable);
+ mChoreographer.removeDrawCallbacks(mFrameRunnable, null);
}
}
@@ -4051,7 +4051,7 @@
}
if (mPosted && mViews.isEmpty() && mViewRects.isEmpty()) {
- mChoreographer.removeAnimationCallbacks(this);
+ mChoreographer.removeAnimationCallbacks(this, null);
mPosted = false;
}
}
@@ -4092,7 +4092,7 @@
private void postIfNeededLocked() {
if (!mPosted) {
- mChoreographer.postAnimationCallback(this);
+ mChoreographer.postAnimationCallback(this, null);
mPosted = true;
}
}
diff --git a/core/java/android/view/accessibility/AccessibilityEvent.java b/core/java/android/view/accessibility/AccessibilityEvent.java
index 75b875a..58844fc 100644
--- a/core/java/android/view/accessibility/AccessibilityEvent.java
+++ b/core/java/android/view/accessibility/AccessibilityEvent.java
@@ -429,6 +429,26 @@
* view.</br>
* </p>
* <p>
+ * <b>MISCELLANEOUS TYPES</b></br>
+ * </p>
+ * <p>
+ * <b>Announcement</b> - represents the event of an application making an
+ * announcement. Usually this announcement is related to some sort of a context
+ * change for which none of the events representing UI transitions is a good fit.
+ * For example, announcing a new page in a book.</br>
+ * <em>Type:</em> {@link #TYPE_ANNOUNCEMENT}</br>
+ * <em>Properties:</em></br>
+ * <ul>
+ * <li>{@link #getEventType()} - The type of the event.</li>
+ * <li>{@link #getSource()} - The source info (for registered clients).</li>
+ * <li>{@link #getClassName()} - The class name of the source.</li>
+ * <li>{@link #getPackageName()} - The package name of the source.</li>
+ * <li>{@link #getEventTime()} - The event time.</li>
+ * <li>{@link #getText()} - The text of the announcement.</li>
+ * <li>{@link #isEnabled()} - Whether the source is enabled.</li>
+ * </ul>
+ * </p>
+ * <p>
* <b>Security note</b>
* <p>
* Since an event contains the text of its source privacy can be compromised by leaking
@@ -538,6 +558,11 @@
public static final int TYPE_VIEW_TEXT_SELECTION_CHANGED = 0x00002000;
/**
+ * Represents the event of an application making an announcement.
+ */
+ public static final int TYPE_ANNOUNCEMENT = 0x00004000;
+
+ /**
* Mask for {@link AccessibilityEvent} all types.
*
* @see #TYPE_VIEW_CLICKED
@@ -554,6 +579,7 @@
* @see #TYPE_WINDOW_CONTENT_CHANGED
* @see #TYPE_VIEW_SCROLLED
* @see #TYPE_VIEW_TEXT_SELECTION_CHANGED
+ * @see #TYPE_ANNOUNCEMENT
*/
public static final int TYPES_ALL_MASK = 0xFFFFFFFF;
@@ -984,6 +1010,8 @@
return "TYPE_VIEW_TEXT_SELECTION_CHANGED";
case TYPE_VIEW_SCROLLED:
return "TYPE_VIEW_SCROLLED";
+ case TYPE_ANNOUNCEMENT:
+ return "TYPE_ANNOUNCEMENT";
default:
return null;
}
diff --git a/core/java/android/webkit/WebViewClassic.java b/core/java/android/webkit/WebViewClassic.java
index 72aed4b..af011a1b 100644
--- a/core/java/android/webkit/WebViewClassic.java
+++ b/core/java/android/webkit/WebViewClassic.java
@@ -3896,6 +3896,7 @@
// helper to pin the scrollTo parameters (already in view coordinates)
// returns true if the scroll was changed
private boolean pinScrollTo(int x, int y, boolean animate, int animationDuration) {
+ abortAnimation();
x = pinLocX(x);
y = pinLocY(y);
int dx = x - getScrollX();
@@ -3904,7 +3905,6 @@
if ((dx | dy) == 0) {
return false;
}
- abortAnimation();
if (animate) {
// Log.d(LOGTAG, "startScroll: " + dx + " " + dy);
mScroller.startScroll(getScrollX(), getScrollY(), dx, dy,
@@ -4176,9 +4176,9 @@
// is used in the view system.
return;
}
- int vx = contentToViewX(cx);
- int vy = contentToViewY(cy);
- pinScrollTo(vx, vy, true, 0);
+ int vx = contentToViewDimension(cx - mScrollOffset.x);
+ int vy = contentToViewDimension(cy - mScrollOffset.y);
+ pinScrollBy(vx, vy, true, 0);
}
/**
diff --git a/core/java/android/widget/CheckedTextView.java b/core/java/android/widget/CheckedTextView.java
index 19fb7b1..233d892 100644
--- a/core/java/android/widget/CheckedTextView.java
+++ b/core/java/android/widget/CheckedTextView.java
@@ -227,16 +227,6 @@
}
@Override
- public void onPopulateAccessibilityEvent(AccessibilityEvent event) {
- super.onPopulateAccessibilityEvent(event);
- if (isChecked()) {
- event.getText().add(mContext.getString(R.string.radiobutton_selected));
- } else {
- event.getText().add(mContext.getString(R.string.radiobutton_not_selected));
- }
- }
-
- @Override
public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
super.onInitializeAccessibilityNodeInfo(info);
info.setClassName(CheckedTextView.class.getName());
diff --git a/core/java/android/widget/RadioButton.java b/core/java/android/widget/RadioButton.java
index b6dac3e..b1bb1c0 100644
--- a/core/java/android/widget/RadioButton.java
+++ b/core/java/android/widget/RadioButton.java
@@ -78,16 +78,6 @@
}
@Override
- public void onPopulateAccessibilityEvent(AccessibilityEvent event) {
- super.onPopulateAccessibilityEvent(event);
- if (isChecked()) {
- event.getText().add(mContext.getString(R.string.radiobutton_selected));
- } else {
- event.getText().add(mContext.getString(R.string.radiobutton_not_selected));
- }
- }
-
- @Override
public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
super.onInitializeAccessibilityEvent(event);
event.setClassName(RadioButton.class.getName());
diff --git a/core/java/android/widget/Spinner.java b/core/java/android/widget/Spinner.java
index 6540613..aef8a34 100644
--- a/core/java/android/widget/Spinner.java
+++ b/core/java/android/widget/Spinner.java
@@ -26,6 +26,7 @@
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
+import android.util.Log;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
@@ -202,6 +203,130 @@
}
}
+ /**
+ * Set the background drawable for the spinner's popup window of choices.
+ * Only valid in {@link #MODE_DROPDOWN}; this method is a no-op in other modes.
+ *
+ * @param background Background drawable
+ *
+ * @attr ref android.R.styleable#Spinner_popupBackground
+ */
+ public void setPopupBackgroundDrawable(Drawable background) {
+ if (!(mPopup instanceof DropdownPopup)) {
+ Log.e(TAG, "setPopupBackgroundDrawable: incompatible spinner mode; ignoring...");
+ return;
+ }
+ ((DropdownPopup) mPopup).setBackgroundDrawable(background);
+ }
+
+ /**
+ * Set the background drawable for the spinner's popup window of choices.
+ * Only valid in {@link #MODE_DROPDOWN}; this method is a no-op in other modes.
+ *
+ * @param resId Resource ID of a background drawable
+ *
+ * @attr ref android.R.styleable#Spinner_popupBackground
+ */
+ public void setPopupBackgroundResource(int resId) {
+ setPopupBackgroundDrawable(getContext().getResources().getDrawable(resId));
+ }
+
+ /**
+ * Get the background drawable for the spinner's popup window of choices.
+ * Only valid in {@link #MODE_DROPDOWN}; other modes will return null.
+ *
+ * @return background Background drawable
+ *
+ * @attr ref android.R.styleable#Spinner_popupBackground
+ */
+ public Drawable getPopupBackground() {
+ return mPopup.getBackground();
+ }
+
+ /**
+ * Set a vertical offset in pixels for the spinner's popup window of choices.
+ * Only valid in {@link #MODE_DROPDOWN}; this method is a no-op in other modes.
+ *
+ * @param pixels Vertical offset in pixels
+ *
+ * @attr ref android.R.styleable#Spinner_dropDownVerticalOffset
+ */
+ public void setDropDownVerticalOffset(int pixels) {
+ mPopup.setVerticalOffset(pixels);
+ }
+
+ /**
+ * Get the configured vertical offset in pixels for the spinner's popup window of choices.
+ * Only valid in {@link #MODE_DROPDOWN}; other modes will return 0.
+ *
+ * @return Vertical offset in pixels
+ *
+ * @attr ref android.R.styleable#Spinner_dropDownVerticalOffset
+ */
+ public int getDropDownVerticalOffset() {
+ return mPopup.getVerticalOffset();
+ }
+
+ /**
+ * Set a horizontal offset in pixels for the spinner's popup window of choices.
+ * Only valid in {@link #MODE_DROPDOWN}; this method is a no-op in other modes.
+ *
+ * @param pixels Horizontal offset in pixels
+ *
+ * @attr ref android.R.styleable#Spinner_dropDownHorizontalOffset
+ */
+ public void setDropDownHorizontalOffset(int pixels) {
+ mPopup.setHorizontalOffset(pixels);
+ }
+
+ /**
+ * Get the configured horizontal offset in pixels for the spinner's popup window of choices.
+ * Only valid in {@link #MODE_DROPDOWN}; other modes will return 0.
+ *
+ * @return Horizontal offset in pixels
+ *
+ * @attr ref android.R.styleable#Spinner_dropDownHorizontalOffset
+ */
+ public int getDropDownHorizontalOffset() {
+ return mPopup.getHorizontalOffset();
+ }
+
+ /**
+ * Set the width of the spinner's popup window of choices in pixels. This value
+ * may also be set to {@link android.view.ViewGroup.LayoutParams#MATCH_PARENT}
+ * to match the width of the Spinner itself, or
+ * {@link android.view.ViewGroup.LayoutParams#WRAP_CONTENT} to wrap to the measured size
+ * of contained dropdown list items.
+ *
+ * <p>Only valid in {@link #MODE_DROPDOWN}; this method is a no-op in other modes.</p>
+ *
+ * @param pixels Width in pixels, WRAP_CONTENT, or MATCH_PARENT
+ *
+ * @attr ref android.R.styleable#Spinner_dropDownWidth
+ */
+ public void setDropDownWidth(int pixels) {
+ if (!(mPopup instanceof DropdownPopup)) {
+ Log.e(TAG, "Cannot set dropdown width for MODE_DIALOG, ignoring");
+ return;
+ }
+ mDropDownWidth = pixels;
+ }
+
+ /**
+ * Get the configured width of the spinner's popup window of choices in pixels.
+ * The returned value may also be {@link android.view.ViewGroup.LayoutParams#MATCH_PARENT}
+ * meaning the popup window will match the width of the Spinner itself, or
+ * {@link android.view.ViewGroup.LayoutParams#WRAP_CONTENT} to wrap to the measured size
+ * of contained dropdown list items.
+ *
+ * @return Width in pixels, WRAP_CONTENT, or MATCH_PARENT
+ *
+ * @attr ref android.R.styleable#Spinner_dropDownWidth
+ */
+ public int getDropDownWidth() {
+ return mDropDownWidth;
+ }
+
@Override
public void setEnabled(boolean enabled) {
super.setEnabled(enabled);
@@ -231,6 +356,16 @@
}
}
+ /**
+ * Describes how the selected item view is positioned. The default is determined by the
+ * current theme.
+ *
+ * @return A {@link android.view.Gravity Gravity} value
+ */
+ public int getGravity() {
+ return mGravity;
+ }
+
@Override
public void setAdapter(SpinnerAdapter adapter) {
super.setAdapter(adapter);
@@ -675,6 +810,13 @@
*/
public void setPromptText(CharSequence hintText);
public CharSequence getHintText();
+
+ public void setBackgroundDrawable(Drawable bg);
+ public void setVerticalOffset(int px);
+ public void setHorizontalOffset(int px);
+ public Drawable getBackground();
+ public int getVerticalOffset();
+ public int getHorizontalOffset();
}
private class DialogPopup implements SpinnerPopup, DialogInterface.OnClickListener {
@@ -719,6 +861,36 @@
}
dismiss();
}
+
+ @Override
+ public void setBackgroundDrawable(Drawable bg) {
+ Log.e(TAG, "Cannot set popup background for MODE_DIALOG, ignoring");
+ }
+
+ @Override
+ public void setVerticalOffset(int px) {
+ Log.e(TAG, "Cannot set vertical offset for MODE_DIALOG, ignoring");
+ }
+
+ @Override
+ public void setHorizontalOffset(int px) {
+ Log.e(TAG, "Cannot set horizontal offset for MODE_DIALOG, ignoring");
+ }
+
+ @Override
+ public Drawable getBackground() {
+ return null;
+ }
+
+ @Override
+ public int getVerticalOffset() {
+ return 0;
+ }
+
+ @Override
+ public int getHorizontalOffset() {
+ return 0;
+ }
}
private class DropdownPopup extends ListPopupWindow implements SpinnerPopup {
diff --git a/core/java/android/widget/Switch.java b/core/java/android/widget/Switch.java
index 334b9c4..a897cc3 100644
--- a/core/java/android/widget/Switch.java
+++ b/core/java/android/widget/Switch.java
@@ -169,6 +169,8 @@
/**
* Sets the switch text color, size, style, hint color, and highlight color
* from the specified TextAppearance resource.
+ *
+ * @attr ref android.R.styleable#Switch_switchTextAppearance
*/
public void setSwitchTextAppearance(Context context, int resid) {
TypedArray appearance =
@@ -274,7 +276,151 @@
}
/**
+ * Set the amount of horizontal padding between the switch and the associated text.
+ *
+ * @param pixels Amount of padding in pixels
+ *
+ * @attr ref android.R.styleable#Switch_switchPadding
+ */
+ public void setSwitchPadding(int pixels) {
+ mSwitchPadding = pixels;
+ requestLayout();
+ }
+
+ /**
+ * Get the amount of horizontal padding between the switch and the associated text.
+ *
+ * @return Amount of padding in pixels
+ *
+ * @attr ref android.R.styleable#Switch_switchPadding
+ */
+ public int getSwitchPadding() {
+ return mSwitchPadding;
+ }
+
+ /**
+ * Set the minimum width of the switch in pixels. The switch's width will be the maximum
+ * of this value and its measured width as determined by the switch drawables and text used.
+ *
+ * @param pixels Minimum width of the switch in pixels
+ *
+ * @attr ref android.R.styleable#Switch_switchMinWidth
+ */
+ public void setSwitchMinWidth(int pixels) {
+ mSwitchMinWidth = pixels;
+ requestLayout();
+ }
+
+ /**
+ * Get the minimum width of the switch in pixels. The switch's width will be the maximum
+ * of this value and its measured width as determined by the switch drawables and text used.
+ *
+ * @return Minimum width of the switch in pixels
+ *
+ * @attr ref android.R.styleable#Switch_switchMinWidth
+ */
+ public int getSwitchMinWidth() {
+ return mSwitchMinWidth;
+ }
+
+ /**
+ * Set the horizontal padding around the text drawn on the switch itself.
+ *
+ * @param pixels Horizontal padding for switch thumb text in pixels
+ *
+ * @attr ref android.R.styleable#Switch_thumbTextPadding
+ */
+ public void setThumbTextPadding(int pixels) {
+ mThumbTextPadding = pixels;
+ requestLayout();
+ }
+
+ /**
+ * Get the horizontal padding around the text drawn on the switch itself.
+ *
+ * @return Horizontal padding for switch thumb text in pixels
+ *
+ * @attr ref android.R.styleable#Switch_thumbTextPadding
+ */
+ public int getThumbTextPadding() {
+ return mThumbTextPadding;
+ }
+
+ /**
+ * Set the drawable used for the track that the switch slides within.
+ *
+ * @param track Track drawable
+ *
+ * @attr ref android.R.styleable#Switch_track
+ */
+ public void setTrackDrawable(Drawable track) {
+ mTrackDrawable = track;
+ requestLayout();
+ }
+
+ /**
+ * Set the drawable used for the track that the switch slides within.
+ *
+ * @param resId Resource ID of a track drawable
+ *
+ * @attr ref android.R.styleable#Switch_track
+ */
+ public void setTrackResource(int resId) {
+ setTrackDrawable(getContext().getResources().getDrawable(resId));
+ }
+
+ /**
+ * Get the drawable used for the track that the switch slides within.
+ *
+ * @return Track drawable
+ *
+ * @attr ref android.R.styleable#Switch_track
+ */
+ public Drawable getTrackDrawable() {
+ return mTrackDrawable;
+ }
+
+ /**
+ * Set the drawable used for the switch "thumb" - the piece that the user
+ * can physically touch and drag along the track.
+ *
+ * @param thumb Thumb drawable
+ *
+ * @attr ref android.R.styleable#Switch_thumb
+ */
+ public void setThumbDrawable(Drawable thumb) {
+ mThumbDrawable = thumb;
+ requestLayout();
+ }
+
+ /**
+ * Set the drawable used for the switch "thumb" - the piece that the user
+ * can physically touch and drag along the track.
+ *
+ * @param resId Resource ID of a thumb drawable
+ *
+ * @attr ref android.R.styleable#Switch_thumb
+ */
+ public void setThumbResource(int resId) {
+ setThumbDrawable(getContext().getResources().getDrawable(resId));
+ }
+
+ /**
+ * Get the drawable used for the switch "thumb" - the piece that the user
+ * can physically touch and drag along the track.
+ *
+ * @return Thumb drawable
+ *
+ * @attr ref android.R.styleable#Switch_thumb
+ */
+ public Drawable getThumbDrawable() {
+ return mThumbDrawable;
+ }
+
+ /**
* Returns the text displayed when the button is in the checked state.
+ *
+ * @attr ref android.R.styleable#Switch_textOn
*/
public CharSequence getTextOn() {
return mTextOn;
@@ -282,6 +428,8 @@
/**
* Sets the text displayed when the button is in the checked state.
+ *
+ * @attr ref android.R.styleable#Switch_textOn
*/
public void setTextOn(CharSequence textOn) {
mTextOn = textOn;
@@ -290,6 +438,8 @@
/**
* Returns the text displayed when the button is not in the checked state.
+ *
+ * @attr ref android.R.styleable#Switch_textOff
*/
public CharSequence getTextOff() {
return mTextOff;
@@ -297,6 +447,8 @@
/**
* Sets the text displayed when the button is not in the checked state.
+ *
+ * @attr ref android.R.styleable#Switch_textOff
*/
public void setTextOff(CharSequence textOff) {
mTextOff = textOff;
@@ -367,17 +519,8 @@
@Override
public void onPopulateAccessibilityEvent(AccessibilityEvent event) {
super.onPopulateAccessibilityEvent(event);
- if (isChecked()) {
- CharSequence text = mOnLayout.getText();
- if (TextUtils.isEmpty(text)) {
- text = mContext.getString(R.string.switch_on);
- }
- event.getText().add(text);
- } else {
- CharSequence text = mOffLayout.getText();
- if (TextUtils.isEmpty(text)) {
- text = mContext.getString(R.string.switch_off);
- }
+ CharSequence text = isChecked() ? mOnLayout.getText() : mOffLayout.getText();
+ if (!TextUtils.isEmpty(text)) {
event.getText().add(text);
}
}
diff --git a/core/java/android/widget/ToggleButton.java b/core/java/android/widget/ToggleButton.java
index a0edafe..4beee96 100644
--- a/core/java/android/widget/ToggleButton.java
+++ b/core/java/android/widget/ToggleButton.java
@@ -154,16 +154,6 @@
}
@Override
- public void onPopulateAccessibilityEvent(AccessibilityEvent event) {
- super.onPopulateAccessibilityEvent(event);
- if (isChecked()) {
- event.getText().add(mContext.getString(R.string.togglebutton_pressed));
- } else {
- event.getText().add(mContext.getString(R.string.togglebutton_not_pressed));
- }
- }
-
- @Override
public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
super.onInitializeAccessibilityEvent(event);
event.setClassName(ToggleButton.class.getName());
diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java
index 6a99a2b..998c037 100644
--- a/core/java/com/android/internal/os/ZygoteInit.java
+++ b/core/java/com/android/internal/os/ZygoteInit.java
@@ -348,6 +348,7 @@
TypedArray ar = mResources.obtainTypedArray(
com.android.internal.R.array.preloaded_drawables);
int N = preloadDrawables(runtime, ar);
+ ar.recycle();
Log.i(TAG, "...preloaded " + N + " resources in "
+ (SystemClock.uptimeMillis()-startTime) + "ms.");
@@ -355,6 +356,7 @@
ar = mResources.obtainTypedArray(
com.android.internal.R.array.preloaded_color_state_lists);
N = preloadColorStateLists(runtime, ar);
+ ar.recycle();
Log.i(TAG, "...preloaded " + N + " resources in "
+ (SystemClock.uptimeMillis()-startTime) + "ms.");
}
diff --git a/core/jni/Android.mk b/core/jni/Android.mk
index c389cf7..642988b 100644
--- a/core/jni/Android.mk
+++ b/core/jni/Android.mk
@@ -64,6 +64,7 @@
android_os_MemoryFile.cpp \
android_os_MessageQueue.cpp \
android_os_ParcelFileDescriptor.cpp \
+ android_os_Parcel.cpp \
android_os_Power.cpp \
android_os_StatFs.cpp \
android_os_SystemClock.cpp \
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index 3067e75..de9fd33 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -130,6 +130,7 @@
extern int register_android_text_format_Time(JNIEnv* env);
extern int register_android_os_Debug(JNIEnv* env);
extern int register_android_os_MessageQueue(JNIEnv* env);
+extern int register_android_os_Parcel(JNIEnv* env);
extern int register_android_os_ParcelFileDescriptor(JNIEnv *env);
extern int register_android_os_Power(JNIEnv *env);
extern int register_android_os_StatFs(JNIEnv *env);
@@ -1094,6 +1095,7 @@
REG_JNI(register_android_os_Process),
REG_JNI(register_android_os_SystemProperties),
REG_JNI(register_android_os_Binder),
+ REG_JNI(register_android_os_Parcel),
REG_JNI(register_android_view_Display),
REG_JNI(register_android_view_DisplayEventReceiver),
REG_JNI(register_android_nio_utils),
diff --git a/core/jni/android/graphics/Bitmap.cpp b/core/jni/android/graphics/Bitmap.cpp
index d1d3b78..5e73a5f 100644
--- a/core/jni/android/graphics/Bitmap.cpp
+++ b/core/jni/android/graphics/Bitmap.cpp
@@ -7,6 +7,7 @@
#include "SkUnPreMultiply.h"
#include <binder/Parcel.h>
+#include "android_os_Parcel.h"
#include "android_util_Binder.h"
#include "android_nio_utils.h"
#include "CreateJavaOutputStreamAdaptor.h"
diff --git a/core/jni/android/graphics/Region.cpp b/core/jni/android/graphics/Region.cpp
index 5c6ebdf..866d223 100644
--- a/core/jni/android/graphics/Region.cpp
+++ b/core/jni/android/graphics/Region.cpp
@@ -19,6 +19,7 @@
#include "GraphicsJNI.h"
#include <binder/Parcel.h>
+#include "android_os_Parcel.h"
#include "android_util_Binder.h"
#include <jni.h>
diff --git a/core/jni/android_database_CursorWindow.cpp b/core/jni/android_database_CursorWindow.cpp
index 579d6ad..ea02f53 100644
--- a/core/jni/android_database_CursorWindow.cpp
+++ b/core/jni/android_database_CursorWindow.cpp
@@ -31,6 +31,7 @@
#include <unistd.h>
#include <androidfw/CursorWindow.h>
+#include "android_os_Parcel.h"
#include "android_util_Binder.h"
#include "android_database_SQLiteCommon.h"
diff --git a/core/jni/android_os_Parcel.cpp b/core/jni/android_os_Parcel.cpp
new file mode 100644
index 0000000..3dfaac3
--- /dev/null
+++ b/core/jni/android_os_Parcel.cpp
@@ -0,0 +1,676 @@
+/*
+ * Copyright (C) 2012 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.
+ */
+
+#define LOG_TAG "Parcel"
+//#define LOG_NDEBUG 0
+
+#include "android_os_Parcel.h"
+#include "android_util_Binder.h"
+
+#include "JNIHelp.h"
+
+#include <fcntl.h>
+#include <stdio.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <utils/Atomic.h>
+#include <binder/IInterface.h>
+#include <binder/IPCThreadState.h>
+#include <utils/Log.h>
+#include <utils/SystemClock.h>
+#include <utils/List.h>
+#include <utils/KeyedVector.h>
+#include <cutils/logger.h>
+#include <binder/Parcel.h>
+#include <binder/ProcessState.h>
+#include <binder/IServiceManager.h>
+#include <utils/threads.h>
+#include <utils/String8.h>
+
+#include <ScopedUtfChars.h>
+#include <ScopedLocalRef.h>
+
+#include <android_runtime/AndroidRuntime.h>
+
+//#undef ALOGV
+//#define ALOGV(...) fprintf(stderr, __VA_ARGS__)
+
+#define DEBUG_DEATH 0
+#if DEBUG_DEATH
+#define LOGDEATH ALOGD
+#else
+#define LOGDEATH ALOGV
+#endif
+
+namespace android {
+
+static struct parcel_offsets_t
+{
+ jfieldID mNativePtr;
+} gParcelOffsets;
+
+Parcel* parcelForJavaObject(JNIEnv* env, jobject obj)
+{
+ if (obj) {
+ Parcel* p = (Parcel*)env->GetIntField(obj, gParcelOffsets.mNativePtr);
+ if (p != NULL) {
+ return p;
+ }
+ jniThrowException(env, "java/lang/IllegalStateException", "Parcel has been finalized!");
+ }
+ return NULL;
+}
+
+static jint android_os_Parcel_dataSize(JNIEnv* env, jclass clazz, jint nativePtr)
+{
+ Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
+ return parcel ? parcel->dataSize() : 0;
+}
+
+static jint android_os_Parcel_dataAvail(JNIEnv* env, jclass clazz, jint nativePtr)
+{
+ Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
+ return parcel ? parcel->dataAvail() : 0;
+}
+
+static jint android_os_Parcel_dataPosition(JNIEnv* env, jclass clazz, jint nativePtr)
+{
+ Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
+ return parcel ? parcel->dataPosition() : 0;
+}
+
+static jint android_os_Parcel_dataCapacity(JNIEnv* env, jclass clazz, jint nativePtr)
+{
+ Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
+ return parcel ? parcel->dataCapacity() : 0;
+}
+
+static void android_os_Parcel_setDataSize(JNIEnv* env, jclass clazz, jint nativePtr, jint size)
+{
+ Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
+ if (parcel != NULL) {
+ const status_t err = parcel->setDataSize(size);
+ if (err != NO_ERROR) {
+ signalExceptionForError(env, clazz, err);
+ }
+ }
+}
+
+static void android_os_Parcel_setDataPosition(JNIEnv* env, jclass clazz, jint nativePtr, jint pos)
+{
+ Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
+ if (parcel != NULL) {
+ parcel->setDataPosition(pos);
+ }
+}
+
+static void android_os_Parcel_setDataCapacity(JNIEnv* env, jclass clazz, jint nativePtr, jint size)
+{
+ Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
+ if (parcel != NULL) {
+ const status_t err = parcel->setDataCapacity(size);
+ if (err != NO_ERROR) {
+ signalExceptionForError(env, clazz, err);
+ }
+ }
+}
+
+static jboolean android_os_Parcel_pushAllowFds(JNIEnv* env, jclass clazz, jint nativePtr, jboolean allowFds)
+{
+ Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
+ jboolean ret = JNI_TRUE;
+ if (parcel != NULL) {
+ ret = (jboolean)parcel->pushAllowFds(allowFds);
+ }
+ return ret;
+}
+
+static void android_os_Parcel_restoreAllowFds(JNIEnv* env, jclass clazz, jint nativePtr, jboolean lastValue)
+{
+ Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
+ if (parcel != NULL) {
+ parcel->restoreAllowFds((bool)lastValue);
+ }
+}
+
+static void android_os_Parcel_writeNative(JNIEnv* env, jclass clazz, jint nativePtr, jobject data,
+ jint offset, jint length)
+{
+ Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
+ if (parcel == NULL) {
+ return;
+ }
+
+ const status_t err = parcel->writeInt32(length);
+ if (err != NO_ERROR) {
+ signalExceptionForError(env, clazz, err);
+ return;
+ }
+
+ void* dest = parcel->writeInplace(length);
+ if (dest == NULL) {
+ signalExceptionForError(env, clazz, NO_MEMORY);
+ return;
+ }
+
+ jbyte* ar = (jbyte*)env->GetPrimitiveArrayCritical((jarray)data, 0);
+ if (ar) {
+ memcpy(dest, ar + offset, length);
+ env->ReleasePrimitiveArrayCritical((jarray)data, ar, 0);
+ }
+}
+
+static void android_os_Parcel_writeInt(JNIEnv* env, jclass clazz, jint nativePtr, jint val) {
+ Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
+ const status_t err = parcel->writeInt32(val);
+ if (err != NO_ERROR) {
+ signalExceptionForError(env, clazz, err);
+ }
+}
+
+static void android_os_Parcel_writeLong(JNIEnv* env, jclass clazz, jint nativePtr, jlong val)
+{
+ Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
+ if (parcel != NULL) {
+ const status_t err = parcel->writeInt64(val);
+ if (err != NO_ERROR) {
+ signalExceptionForError(env, clazz, err);
+ }
+ }
+}
+
+static void android_os_Parcel_writeFloat(JNIEnv* env, jclass clazz, jint nativePtr, jfloat val)
+{
+ Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
+ if (parcel != NULL) {
+ const status_t err = parcel->writeFloat(val);
+ if (err != NO_ERROR) {
+ signalExceptionForError(env, clazz, err);
+ }
+ }
+}
+
+static void android_os_Parcel_writeDouble(JNIEnv* env, jclass clazz, jint nativePtr, jdouble val)
+{
+ Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
+ if (parcel != NULL) {
+ const status_t err = parcel->writeDouble(val);
+ if (err != NO_ERROR) {
+ signalExceptionForError(env, clazz, err);
+ }
+ }
+}
+
+static void android_os_Parcel_writeString(JNIEnv* env, jclass clazz, jint nativePtr, jstring val)
+{
+ Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
+ if (parcel != NULL) {
+ status_t err = NO_MEMORY;
+ if (val) {
+ const jchar* str = env->GetStringCritical(val, 0);
+ if (str) {
+ err = parcel->writeString16(str, env->GetStringLength(val));
+ env->ReleaseStringCritical(val, str);
+ }
+ } else {
+ err = parcel->writeString16(NULL, 0);
+ }
+ if (err != NO_ERROR) {
+ signalExceptionForError(env, clazz, err);
+ }
+ }
+}
+
+static void android_os_Parcel_writeStrongBinder(JNIEnv* env, jclass clazz, jint nativePtr, jobject object)
+{
+ Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
+ if (parcel != NULL) {
+ const status_t err = parcel->writeStrongBinder(ibinderForJavaObject(env, object));
+ if (err != NO_ERROR) {
+ signalExceptionForError(env, clazz, err);
+ }
+ }
+}
+
+static void android_os_Parcel_writeFileDescriptor(JNIEnv* env, jclass clazz, jint nativePtr, jobject object)
+{
+ Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
+ if (parcel != NULL) {
+ const status_t err =
+ parcel->writeDupFileDescriptor(jniGetFDFromFileDescriptor(env, object));
+ if (err != NO_ERROR) {
+ signalExceptionForError(env, clazz, err);
+ }
+ }
+}
+
+static jbyteArray android_os_Parcel_createByteArray(JNIEnv* env, jclass clazz, jint nativePtr)
+{
+ jbyteArray ret = NULL;
+
+ Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
+ if (parcel != NULL) {
+ int32_t len = parcel->readInt32();
+
+ // sanity check the stored length against the true data size
+ if (len >= 0 && len <= (int32_t)parcel->dataAvail()) {
+ ret = env->NewByteArray(len);
+
+ if (ret != NULL) {
+ jbyte* a2 = (jbyte*)env->GetPrimitiveArrayCritical(ret, 0);
+ if (a2) {
+ const void* data = parcel->readInplace(len);
+ memcpy(a2, data, len);
+ env->ReleasePrimitiveArrayCritical(ret, a2, 0);
+ }
+ }
+ }
+ }
+
+ return ret;
+}
+
+static jint android_os_Parcel_readInt(JNIEnv* env, jclass clazz, jint nativePtr)
+{
+ Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
+ if (parcel != NULL) {
+ return parcel->readInt32();
+ }
+ return 0;
+}
+
+static jlong android_os_Parcel_readLong(JNIEnv* env, jclass clazz, jint nativePtr)
+{
+ Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
+ if (parcel != NULL) {
+ return parcel->readInt64();
+ }
+ return 0;
+}
+
+static jfloat android_os_Parcel_readFloat(JNIEnv* env, jclass clazz, jint nativePtr)
+{
+ Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
+ if (parcel != NULL) {
+ return parcel->readFloat();
+ }
+ return 0;
+}
+
+static jdouble android_os_Parcel_readDouble(JNIEnv* env, jclass clazz, jint nativePtr)
+{
+ Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
+ if (parcel != NULL) {
+ return parcel->readDouble();
+ }
+ return 0;
+}
+
+static jstring android_os_Parcel_readString(JNIEnv* env, jclass clazz, jint nativePtr)
+{
+ Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
+ if (parcel != NULL) {
+ size_t len;
+ const char16_t* str = parcel->readString16Inplace(&len);
+ if (str) {
+ return env->NewString(str, len);
+ }
+ return NULL;
+ }
+ return NULL;
+}
+
+static jobject android_os_Parcel_readStrongBinder(JNIEnv* env, jclass clazz, jint nativePtr)
+{
+ Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
+ if (parcel != NULL) {
+ return javaObjectForIBinder(env, parcel->readStrongBinder());
+ }
+ return NULL;
+}
+
+static jobject android_os_Parcel_readFileDescriptor(JNIEnv* env, jclass clazz, jint nativePtr)
+{
+ Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
+ if (parcel != NULL) {
+ int fd = parcel->readFileDescriptor();
+ if (fd < 0) return NULL;
+ fd = dup(fd);
+ if (fd < 0) return NULL;
+ return jniCreateFileDescriptor(env, fd);
+ }
+ return NULL;
+}
+
+static jobject android_os_Parcel_openFileDescriptor(JNIEnv* env, jclass clazz,
+ jstring name, jint mode)
+{
+ if (name == NULL) {
+ jniThrowNullPointerException(env, NULL);
+ return NULL;
+ }
+ const jchar* str = env->GetStringCritical(name, 0);
+ if (str == NULL) {
+ // Whatever, whatever.
+ jniThrowException(env, "java/lang/IllegalStateException", NULL);
+ return NULL;
+ }
+ String8 name8(str, env->GetStringLength(name));
+ env->ReleaseStringCritical(name, str);
+ int flags=0;
+ switch (mode&0x30000000) {
+ case 0:
+ case 0x10000000:
+ flags = O_RDONLY;
+ break;
+ case 0x20000000:
+ flags = O_WRONLY;
+ break;
+ case 0x30000000:
+ flags = O_RDWR;
+ break;
+ }
+
+ if (mode&0x08000000) flags |= O_CREAT;
+ if (mode&0x04000000) flags |= O_TRUNC;
+ if (mode&0x02000000) flags |= O_APPEND;
+
+ int realMode = S_IRWXU|S_IRWXG;
+ if (mode&0x00000001) realMode |= S_IROTH;
+ if (mode&0x00000002) realMode |= S_IWOTH;
+
+ int fd = open(name8.string(), flags, realMode);
+ if (fd < 0) {
+ jniThrowException(env, "java/io/FileNotFoundException", strerror(errno));
+ return NULL;
+ }
+ jobject object = jniCreateFileDescriptor(env, fd);
+ if (object == NULL) {
+ close(fd);
+ }
+ return object;
+}
+
+static jobject android_os_Parcel_dupFileDescriptor(JNIEnv* env, jclass clazz, jobject orig)
+{
+ if (orig == NULL) {
+ jniThrowNullPointerException(env, NULL);
+ return NULL;
+ }
+ int origfd = jniGetFDFromFileDescriptor(env, orig);
+ if (origfd < 0) {
+ jniThrowException(env, "java/lang/IllegalArgumentException", "bad FileDescriptor");
+ return NULL;
+ }
+
+ int fd = dup(origfd);
+ if (fd < 0) {
+ jniThrowIOException(env, errno);
+ return NULL;
+ }
+ jobject object = jniCreateFileDescriptor(env, fd);
+ if (object == NULL) {
+ close(fd);
+ }
+ return object;
+}
+
+static void android_os_Parcel_closeFileDescriptor(JNIEnv* env, jclass clazz, jobject object)
+{
+ if (object == NULL) {
+ jniThrowNullPointerException(env, NULL);
+ return;
+ }
+ int fd = jniGetFDFromFileDescriptor(env, object);
+ if (fd >= 0) {
+ jniSetFileDescriptorOfFD(env, object, -1);
+ //ALOGI("Closing ParcelFileDescriptor %d\n", fd);
+ close(fd);
+ }
+}
+
+static void android_os_Parcel_clearFileDescriptor(JNIEnv* env, jclass clazz, jobject object)
+{
+ if (object == NULL) {
+ jniThrowNullPointerException(env, NULL);
+ return;
+ }
+ int fd = jniGetFDFromFileDescriptor(env, object);
+ if (fd >= 0) {
+ jniSetFileDescriptorOfFD(env, object, -1);
+ }
+}
+
+static jint android_os_Parcel_create(JNIEnv* env, jclass clazz)
+{
+ Parcel* parcel = new Parcel();
+ return reinterpret_cast<jint>(parcel);
+}
+
+static void android_os_Parcel_freeBuffer(JNIEnv* env, jclass clazz, jint nativePtr)
+{
+ Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
+ if (parcel != NULL) {
+ parcel->freeData();
+ }
+}
+
+static void android_os_Parcel_destroy(JNIEnv* env, jclass clazz, jint nativePtr)
+{
+ Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
+ delete parcel;
+}
+
+static jbyteArray android_os_Parcel_marshall(JNIEnv* env, jclass clazz, jint nativePtr)
+{
+ Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
+ if (parcel == NULL) {
+ return NULL;
+ }
+
+ // do not marshall if there are binder objects in the parcel
+ if (parcel->objectsCount())
+ {
+ jniThrowException(env, "java/lang/RuntimeException", "Tried to marshall a Parcel that contained Binder objects.");
+ return NULL;
+ }
+
+ jbyteArray ret = env->NewByteArray(parcel->dataSize());
+
+ if (ret != NULL)
+ {
+ jbyte* array = (jbyte*)env->GetPrimitiveArrayCritical(ret, 0);
+ if (array != NULL)
+ {
+ memcpy(array, parcel->data(), parcel->dataSize());
+ env->ReleasePrimitiveArrayCritical(ret, array, 0);
+ }
+ }
+
+ return ret;
+}
+
+static void android_os_Parcel_unmarshall(JNIEnv* env, jclass clazz, jint nativePtr,
+ jbyteArray data, jint offset, jint length)
+{
+ Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
+ if (parcel == NULL || length < 0) {
+ return;
+ }
+
+ jbyte* array = (jbyte*)env->GetPrimitiveArrayCritical(data, 0);
+ if (array)
+ {
+ parcel->setDataSize(length);
+ parcel->setDataPosition(0);
+
+ void* raw = parcel->writeInplace(length);
+ memcpy(raw, (array + offset), length);
+
+ env->ReleasePrimitiveArrayCritical(data, array, 0);
+ }
+}
+
+static void android_os_Parcel_appendFrom(JNIEnv* env, jclass clazz, jint thisNativePtr,
+ jint otherNativePtr, jint offset, jint length)
+{
+ Parcel* thisParcel = reinterpret_cast<Parcel*>(thisNativePtr);
+ if (thisParcel == NULL) {
+ return;
+ }
+ Parcel* otherParcel = reinterpret_cast<Parcel*>(otherNativePtr);
+ if (otherParcel == NULL) {
+ return;
+ }
+
+ status_t err = thisParcel->appendFrom(otherParcel, offset, length);
+ if (err != NO_ERROR) {
+ signalExceptionForError(env, clazz, err);
+ }
+}
+
+static jboolean android_os_Parcel_hasFileDescriptors(JNIEnv* env, jclass clazz, jint nativePtr)
+{
+ jboolean ret = JNI_FALSE;
+ Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
+ if (parcel != NULL) {
+ if (parcel->hasFileDescriptors()) {
+ ret = JNI_TRUE;
+ }
+ }
+ return ret;
+}
+
+static void android_os_Parcel_writeInterfaceToken(JNIEnv* env, jclass clazz, jint nativePtr,
+ jstring name)
+{
+ Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
+ if (parcel != NULL) {
+ // In the current implementation, the token is just the serialized interface name that
+ // the caller expects to be invoking
+ const jchar* str = env->GetStringCritical(name, 0);
+ if (str != NULL) {
+ parcel->writeInterfaceToken(String16(str, env->GetStringLength(name)));
+ env->ReleaseStringCritical(name, str);
+ }
+ }
+}
+
+static void android_os_Parcel_enforceInterface(JNIEnv* env, jclass clazz, jint nativePtr, jstring name)
+{
+ jboolean ret = JNI_FALSE;
+
+ Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
+ if (parcel != NULL) {
+ const jchar* str = env->GetStringCritical(name, 0);
+ if (str) {
+ IPCThreadState* threadState = IPCThreadState::self();
+ const int32_t oldPolicy = threadState->getStrictModePolicy();
+ const bool isValid = parcel->enforceInterface(
+ String16(str, env->GetStringLength(name)),
+ threadState);
+ env->ReleaseStringCritical(name, str);
+ if (isValid) {
+ const int32_t newPolicy = threadState->getStrictModePolicy();
+ if (oldPolicy != newPolicy) {
+ // Need to keep the Java-level thread-local strict
+ // mode policy in sync for the libcore
+ // enforcements, which involves an upcall back
+ // into Java. (We can't modify the
+ // Parcel.enforceInterface signature, as it's
+ // pseudo-public, and used via AIDL
+ // auto-generation...)
+ set_dalvik_blockguard_policy(env, newPolicy);
+ }
+ return; // everything was correct -> return silently
+ }
+ }
+ }
+
+ // all error conditions wind up here
+ jniThrowException(env, "java/lang/SecurityException",
+ "Binder invocation to an incorrect interface");
+}
+
+// ----------------------------------------------------------------------------
+
+static const JNINativeMethod gParcelMethods[] = {
+ {"nativeDataSize", "(I)I", (void*)android_os_Parcel_dataSize},
+ {"nativeDataAvail", "(I)I", (void*)android_os_Parcel_dataAvail},
+ {"nativeDataPosition", "(I)I", (void*)android_os_Parcel_dataPosition},
+ {"nativeDataCapacity", "(I)I", (void*)android_os_Parcel_dataCapacity},
+ {"nativeSetDataSize", "(II)V", (void*)android_os_Parcel_setDataSize},
+ {"nativeSetDataPosition", "(II)V", (void*)android_os_Parcel_setDataPosition},
+ {"nativeSetDataCapacity", "(II)V", (void*)android_os_Parcel_setDataCapacity},
+
+ {"nativePushAllowFds", "(IZ)Z", (void*)android_os_Parcel_pushAllowFds},
+ {"nativeRestoreAllowFds", "(IZ)V", (void*)android_os_Parcel_restoreAllowFds},
+
+ {"nativeWriteByteArray", "(I[BII)V", (void*)android_os_Parcel_writeNative},
+ {"nativeWriteInt", "(II)V", (void*)android_os_Parcel_writeInt},
+ {"nativeWriteLong", "(IJ)V", (void*)android_os_Parcel_writeLong},
+ {"nativeWriteFloat", "(IF)V", (void*)android_os_Parcel_writeFloat},
+ {"nativeWriteDouble", "(ID)V", (void*)android_os_Parcel_writeDouble},
+ {"nativeWriteString", "(ILjava/lang/String;)V", (void*)android_os_Parcel_writeString},
+ {"nativeWriteStrongBinder", "(ILandroid/os/IBinder;)V", (void*)android_os_Parcel_writeStrongBinder},
+ {"nativeWriteFileDescriptor", "(ILjava/io/FileDescriptor;)V", (void*)android_os_Parcel_writeFileDescriptor},
+
+ {"nativeCreateByteArray", "(I)[B", (void*)android_os_Parcel_createByteArray},
+ {"nativeReadInt", "(I)I", (void*)android_os_Parcel_readInt},
+ {"nativeReadLong", "(I)J", (void*)android_os_Parcel_readLong},
+ {"nativeReadFloat", "(I)F", (void*)android_os_Parcel_readFloat},
+ {"nativeReadDouble", "(I)D", (void*)android_os_Parcel_readDouble},
+ {"nativeReadString", "(I)Ljava/lang/String;", (void*)android_os_Parcel_readString},
+ {"nativeReadStrongBinder", "(I)Landroid/os/IBinder;", (void*)android_os_Parcel_readStrongBinder},
+ {"nativeReadFileDescriptor", "(I)Ljava/io/FileDescriptor;", (void*)android_os_Parcel_readFileDescriptor},
+
+ {"openFileDescriptor", "(Ljava/lang/String;I)Ljava/io/FileDescriptor;", (void*)android_os_Parcel_openFileDescriptor},
+ {"dupFileDescriptor", "(Ljava/io/FileDescriptor;)Ljava/io/FileDescriptor;", (void*)android_os_Parcel_dupFileDescriptor},
+ {"closeFileDescriptor", "(Ljava/io/FileDescriptor;)V", (void*)android_os_Parcel_closeFileDescriptor},
+ {"clearFileDescriptor", "(Ljava/io/FileDescriptor;)V", (void*)android_os_Parcel_clearFileDescriptor},
+
+ {"nativeCreate", "()I", (void*)android_os_Parcel_create},
+ {"nativeFreeBuffer", "(I)V", (void*)android_os_Parcel_freeBuffer},
+ {"nativeDestroy", "(I)V", (void*)android_os_Parcel_destroy},
+
+ {"nativeMarshall", "(I)[B", (void*)android_os_Parcel_marshall},
+ {"nativeUnmarshall", "(I[BII)V", (void*)android_os_Parcel_unmarshall},
+ {"nativeAppendFrom", "(IIII)V", (void*)android_os_Parcel_appendFrom},
+ {"nativeHasFileDescriptors", "(I)Z", (void*)android_os_Parcel_hasFileDescriptors},
+ {"nativeWriteInterfaceToken", "(ILjava/lang/String;)V", (void*)android_os_Parcel_writeInterfaceToken},
+ {"nativeEnforceInterface", "(ILjava/lang/String;)V", (void*)android_os_Parcel_enforceInterface},
+};
+
+const char* const kParcelPathName = "android/os/Parcel";
+
+int register_android_os_Parcel(JNIEnv* env)
+{
+ jclass clazz;
+
+ clazz = env->FindClass(kParcelPathName);
+ LOG_FATAL_IF(clazz == NULL, "Unable to find class android.os.Parcel");
+
+ gParcelOffsets.mNativePtr
+ = env->GetFieldID(clazz, "mNativePtr", "I");
+
+ return AndroidRuntime::registerNativeMethods(
+ env, kParcelPathName,
+ gParcelMethods, NELEM(gParcelMethods));
+}
+
+};
diff --git a/core/jni/android_os_Parcel.h b/core/jni/android_os_Parcel.h
new file mode 100644
index 0000000..65f3819e
--- /dev/null
+++ b/core/jni/android_os_Parcel.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2012 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.
+ */
+
+#include <binder/IBinder.h>
+
+#include "jni.h"
+
+namespace android {
+
+// Conversion from Java Parcel Object to C++ Parcel instance.
+// Note: does not type checking; must guarantee jobject is a Java Parcel
+extern Parcel* parcelForJavaObject(JNIEnv* env, jobject obj);
+
+}
diff --git a/core/jni/android_util_Binder.cpp b/core/jni/android_util_Binder.cpp
index e00970a..0f99fb2 100644
--- a/core/jni/android_util_Binder.cpp
+++ b/core/jni/android_util_Binder.cpp
@@ -17,7 +17,9 @@
#define LOG_TAG "JavaBinder"
//#define LOG_NDEBUG 0
+#include "android_os_Parcel.h"
#include "android_util_Binder.h"
+
#include "JNIHelp.h"
#include <fcntl.h>
@@ -127,12 +129,6 @@
// ----------------------------------------------------------------------------
-static struct parcel_offsets_t
-{
- jfieldID mObject;
- jfieldID mOwnObject;
-} gParcelOffsets;
-
static struct log_offsets_t
{
// Class state.
@@ -232,15 +228,6 @@
env->DeleteLocalRef(msgstr);
}
-static void set_dalvik_blockguard_policy(JNIEnv* env, jint strict_policy)
-{
- // Call back into android.os.StrictMode#onBinderStrictModePolicyChange
- // to sync our state back to it. See the comments in StrictMode.java.
- env->CallStaticVoidMethod(gStrictModeCallbackOffsets.mClass,
- gStrictModeCallbackOffsets.mCallback,
- strict_policy);
-}
-
class JavaBBinderHolder;
class JavaBBinder : public BBinder
@@ -634,26 +621,23 @@
return NULL;
}
-Parcel* parcelForJavaObject(JNIEnv* env, jobject obj)
-{
- if (obj) {
- Parcel* p = (Parcel*)env->GetIntField(obj, gParcelOffsets.mObject);
- if (p != NULL) {
- return p;
- }
- jniThrowException(env, "java/lang/IllegalStateException", "Parcel has been finalized!");
- }
- return NULL;
-}
-
jobject newParcelFileDescriptor(JNIEnv* env, jobject fileDesc)
{
return env->NewObject(
gParcelFileDescriptorOffsets.mClass, gParcelFileDescriptorOffsets.mConstructor, fileDesc);
}
-static void signalExceptionForError(JNIEnv* env, jobject obj, status_t err,
- bool canThrowRemoteException = false)
+void set_dalvik_blockguard_policy(JNIEnv* env, jint strict_policy)
+{
+ // Call back into android.os.StrictMode#onBinderStrictModePolicyChange
+ // to sync our state back to it. See the comments in StrictMode.java.
+ env->CallStaticVoidMethod(gStrictModeCallbackOffsets.mClass,
+ gStrictModeCallbackOffsets.mCallback,
+ strict_policy);
+}
+
+void signalExceptionForError(JNIEnv* env, jobject obj, status_t err,
+ bool canThrowRemoteException)
{
switch (err) {
case UNKNOWN_ERROR:
@@ -1273,612 +1257,15 @@
// ****************************************************************************
// ****************************************************************************
-static jint android_os_Parcel_dataSize(JNIEnv* env, jobject clazz)
+int register_android_os_Binder(JNIEnv* env)
{
- Parcel* parcel = parcelForJavaObject(env, clazz);
- return parcel ? parcel->dataSize() : 0;
-}
+ if (int_register_android_os_Binder(env) < 0)
+ return -1;
+ if (int_register_android_os_BinderInternal(env) < 0)
+ return -1;
+ if (int_register_android_os_BinderProxy(env) < 0)
+ return -1;
-static jint android_os_Parcel_dataAvail(JNIEnv* env, jobject clazz)
-{
- Parcel* parcel = parcelForJavaObject(env, clazz);
- return parcel ? parcel->dataAvail() : 0;
-}
-
-static jint android_os_Parcel_dataPosition(JNIEnv* env, jobject clazz)
-{
- Parcel* parcel = parcelForJavaObject(env, clazz);
- return parcel ? parcel->dataPosition() : 0;
-}
-
-static jint android_os_Parcel_dataCapacity(JNIEnv* env, jobject clazz)
-{
- Parcel* parcel = parcelForJavaObject(env, clazz);
- return parcel ? parcel->dataCapacity() : 0;
-}
-
-static void android_os_Parcel_setDataSize(JNIEnv* env, jobject clazz, jint size)
-{
- Parcel* parcel = parcelForJavaObject(env, clazz);
- if (parcel != NULL) {
- const status_t err = parcel->setDataSize(size);
- if (err != NO_ERROR) {
- signalExceptionForError(env, clazz, err);
- }
- }
-}
-
-static void android_os_Parcel_setDataPosition(JNIEnv* env, jobject clazz, jint pos)
-{
- Parcel* parcel = parcelForJavaObject(env, clazz);
- if (parcel != NULL) {
- parcel->setDataPosition(pos);
- }
-}
-
-static void android_os_Parcel_setDataCapacity(JNIEnv* env, jobject clazz, jint size)
-{
- Parcel* parcel = parcelForJavaObject(env, clazz);
- if (parcel != NULL) {
- const status_t err = parcel->setDataCapacity(size);
- if (err != NO_ERROR) {
- signalExceptionForError(env, clazz, err);
- }
- }
-}
-
-static jboolean android_os_Parcel_pushAllowFds(JNIEnv* env, jobject clazz, jboolean allowFds)
-{
- Parcel* parcel = parcelForJavaObject(env, clazz);
- jboolean ret = JNI_TRUE;
- if (parcel != NULL) {
- ret = (jboolean)parcel->pushAllowFds(allowFds);
- }
- return ret;
-}
-
-static void android_os_Parcel_restoreAllowFds(JNIEnv* env, jobject clazz, jboolean lastValue)
-{
- Parcel* parcel = parcelForJavaObject(env, clazz);
- if (parcel != NULL) {
- parcel->restoreAllowFds((bool)lastValue);
- }
-}
-
-static void android_os_Parcel_writeNative(JNIEnv* env, jobject clazz,
- jobject data, jint offset,
- jint length)
-{
- Parcel* parcel = parcelForJavaObject(env, clazz);
- if (parcel == NULL) {
- return;
- }
-
- const status_t err = parcel->writeInt32(length);
- if (err != NO_ERROR) {
- signalExceptionForError(env, clazz, err);
- return;
- }
-
- void* dest = parcel->writeInplace(length);
- if (dest == NULL) {
- signalExceptionForError(env, clazz, NO_MEMORY);
- return;
- }
-
- jbyte* ar = (jbyte*)env->GetPrimitiveArrayCritical((jarray)data, 0);
- if (ar) {
- memcpy(dest, ar + offset, length);
- env->ReleasePrimitiveArrayCritical((jarray)data, ar, 0);
- }
-}
-
-
-static void android_os_Parcel_writeInt(JNIEnv* env, jobject clazz, jint val)
-{
- Parcel* parcel = parcelForJavaObject(env, clazz);
- if (parcel != NULL) {
- const status_t err = parcel->writeInt32(val);
- if (err != NO_ERROR) {
- signalExceptionForError(env, clazz, err);
- }
- }
-}
-
-static void android_os_Parcel_writeLong(JNIEnv* env, jobject clazz, jlong val)
-{
- Parcel* parcel = parcelForJavaObject(env, clazz);
- if (parcel != NULL) {
- const status_t err = parcel->writeInt64(val);
- if (err != NO_ERROR) {
- signalExceptionForError(env, clazz, err);
- }
- }
-}
-
-static void android_os_Parcel_writeFloat(JNIEnv* env, jobject clazz, jfloat val)
-{
- Parcel* parcel = parcelForJavaObject(env, clazz);
- if (parcel != NULL) {
- const status_t err = parcel->writeFloat(val);
- if (err != NO_ERROR) {
- signalExceptionForError(env, clazz, err);
- }
- }
-}
-
-static void android_os_Parcel_writeDouble(JNIEnv* env, jobject clazz, jdouble val)
-{
- Parcel* parcel = parcelForJavaObject(env, clazz);
- if (parcel != NULL) {
- const status_t err = parcel->writeDouble(val);
- if (err != NO_ERROR) {
- signalExceptionForError(env, clazz, err);
- }
- }
-}
-
-static void android_os_Parcel_writeString(JNIEnv* env, jobject clazz, jstring val)
-{
- Parcel* parcel = parcelForJavaObject(env, clazz);
- if (parcel != NULL) {
- status_t err = NO_MEMORY;
- if (val) {
- const jchar* str = env->GetStringCritical(val, 0);
- if (str) {
- err = parcel->writeString16(str, env->GetStringLength(val));
- env->ReleaseStringCritical(val, str);
- }
- } else {
- err = parcel->writeString16(NULL, 0);
- }
- if (err != NO_ERROR) {
- signalExceptionForError(env, clazz, err);
- }
- }
-}
-
-static void android_os_Parcel_writeStrongBinder(JNIEnv* env, jobject clazz, jobject object)
-{
- Parcel* parcel = parcelForJavaObject(env, clazz);
- if (parcel != NULL) {
- const status_t err = parcel->writeStrongBinder(ibinderForJavaObject(env, object));
- if (err != NO_ERROR) {
- signalExceptionForError(env, clazz, err);
- }
- }
-}
-
-static void android_os_Parcel_writeFileDescriptor(JNIEnv* env, jobject clazz, jobject object)
-{
- Parcel* parcel = parcelForJavaObject(env, clazz);
- if (parcel != NULL) {
- const status_t err =
- parcel->writeDupFileDescriptor(jniGetFDFromFileDescriptor(env, object));
- if (err != NO_ERROR) {
- signalExceptionForError(env, clazz, err);
- }
- }
-}
-
-static jbyteArray android_os_Parcel_createByteArray(JNIEnv* env, jobject clazz)
-{
- jbyteArray ret = NULL;
-
- Parcel* parcel = parcelForJavaObject(env, clazz);
- if (parcel != NULL) {
- int32_t len = parcel->readInt32();
-
- // sanity check the stored length against the true data size
- if (len >= 0 && len <= (int32_t)parcel->dataAvail()) {
- ret = env->NewByteArray(len);
-
- if (ret != NULL) {
- jbyte* a2 = (jbyte*)env->GetPrimitiveArrayCritical(ret, 0);
- if (a2) {
- const void* data = parcel->readInplace(len);
- memcpy(a2, data, len);
- env->ReleasePrimitiveArrayCritical(ret, a2, 0);
- }
- }
- }
- }
-
- return ret;
-}
-
-static jint android_os_Parcel_readInt(JNIEnv* env, jobject clazz)
-{
- Parcel* parcel = parcelForJavaObject(env, clazz);
- if (parcel != NULL) {
- return parcel->readInt32();
- }
- return 0;
-}
-
-static jlong android_os_Parcel_readLong(JNIEnv* env, jobject clazz)
-{
- Parcel* parcel = parcelForJavaObject(env, clazz);
- if (parcel != NULL) {
- return parcel->readInt64();
- }
- return 0;
-}
-
-static jfloat android_os_Parcel_readFloat(JNIEnv* env, jobject clazz)
-{
- Parcel* parcel = parcelForJavaObject(env, clazz);
- if (parcel != NULL) {
- return parcel->readFloat();
- }
- return 0;
-}
-
-static jdouble android_os_Parcel_readDouble(JNIEnv* env, jobject clazz)
-{
- Parcel* parcel = parcelForJavaObject(env, clazz);
- if (parcel != NULL) {
- return parcel->readDouble();
- }
- return 0;
-}
-
-static jstring android_os_Parcel_readString(JNIEnv* env, jobject clazz)
-{
- Parcel* parcel = parcelForJavaObject(env, clazz);
- if (parcel != NULL) {
- size_t len;
- const char16_t* str = parcel->readString16Inplace(&len);
- if (str) {
- return env->NewString(str, len);
- }
- return NULL;
- }
- return NULL;
-}
-
-static jobject android_os_Parcel_readStrongBinder(JNIEnv* env, jobject clazz)
-{
- Parcel* parcel = parcelForJavaObject(env, clazz);
- if (parcel != NULL) {
- return javaObjectForIBinder(env, parcel->readStrongBinder());
- }
- return NULL;
-}
-
-static jobject android_os_Parcel_readFileDescriptor(JNIEnv* env, jobject clazz)
-{
- Parcel* parcel = parcelForJavaObject(env, clazz);
- if (parcel != NULL) {
- int fd = parcel->readFileDescriptor();
- if (fd < 0) return NULL;
- fd = dup(fd);
- if (fd < 0) return NULL;
- return jniCreateFileDescriptor(env, fd);
- }
- return NULL;
-}
-
-static jobject android_os_Parcel_openFileDescriptor(JNIEnv* env, jobject clazz,
- jstring name, jint mode)
-{
- if (name == NULL) {
- jniThrowNullPointerException(env, NULL);
- return NULL;
- }
- const jchar* str = env->GetStringCritical(name, 0);
- if (str == NULL) {
- // Whatever, whatever.
- jniThrowException(env, "java/lang/IllegalStateException", NULL);
- return NULL;
- }
- String8 name8(str, env->GetStringLength(name));
- env->ReleaseStringCritical(name, str);
- int flags=0;
- switch (mode&0x30000000) {
- case 0:
- case 0x10000000:
- flags = O_RDONLY;
- break;
- case 0x20000000:
- flags = O_WRONLY;
- break;
- case 0x30000000:
- flags = O_RDWR;
- break;
- }
-
- if (mode&0x08000000) flags |= O_CREAT;
- if (mode&0x04000000) flags |= O_TRUNC;
- if (mode&0x02000000) flags |= O_APPEND;
-
- int realMode = S_IRWXU|S_IRWXG;
- if (mode&0x00000001) realMode |= S_IROTH;
- if (mode&0x00000002) realMode |= S_IWOTH;
-
- int fd = open(name8.string(), flags, realMode);
- if (fd < 0) {
- jniThrowException(env, "java/io/FileNotFoundException", strerror(errno));
- return NULL;
- }
- jobject object = jniCreateFileDescriptor(env, fd);
- if (object == NULL) {
- close(fd);
- }
- return object;
-}
-
-static jobject android_os_Parcel_dupFileDescriptor(JNIEnv* env, jobject clazz, jobject orig)
-{
- if (orig == NULL) {
- jniThrowNullPointerException(env, NULL);
- return NULL;
- }
- int origfd = jniGetFDFromFileDescriptor(env, orig);
- if (origfd < 0) {
- jniThrowException(env, "java/lang/IllegalArgumentException", "bad FileDescriptor");
- return NULL;
- }
-
- int fd = dup(origfd);
- if (fd < 0) {
- jniThrowIOException(env, errno);
- return NULL;
- }
- jobject object = jniCreateFileDescriptor(env, fd);
- if (object == NULL) {
- close(fd);
- }
- return object;
-}
-
-static void android_os_Parcel_closeFileDescriptor(JNIEnv* env, jobject clazz, jobject object)
-{
- if (object == NULL) {
- jniThrowNullPointerException(env, NULL);
- return;
- }
- int fd = jniGetFDFromFileDescriptor(env, object);
- if (fd >= 0) {
- jniSetFileDescriptorOfFD(env, object, -1);
- //ALOGI("Closing ParcelFileDescriptor %d\n", fd);
- close(fd);
- }
-}
-
-static void android_os_Parcel_clearFileDescriptor(JNIEnv* env, jobject clazz, jobject object)
-{
- if (object == NULL) {
- jniThrowNullPointerException(env, NULL);
- return;
- }
- int fd = jniGetFDFromFileDescriptor(env, object);
- if (fd >= 0) {
- jniSetFileDescriptorOfFD(env, object, -1);
- }
-}
-
-static void android_os_Parcel_freeBuffer(JNIEnv* env, jobject clazz)
-{
- int32_t own = env->GetIntField(clazz, gParcelOffsets.mOwnObject);
- if (own) {
- Parcel* parcel = parcelForJavaObject(env, clazz);
- if (parcel != NULL) {
- //ALOGI("Parcel.freeBuffer() called for C++ Parcel %p\n", parcel);
- parcel->freeData();
- }
- }
-}
-
-static void android_os_Parcel_init(JNIEnv* env, jobject clazz, jint parcelInt)
-{
- Parcel* parcel = (Parcel*)parcelInt;
- int own = 0;
- if (!parcel) {
- //ALOGI("Initializing obj %p: creating new Parcel\n", clazz);
- own = 1;
- parcel = new Parcel;
- } else {
- //ALOGI("Initializing obj %p: given existing Parcel %p\n", clazz, parcel);
- }
- if (parcel == NULL) {
- jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
- return;
- }
- //ALOGI("Initializing obj %p from C++ Parcel %p, own=%d\n", clazz, parcel, own);
- env->SetIntField(clazz, gParcelOffsets.mOwnObject, own);
- env->SetIntField(clazz, gParcelOffsets.mObject, (int)parcel);
-}
-
-static void android_os_Parcel_destroy(JNIEnv* env, jobject clazz)
-{
- int32_t own = env->GetIntField(clazz, gParcelOffsets.mOwnObject);
- if (own) {
- Parcel* parcel = parcelForJavaObject(env, clazz);
- env->SetIntField(clazz, gParcelOffsets.mObject, 0);
- //ALOGI("Destroying obj %p: deleting C++ Parcel %p\n", clazz, parcel);
- delete parcel;
- } else {
- env->SetIntField(clazz, gParcelOffsets.mObject, 0);
- //ALOGI("Destroying obj %p: leaving C++ Parcel %p\n", clazz);
- }
-}
-
-static jbyteArray android_os_Parcel_marshall(JNIEnv* env, jobject clazz)
-{
- Parcel* parcel = parcelForJavaObject(env, clazz);
- if (parcel == NULL) {
- return NULL;
- }
-
- // do not marshall if there are binder objects in the parcel
- if (parcel->objectsCount())
- {
- jniThrowException(env, "java/lang/RuntimeException", "Tried to marshall a Parcel that contained Binder objects.");
- return NULL;
- }
-
- jbyteArray ret = env->NewByteArray(parcel->dataSize());
-
- if (ret != NULL)
- {
- jbyte* array = (jbyte*)env->GetPrimitiveArrayCritical(ret, 0);
- if (array != NULL)
- {
- memcpy(array, parcel->data(), parcel->dataSize());
- env->ReleasePrimitiveArrayCritical(ret, array, 0);
- }
- }
-
- return ret;
-}
-
-static void android_os_Parcel_unmarshall(JNIEnv* env, jobject clazz, jbyteArray data, jint offset, jint length)
-{
- Parcel* parcel = parcelForJavaObject(env, clazz);
- if (parcel == NULL || length < 0) {
- return;
- }
-
- jbyte* array = (jbyte*)env->GetPrimitiveArrayCritical(data, 0);
- if (array)
- {
- parcel->setDataSize(length);
- parcel->setDataPosition(0);
-
- void* raw = parcel->writeInplace(length);
- memcpy(raw, (array + offset), length);
-
- env->ReleasePrimitiveArrayCritical(data, array, 0);
- }
-}
-
-static void android_os_Parcel_appendFrom(JNIEnv* env, jobject clazz, jobject parcel, jint offset, jint length)
-{
- Parcel* thisParcel = parcelForJavaObject(env, clazz);
- if (thisParcel == NULL) {
- return;
- }
- Parcel* otherParcel = parcelForJavaObject(env, parcel);
- if (otherParcel == NULL) {
- return;
- }
-
- status_t err = thisParcel->appendFrom(otherParcel, offset, length);
- if (err != NO_ERROR) {
- signalExceptionForError(env, clazz, err);
- }
-}
-
-static jboolean android_os_Parcel_hasFileDescriptors(JNIEnv* env, jobject clazz)
-{
- jboolean ret = JNI_FALSE;
- Parcel* parcel = parcelForJavaObject(env, clazz);
- if (parcel != NULL) {
- if (parcel->hasFileDescriptors()) {
- ret = JNI_TRUE;
- }
- }
- return ret;
-}
-
-static void android_os_Parcel_writeInterfaceToken(JNIEnv* env, jobject clazz, jstring name)
-{
- Parcel* parcel = parcelForJavaObject(env, clazz);
- if (parcel != NULL) {
- // In the current implementation, the token is just the serialized interface name that
- // the caller expects to be invoking
- const jchar* str = env->GetStringCritical(name, 0);
- if (str != NULL) {
- parcel->writeInterfaceToken(String16(str, env->GetStringLength(name)));
- env->ReleaseStringCritical(name, str);
- }
- }
-}
-
-static void android_os_Parcel_enforceInterface(JNIEnv* env, jobject clazz, jstring name)
-{
- jboolean ret = JNI_FALSE;
-
- Parcel* parcel = parcelForJavaObject(env, clazz);
- if (parcel != NULL) {
- const jchar* str = env->GetStringCritical(name, 0);
- if (str) {
- IPCThreadState* threadState = IPCThreadState::self();
- const int32_t oldPolicy = threadState->getStrictModePolicy();
- const bool isValid = parcel->enforceInterface(
- String16(str, env->GetStringLength(name)),
- threadState);
- env->ReleaseStringCritical(name, str);
- if (isValid) {
- const int32_t newPolicy = threadState->getStrictModePolicy();
- if (oldPolicy != newPolicy) {
- // Need to keep the Java-level thread-local strict
- // mode policy in sync for the libcore
- // enforcements, which involves an upcall back
- // into Java. (We can't modify the
- // Parcel.enforceInterface signature, as it's
- // pseudo-public, and used via AIDL
- // auto-generation...)
- set_dalvik_blockguard_policy(env, newPolicy);
- }
- return; // everything was correct -> return silently
- }
- }
- }
-
- // all error conditions wind up here
- jniThrowException(env, "java/lang/SecurityException",
- "Binder invocation to an incorrect interface");
-}
-
-// ----------------------------------------------------------------------------
-
-static const JNINativeMethod gParcelMethods[] = {
- {"dataSize", "()I", (void*)android_os_Parcel_dataSize},
- {"dataAvail", "()I", (void*)android_os_Parcel_dataAvail},
- {"dataPosition", "()I", (void*)android_os_Parcel_dataPosition},
- {"dataCapacity", "()I", (void*)android_os_Parcel_dataCapacity},
- {"setDataSize", "(I)V", (void*)android_os_Parcel_setDataSize},
- {"setDataPosition", "(I)V", (void*)android_os_Parcel_setDataPosition},
- {"setDataCapacity", "(I)V", (void*)android_os_Parcel_setDataCapacity},
- {"pushAllowFds", "(Z)Z", (void*)android_os_Parcel_pushAllowFds},
- {"restoreAllowFds", "(Z)V", (void*)android_os_Parcel_restoreAllowFds},
- {"writeNative", "([BII)V", (void*)android_os_Parcel_writeNative},
- {"writeInt", "(I)V", (void*)android_os_Parcel_writeInt},
- {"writeLong", "(J)V", (void*)android_os_Parcel_writeLong},
- {"writeFloat", "(F)V", (void*)android_os_Parcel_writeFloat},
- {"writeDouble", "(D)V", (void*)android_os_Parcel_writeDouble},
- {"writeString", "(Ljava/lang/String;)V", (void*)android_os_Parcel_writeString},
- {"writeStrongBinder", "(Landroid/os/IBinder;)V", (void*)android_os_Parcel_writeStrongBinder},
- {"writeFileDescriptor", "(Ljava/io/FileDescriptor;)V", (void*)android_os_Parcel_writeFileDescriptor},
- {"createByteArray", "()[B", (void*)android_os_Parcel_createByteArray},
- {"readInt", "()I", (void*)android_os_Parcel_readInt},
- {"readLong", "()J", (void*)android_os_Parcel_readLong},
- {"readFloat", "()F", (void*)android_os_Parcel_readFloat},
- {"readDouble", "()D", (void*)android_os_Parcel_readDouble},
- {"readString", "()Ljava/lang/String;", (void*)android_os_Parcel_readString},
- {"readStrongBinder", "()Landroid/os/IBinder;", (void*)android_os_Parcel_readStrongBinder},
- {"internalReadFileDescriptor", "()Ljava/io/FileDescriptor;", (void*)android_os_Parcel_readFileDescriptor},
- {"openFileDescriptor", "(Ljava/lang/String;I)Ljava/io/FileDescriptor;", (void*)android_os_Parcel_openFileDescriptor},
- {"dupFileDescriptor", "(Ljava/io/FileDescriptor;)Ljava/io/FileDescriptor;", (void*)android_os_Parcel_dupFileDescriptor},
- {"closeFileDescriptor", "(Ljava/io/FileDescriptor;)V", (void*)android_os_Parcel_closeFileDescriptor},
- {"clearFileDescriptor", "(Ljava/io/FileDescriptor;)V", (void*)android_os_Parcel_clearFileDescriptor},
- {"freeBuffer", "()V", (void*)android_os_Parcel_freeBuffer},
- {"init", "(I)V", (void*)android_os_Parcel_init},
- {"destroy", "()V", (void*)android_os_Parcel_destroy},
- {"marshall", "()[B", (void*)android_os_Parcel_marshall},
- {"unmarshall", "([BII)V", (void*)android_os_Parcel_unmarshall},
- {"appendFrom", "(Landroid/os/Parcel;II)V", (void*)android_os_Parcel_appendFrom},
- {"hasFileDescriptors", "()Z", (void*)android_os_Parcel_hasFileDescriptors},
- {"writeInterfaceToken", "(Ljava/lang/String;)V", (void*)android_os_Parcel_writeInterfaceToken},
- {"enforceInterface", "(Ljava/lang/String;)V", (void*)android_os_Parcel_enforceInterface},
-};
-
-const char* const kParcelPathName = "android/os/Parcel";
-
-static int int_register_android_os_Parcel(JNIEnv* env)
-{
jclass clazz;
clazz = env->FindClass("android/util/Log");
@@ -1894,14 +1281,6 @@
gParcelFileDescriptorOffsets.mConstructor
= env->GetMethodID(clazz, "<init>", "(Ljava/io/FileDescriptor;)V");
- clazz = env->FindClass(kParcelPathName);
- LOG_FATAL_IF(clazz == NULL, "Unable to find class android.os.Parcel");
-
- gParcelOffsets.mObject
- = env->GetFieldID(clazz, "mObject", "I");
- gParcelOffsets.mOwnObject
- = env->GetFieldID(clazz, "mOwnObject", "I");
-
clazz = env->FindClass("android/os/StrictMode");
LOG_FATAL_IF(clazz == NULL, "Unable to find class android.os.StrictMode");
gStrictModeCallbackOffsets.mClass = (jclass) env->NewGlobalRef(clazz);
@@ -1910,20 +1289,5 @@
LOG_FATAL_IF(gStrictModeCallbackOffsets.mCallback == NULL,
"Unable to find strict mode callback.");
- return AndroidRuntime::registerNativeMethods(
- env, kParcelPathName,
- gParcelMethods, NELEM(gParcelMethods));
-}
-
-int register_android_os_Binder(JNIEnv* env)
-{
- if (int_register_android_os_Binder(env) < 0)
- return -1;
- if (int_register_android_os_BinderInternal(env) < 0)
- return -1;
- if (int_register_android_os_BinderProxy(env) < 0)
- return -1;
- if (int_register_android_os_Parcel(env) < 0)
- return -1;
return 0;
}
diff --git a/core/jni/android_util_Binder.h b/core/jni/android_util_Binder.h
index 0122691..ca320ef 100644
--- a/core/jni/android_util_Binder.h
+++ b/core/jni/android_util_Binder.h
@@ -15,6 +15,9 @@
** limitations under the License.
*/
+#ifndef ANDROID_UTIL_BINDER_H
+#define ANDROID_UTIL_BINDER_H
+
#include <binder/IBinder.h>
#include "jni.h"
@@ -25,10 +28,13 @@
extern jobject javaObjectForIBinder(JNIEnv* env, const sp<IBinder>& val);
extern sp<IBinder> ibinderForJavaObject(JNIEnv* env, jobject obj);
-// Conversion from Java Parcel Object to C++ Parcel instance.
-// Note: does not type checking; must guarantee jobject is a Java Parcel
-extern Parcel* parcelForJavaObject(JNIEnv* env, jobject obj);
-
extern jobject newParcelFileDescriptor(JNIEnv* env, jobject fileDesc);
+extern void set_dalvik_blockguard_policy(JNIEnv* env, jint strict_policy);
+
+extern void signalExceptionForError(JNIEnv* env, jobject obj, status_t err,
+ bool canThrowRemoteException = false);
+
}
+
+#endif
diff --git a/core/jni/android_view_InputChannel.cpp b/core/jni/android_view_InputChannel.cpp
index 8350e73..9c44a59 100644
--- a/core/jni/android_view_InputChannel.cpp
+++ b/core/jni/android_view_InputChannel.cpp
@@ -23,6 +23,7 @@
#include <utils/Log.h>
#include <androidfw/InputTransport.h>
#include "android_view_InputChannel.h"
+#include "android_os_Parcel.h"
#include "android_util_Binder.h"
namespace android {
diff --git a/core/jni/android_view_MotionEvent.cpp b/core/jni/android_view_MotionEvent.cpp
index 0fb1b17..e69fb74 100644
--- a/core/jni/android_view_MotionEvent.cpp
+++ b/core/jni/android_view_MotionEvent.cpp
@@ -21,6 +21,7 @@
#include <android_runtime/AndroidRuntime.h>
#include <utils/Log.h>
#include <androidfw/Input.h>
+#include "android_os_Parcel.h"
#include "android_view_MotionEvent.h"
#include "android_util_Binder.h"
#include "android/graphics/Matrix.h"
diff --git a/core/jni/android_view_Surface.cpp b/core/jni/android_view_Surface.cpp
index c387752..30d4e20 100644
--- a/core/jni/android_view_Surface.cpp
+++ b/core/jni/android_view_Surface.cpp
@@ -888,7 +888,7 @@
no.native_region = env->GetFieldID(region, "mNativeRegion", "I");
jclass parcel = env->FindClass("android/os/Parcel");
- no.native_parcel = env->GetFieldID(parcel, "mObject", "I");
+ no.native_parcel = env->GetFieldID(parcel, "mNativePtr", "I");
jclass rect = env->FindClass("android/graphics/Rect");
ro.l = env->GetFieldID(rect, "left", "I");
diff --git a/core/res/res/anim/screen_rotate_180_enter.xml b/core/res/res/anim/screen_rotate_180_enter.xml
index 688a8d5..e2f3ce2 100644
--- a/core/res/res/anim/screen_rotate_180_enter.xml
+++ b/core/res/res/anim/screen_rotate_180_enter.xml
@@ -24,5 +24,5 @@
android:interpolator="@interpolator/decelerate_quint"
android:fillEnabled="true"
android:fillBefore="true" android:fillAfter="true"
- android:duration="@android:integer/config_mediumAnimTime" />
+ android:duration="@android:integer/config_longAnimTime" />
</set>
diff --git a/core/res/res/anim/screen_rotate_180_exit.xml b/core/res/res/anim/screen_rotate_180_exit.xml
index 58a1868..fe4a950 100644
--- a/core/res/res/anim/screen_rotate_180_exit.xml
+++ b/core/res/res/anim/screen_rotate_180_exit.xml
@@ -24,5 +24,5 @@
android:interpolator="@interpolator/decelerate_quint"
android:fillEnabled="true"
android:fillBefore="true" android:fillAfter="true"
- android:duration="@android:integer/config_mediumAnimTime" />
+ android:duration="@android:integer/config_longAnimTime" />
</set>
\ No newline at end of file
diff --git a/core/res/res/anim/screen_rotate_180_frame.xml b/core/res/res/anim/screen_rotate_180_frame.xml
index 19dade1..1a3ee67 100644
--- a/core/res/res/anim/screen_rotate_180_frame.xml
+++ b/core/res/res/anim/screen_rotate_180_frame.xml
@@ -24,5 +24,5 @@
android:interpolator="@interpolator/decelerate_quint"
android:fillEnabled="true"
android:fillBefore="true" android:fillAfter="true"
- android:duration="@android:integer/config_mediumAnimTime" />
+ android:duration="@android:integer/config_longAnimTime" />
</set>
diff --git a/core/res/res/anim/screen_rotate_finish_enter.xml b/core/res/res/anim/screen_rotate_finish_enter.xml
index 9d731e6..f12a1aec 100644
--- a/core/res/res/anim/screen_rotate_finish_enter.xml
+++ b/core/res/res/anim/screen_rotate_finish_enter.xml
@@ -26,7 +26,6 @@
android:fillEnabled="true"
android:fillBefore="true" android:fillAfter="true"
android:duration="@android:integer/config_shortAnimTime"/>
- <!--
<scale android:fromXScale="100%p" android:toXScale="100%"
android:fromYScale="100%p" android:toYScale="100%"
android:pivotX="50%" android:pivotY="50%"
@@ -34,5 +33,4 @@
android:fillEnabled="true"
android:fillBefore="true" android:fillAfter="true"
android:duration="@android:integer/config_mediumAnimTime" />
- -->
</set>
diff --git a/core/res/res/anim/screen_rotate_finish_exit.xml b/core/res/res/anim/screen_rotate_finish_exit.xml
index 60daa18..3d9c569 100644
--- a/core/res/res/anim/screen_rotate_finish_exit.xml
+++ b/core/res/res/anim/screen_rotate_finish_exit.xml
@@ -19,8 +19,8 @@
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:shareInterpolator="false">
- <scale android:fromXScale="1.0" android:toXScale="1.0"
- android:fromYScale="1.0" android:toYScale="1.0"
+ <scale android:fromXScale="1.0" android:toXScale="1.1111111111111"
+ android:fromYScale="1.0" android:toYScale="1.1111111111111"
android:pivotX="50%" android:pivotY="50%"
android:interpolator="@interpolator/accelerate_decelerate"
android:fillEnabled="true"
diff --git a/core/res/res/anim/screen_rotate_minus_90_enter.xml b/core/res/res/anim/screen_rotate_minus_90_enter.xml
index d2aebc9..38a674d 100644
--- a/core/res/res/anim/screen_rotate_minus_90_enter.xml
+++ b/core/res/res/anim/screen_rotate_minus_90_enter.xml
@@ -19,44 +19,10 @@
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:shareInterpolator="false">
- <!--
- <scale android:fromXScale="1.0" android:toXScale="0.565"
- android:fromYScale="1.0" android:toYScale="0.565"
- android:pivotX="50%" android:pivotY="50%"
- android:interpolator="@interpolator/decelerate_quint"
- android:fillEnabled="true"
- android:fillBefore="false" android:fillAfter="true"
- android:duration="@android:integer/config_mediumAnimTime"/>
- <scale android:fromXScale="1.0" android:toXScale="1.777777777"
- android:fromYScale="1.0" android:toYScale="1.777777777"
- android:pivotX="50%" android:pivotY="50%"
- android:interpolator="@interpolator/decelerate_quint"
- android:fillEnabled="true"
- android:fillBefore="false" android:fillAfter="true"
- android:startOffset="@android:integer/config_longAnimTime"
- android:duration="@android:integer/config_mediumAnimTime"/>
- <scale android:fromXScale="100%p" android:toXScale="100%"
- android:fromYScale="100%p" android:toYScale="100%"
- android:pivotX="50%" android:pivotY="50%"
- android:interpolator="@interpolator/decelerate_quint"
- android:fillEnabled="true"
- android:fillBefore="true" android:fillAfter="true"
- android:startOffset="@android:integer/config_longAnimTime"
- android:duration="@android:integer/config_mediumAnimTime" />
- -->
- <!--
- <scale android:fromXScale="100%p" android:toXScale="100%"
- android:fromYScale="100%p" android:toYScale="100%"
- android:pivotX="50%" android:pivotY="50%"
- android:interpolator="@interpolator/decelerate_quint"
- android:fillEnabled="true"
- android:fillBefore="true" android:fillAfter="true"
- android:duration="@android:integer/config_mediumAnimTime" />
- -->
<rotate android:fromDegrees="-90" android:toDegrees="0"
android:pivotX="50%" android:pivotY="50%"
android:interpolator="@interpolator/decelerate_quint"
android:fillEnabled="true"
android:fillBefore="true" android:fillAfter="true"
- android:duration="@android:integer/config_mediumAnimTime" />
+ android:duration="@android:integer/config_longAnimTime" />
</set>
diff --git a/core/res/res/anim/screen_rotate_minus_90_exit.xml b/core/res/res/anim/screen_rotate_minus_90_exit.xml
index c7c38cd..a75aca7 100644
--- a/core/res/res/anim/screen_rotate_minus_90_exit.xml
+++ b/core/res/res/anim/screen_rotate_minus_90_exit.xml
@@ -19,51 +19,10 @@
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:shareInterpolator="false">
- <!--
- <scale android:fromXScale="1.0" android:toXScale="0.565"
- android:fromYScale="1.0" android:toYScale="0.565"
- android:pivotX="50%" android:pivotY="50%"
- android:interpolator="@interpolator/decelerate_quint"
- android:fillEnabled="true"
- android:fillBefore="false" android:fillAfter="true"
- android:duration="@android:integer/config_mediumAnimTime"/>
- <scale android:fromXScale="1.0" android:toXScale="1.777777777"
- android:fromYScale="1.0" android:toYScale="1.777777777"
- android:pivotX="50%" android:pivotY="50%"
- android:interpolator="@interpolator/decelerate_quint"
- android:fillEnabled="true"
- android:fillBefore="false" android:fillAfter="true"
- android:startOffset="@android:integer/config_longAnimTime"
- android:duration="@android:integer/config_mediumAnimTime"/>
- <scale android:fromXScale="100%" android:toXScale="100%p"
- android:fromYScale="100%" android:toYScale="100%p"
- android:pivotX="50%" android:pivotY="50%"
- android:interpolator="@interpolator/decelerate_quint"
- android:startOffset="@android:integer/config_longAnimTime"
- android:duration="@android:integer/config_mediumAnimTime" />
- <alpha android:fromAlpha="1.0" android:toAlpha="0"
- android:interpolator="@interpolator/decelerate_quint"
- android:fillEnabled="true"
- android:fillBefore="false" android:fillAfter="true"
- android:startOffset="@android:integer/config_longAnimTime"
- android:duration="@android:integer/config_mediumAnimTime" />
- -->
- <!--
- <scale android:fromXScale="100%" android:toXScale="100%p"
- android:fromYScale="100%" android:toYScale="100%p"
- android:pivotX="50%" android:pivotY="50%"
- android:interpolator="@interpolator/decelerate_quint"
- android:duration="@android:integer/config_mediumAnimTime" />
- <alpha android:fromAlpha="1.0" android:toAlpha="0"
- android:interpolator="@interpolator/decelerate_quint"
- android:fillEnabled="true"
- android:fillBefore="false" android:fillAfter="true"
- android:duration="@android:integer/config_mediumAnimTime" />
- -->
<rotate android:fromDegrees="0" android:toDegrees="90"
android:pivotX="50%" android:pivotY="50%"
android:interpolator="@interpolator/decelerate_quint"
android:fillEnabled="true"
android:fillBefore="true" android:fillAfter="true"
- android:duration="@android:integer/config_mediumAnimTime" />
+ android:duration="@android:integer/config_longAnimTime" />
</set>
diff --git a/core/res/res/anim/screen_rotate_minus_90_frame.xml b/core/res/res/anim/screen_rotate_minus_90_frame.xml
index 874f2e9..2d198f3 100644
--- a/core/res/res/anim/screen_rotate_minus_90_frame.xml
+++ b/core/res/res/anim/screen_rotate_minus_90_frame.xml
@@ -24,5 +24,5 @@
android:interpolator="@interpolator/decelerate_quint"
android:fillEnabled="true"
android:fillBefore="true" android:fillAfter="true"
- android:duration="@android:integer/config_mediumAnimTime" />
+ android:duration="@android:integer/config_longAnimTime" />
</set>
diff --git a/core/res/res/anim/screen_rotate_plus_90_enter.xml b/core/res/res/anim/screen_rotate_plus_90_enter.xml
index 63d7043..583d2ba 100644
--- a/core/res/res/anim/screen_rotate_plus_90_enter.xml
+++ b/core/res/res/anim/screen_rotate_plus_90_enter.xml
@@ -19,44 +19,10 @@
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:shareInterpolator="false">
- <!--
- <scale android:fromXScale="1.0" android:toXScale="0.565"
- android:fromYScale="1.0" android:toYScale="0.565"
- android:pivotX="50%" android:pivotY="50%"
- android:interpolator="@interpolator/decelerate_quint"
- android:fillEnabled="true"
- android:fillBefore="false" android:fillAfter="true"
- android:duration="@android:integer/config_mediumAnimTime"/>
- <scale android:fromXScale="1.0" android:toXScale="1.777777777"
- android:fromYScale="1.0" android:toYScale="1.777777777"
- android:pivotX="50%" android:pivotY="50%"
- android:interpolator="@interpolator/decelerate_quint"
- android:fillEnabled="true"
- android:fillBefore="false" android:fillAfter="true"
- android:startOffset="75"
- android:duration="@android:integer/config_mediumAnimTime"/>
- <scale android:fromXScale="100%p" android:toXScale="100%"
- android:fromYScale="100%p" android:toYScale="100%"
- android:pivotX="50%" android:pivotY="50%"
- android:interpolator="@interpolator/decelerate_quint"
- android:fillEnabled="true"
- android:fillBefore="true" android:fillAfter="true"
- android:startOffset="75"
- android:duration="@android:integer/config_mediumAnimTime" />
- -->
- <!--
- <scale android:fromXScale="100%p" android:toXScale="100%"
- android:fromYScale="100%p" android:toYScale="100%"
- android:pivotX="50%" android:pivotY="50%"
- android:interpolator="@interpolator/decelerate_quint"
- android:fillEnabled="true"
- android:fillBefore="true" android:fillAfter="true"
- android:duration="@android:integer/config_mediumAnimTime" />
- -->
<rotate android:fromDegrees="90" android:toDegrees="0"
android:pivotX="50%" android:pivotY="50%"
android:interpolator="@interpolator/decelerate_quint"
android:fillEnabled="true"
android:fillBefore="true" android:fillAfter="true"
- android:duration="@android:integer/config_mediumAnimTime" />
+ android:duration="@android:integer/config_longAnimTime" />
</set>
diff --git a/core/res/res/anim/screen_rotate_plus_90_exit.xml b/core/res/res/anim/screen_rotate_plus_90_exit.xml
index ea48c81..a2bef41 100644
--- a/core/res/res/anim/screen_rotate_plus_90_exit.xml
+++ b/core/res/res/anim/screen_rotate_plus_90_exit.xml
@@ -19,51 +19,10 @@
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:shareInterpolator="false">
- <!--
- <scale android:fromXScale="1.0" android:toXScale="0.565"
- android:fromYScale="1.0" android:toYScale="0.565"
- android:pivotX="50%" android:pivotY="50%"
- android:interpolator="@interpolator/decelerate_quint"
- android:fillEnabled="true"
- android:fillBefore="false" android:fillAfter="true"
- android:duration="@android:integer/config_mediumAnimTime"/>
- <scale android:fromXScale="1.0" android:toXScale="1.777777777"
- android:fromYScale="1.0" android:toYScale="1.777777777"
- android:pivotX="50%" android:pivotY="50%"
- android:interpolator="@interpolator/decelerate_quint"
- android:fillEnabled="true"
- android:fillBefore="false" android:fillAfter="true"
- android:startOffset="75"
- android:duration="@android:integer/config_mediumAnimTime"/>
- <scale android:fromXScale="100%" android:toXScale="100%p"
- android:fromYScale="100%" android:toYScale="100%p"
- android:pivotX="50%" android:pivotY="50%"
- android:interpolator="@interpolator/decelerate_quint"
- android:startOffset="75"
- android:duration="@android:integer/config_mediumAnimTime" />
- <alpha android:fromAlpha="1.0" android:toAlpha="0"
- android:interpolator="@interpolator/decelerate_quint"
- android:fillEnabled="true"
- android:fillBefore="false" android:fillAfter="true"
- android:startOffset="75"
- android:duration="@android:integer/config_mediumAnimTime" />
- -->
- <!--
- <scale android:fromXScale="100%" android:toXScale="100%p"
- android:fromYScale="100%" android:toYScale="100%p"
- android:pivotX="50%" android:pivotY="50%"
- android:interpolator="@interpolator/decelerate_quint"
- android:duration="@android:integer/config_mediumAnimTime" />
- <alpha android:fromAlpha="1.0" android:toAlpha="0"
- android:interpolator="@interpolator/decelerate_quint"
- android:fillEnabled="true"
- android:fillBefore="false" android:fillAfter="true"
- android:duration="@android:integer/config_mediumAnimTime" />
- -->
<rotate android:fromDegrees="0" android:toDegrees="-90"
android:pivotX="50%" android:pivotY="50%"
android:interpolator="@interpolator/decelerate_quint"
android:fillEnabled="true"
android:fillBefore="true" android:fillAfter="true"
- android:duration="@android:integer/config_mediumAnimTime" />
+ android:duration="@android:integer/config_longAnimTime" />
</set>
diff --git a/core/res/res/anim/screen_rotate_plus_90_frame.xml b/core/res/res/anim/screen_rotate_plus_90_frame.xml
index 03c6aa6..cd20050 100644
--- a/core/res/res/anim/screen_rotate_plus_90_frame.xml
+++ b/core/res/res/anim/screen_rotate_plus_90_frame.xml
@@ -24,5 +24,5 @@
android:interpolator="@interpolator/decelerate_quint"
android:fillEnabled="true"
android:fillBefore="true" android:fillAfter="true"
- android:duration="@android:integer/config_mediumAnimTime" />
+ android:duration="@android:integer/config_longAnimTime" />
</set>
diff --git a/core/res/res/layout/action_bar_title_item.xml b/core/res/res/layout/action_bar_title_item.xml
index 4c74f6a..2e21383 100644
--- a/core/res/res/layout/action_bar_title_item.xml
+++ b/core/res/res/layout/action_bar_title_item.xml
@@ -18,7 +18,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
- android:paddingRight="16dip"
+ android:paddingRight="8dip"
android:background="?android:attr/actionBarItemBackground"
android:enabled="false">
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index 1a0d479..8e36948 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -671,7 +671,7 @@
<string name="faceunlock_multiple_failures" msgid="754137583022792429">"Se superó el máximo de intentos permitido para el desbloqueo facial del dispositivo."</string>
<string name="lockscreen_plugged_in" msgid="8057762828355572315">"Cargando <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
<string name="lockscreen_charged" msgid="4938930459620989972">"Cargada."</string>
- <string name="lockscreen_battery_short" msgid="4477264849386850266">"<xliff:g id="NUMBER">%d</xliff:g> <xliff:g id="PERCENT">%%</xliff:g>"</string>
+ <string name="lockscreen_battery_short" msgid="4477264849386850266">"<xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
<string name="lockscreen_low_battery" msgid="1482873981919249740">"Conecta tu cargador."</string>
<string name="lockscreen_missing_sim_message_short" msgid="7381499217732227295">"No hay tarjeta SIM."</string>
<string name="lockscreen_missing_sim_message" product="tablet" msgid="151659196095791474">"No hay tarjeta SIM en el tablet."</string>
@@ -768,8 +768,8 @@
<string name="permdesc_serialPort" msgid="2991639985224598193">"Permite acceder a puertos serie a través de la API SerialManager."</string>
<string name="permlab_accessContentProvidersExternally" msgid="5077774297943409285">"acceder a proveedores externamente"</string>
<string name="permdesc_accessContentProvidersExternally" msgid="4544346486697853685">"Permite acceder a los proveedores de contenido desde la interfaz. Las aplicaciones normales nunca deberían necesitarlo."</string>
- <string name="permlab_updateLock" msgid="3527558366616680889">"desalentar a las actualizaciones automáticas de dispositivos"</string>
- <string name="permdesc_updateLock" msgid="1655625832166778492">"Permite a su titular a ofrecer información al sistema acerca de cuándo sería un buen momento para reiniciar el sistema no interactivo para actualizar el dispositivo."</string>
+ <string name="permlab_updateLock" msgid="3527558366616680889">"no realizar actualizaciones automáticas"</string>
+ <string name="permdesc_updateLock" msgid="1655625832166778492">"Permite a su propietario ofrecer información al sistema acerca de cuándo sería adecuado reiniciar el sistema de forma no interactiva y actualizar el dispositivo."</string>
<string name="save_password_message" msgid="767344687139195790">"¿Quieres recordar esta contraseña en el navegador?"</string>
<string name="save_password_notnow" msgid="6389675316706699758">"Ahora no."</string>
<string name="save_password_remember" msgid="6491879678996749466">"Recuerda"</string>
diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml
index 5bb95af..385bebb 100644
--- a/core/res/res/values-ms/strings.xml
+++ b/core/res/res/values-ms/strings.xml
@@ -769,7 +769,7 @@
<string name="permlab_accessContentProvidersExternally" msgid="5077774297943409285">"akses pembekal kandungan secara luaran"</string>
<string name="permdesc_accessContentProvidersExternally" msgid="4544346486697853685">"Membolehkan pemegang mengakses pembekal kandungan dari luar. Tidak akan sekali-kali diperlukan untuk apl biasa."</string>
<string name="permlab_updateLock" msgid="3527558366616680889">"tidak menggalakkan kemas kini peranti automatik"</string>
- <string name="permdesc_updateLock" msgid="1655625832166778492">"Membenarkan pemegang untuk menawarkan maklumat kepada sistem tentang bila akan menjadi masa yang baik untuk but semula bukan interaktif untuk menaik taraf peranti."</string>
+ <string name="permdesc_updateLock" msgid="1655625832166778492">"Membenarkan aplikasi untuk menawarkan maklumat kepada sistem tentang bila akan menjadi masa yang baik untuk but semula bukan interaktif untuk menaik taraf peranti."</string>
<string name="save_password_message" msgid="767344687139195790">"Adakah anda mahu penyemak imbas mengingati kata laluan ini?"</string>
<string name="save_password_notnow" msgid="6389675316706699758">"Bukan sekarang"</string>
<string name="save_password_remember" msgid="6491879678996749466">"Ingat"</string>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index 6a9f846..e70a664 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -671,7 +671,7 @@
<string name="faceunlock_multiple_failures" msgid="754137583022792429">"Du har overskredet grensen for opplåsingsforsøk med Ansiktslås"</string>
<string name="lockscreen_plugged_in" msgid="8057762828355572315">"Lader, <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
<string name="lockscreen_charged" msgid="4938930459620989972">"Fullt ladet"</string>
- <string name="lockscreen_battery_short" msgid="4477264849386850266">"<xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
+ <string name="lockscreen_battery_short" msgid="4477264849386850266">"<xliff:g id="NUMBER">%d</xliff:g> <xliff:g id="PERCENT">%%</xliff:g>"</string>
<string name="lockscreen_low_battery" msgid="1482873981919249740">"Koble til en batterilader."</string>
<string name="lockscreen_missing_sim_message_short" msgid="7381499217732227295">"Mangler SIM-kort."</string>
<string name="lockscreen_missing_sim_message" product="tablet" msgid="151659196095791474">"Nettbrettet mangler SIM-kort."</string>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index 286c32c..96dcfa0 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -768,8 +768,8 @@
<string name="permdesc_serialPort" msgid="2991639985224598193">"Umożliwia posiadaczowi dostęp do portów szeregowych przy użyciu interfejsu API narzędzia SerialManager."</string>
<string name="permlab_accessContentProvidersExternally" msgid="5077774297943409285">"Dostęp do dostawców treści z zewnątrz"</string>
<string name="permdesc_accessContentProvidersExternally" msgid="4544346486697853685">"Pozwala na dostęp do dostawców treści z powłoki. To uprawnienie nie powinno być potrzebne zwykłym aplikacjom."</string>
- <string name="permlab_updateLock" msgid="3527558366616680889">"odradź automatyczne aktualizacje urządzenia"</string>
- <string name="permdesc_updateLock" msgid="1655625832166778492">"Umożliwia posiadaczowi poinformowanie systemu, kiedy będzie dobry moment na nieinteraktywne uruchomienie ponowne wymagane do uaktualnienia urządzenia."</string>
+ <string name="permlab_updateLock" msgid="3527558366616680889">"odradzanie automatycznych aktualizacji urządzenia"</string>
+ <string name="permdesc_updateLock" msgid="1655625832166778492">"Umożliwia posiadaczowi poinformowanie systemu, kiedy będzie dobry moment na ponowne uruchomienie wymagane do uaktualnienia urządzenia."</string>
<string name="save_password_message" msgid="767344687139195790">"Czy chcesz, aby zapamiętać to hasło w przeglądarce?"</string>
<string name="save_password_notnow" msgid="6389675316706699758">"Nie teraz"</string>
<string name="save_password_remember" msgid="6491879678996749466">"Zapamiętaj"</string>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index 286e6d6..13053ab 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -768,8 +768,8 @@
<string name="permdesc_serialPort" msgid="2991639985224598193">"Inaruhusu mmiliki kufikia vituo tambulishi kwa kutumia KisimamiziTambulishi cha API."</string>
<string name="permlab_accessContentProvidersExternally" msgid="5077774297943409285">"fikia watoa huduma nje"</string>
<string name="permdesc_accessContentProvidersExternally" msgid="4544346486697853685">"Inaruhusu mmiliki kufikia watoa huduma kutoka kwa onyesho. Haifai kuhitajika kamwe kwa programu za kawaida."</string>
- <string name="permlab_updateLock" msgid="3527558366616680889">"katisha tamaa usasishaji kifaa kiotomatiki"</string>
- <string name="permdesc_updateLock" msgid="1655625832166778492">"Inaruhusu mmiliki kutoa maelezo kwa mfumo kuhusu ni lini itakuwa wakati mzuri wa uwashaji upya usiotagusana ili kuboresha kifaa."</string>
+ <string name="permlab_updateLock" msgid="3527558366616680889">"pinga usasishaji kifaa kiotomatiki"</string>
+ <string name="permdesc_updateLock" msgid="1655625832166778492">"Inaruhusu mmiliki kutoa maelezo kwa mfumo kuhusu ni lini itakuwa wakati mzuri wa uwashaji upya usiotagusana ili kupandisha gredi kifaa."</string>
<string name="save_password_message" msgid="767344687139195790">"Unataka kuvinjari ili ukumbuke nenosiri hili?"</string>
<string name="save_password_notnow" msgid="6389675316706699758">"Si Sasa"</string>
<string name="save_password_remember" msgid="6491879678996749466">"Kumbuka"</string>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index 24b726d..2664ad3 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -769,7 +769,7 @@
<string name="permlab_accessContentProvidersExternally" msgid="5077774297943409285">"从外部访问内容提供程序"</string>
<string name="permdesc_accessContentProvidersExternally" msgid="4544346486697853685">"允许持有者通过界面访问内容提供程序。普通应用绝不需要此权限。"</string>
<string name="permlab_updateLock" msgid="3527558366616680889">"阻止自动设备更新"</string>
- <string name="permdesc_updateLock" msgid="1655625832166778492">"允许持有人向系统提供相关信息,以确定什么时候适合执行非交互式重新启动来升级设备。"</string>
+ <string name="permdesc_updateLock" msgid="1655625832166778492">"允许应用向系统提供相关信息,以确定何时适合执行非交互式重启以升级设备。"</string>
<string name="save_password_message" msgid="767344687139195790">"是否希望浏览器记住此密码?"</string>
<string name="save_password_notnow" msgid="6389675316706699758">"暂不保存"</string>
<string name="save_password_remember" msgid="6491879678996749466">"记住"</string>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index c8df649..373e88c 100755
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -3194,30 +3194,6 @@
<!-- Description of the button to decrement the DatePicker's year value. [CHAR LIMIT=NONE] -->
<string name="date_picker_decrement_year_button">Decrement year</string>
- <!-- CheckBox - accessibility support -->
- <!-- Description of the checked state of a CheckBox. [CHAR LIMIT=NONE] -->
- <string name="checkbox_checked">checked</string>
- <!-- Description of the not checked state of a CheckBox. [CHAR LIMIT=NONE] -->
- <string name="checkbox_not_checked">not checked</string>
-
- <!-- RadioButton/CheckedTextView - accessibility support -->
- <!-- Description of the selected state of a RadioButton. [CHAR LIMIT=NONE] -->
- <string name="radiobutton_selected">selected</string>
- <!-- Description of the not selected state of a RadioButton. [CHAR LIMIT=NONE] -->
- <string name="radiobutton_not_selected">not selected</string>
-
- <!-- Switch - accessibility support -->
- <!-- Description of the on state of a Switch. [CHAR LIMIT=NONE] -->
- <string name="switch_on">on</string>
- <!-- Description of the off state of a Switch. [CHAR LIMIT=NONE] -->
- <string name="switch_off">off</string>
-
- <!-- ToggleButton - accessibility support -->
- <!-- Description of the pressed state of a ToggleButton. [CHAR LIMIT=NONE] -->
- <string name="togglebutton_pressed">pressed</string>
- <!-- Description of the not pressed state of a ToggleButton. [CHAR LIMIT=NONE] -->
- <string name="togglebutton_not_pressed">not pressed</string>
-
<!-- KeyboardView - accessibility support -->
<!-- Description of the Alt button in a KeyboardView. [CHAR LIMIT=NONE] -->
<string name="keyboardview_keycode_alt">Alt</string>
diff --git a/graphics/java/android/graphics/RectF.java b/graphics/java/android/graphics/RectF.java
index 293dfcc..c633d84 100644
--- a/graphics/java/android/graphics/RectF.java
+++ b/graphics/java/android/graphics/RectF.java
@@ -84,7 +84,7 @@
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
- Rect r = (Rect) o;
+ RectF r = (RectF) o;
return left == r.left && top == r.top && right == r.right && bottom == r.bottom;
}
diff --git a/include/media/AudioSystem.h b/include/media/AudioSystem.h
index d54ab35..cc0a594 100644
--- a/include/media/AudioSystem.h
+++ b/include/media/AudioSystem.h
@@ -185,7 +185,7 @@
audio_devices_t device);
static uint32_t getStrategyForStream(audio_stream_type_t stream);
- static uint32_t getDevicesForStream(audio_stream_type_t stream);
+ static audio_devices_t getDevicesForStream(audio_stream_type_t stream);
static audio_io_handle_t getOutputForEffect(effect_descriptor_t *desc);
static status_t registerEffect(effect_descriptor_t *desc,
diff --git a/include/media/IAudioPolicyService.h b/include/media/IAudioPolicyService.h
index bdd7747..04c927a 100644
--- a/include/media/IAudioPolicyService.h
+++ b/include/media/IAudioPolicyService.h
@@ -79,7 +79,7 @@
int *index,
audio_devices_t device) = 0;
virtual uint32_t getStrategyForStream(audio_stream_type_t stream) = 0;
- virtual uint32_t getDevicesForStream(audio_stream_type_t stream) = 0;
+ virtual audio_devices_t getDevicesForStream(audio_stream_type_t stream) = 0;
virtual audio_io_handle_t getOutputForEffect(effect_descriptor_t *desc) = 0;
virtual status_t registerEffect(effect_descriptor_t *desc,
audio_io_handle_t io,
diff --git a/libs/androidfw/ResourceTypes.cpp b/libs/androidfw/ResourceTypes.cpp
index 07f3b16..f3a1d9a 100644
--- a/libs/androidfw/ResourceTypes.cpp
+++ b/libs/androidfw/ResourceTypes.cpp
@@ -1687,7 +1687,9 @@
// The configuration closest to the actual size is best.
// We assume that larger configs have already been filtered
// out at this point. That means we just want the largest one.
- return smallestScreenWidthDp >= o.smallestScreenWidthDp;
+ if (smallestScreenWidthDp != o.smallestScreenWidthDp) {
+ return smallestScreenWidthDp > o.smallestScreenWidthDp;
+ }
}
if (screenSizeDp || o.screenSizeDp) {
@@ -1711,7 +1713,9 @@
//ALOGI("Comparing this %dx%d to other %dx%d in %dx%d: myDelta=%d otherDelta=%d",
// screenWidthDp, screenHeightDp, o.screenWidthDp, o.screenHeightDp,
// requested->screenWidthDp, requested->screenHeightDp, myDelta, otherDelta);
- return (myDelta <= otherDelta);
+ if (myDelta != otherDelta) {
+ return myDelta < otherDelta;
+ }
}
if (screenLayout || o.screenLayout) {
@@ -1738,7 +1742,9 @@
if (mySL == 0) return false;
return true;
}
- return fixedMySL >= fixedOSL;
+ if (fixedMySL != fixedOSL) {
+ return fixedMySL > fixedOSL;
+ }
}
if (((screenLayout^o.screenLayout) & MASK_SCREENLONG) != 0
&& (requested->screenLayout & MASK_SCREENLONG)) {
@@ -1857,7 +1863,9 @@
myDelta += requested->screenHeight - screenHeight;
otherDelta += requested->screenHeight - o.screenHeight;
}
- return (myDelta <= otherDelta);
+ if (myDelta != otherDelta) {
+ return myDelta < otherDelta;
+ }
}
if (version || o.version) {
@@ -2150,7 +2158,7 @@
res.append("nodpi");
break;
default:
- res.appendFormat("density=%d", dtohs(density));
+ res.appendFormat("%ddpi", dtohs(density));
break;
}
}
@@ -2440,7 +2448,7 @@
uint32_t bagTypeSpecFlags = 0;
mTable.lock();
const ssize_t N = mTable.getBagLocked(resID, &bag, &bagTypeSpecFlags);
- TABLE_NOISY(LOGV("Applying style 0x%08x to theme %p, count=%d", resID, this, N));
+ TABLE_NOISY(ALOGV("Applying style 0x%08x to theme %p, count=%d", resID, this, N));
if (N < 0) {
mTable.unlock();
return N;
@@ -2506,7 +2514,7 @@
continue;
}
theme_entry* curEntry = curEntries + e;
- TABLE_NOISY(LOGV("Attr 0x%08x: type=0x%x, data=0x%08x; curType=0x%x",
+ TABLE_NOISY(ALOGV("Attr 0x%08x: type=0x%x, data=0x%08x; curType=0x%x",
attrRes, bag->map.value.dataType, bag->map.value.data,
curEntry->value.dataType));
if (force || curEntry->value.dataType == Res_value::TYPE_NULL) {
@@ -2577,22 +2585,22 @@
const uint32_t t = Res_GETTYPE(resID);
const uint32_t e = Res_GETENTRY(resID);
- TABLE_THEME(LOGI("Looking up attr 0x%08x in theme %p", resID, this));
+ TABLE_THEME(ALOGI("Looking up attr 0x%08x in theme %p", resID, this));
if (p >= 0) {
const package_info* const pi = mPackages[p];
- TABLE_THEME(LOGI("Found package: %p", pi));
+ TABLE_THEME(ALOGI("Found package: %p", pi));
if (pi != NULL) {
- TABLE_THEME(LOGI("Desired type index is %ld in avail %d", t, pi->numTypes));
+ TABLE_THEME(ALOGI("Desired type index is %ld in avail %d", t, pi->numTypes));
if (t < pi->numTypes) {
const type_info& ti = pi->types[t];
- TABLE_THEME(LOGI("Desired entry index is %ld in avail %d", e, ti.numEntries));
+ TABLE_THEME(ALOGI("Desired entry index is %ld in avail %d", e, ti.numEntries));
if (e < ti.numEntries) {
const theme_entry& te = ti.entries[e];
if (outTypeSpecFlags != NULL) {
*outTypeSpecFlags |= te.typeSpecFlags;
}
- TABLE_THEME(LOGI("Theme value: type=0x%x, data=0x%08x",
+ TABLE_THEME(ALOGI("Theme value: type=0x%x, data=0x%08x",
te.value.dataType, te.value.data));
const uint8_t type = te.value.dataType;
if (type == Res_value::TYPE_ATTRIBUTE) {
@@ -2627,7 +2635,7 @@
if (inOutValue->dataType == Res_value::TYPE_ATTRIBUTE) {
uint32_t newTypeSpecFlags;
blockIndex = getAttribute(inOutValue->data, inOutValue, &newTypeSpecFlags);
- TABLE_THEME(LOGI("Resolving attr reference: blockIndex=%d, type=0x%x, data=%p\n",
+ TABLE_THEME(ALOGI("Resolving attr reference: blockIndex=%d, type=0x%x, data=%p\n",
(int)blockIndex, (int)inOutValue->dataType, (void*)inOutValue->data));
if (inoutTypeSpecFlags != NULL) *inoutTypeSpecFlags |= newTypeSpecFlags;
//printf("Retrieved attribute new type=0x%x\n", inOutValue->dataType);
@@ -2772,7 +2780,7 @@
header->size = dtohl(header->header->header.size);
//ALOGI("Got size 0x%x, again size 0x%x, raw size 0x%x\n", header->size,
// dtohl(header->header->header.size), header->header->header.size);
- LOAD_TABLE_NOISY(LOGV("Loading ResTable @%p:\n", header->header));
+ LOAD_TABLE_NOISY(ALOGV("Loading ResTable @%p:\n", header->header));
LOAD_TABLE_NOISY(printHexData(2, header->header, header->size < 256 ? header->size : 256,
16, 16, 0, false, printToLogFunc));
if (dtohs(header->header->header.headerSize) > header->size
@@ -2802,7 +2810,7 @@
if (err != NO_ERROR) {
return (mError=err);
}
- TABLE_NOISY(LOGV("Chunk: type=0x%x, headerSize=0x%x, size=0x%x, pos=%p\n",
+ TABLE_NOISY(ALOGV("Chunk: type=0x%x, headerSize=0x%x, size=0x%x, pos=%p\n",
dtohs(chunk->type), dtohs(chunk->headerSize), dtohl(chunk->size),
(void*)(((const uint8_t*)chunk) - ((const uint8_t*)header->header))));
const size_t csize = dtohl(chunk->size);
@@ -2856,7 +2864,7 @@
ALOGW("No string values found in resource table!");
}
- TABLE_NOISY(LOGV("Returning from add with mError=%d\n", mError));
+ TABLE_NOISY(ALOGV("Returning from add with mError=%d\n", mError));
return mError;
}
@@ -3127,7 +3135,7 @@
if (newIndex == BAD_INDEX) {
return BAD_INDEX;
}
- TABLE_THEME(LOGI("Resolving reference %p: newIndex=%d, type=0x%x, data=%p\n",
+ TABLE_THEME(ALOGI("Resolving reference %p: newIndex=%d, type=0x%x, data=%p\n",
(void*)lastRef, (int)newIndex, (int)value->dataType, (void*)value->data));
//printf("Getting reference 0x%08x: newIndex=%d\n", value->data, newIndex);
if (inoutTypeSpecFlags != NULL) *inoutTypeSpecFlags |= newFlags;
@@ -3268,7 +3276,7 @@
// This is what we are building.
bag_set* set = NULL;
- TABLE_NOISY(LOGI("Building bag: %p\n", (void*)resID));
+ TABLE_NOISY(ALOGI("Building bag: %p\n", (void*)resID));
ResTable_config bestConfig;
memset(&bestConfig, 0, sizeof(bestConfig));
@@ -3338,7 +3346,7 @@
size_t N = count;
- TABLE_NOISY(LOGI("Found map: size=%p parent=%p count=%d\n",
+ TABLE_NOISY(ALOGI("Found map: size=%p parent=%p count=%d\n",
entrySize, parent, count));
// If this map inherits from another, we need to start
@@ -3357,9 +3365,9 @@
if (NP > 0) {
memcpy(set+1, parentBag, NP*sizeof(bag_entry));
set->numAttrs = NP;
- TABLE_NOISY(LOGI("Initialized new bag with %d inherited attributes.\n", NP));
+ TABLE_NOISY(ALOGI("Initialized new bag with %d inherited attributes.\n", NP));
} else {
- TABLE_NOISY(LOGI("Initialized new bag with no inherited attributes.\n"));
+ TABLE_NOISY(ALOGI("Initialized new bag with no inherited attributes.\n"));
set->numAttrs = 0;
}
set->availAttrs = NT;
@@ -3386,7 +3394,7 @@
bag_entry* entries = (bag_entry*)(set+1);
size_t curEntry = 0;
uint32_t pos = 0;
- TABLE_NOISY(LOGI("Starting with set %p, entries=%p, avail=%d\n",
+ TABLE_NOISY(ALOGI("Starting with set %p, entries=%p, avail=%d\n",
set, entries, set->availAttrs));
while (pos < count) {
TABLE_NOISY(printf("Now at %p\n", (void*)curOff));
@@ -3465,7 +3473,7 @@
*outTypeSpecFlags = set->typeSpecFlags;
}
*outBag = (bag_entry*)(set+1);
- TABLE_NOISY(LOGI("Returning %d attrs\n", set->numAttrs));
+ TABLE_NOISY(ALOGI("Returning %d attrs\n", set->numAttrs));
return set->numAttrs;
}
return BAD_INDEX;
@@ -3474,27 +3482,10 @@
void ResTable::setParameters(const ResTable_config* params)
{
mLock.lock();
- TABLE_GETENTRY(LOGI("Setting parameters: imsi:%d/%d lang:%c%c cnt:%c%c "
- "orien:%d touch:%d density:%d key:%d inp:%d nav:%d sz:%dx%d sw%ddp w%ddp h%ddp\n",
- params->mcc, params->mnc,
- params->language[0] ? params->language[0] : '-',
- params->language[1] ? params->language[1] : '-',
- params->country[0] ? params->country[0] : '-',
- params->country[1] ? params->country[1] : '-',
- params->orientation,
- params->touchscreen,
- params->density,
- params->keyboard,
- params->inputFlags,
- params->navigation,
- params->screenWidth,
- params->screenHeight,
- params->smallestScreenWidthDp,
- params->screenWidthDp,
- params->screenHeightDp));
+ TABLE_GETENTRY(ALOGI("Setting parameters: %s\n", params->toString().string()));
mParams = *params;
for (size_t i=0; i<mPackageGroups.size(); i++) {
- TABLE_NOISY(LOGI("CLEARING BAGS FOR GROUP %d!", i));
+ TABLE_NOISY(ALOGI("CLEARING BAGS FOR GROUP %d!", i));
mPackageGroups[i]->clearBagCache();
}
mLock.unlock();
@@ -4840,13 +4831,13 @@
ResTable_config thisConfig;
thisConfig.copyFromDtoH(thisType->config);
- TABLE_GETENTRY(LOGI("Match entry 0x%x in type 0x%x (sz 0x%x): %s\n",
+ TABLE_GETENTRY(ALOGI("Match entry 0x%x in type 0x%x (sz 0x%x): %s\n",
entryIndex, typeIndex+1, dtohl(thisType->config.size),
thisConfig.toString().string()));
// Check to make sure this one is valid for the current parameters.
if (config && !thisConfig.match(*config)) {
- TABLE_GETENTRY(LOGI("Does not match config!\n"));
+ TABLE_GETENTRY(ALOGI("Does not match config!\n"));
continue;
}
@@ -4859,7 +4850,7 @@
uint32_t thisOffset = dtohl(eindex[entryIndex]);
if (thisOffset == ResTable_type::NO_ENTRY) {
- TABLE_GETENTRY(LOGI("Skipping because it is not defined!\n"));
+ TABLE_GETENTRY(ALOGI("Skipping because it is not defined!\n"));
continue;
}
@@ -4868,7 +4859,7 @@
// we will skip it. We check starting with things we most care
// about to those we least care about.
if (!thisConfig.isBetterThan(bestConfig, config)) {
- TABLE_GETENTRY(LOGI("This config is worse than last!\n"));
+ TABLE_GETENTRY(ALOGI("This config is worse than last!\n"));
continue;
}
}
@@ -4876,12 +4867,12 @@
type = thisType;
offset = thisOffset;
bestConfig = thisConfig;
- TABLE_GETENTRY(LOGI("Best entry so far -- using it!\n"));
+ TABLE_GETENTRY(ALOGI("Best entry so far -- using it!\n"));
if (!config) break;
}
if (type == NULL) {
- TABLE_GETENTRY(LOGI("No value found for requested entry!\n"));
+ TABLE_GETENTRY(ALOGI("No value found for requested entry!\n"));
return BAD_INDEX;
}
@@ -5024,7 +5015,7 @@
const uint8_t* endPos = ((const uint8_t*)pkg) + dtohs(pkg->header.size);
while (((const uint8_t*)chunk) <= (endPos-sizeof(ResChunk_header)) &&
((const uint8_t*)chunk) <= (endPos-dtohl(chunk->size))) {
- TABLE_NOISY(LOGV("PackageChunk: type=0x%x, headerSize=0x%x, size=0x%x, pos=%p\n",
+ TABLE_NOISY(ALOGV("PackageChunk: type=0x%x, headerSize=0x%x, size=0x%x, pos=%p\n",
dtohs(chunk->type), dtohs(chunk->headerSize), dtohl(chunk->size),
(void*)(((const uint8_t*)chunk) - ((const uint8_t*)header->header))));
const size_t csize = dtohl(chunk->size);
diff --git a/libs/rs/RenderScript.cpp b/libs/rs/RenderScript.cpp
index 0b42055..217b921 100644
--- a/libs/rs/RenderScript.cpp
+++ b/libs/rs/RenderScript.cpp
@@ -21,6 +21,7 @@
#include <string.h>
#include "RenderScript.h"
+#include "rs.h"
bool RenderScript::gInitialized = false;
pthread_mutex_t RenderScript::gInitMutex = PTHREAD_MUTEX_INITIALIZER;
diff --git a/libs/rs/RenderScript.h b/libs/rs/RenderScript.h
index 0eb6a6d..5ad76e2 100644
--- a/libs/rs/RenderScript.h
+++ b/libs/rs/RenderScript.h
@@ -22,7 +22,7 @@
#include <utils/String8.h>
#include <utils/Vector.h>
-#include "rs.h"
+#include "rsDefines.h"
class Element;
class Type;
diff --git a/libs/rs/driver/rsdGL.cpp b/libs/rs/driver/rsdGL.cpp
index 63bf7cc..fae602c 100644
--- a/libs/rs/driver/rsdGL.cpp
+++ b/libs/rs/driver/rsdGL.cpp
@@ -37,6 +37,7 @@
#include <malloc.h>
#include "rsContext.h"
+#include "rsDevice.h"
#include "rsdShaderCache.h"
#include "rsdVertexArray.h"
#include "rsdFrameBufferObj.h"
diff --git a/libs/rs/rs.h b/libs/rs/rs.h
index fbcaf4a..825b9b8 100644
--- a/libs/rs/rs.h
+++ b/libs/rs/rs.h
@@ -20,10 +20,6 @@
#include <stdint.h>
#include <sys/types.h>
-#ifdef __cplusplus
-extern "C" {
-#endif
-
#include "rsDefines.h"
//
@@ -61,10 +57,6 @@
#include "rsgApiFuncDecl.h"
-#ifdef __cplusplus
-};
-#endif
-
#endif // RENDER_SCRIPT_H
diff --git a/libs/rs/rsAdapter.cpp b/libs/rs/rsAdapter.cpp
index 177fb60..41811ae 100644
--- a/libs/rs/rsAdapter.cpp
+++ b/libs/rs/rsAdapter.cpp
@@ -16,6 +16,7 @@
*/
#include "rsContext.h"
+#include "rsAdapter.h"
using namespace android;
using namespace android::renderscript;
diff --git a/libs/rs/rsAllocation.cpp b/libs/rs/rsAllocation.cpp
index 83c88fd..a404c49 100644
--- a/libs/rs/rsAllocation.cpp
+++ b/libs/rs/rsAllocation.cpp
@@ -15,6 +15,8 @@
*/
#include "rsContext.h"
+#include "rsAllocation.h"
+#include "rsAdapter.h"
#include "rs_hal.h"
#include "system/window.h"
diff --git a/libs/rs/rsAnimation.h b/libs/rs/rsAnimation.h
index bff8d6f..526a081 100644
--- a/libs/rs/rsAnimation.h
+++ b/libs/rs/rsAnimation.h
@@ -19,7 +19,7 @@
#include "rsUtils.h"
#include "rsObjectBase.h"
-
+#include "rsDefines.h"
// ---------------------------------------------------------------------------
namespace android {
namespace renderscript {
diff --git a/libs/rs/rsComponent.h b/libs/rs/rsComponent.h
index 8629d0d..a2e8c0f 100644
--- a/libs/rs/rsComponent.h
+++ b/libs/rs/rsComponent.h
@@ -18,6 +18,7 @@
#define ANDROID_COMPONENT_H
#include "rsUtils.h"
+#include "rsDefines.h"
// ---------------------------------------------------------------------------
namespace android {
diff --git a/libs/rs/rsContext.cpp b/libs/rs/rsContext.cpp
index 0f3cea7..1b51872 100644
--- a/libs/rs/rsContext.cpp
+++ b/libs/rs/rsContext.cpp
@@ -14,9 +14,11 @@
* limitations under the License.
*/
+#include "rs.h"
#include "rsDevice.h"
#include "rsContext.h"
#include "rsThreadIO.h"
+#include "rsMesh.h"
#include <ui/FramebufferNativeWindow.h>
#include <gui/DisplayEventReceiver.h>
diff --git a/libs/rs/rsContext.h b/libs/rs/rsContext.h
index 05c799e..0f44267 100644
--- a/libs/rs/rsContext.h
+++ b/libs/rs/rsContext.h
@@ -18,18 +18,10 @@
#define ANDROID_RS_CONTEXT_H
#include "rsUtils.h"
-#include "rsType.h"
-#include "rsAllocation.h"
-#include "rsMesh.h"
-
#include "rs_hal.h"
-#include "rsMutex.h"
#include "rsThreadIO.h"
-#include "rsMatrix4x4.h"
-#include "rsDevice.h"
#include "rsScriptC.h"
-#include "rsAdapter.h"
#include "rsSampler.h"
#include "rsFont.h"
#include "rsPath.h"
@@ -39,13 +31,13 @@
#include "rsProgramVertex.h"
#include "rsFBOCache.h"
-#include "rsgApiStructs.h"
-
// ---------------------------------------------------------------------------
namespace android {
namespace renderscript {
+class Device;
+
#if 0
#define CHECK_OBJ(o) { \
GET_TLS(); \
diff --git a/libs/rs/rsElement.h b/libs/rs/rsElement.h
index 4b6b460..b86d3bc 100644
--- a/libs/rs/rsElement.h
+++ b/libs/rs/rsElement.h
@@ -19,6 +19,7 @@
#include "rsComponent.h"
#include "rsUtils.h"
+#include "rsDefines.h"
#include "rsObjectBase.h"
// ---------------------------------------------------------------------------
diff --git a/libs/rs/rsFileA3D.cpp b/libs/rs/rsFileA3D.cpp
index ac658c8..173b9a5 100644
--- a/libs/rs/rsFileA3D.cpp
+++ b/libs/rs/rsFileA3D.cpp
@@ -20,7 +20,7 @@
#include "rsMesh.h"
#include "rsAnimation.h"
-
+#include "rs.h"
using namespace android;
using namespace android::renderscript;
diff --git a/libs/rs/rsFileA3D.h b/libs/rs/rsFileA3D.h
index baf81de5..08062c6 100644
--- a/libs/rs/rsFileA3D.h
+++ b/libs/rs/rsFileA3D.h
@@ -17,7 +17,6 @@
#ifndef ANDROID_RS_FILE_A3D_H
#define ANDROID_RS_FILE_A3D_H
-#include "rs.h"
#include "rsMesh.h"
#include <androidfw/Asset.h>
diff --git a/libs/rs/rsFont.cpp b/libs/rs/rsFont.cpp
index c4276cf..1f53c79 100644
--- a/libs/rs/rsFont.cpp
+++ b/libs/rs/rsFont.cpp
@@ -16,9 +16,10 @@
*/
#include "rsContext.h"
-
+#include "rs.h"
#include "rsFont.h"
#include "rsProgramFragment.h"
+#include "rsMesh.h"
#include <cutils/properties.h>
#ifndef ANDROID_RS_SERIALIZE
diff --git a/libs/rs/rsFont.h b/libs/rs/rsFont.h
index 88c4795..2bd30b7 100644
--- a/libs/rs/rsFont.h
+++ b/libs/rs/rsFont.h
@@ -17,7 +17,6 @@
#ifndef ANDROID_RS_FONT_H
#define ANDROID_RS_FONT_H
-#include "rs.h"
#include "rsStream.h"
#include <utils/String8.h>
#include <utils/Vector.h>
diff --git a/libs/rs/rsMesh.cpp b/libs/rs/rsMesh.cpp
index 67c7299..399a52b 100644
--- a/libs/rs/rsMesh.cpp
+++ b/libs/rs/rsMesh.cpp
@@ -15,6 +15,8 @@
*/
#include "rsContext.h"
+#include "rsMesh.h"
+#include "rs.h"
using namespace android;
using namespace android::renderscript;
diff --git a/libs/rs/rsMesh.h b/libs/rs/rsMesh.h
index 8eea427..7ca63cf 100644
--- a/libs/rs/rsMesh.h
+++ b/libs/rs/rsMesh.h
@@ -18,7 +18,7 @@
#define ANDROID_RS_MESH_H
-#include "rs.h"
+#include "rsObjectBase.h"
// ---------------------------------------------------------------------------
namespace android {
diff --git a/libs/rs/rsObjectBase.h b/libs/rs/rsObjectBase.h
index d9f5f3b..586da19 100644
--- a/libs/rs/rsObjectBase.h
+++ b/libs/rs/rsObjectBase.h
@@ -18,6 +18,7 @@
#define ANDROID_RS_OBJECT_BASE_H
#include "rsUtils.h"
+#include "rsDefines.h"
#define RS_OBJECT_DEBUG 0
diff --git a/libs/rs/rsPath.cpp b/libs/rs/rsPath.cpp
index c4f4978..055bb86 100644
--- a/libs/rs/rsPath.cpp
+++ b/libs/rs/rsPath.cpp
@@ -15,6 +15,7 @@
*/
#include "rsContext.h"
+#include "rs.h"
using namespace android;
using namespace android::renderscript;
diff --git a/libs/rs/rsPath.h b/libs/rs/rsPath.h
index 7c05503..1abfc9a 100644
--- a/libs/rs/rsPath.h
+++ b/libs/rs/rsPath.h
@@ -18,7 +18,7 @@
#define ANDROID_RS_PATH_H
-#include "rs.h"
+#include "rsObjectBase.h"
// ---------------------------------------------------------------------------
namespace android {
diff --git a/libs/rs/rsProgramVertex.cpp b/libs/rs/rsProgramVertex.cpp
index c8a53ea..23fcbe7 100644
--- a/libs/rs/rsProgramVertex.cpp
+++ b/libs/rs/rsProgramVertex.cpp
@@ -16,6 +16,7 @@
#include "rsContext.h"
#include "rsProgramVertex.h"
+#include "rsMatrix4x4.h"
using namespace android;
using namespace android::renderscript;
diff --git a/libs/rs/rsSampler.cpp b/libs/rs/rsSampler.cpp
index 5fc64a4..c7180bd 100644
--- a/libs/rs/rsSampler.cpp
+++ b/libs/rs/rsSampler.cpp
@@ -16,7 +16,7 @@
#include "rsContext.h"
#include "rsSampler.h"
-
+#include "rs.h"
using namespace android;
using namespace android::renderscript;
diff --git a/libs/rs/rsSampler.h b/libs/rs/rsSampler.h
index 013e4ca..dea4cb6 100644
--- a/libs/rs/rsSampler.h
+++ b/libs/rs/rsSampler.h
@@ -18,7 +18,6 @@
#define ANDROID_RS_SAMPLER_H
#include "rsAllocation.h"
-#include "rs.h"
// ---------------------------------------------------------------------------
namespace android {
diff --git a/libs/rs/rsScriptC_Lib.cpp b/libs/rs/rsScriptC_Lib.cpp
index a5a0fae..749495d 100644
--- a/libs/rs/rsScriptC_Lib.cpp
+++ b/libs/rs/rsScriptC_Lib.cpp
@@ -19,6 +19,7 @@
#include "rsMatrix4x4.h"
#include "rsMatrix3x3.h"
#include "rsMatrix2x2.h"
+#include "rsgApiStructs.h"
#include "utils/Timers.h"
diff --git a/libs/rs/rsScriptC_LibGL.cpp b/libs/rs/rsScriptC_LibGL.cpp
index bda18fd..21b1c42 100644
--- a/libs/rs/rsScriptC_LibGL.cpp
+++ b/libs/rs/rsScriptC_LibGL.cpp
@@ -19,6 +19,8 @@
#include "rsMatrix4x4.h"
#include "rsMatrix3x3.h"
#include "rsMatrix2x2.h"
+#include "rsMesh.h"
+#include "rsgApiStructs.h"
#include "utils/Timers.h"
#include "driver/rsdVertexArray.h"
diff --git a/libs/rs/rsThreadIO.cpp b/libs/rs/rsThreadIO.cpp
index 7182f53..8a0a5dc 100644
--- a/libs/rs/rsThreadIO.cpp
+++ b/libs/rs/rsThreadIO.cpp
@@ -15,8 +15,8 @@
*/
#include "rsContext.h"
-
#include "rsThreadIO.h"
+#include "rsgApiStructs.h"
#include <unistd.h>
#include <sys/types.h>
diff --git a/libs/rs/rsType.cpp b/libs/rs/rsType.cpp
index 70ab7b7..9ac553e 100644
--- a/libs/rs/rsType.cpp
+++ b/libs/rs/rsType.cpp
@@ -20,9 +20,8 @@
using namespace android::renderscript;
Type::Type(Context *rsc) : ObjectBase(rsc) {
- mLODs = 0;
- mLODCount = 0;
- clear();
+ memset(&mHal, 0, sizeof(mHal));
+ mDimLOD = false;
}
void Type::preDestroy() const {
@@ -35,16 +34,15 @@
}
Type::~Type() {
- if (mLODs) {
- delete [] mLODs;
- mLODs = NULL;
- }
+ clear();
}
void Type::clear() {
- if (mLODs) {
- delete [] mLODs;
- mLODs = NULL;
+ if (mHal.state.lodCount) {
+ delete [] mHal.state.lodDimX;
+ delete [] mHal.state.lodDimY;
+ delete [] mHal.state.lodDimZ;
+ delete [] mHal.state.lodOffset;
}
mElement.clear();
memset(&mHal, 0, sizeof(mHal));
@@ -63,33 +61,39 @@
}
void Type::compute() {
- uint32_t oldLODCount = mLODCount;
- if (mHal.state.dimLOD) {
+ uint32_t oldLODCount = mHal.state.lodCount;
+ if (mDimLOD) {
uint32_t l2x = rsFindHighBit(mHal.state.dimX) + 1;
uint32_t l2y = rsFindHighBit(mHal.state.dimY) + 1;
uint32_t l2z = rsFindHighBit(mHal.state.dimZ) + 1;
- mLODCount = rsMax(l2x, l2y);
- mLODCount = rsMax(mLODCount, l2z);
+ mHal.state.lodCount = rsMax(l2x, l2y);
+ mHal.state.lodCount = rsMax(mHal.state.lodCount, l2z);
} else {
- mLODCount = 1;
+ mHal.state.lodCount = 1;
}
- if (mLODCount != oldLODCount) {
- if (mLODs){
- delete [] mLODs;
+ if (mHal.state.lodCount != oldLODCount) {
+ if (oldLODCount) {
+ delete [] mHal.state.lodDimX;
+ delete [] mHal.state.lodDimY;
+ delete [] mHal.state.lodDimZ;
+ delete [] mHal.state.lodOffset;
}
- mLODs = new LOD[mLODCount];
+ mHal.state.lodDimX = new uint32_t[mHal.state.lodCount];
+ mHal.state.lodDimY = new uint32_t[mHal.state.lodCount];
+ mHal.state.lodDimZ = new uint32_t[mHal.state.lodCount];
+ mHal.state.lodOffset = new uint32_t[mHal.state.lodCount];
}
uint32_t tx = mHal.state.dimX;
uint32_t ty = mHal.state.dimY;
uint32_t tz = mHal.state.dimZ;
size_t offset = 0;
- for (uint32_t lod=0; lod < mLODCount; lod++) {
- mLODs[lod].mX = tx;
- mLODs[lod].mY = ty;
- mLODs[lod].mZ = tz;
- mLODs[lod].mOffset = offset;
+ for (uint32_t lod=0; lod < mHal.state.lodCount; lod++) {
+ mHal.state.lodDimX[lod] = tx;
+ mHal.state.lodDimY[lod] = ty;
+ mHal.state.lodDimZ[lod] = tz;
+ mHal.state.lodOffset[lod] = offset;
offset += tx * rsMax(ty, 1u) * rsMax(tz, 1u) * mElement->getSizeBytes();
if (tx > 1) tx >>= 1;
if (ty > 1) ty >>= 1;
@@ -107,27 +111,29 @@
}
uint32_t Type::getLODOffset(uint32_t lod, uint32_t x) const {
- uint32_t offset = mLODs[lod].mOffset;
+ uint32_t offset = mHal.state.lodOffset[lod];
offset += x * mElement->getSizeBytes();
return offset;
}
uint32_t Type::getLODOffset(uint32_t lod, uint32_t x, uint32_t y) const {
- uint32_t offset = mLODs[lod].mOffset;
- offset += (x + y * mLODs[lod].mX) * mElement->getSizeBytes();
+ uint32_t offset = mHal.state.lodOffset[lod];
+ offset += (x + y * mHal.state.lodDimX[lod]) * mElement->getSizeBytes();
return offset;
}
uint32_t Type::getLODOffset(uint32_t lod, uint32_t x, uint32_t y, uint32_t z) const {
- uint32_t offset = mLODs[lod].mOffset;
- offset += (x + y*mLODs[lod].mX + z*mLODs[lod].mX*mLODs[lod].mY) * mElement->getSizeBytes();
+ uint32_t offset = mHal.state.lodOffset[lod];
+ offset += (x +
+ y * mHal.state.lodDimX[lod] +
+ z * mHal.state.lodDimX[lod] * mHal.state.lodDimY[lod]) * mElement->getSizeBytes();
return offset;
}
uint32_t Type::getLODFaceOffset(uint32_t lod, RsAllocationCubemapFace face,
uint32_t x, uint32_t y) const {
- uint32_t offset = mLODs[lod].mOffset;
- offset += (x + y * mLODs[lod].mX) * mElement->getSizeBytes();
+ uint32_t offset = mHal.state.lodOffset[lod];
+ offset += (x + y * mHal.state.lodDimX[lod]) * mElement->getSizeBytes();
if (face != 0) {
uint32_t faceOffset = getSizeBytes() / 6;
@@ -143,7 +149,7 @@
mHal.state.dimX,
mHal.state.dimY,
mHal.state.dimZ,
- mHal.state.dimLOD,
+ mHal.state.lodCount,
mHal.state.faces);
snprintf(buf, sizeof(buf), "%s element: ", prefix);
mElement->dumpLOGV(buf);
@@ -162,7 +168,7 @@
stream->addU32(mHal.state.dimY);
stream->addU32(mHal.state.dimZ);
- stream->addU8((uint8_t)(mHal.state.dimLOD ? 1 : 0));
+ stream->addU8((uint8_t)(mHal.state.lodCount ? 1 : 0));
stream->addU8((uint8_t)(mHal.state.faces ? 1 : 0));
}
@@ -233,12 +239,12 @@
Type *nt = new Type(rsc);
+ nt->mDimLOD = dimLOD;
returnRef.set(nt);
nt->mElement.set(e);
nt->mHal.state.dimX = dimX;
nt->mHal.state.dimY = dimY;
nt->mHal.state.dimZ = dimZ;
- nt->mHal.state.dimLOD = dimLOD;
nt->mHal.state.faces = dimFaces;
nt->compute();
@@ -251,14 +257,14 @@
ObjectBaseRef<Type> Type::cloneAndResize1D(Context *rsc, uint32_t dimX) const {
return getTypeRef(rsc, mElement.get(), dimX,
- mHal.state.dimY, mHal.state.dimZ, mHal.state.dimLOD, mHal.state.faces);
+ mHal.state.dimY, mHal.state.dimZ, mHal.state.lodCount, mHal.state.faces);
}
ObjectBaseRef<Type> Type::cloneAndResize2D(Context *rsc,
uint32_t dimX,
uint32_t dimY) const {
return getTypeRef(rsc, mElement.get(), dimX, dimY,
- mHal.state.dimZ, mHal.state.dimLOD, mHal.state.faces);
+ mHal.state.dimZ, mHal.state.lodCount, mHal.state.faces);
}
@@ -280,13 +286,13 @@
void rsaTypeGetNativeData(RsContext con, RsType type, uint32_t *typeData, uint32_t typeDataSize) {
rsAssert(typeDataSize == 6);
// Pack the data in the follofing way mHal.state.dimX; mHal.state.dimY; mHal.state.dimZ;
- // mHal.state.dimLOD; mHal.state.faces; mElement; into typeData
+ // mHal.state.lodCount; mHal.state.faces; mElement; into typeData
Type *t = static_cast<Type *>(type);
(*typeData++) = t->getDimX();
(*typeData++) = t->getDimY();
(*typeData++) = t->getDimZ();
- (*typeData++) = t->getDimLOD();
+ (*typeData++) = t->getDimLOD() ? 1 : 0;
(*typeData++) = t->getDimFaces() ? 1 : 0;
(*typeData++) = (uint32_t)t->getElement();
t->getElement()->incUserRef();
diff --git a/libs/rs/rsType.h b/libs/rs/rsType.h
index 3878156..f1aeb0a 100644
--- a/libs/rs/rsType.h
+++ b/libs/rs/rsType.h
@@ -44,7 +44,11 @@
uint32_t dimX;
uint32_t dimY;
uint32_t dimZ;
- bool dimLOD;
+ uint32_t *lodDimX;
+ uint32_t *lodDimY;
+ uint32_t *lodDimZ;
+ uint32_t *lodOffset;
+ uint32_t lodCount;
bool faces;
};
State state;
@@ -62,15 +66,24 @@
uint32_t getDimX() const {return mHal.state.dimX;}
uint32_t getDimY() const {return mHal.state.dimY;}
uint32_t getDimZ() const {return mHal.state.dimZ;}
- uint32_t getDimLOD() const {return mHal.state.dimLOD;}
+ bool getDimLOD() const {return mDimLOD;}
bool getDimFaces() const {return mHal.state.faces;}
- uint32_t getLODDimX(uint32_t lod) const {rsAssert(lod < mLODCount); return mLODs[lod].mX;}
- uint32_t getLODDimY(uint32_t lod) const {rsAssert(lod < mLODCount); return mLODs[lod].mY;}
- uint32_t getLODDimZ(uint32_t lod) const {rsAssert(lod < mLODCount); return mLODs[lod].mZ;}
-
+ uint32_t getLODDimX(uint32_t lod) const {
+ rsAssert(lod < mHal.state.lodCount);
+ return mHal.state.lodDimX[lod];
+ }
+ uint32_t getLODDimY(uint32_t lod) const {
+ rsAssert(lod < mHal.state.lodCount);
+ return mHal.state.lodDimY[lod];
+ }
+ uint32_t getLODDimZ(uint32_t lod) const {
+ rsAssert(lod < mHal.state.lodCount);
+ return mHal.state.lodDimZ[lod];
+ }
uint32_t getLODOffset(uint32_t lod) const {
- rsAssert(lod < mLODCount); return mLODs[lod].mOffset;
+ rsAssert(lod < mHal.state.lodCount);
+ return mHal.state.lodOffset[lod];
}
uint32_t getLODOffset(uint32_t lod, uint32_t x) const;
uint32_t getLODOffset(uint32_t lod, uint32_t x, uint32_t y) const;
@@ -79,7 +92,7 @@
uint32_t getLODFaceOffset(uint32_t lod, RsAllocationCubemapFace face,
uint32_t x, uint32_t y) const;
- uint32_t getLODCount() const {return mLODCount;}
+ uint32_t getLODCount() const {return mHal.state.lodCount;}
bool getIsNp2() const;
void clear();
@@ -106,14 +119,8 @@
}
protected:
- struct LOD {
- size_t mX;
- size_t mY;
- size_t mZ;
- size_t mOffset;
- };
-
void makeLODTable();
+ bool mDimLOD;
// Internal structure from most to least significant.
// * Array dimensions
@@ -127,9 +134,6 @@
size_t mMipChainSizeBytes;
size_t mTotalSizeBytes;
- LOD *mLODs;
- uint32_t mLODCount;
-
protected:
virtual void preDestroy() const;
virtual ~Type();
diff --git a/libs/rs/rsUtils.h b/libs/rs/rsUtils.h
index a9a992a..cbbae6c 100644
--- a/libs/rs/rsUtils.h
+++ b/libs/rs/rsUtils.h
@@ -34,8 +34,6 @@
#include <math.h>
-#include "rs.h"
-
namespace android {
namespace renderscript {
diff --git a/libs/rs/rsg_generator.c b/libs/rs/rsg_generator.c
index 99c305e..c0f82dc 100644
--- a/libs/rs/rsg_generator.c
+++ b/libs/rs/rsg_generator.c
@@ -187,7 +187,7 @@
fprintf(f, "#include \"rsDevice.h\"\n");
fprintf(f, "#include \"rsContext.h\"\n");
fprintf(f, "#include \"rsThreadIO.h\"\n");
- //fprintf(f, "#include \"rsgApiStructs.h\"\n");
+ fprintf(f, "#include \"rsgApiStructs.h\"\n");
fprintf(f, "#include \"rsgApiFuncDecl.h\"\n");
fprintf(f, "#include \"rsFifo.h\"\n");
fprintf(f, "\n");
@@ -408,6 +408,7 @@
fprintf(f, "#include \"rsDevice.h\"\n");
fprintf(f, "#include \"rsContext.h\"\n");
fprintf(f, "#include \"rsThreadIO.h\"\n");
+ fprintf(f, "#include \"rsgApiStructs.h\"\n");
fprintf(f, "#include \"rsgApiFuncDecl.h\"\n");
fprintf(f, "\n");
fprintf(f, "namespace android {\n");
diff --git a/media/jni/android_media_MediaPlayer.cpp b/media/jni/android_media_MediaPlayer.cpp
index 6ec5d20..f572f71 100644
--- a/media/jni/android_media_MediaPlayer.cpp
+++ b/media/jni/android_media_MediaPlayer.cpp
@@ -36,6 +36,7 @@
#include "utils/String8.h"
#include "android_media_Utils.h"
+#include "android_os_Parcel.h"
#include "android_util_Binder.h"
#include <binder/Parcel.h>
#include <gui/ISurfaceTexture.h>
diff --git a/media/libmedia/AudioSystem.cpp b/media/libmedia/AudioSystem.cpp
index e0b186a..a1cbf0f 100644
--- a/media/libmedia/AudioSystem.cpp
+++ b/media/libmedia/AudioSystem.cpp
@@ -701,10 +701,10 @@
return aps->getStrategyForStream(stream);
}
-uint32_t AudioSystem::getDevicesForStream(audio_stream_type_t stream)
+audio_devices_t AudioSystem::getDevicesForStream(audio_stream_type_t stream)
{
const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
- if (aps == 0) return 0;
+ if (aps == 0) return (audio_devices_t)0;
return aps->getDevicesForStream(stream);
}
diff --git a/media/libmedia/IAudioPolicyService.cpp b/media/libmedia/IAudioPolicyService.cpp
index 99385aa4..da7c124 100644
--- a/media/libmedia/IAudioPolicyService.cpp
+++ b/media/libmedia/IAudioPolicyService.cpp
@@ -267,13 +267,13 @@
return reply.readInt32();
}
- virtual uint32_t getDevicesForStream(audio_stream_type_t stream)
+ virtual audio_devices_t getDevicesForStream(audio_stream_type_t stream)
{
Parcel data, reply;
data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
data.writeInt32(static_cast <uint32_t>(stream));
remote()->transact(GET_DEVICES_FOR_STREAM, data, &reply);
- return (uint32_t) reply.readInt32();
+ return (audio_devices_t) reply.readInt32();
}
virtual audio_io_handle_t getOutputForEffect(effect_descriptor_t *desc)
diff --git a/media/libstagefright/AudioPlayer.cpp b/media/libstagefright/AudioPlayer.cpp
index 650b6c4..2b3cb1a 100644
--- a/media/libstagefright/AudioPlayer.cpp
+++ b/media/libstagefright/AudioPlayer.cpp
@@ -437,8 +437,11 @@
kKeyTime, &mPositionTimeMediaUs));
mPositionTimeRealUs =
- ((mNumFramesPlayed + size_done / mFrameSize) * 1000000)
+ -mLatencyUs + ((mNumFramesPlayed + size_done / mFrameSize) * 1000000)
/ mSampleRate;
+ if (mPositionTimeRealUs < 0) {
+ mPositionTimeRealUs = 0;
+ }
ALOGV("buffer->size() = %d, "
"mPositionTimeMediaUs=%.2f mPositionTimeRealUs=%.2f",
@@ -493,7 +496,9 @@
int64_t AudioPlayer::getRealTimeUsLocked() const {
CHECK(mStarted);
CHECK_NE(mSampleRate, 0);
- return -mLatencyUs + (mNumFramesPlayed * 1000000) / mSampleRate;
+ int64_t t = -mLatencyUs + (mNumFramesPlayed * 1000000) / mSampleRate;
+ if (t < 0) return 0;
+ return t;
}
int64_t AudioPlayer::getMediaTimeUs() {
diff --git a/media/libstagefright/AwesomePlayer.cpp b/media/libstagefright/AwesomePlayer.cpp
index b21e86a..9e00bb3 100644
--- a/media/libstagefright/AwesomePlayer.cpp
+++ b/media/libstagefright/AwesomePlayer.cpp
@@ -2108,6 +2108,8 @@
mWVMExtractor = new WVMExtractor(dataSource);
mWVMExtractor->setAdaptiveStreamingMode(true);
+ if (mUIDValid)
+ mWVMExtractor->setUID(mUID);
extractor = mWVMExtractor;
} else {
extractor = MediaExtractor::Create(
diff --git a/media/libstagefright/WVMExtractor.cpp b/media/libstagefright/WVMExtractor.cpp
index c7ad513..dac8106 100644
--- a/media/libstagefright/WVMExtractor.cpp
+++ b/media/libstagefright/WVMExtractor.cpp
@@ -123,6 +123,12 @@
}
}
+void WVMExtractor::setUID(uid_t uid) {
+ if (mImpl != NULL) {
+ mImpl->setUID(uid);
+ }
+}
+
bool SniffWVM(
const sp<DataSource> &source, String8 *mimeType, float *confidence,
sp<AMessage> *) {
diff --git a/media/libstagefright/include/WVMExtractor.h b/media/libstagefright/include/WVMExtractor.h
index 9f763f9..3c3ca89 100644
--- a/media/libstagefright/include/WVMExtractor.h
+++ b/media/libstagefright/include/WVMExtractor.h
@@ -34,6 +34,7 @@
virtual int64_t getCachedDurationUs(status_t *finalStatus) = 0;
virtual void setAdaptiveStreamingMode(bool adaptive) = 0;
+ virtual void setUID(uid_t uid) = 0;
};
class WVMExtractor : public MediaExtractor {
@@ -60,6 +61,8 @@
// is used.
void setAdaptiveStreamingMode(bool adaptive);
+ void setUID(uid_t uid);
+
static bool getVendorLibHandle();
protected:
diff --git a/packages/SystemUI/res/layout-sw600dp/status_bar.xml b/packages/SystemUI/res/layout-sw600dp/status_bar.xml
index b96c357..2308bf0 100644
--- a/packages/SystemUI/res/layout-sw600dp/status_bar.xml
+++ b/packages/SystemUI/res/layout-sw600dp/status_bar.xml
@@ -54,7 +54,7 @@
android:clipToPadding="false"
>
<com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/back"
- android:layout_width="80dip"
+ android:layout_width="@dimen/navigation_key_width"
android:layout_height="match_parent"
android:src="@drawable/ic_sysbar_back"
systemui:keyCode="4"
@@ -62,7 +62,7 @@
systemui:glowBackground="@drawable/ic_sysbar_highlight"
/>
<com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/home"
- android:layout_width="80dip"
+ android:layout_width="@dimen/navigation_key_width"
android:layout_height="match_parent"
android:src="@drawable/ic_sysbar_home"
systemui:keyCode="3"
@@ -70,14 +70,14 @@
systemui:glowBackground="@drawable/ic_sysbar_highlight"
/>
<com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/recent_apps"
- android:layout_width="80dip"
+ android:layout_width="@dimen/navigation_key_width"
android:layout_height="match_parent"
android:src="@drawable/ic_sysbar_recent"
android:contentDescription="@string/accessibility_recent"
systemui:glowBackground="@drawable/ic_sysbar_highlight"
/>
<com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/menu"
- android:layout_width="80dip"
+ android:layout_width="@dimen/navigation_menu_key_width"
android:layout_height="match_parent"
android:src="@drawable/ic_sysbar_menu"
systemui:keyCode="82"
diff --git a/packages/SystemUI/res/layout/navigation_bar.xml b/packages/SystemUI/res/layout/navigation_bar.xml
index 82fcc88..bb80098 100644
--- a/packages/SystemUI/res/layout/navigation_bar.xml
+++ b/packages/SystemUI/res/layout/navigation_bar.xml
@@ -49,7 +49,7 @@
android:visibility="invisible"
/>
<com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/back"
- android:layout_width="80dp"
+ android:layout_width="@dimen/navigation_key_width"
android:layout_height="match_parent"
android:src="@drawable/ic_sysbar_back"
systemui:keyCode="4"
@@ -64,7 +64,7 @@
android:visibility="invisible"
/>
<com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/home"
- android:layout_width="80dp"
+ android:layout_width="@dimen/navigation_key_width"
android:layout_height="match_parent"
android:src="@drawable/ic_sysbar_home"
systemui:keyCode="3"
@@ -80,7 +80,7 @@
android:visibility="invisible"
/>
<com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/recent_apps"
- android:layout_width="80dp"
+ android:layout_width="@dimen/navigation_key_width"
android:layout_height="match_parent"
android:src="@drawable/ic_sysbar_recent"
android:layout_weight="0"
@@ -88,7 +88,7 @@
android:contentDescription="@string/accessibility_recent"
/>
<com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/menu"
- android:layout_width="40dp"
+ android:layout_width="@dimen/navigation_menu_key_width"
android:layout_height="match_parent"
android:src="@drawable/ic_sysbar_menu"
systemui:keyCode="82"
diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml
index 7c1cd18..1e82646 100644
--- a/packages/SystemUI/res/values-in/strings.xml
+++ b/packages/SystemUI/res/values-in/strings.xml
@@ -26,7 +26,7 @@
<string name="status_bar_recent_remove_item_title" msgid="6026395868129852968">"Hapus dari daftar"</string>
<string name="status_bar_recent_inspect_item_title" msgid="7793624864528818569">"Info apl"</string>
<string name="status_bar_no_recent_apps" msgid="6576392951053994640">"Tidak ada apl terbaru"</string>
- <string name="status_bar_accessibility_dismiss_recents" msgid="4576076075226540105">"Singkirkan aplikasi terbaru"</string>
+ <string name="status_bar_accessibility_dismiss_recents" msgid="4576076075226540105">"Tutup aplikasi terbaru"</string>
<plurals name="status_bar_accessibility_recent_apps">
<item quantity="one" msgid="5854176083865845541">"1 apl terbaru"</item>
<item quantity="other" msgid="1040784359794890744">"%d apl terbaru"</item>
diff --git a/packages/SystemUI/res/values-sw600dp-port/dimens.xml b/packages/SystemUI/res/values-sw600dp-port/dimens.xml
index b8a6cfe..39eade6 100644
--- a/packages/SystemUI/res/values-sw600dp-port/dimens.xml
+++ b/packages/SystemUI/res/values-sw600dp-port/dimens.xml
@@ -18,5 +18,11 @@
<resources>
<!-- gap on either side of status bar notification icons -->
<dimen name="status_bar_icon_padding">0dp</dimen>
+
+ <!-- The width of the view containing non-menu status bar icons -->
+ <dimen name="navigation_key_width">70dip</dimen>
+
+ <!-- The width of the view containing the menu status bar icon -->
+ <dimen name="navigation_menu_key_width">40dip</dimen>
</resources>
diff --git a/packages/SystemUI/res/values-sw600dp/dimens.xml b/packages/SystemUI/res/values-sw600dp/dimens.xml
index f522285..ba1cdfa 100644
--- a/packages/SystemUI/res/values-sw600dp/dimens.xml
+++ b/packages/SystemUI/res/values-sw600dp/dimens.xml
@@ -67,4 +67,10 @@
<!-- opacity at which Notification icons will be drawn in the status bar -->
<item type="dimen" name="status_bar_icon_drawing_alpha">100%</item>
+
+ <!-- The width of the view containing non-menu status bar icons -->
+ <dimen name="navigation_key_width">80dip</dimen>
+
+ <!-- The width of the view containing the menu status bar icon -->
+ <dimen name="navigation_menu_key_width">40dip</dimen>
</resources>
diff --git a/packages/SystemUI/res/values-sw720dp/dimens.xml b/packages/SystemUI/res/values-sw720dp/dimens.xml
index 6736c1a..b16b1e8 100644
--- a/packages/SystemUI/res/values-sw720dp/dimens.xml
+++ b/packages/SystemUI/res/values-sw720dp/dimens.xml
@@ -21,5 +21,11 @@
<!-- opacity at which Notification icons will be drawn in the status bar -->
<item type="dimen" name="status_bar_icon_drawing_alpha">100%</item>
+
+ <!-- The width of the view containing non-menu status bar icons -->
+ <dimen name="navigation_key_width">80dip</dimen>
+
+ <!-- The width of the view containing the menu status bar icon -->
+ <dimen name="navigation_menu_key_width">80dip</dimen>
</resources>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 8fba86a..2c22e3c 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -91,4 +91,9 @@
<!-- The padding on the global screenshot background image -->
<dimen name="global_screenshot_bg_padding">20dp</dimen>
+ <!-- The width of the view containing non-menu status bar icons -->
+ <dimen name="navigation_key_width">80dip</dimen>
+
+ <!-- The width of the view containing the menu status bar icon -->
+ <dimen name="navigation_menu_key_width">40dip</dimen>
</resources>
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
index eda52fc..87eb9cc 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
@@ -123,6 +123,8 @@
int mNaturalBarHeight = -1;
int mIconSize = -1;
int mIconHPadding = -1;
+ int mNavIconWidth = -1;
+ int mMenuNavIconWidth = -1;
private int mMaxNotificationIcons = 5;
H mHandler = new H();
@@ -462,6 +464,26 @@
com.android.internal.R.dimen.system_bar_icon_size);
int newIconHPadding = res.getDimensionPixelSize(
R.dimen.status_bar_icon_padding);
+ int newNavIconWidth = res.getDimensionPixelSize(R.dimen.navigation_key_width);
+ int newMenuNavIconWidth = res.getDimensionPixelSize(R.dimen.navigation_menu_key_width);
+
+ if (mNavigationArea != null && newNavIconWidth != mNavIconWidth) {
+ mNavIconWidth = newNavIconWidth;
+
+ LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
+ mNavIconWidth, ViewGroup.LayoutParams.MATCH_PARENT);
+ mBackButton.setLayoutParams(lp);
+ mHomeButton.setLayoutParams(lp);
+ mRecentButton.setLayoutParams(lp);
+ }
+
+ if (mNavigationArea != null && newMenuNavIconWidth != mMenuNavIconWidth) {
+ mMenuNavIconWidth = newMenuNavIconWidth;
+
+ LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
+ mMenuNavIconWidth, ViewGroup.LayoutParams.MATCH_PARENT);
+ mMenuButton.setLayoutParams(lp);
+ }
if (newIconHPadding != mIconHPadding || newIconSize != mIconSize) {
// Slog.d(TAG, "size=" + newIconSize + " padding=" + newIconHPadding);
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index 986c40a..37f15e2 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -1621,7 +1621,7 @@
uint32_t strategy = AudioSystem::getStrategyForStream(streamType);
for (size_t i = 0; i < mTracks.size(); ++i) {
sp<Track> t = mTracks[i];
- if (t != 0) {
+ if (t != 0 && !t->isOutputTrack()) {
uint32_t actual = AudioSystem::getStrategyForStream(t->streamType());
if (sessionId == t->sessionId() && strategy != actual) {
ALOGE("createTrack_l() mismatched strategy; expected %u but found %u",
diff --git a/services/audioflinger/AudioPolicyService.cpp b/services/audioflinger/AudioPolicyService.cpp
index 753b1d2..d57326b 100644
--- a/services/audioflinger/AudioPolicyService.cpp
+++ b/services/audioflinger/AudioPolicyService.cpp
@@ -298,8 +298,7 @@
ssize_t idx = mInputs.indexOfKey(input);
InputDesc *inputDesc;
if (idx < 0) {
- inputDesc = new InputDesc();
- inputDesc->mSessionId = audioSession;
+ inputDesc = new InputDesc(audioSession);
mInputs.add(input, inputDesc);
} else {
inputDesc = mInputs.valueAt(idx);
@@ -358,7 +357,6 @@
}
InputDesc *inputDesc = mInputs.valueAt(index);
setPreProcessorEnabled(inputDesc, false);
- inputDesc->mEffects.clear();
delete inputDesc;
mInputs.removeItemsAt(index);
}
@@ -432,10 +430,12 @@
return mpAudioPolicy->get_strategy_for_stream(mpAudioPolicy, stream);
}
-uint32_t AudioPolicyService::getDevicesForStream(audio_stream_type_t stream)
+//audio policy: use audio_device_t appropriately
+
+audio_devices_t AudioPolicyService::getDevicesForStream(audio_stream_type_t stream)
{
if (mpAudioPolicy == NULL) {
- return 0;
+ return (audio_devices_t)0;
}
return mpAudioPolicy->get_devices_for_stream(mpAudioPolicy, stream);
}
@@ -600,9 +600,9 @@
return NO_ERROR;
}
-void AudioPolicyService::setPreProcessorEnabled(InputDesc *inputDesc, bool enabled)
+void AudioPolicyService::setPreProcessorEnabled(const InputDesc *inputDesc, bool enabled)
{
- Vector<sp<AudioEffect> > fxVector = inputDesc->mEffects;
+ const Vector<sp<AudioEffect> > &fxVector = inputDesc->mEffects;
for (size_t i = 0; i < fxVector.size(); i++) {
fxVector.itemAt(i)->setEnabled(enabled);
}
diff --git a/services/audioflinger/AudioPolicyService.h b/services/audioflinger/AudioPolicyService.h
index 962c917..7119b90 100644
--- a/services/audioflinger/AudioPolicyService.h
+++ b/services/audioflinger/AudioPolicyService.h
@@ -95,7 +95,7 @@
audio_devices_t device);
virtual uint32_t getStrategyForStream(audio_stream_type_t stream);
- virtual uint32_t getDevicesForStream(audio_stream_type_t stream);
+ virtual audio_devices_t getDevicesForStream(audio_stream_type_t stream);
virtual audio_io_handle_t getOutputForEffect(effect_descriptor_t *desc);
virtual status_t registerEffect(effect_descriptor_t *desc,
@@ -279,15 +279,15 @@
class InputDesc {
public:
- InputDesc() {}
- virtual ~InputDesc() {}
- int mSessionId;
+ InputDesc(int session) : mSessionId(session) {}
+ /*virtual*/ ~InputDesc() {}
+ const int mSessionId;
Vector< sp<AudioEffect> >mEffects;
};
static const char * const kInputSourceNames[AUDIO_SOURCE_CNT -1];
- void setPreProcessorEnabled(InputDesc *inputDesc, bool enabled);
+ void setPreProcessorEnabled(const InputDesc *inputDesc, bool enabled);
status_t loadPreProcessorConfig(const char *path);
status_t loadEffects(cnode *root, Vector <EffectDesc *>& effects);
EffectDesc *loadEffect(cnode *root);
diff --git a/services/java/com/android/server/NetworkManagementService.java b/services/java/com/android/server/NetworkManagementService.java
index 720b5fe..09d0698 100644
--- a/services/java/com/android/server/NetworkManagementService.java
+++ b/services/java/com/android/server/NetworkManagementService.java
@@ -880,7 +880,6 @@
mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
try {
wifiFirmwareReload(wlanIface, "AP");
- mConnector.execute("softap", "start", wlanIface);
if (wifiConfig == null) {
mConnector.execute("softap", "set", wlanIface, softapIface);
} else {
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index 2538455..fd968e0 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -4934,7 +4934,7 @@
void grantUriPermissionFromIntentLocked(int callingUid,
String targetPkg, Intent intent, UriPermissionOwner owner) {
NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
- intent, intent.getFlags(), null);
+ intent, intent != null ? intent.getFlags() : 0, null);
if (needed == null) {
return;
}
diff --git a/services/java/com/android/server/wm/ScreenRotationAnimation.java b/services/java/com/android/server/wm/ScreenRotationAnimation.java
index 7ac67b6..7b5bf08 100644
--- a/services/java/com/android/server/wm/ScreenRotationAnimation.java
+++ b/services/java/com/android/server/wm/ScreenRotationAnimation.java
@@ -372,6 +372,12 @@
break;
}
+ // Compute partial steps between original and final sizes. These
+ // are used for the dimensions of the exiting and entering elements,
+ // so they are never stretched too significantly.
+ final int halfWidth = (finalWidth + mOriginalWidth) / 2;
+ final int halfHeight = (finalHeight + mOriginalHeight) / 2;
+
// Initialize the animations. This is a hack, redefining what "parent"
// means to allow supplying the last and next size. In this definition
// "%p" is the original (let's call it "previous") size, and "%" is the
@@ -379,14 +385,14 @@
if (firstStart) {
if (DEBUG_STATE) Slog.v(TAG, "Initializing start and finish animations");
mStartEnterAnimation.initialize(finalWidth, finalHeight,
- mOriginalWidth, mOriginalHeight);
- mStartExitAnimation.initialize(finalWidth, finalHeight,
+ halfWidth, halfHeight);
+ mStartExitAnimation.initialize(halfWidth, halfHeight,
mOriginalWidth, mOriginalHeight);
mStartFrameAnimation.initialize(finalWidth, finalHeight,
mOriginalWidth, mOriginalHeight);
mFinishEnterAnimation.initialize(finalWidth, finalHeight,
- mOriginalWidth, mOriginalHeight);
- mFinishExitAnimation.initialize(finalWidth, finalHeight,
+ halfWidth, halfHeight);
+ mFinishExitAnimation.initialize(halfWidth, halfHeight,
mOriginalWidth, mOriginalHeight);
mFinishFrameAnimation.initialize(finalWidth, finalHeight,
mOriginalWidth, mOriginalHeight);
diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java
index def22a9..18b51a7 100644
--- a/services/java/com/android/server/wm/WindowManagerService.java
+++ b/services/java/com/android/server/wm/WindowManagerService.java
@@ -9173,7 +9173,7 @@
void scheduleAnimationLocked() {
if (!mAnimationScheduled) {
- mChoreographer.postAnimationCallback(mAnimationRunnable);
+ mChoreographer.postAnimationCallback(mAnimationRunnable, null);
mAnimationScheduled = true;
}
}
diff --git a/telephony/java/android/telephony/PhoneNumberFormattingTextWatcher.java b/telephony/java/android/telephony/PhoneNumberFormattingTextWatcher.java
index 6f85c7d..983c349 100644
--- a/telephony/java/android/telephony/PhoneNumberFormattingTextWatcher.java
+++ b/telephony/java/android/telephony/PhoneNumberFormattingTextWatcher.java
@@ -39,30 +39,6 @@
* The formatting will be restarted once the text is cleared.
*/
public class PhoneNumberFormattingTextWatcher implements TextWatcher {
- /**
- * One or more characters were removed from the end.
- */
- private final static int STATE_REMOVE_LAST = 0;
-
- /**
- * One or more characters were appended.
- */
- private final static int STATE_APPEND = 1;
-
- /**
- * One or more digits were changed in the beginning or the middle of text.
- */
- private final static int STATE_MODIFY_DIGITS = 2;
-
- /**
- * The changes other than the above.
- */
- private final static int STATE_OTHER = 3;
-
- /**
- * The state of this change could be one value of the above
- */
- private int mState;
/**
* Indicates the change was caused by ourselves.
@@ -97,46 +73,30 @@
mFormatter = PhoneNumberUtil.getInstance().getAsYouTypeFormatter(countryCode);
}
+ @Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
if (mSelfChange || mStopFormatting) {
return;
}
- if (count == 0 && s.length() == start) {
- // Append one or more new chars
- mState = STATE_APPEND;
- } else if (after == 0 && start + count == s.length() && count > 0) {
- // Remove one or more chars from the end of string.
- mState = STATE_REMOVE_LAST;
- } else if (count > 0 && !hasSeparator(s, start, count)) {
- // Remove the dialable chars in the begin or middle of text.
- mState = STATE_MODIFY_DIGITS;
- } else {
- mState = STATE_OTHER;
+ // If the user manually deleted any non-dialable characters, stop formatting
+ if (count > 0 && hasSeparator(s, start, count)) {
+ stopFormatting();
}
}
+ @Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
if (mSelfChange || mStopFormatting) {
return;
}
- if (mState == STATE_OTHER) {
- if (count > 0 && !hasSeparator(s, start, count)) {
- // User inserted the dialable characters in the middle of text.
- mState = STATE_MODIFY_DIGITS;
- }
- }
- // Check whether we should stop formatting.
- if (mState == STATE_APPEND && count > 0 && hasSeparator(s, start, count)) {
- // User appended the non-dialable character, stop formatting.
- stopFormatting();
- } else if (mState == STATE_OTHER) {
- // User must insert or remove the non-dialable characters in the begin or middle of
- // number, stop formatting.
+ // If the user inserted any non-dialable characters, stop formatting
+ if (count > 0 && hasSeparator(s, start, count)) {
stopFormatting();
}
}
+ @Override
public synchronized void afterTextChanged(Editable s) {
if (mStopFormatting) {
// Restart the formatting when all texts were clear.
diff --git a/telephony/tests/telephonytests/src/com/android/internal/telephony/PhoneNumberWatcherTest.java b/telephony/tests/telephonytests/src/com/android/internal/telephony/PhoneNumberWatcherTest.java
index 6f0175e..a6a0fce 100644
--- a/telephony/tests/telephonytests/src/com/android/internal/telephony/PhoneNumberWatcherTest.java
+++ b/telephony/tests/telephonytests/src/com/android/internal/telephony/PhoneNumberWatcherTest.java
@@ -182,14 +182,17 @@
public void testTextChangedByOtherTextWatcher() {
final TextWatcher cleanupTextWatcher = new TextWatcher() {
+ @Override
public void afterTextChanged(Editable s) {
s.clear();
}
+ @Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
}
+ @Override
public void onTextChanged(CharSequence s, int start, int before,
int count) {
}
@@ -208,6 +211,81 @@
assertEquals(expected1, number.toString());
}
+ /**
+ * Test the case where some other component is auto-completing what the user is typing
+ */
+ public void testAutoCompleteWithFormattedNumber() {
+ String init = "650-1";
+ String expected = "+1-650-123-4567"; // Different formatting than ours
+ testReplacement(init, expected, expected);
+ }
+
+ /**
+ * Test the case where some other component is auto-completing what the user is typing
+ */
+ public void testAutoCompleteWithFormattedNameAndNumber() {
+ String init = "650-1";
+ String expected = "Test User <650-123-4567>";
+ testReplacement(init, expected, expected);
+ }
+
+ /**
+ * Test the case where some other component is auto-completing what the user is typing
+ */
+ public void testAutoCompleteWithNumericNameAndNumber() {
+ String init = "650";
+ String expected = "2nd Test User <650-123-4567>";
+ testReplacement(init, expected, expected);
+ }
+
+ /**
+ * Test the case where some other component is auto-completing what the user is typing
+ */
+ public void testAutoCompleteWithUnformattedNumber() {
+ String init = "650-1";
+ String expected = "6501234567";
+ testReplacement(init, expected, expected);
+ }
+
+ /**
+ * Test the case where some other component is auto-completing what the user is typing, where
+ * the deleted text doesn't have any formatting and neither does the replacement text: in this
+ * case the replacement text should be formatted by the PhoneNumberFormattingTextWatcher.
+ */
+ public void testAutoCompleteUnformattedWithUnformattedNumber() {
+ String init = "650";
+ String replacement = "6501234567";
+ String expected = "(650) 123-4567";
+ testReplacement(init, replacement, expected);
+
+ String init2 = "650";
+ String replacement2 = "16501234567";
+ String expected2 = "1 650-123-4567";
+ testReplacement(init2, replacement2, expected2);
+ }
+
+ /**
+ * Helper method for testing replacing the entire string with another string
+ * @param init The initial string
+ * @param expected
+ */
+ private void testReplacement(String init, String replacement, String expected) {
+ TextWatcher textWatcher = getTextWatcher();
+
+ SpannableStringBuilder number = new SpannableStringBuilder(init);
+
+ // Replace entire text with the given values
+ textWatcher.beforeTextChanged(number, 0, init.length(), replacement.length());
+ number.replace(0, init.length(), replacement, 0, replacement.length());
+ Selection.setSelection(number, replacement.length()); // move the cursor to the end
+ textWatcher.onTextChanged(number, 0, init.length(), replacement.length());
+ textWatcher.afterTextChanged(number);
+
+ assertEquals(expected, number.toString());
+ // the cursor should be still at the end
+ assertEquals(expected.length(), Selection.getSelectionEnd(number));
+ }
+
private TextWatcher getTextWatcher() {
return new PhoneNumberFormattingTextWatcher("US");
}
diff --git a/tests/RenderScriptTests/SampleTest/res/drawable-nodpi/city.png b/tests/RenderScriptTests/SampleTest/res/drawable-nodpi/city.png
new file mode 100644
index 0000000..27c4618
--- /dev/null
+++ b/tests/RenderScriptTests/SampleTest/res/drawable-nodpi/city.png
Binary files differ
diff --git a/tests/RenderScriptTests/SampleTest/src/com/android/rs/sample/SampleRSActivity.java b/tests/RenderScriptTests/SampleTest/src/com/android/rs/sample/SampleRSActivity.java
index cd5d53f..77cbf84 100644
--- a/tests/RenderScriptTests/SampleTest/src/com/android/rs/sample/SampleRSActivity.java
+++ b/tests/RenderScriptTests/SampleTest/src/com/android/rs/sample/SampleRSActivity.java
@@ -18,6 +18,7 @@
import android.app.Activity;
import android.graphics.Bitmap;
+import android.graphics.Bitmap.Config;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.SurfaceTexture;
@@ -66,13 +67,14 @@
}
private final String TAG = "Img";
- private Bitmap mBitmapIn;
- private TextureView mDisplayView;
+ private Bitmap mBitmapTwoByTwo;
+ private Bitmap mBitmapCity;
private TextView mBenchmarkResult;
private RenderScript mRS;
- private Allocation mInPixelsAllocation;
+ private Allocation mTwoByTwoAlloc;
+ private Allocation mCityAlloc;
private ScriptC_sample mScript;
public void onStartTrackingTouch(SeekBar seekBar) {
@@ -86,14 +88,18 @@
super.onCreate(savedInstanceState);
setContentView(R.layout.rs);
- mBitmapIn = loadBitmap(R.drawable.twobytwo);
- mDisplayView = (TextureView) findViewById(R.id.display);
+ mBitmapTwoByTwo = loadBitmap(R.drawable.twobytwo);
+ mBitmapCity = loadBitmap(R.drawable.city);
mBenchmarkResult = (TextView) findViewById(R.id.benchmarkText);
mBenchmarkResult.setText("Result: not run");
mRS = RenderScript.create(this);
- mInPixelsAllocation = Allocation.createFromBitmap(mRS, mBitmapIn,
+ mTwoByTwoAlloc = Allocation.createFromBitmap(mRS, mBitmapTwoByTwo,
+ Allocation.MipmapControl.MIPMAP_NONE,
+ Allocation.USAGE_SCRIPT);
+
+ mCityAlloc = Allocation.createFromBitmap(mRS, mBitmapCity,
Allocation.MipmapControl.MIPMAP_NONE,
Allocation.USAGE_SCRIPT);
@@ -101,8 +107,8 @@
int usage = Allocation.USAGE_SCRIPT | Allocation.USAGE_IO_OUTPUT;
- int outX = 32;
- int outY = 32;
+ int outX = 256;
+ int outY = 256;
// Wrap Linear
Allocation outAlloc = Allocation.createTyped(mRS, b.setX(outX).setY(outY).create(), usage);
@@ -144,7 +150,7 @@
private synchronized void filterAlloc(Allocation alloc, Sampler sampler) {
long t = java.lang.System.currentTimeMillis();
- mScript.invoke_setSampleData(alloc, mInPixelsAllocation, sampler);
+ mScript.invoke_setSampleData(alloc, mTwoByTwoAlloc, sampler);
mScript.forEach_root(alloc);
alloc.ioSendOutput();
mRS.finish();
diff --git a/tests/RenderScriptTests/SampleTest/src/com/android/rs/sample/sample.rs b/tests/RenderScriptTests/SampleTest/src/com/android/rs/sample/sample.rs
index 8a027b2..0f3c0a7 100644
--- a/tests/RenderScriptTests/SampleTest/src/com/android/rs/sample/sample.rs
+++ b/tests/RenderScriptTests/SampleTest/src/com/android/rs/sample/sample.rs
@@ -38,39 +38,113 @@
return max(0, min(coord, size - 1));
}
-static float2 wrap(rs_sampler_value wrapS, rs_sampler_value wrapT, float2 coord) {
- float2 wrappedCoord;
- float temp;
- if (wrapS == RS_SAMPLER_WRAP) {
- wrappedCoord.x = fract(coord.x, &temp);
- // Make sure that non zero integer uv's map to one
- if (wrappedCoord.x == 0.0f && coord.x != 0.0f) {
- wrappedCoord.x = 1.0f;
+#define convert_float(v) (float)v
+#define SAMPLE_1D_FUNC(vecsize) \
+ static float##vecsize get1DSample##vecsize(rs_allocation a, float2 weights, \
+ int iPixel, int next) { \
+ uchar##vecsize *p0c = (uchar##vecsize*)rsGetElementAt(a, iPixel); \
+ uchar##vecsize *p1c = (uchar##vecsize*)rsGetElementAt(a, next); \
+ float##vecsize p0 = convert_float##vecsize(*p0c); \
+ float##vecsize p1 = convert_float##vecsize(*p1c); \
+ return p0 * weights.x + p1 * weights.y; \
}
- if (wrappedCoord.x < 0.0f) {
- wrappedCoord.x += 1.0f;
+#define SAMPLE_2D_FUNC(vecsize) \
+ static float##vecsize get2DSample##vecsize(rs_allocation a, float4 weights, \
+ int2 iPixel, int nextX, int nextY) { \
+ uchar##vecsize *p0c = (uchar##vecsize*)rsGetElementAt(a, iPixel.x, iPixel.y); \
+ uchar##vecsize *p1c = (uchar##vecsize*)rsGetElementAt(a, nextX, iPixel.y); \
+ uchar##vecsize *p2c = (uchar##vecsize*)rsGetElementAt(a, iPixel.x, nextY); \
+ uchar##vecsize *p3c = (uchar##vecsize*)rsGetElementAt(a, nextX, nextY); \
+ float##vecsize p0 = convert_float##vecsize(*p0c); \
+ float##vecsize p1 = convert_float##vecsize(*p1c); \
+ float##vecsize p2 = convert_float##vecsize(*p2c); \
+ float##vecsize p3 = convert_float##vecsize(*p3c); \
+ return p0 * weights.x + p1 * weights.y + p2 * weights.z + p3 * weights.w; \
}
- } else {
- wrappedCoord.x = max(0.0f, min(coord.x, 1.0f));
+
+SAMPLE_1D_FUNC()
+SAMPLE_1D_FUNC(2)
+SAMPLE_1D_FUNC(3)
+SAMPLE_1D_FUNC(4)
+
+SAMPLE_2D_FUNC()
+SAMPLE_2D_FUNC(2)
+SAMPLE_2D_FUNC(3)
+SAMPLE_2D_FUNC(4)
+
+static float4 getBilinearSample565(rs_allocation a, float4 weights,
+ int2 iPixel, int nextX, int nextY) {
+ float4 zero = {0.0f, 0.0f, 0.0f, 0.0f};
+ return zero;
+}
+
+static float4 getBilinearSample(rs_allocation a, float4 weights,
+ int2 iPixel, int nextX, int nextY,
+ uint32_t vecSize, rs_data_type dt) {
+ if (dt == RS_TYPE_UNSIGNED_5_6_5) {
+ return getBilinearSample565(a, weights, iPixel, nextX, nextY);
}
- if (wrapT == RS_SAMPLER_WRAP) {
- wrappedCoord.y = fract(coord.y, &temp);
- // Make sure that non zero integer uv's map to one
- if (wrappedCoord.y == 0.0f && coord.y != 0.0f) {
- wrappedCoord.y = 1.0f;
- }
- if (wrappedCoord.y < 0.0f) {
- wrappedCoord.y += 1.0f;
- }
- } else {
- wrappedCoord.y = max(0.0f, min(coord.y, 1.0f));
+ float4 result;
+ switch(vecSize) {
+ case 1:
+ result.x = get2DSample(a, weights, iPixel, nextX, nextY);
+ result.yzw = 0.0f;
+ break;
+ case 2:
+ result.xy = get2DSample2(a, weights, iPixel, nextX, nextY);
+ result.zw = 0.0f;
+ break;
+ case 3:
+ result.xyz = get2DSample3(a, weights, iPixel, nextX, nextY);
+ result.w = 0.0f;
+ break;
+ case 4:
+ result = get2DSample4(a, weights, iPixel, nextX, nextY);
+ break;
}
- return wrappedCoord;
+
+ return result;
}
+static float4 getNearestSample(rs_allocation a, int2 iPixel, uint32_t vecSize, rs_data_type dt) {
+ if (dt == RS_TYPE_UNSIGNED_5_6_5) {
+ float4 zero = {0.0f, 0.0f, 0.0f, 0.0f};
+ return zero;
+ }
+
+ float4 result;
+ switch(vecSize) {
+ case 1:
+ result.x = convert_float(*((uchar*)rsGetElementAt(a, iPixel.x, iPixel.y)));
+ result.yzw = 0.0f;
+ case 2:
+ result.xy = convert_float2(*((uchar2*)rsGetElementAt(a, iPixel.x, iPixel.y)));
+ result.zw = 0.0f;
+ case 3:
+ result.xyz = convert_float3(*((uchar3*)rsGetElementAt(a, iPixel.x, iPixel.y)));
+ result.w = 0.0f;
+ case 4:
+ result = convert_float4(*((uchar4*)rsGetElementAt(a, iPixel.x, iPixel.y)));
+ }
+
+ return result;
+}
+
+
// Naive implementation of texture filtering for prototyping purposes
static float4 sample(rs_allocation a, rs_sampler s, float2 uv) {
+
+ // Find out what kind of input data we are sampling
+ rs_element elem = rsAllocationGetElement(a);
+ uint32_t vecSize = rsElementGetVectorSize(elem);
+ rs_data_kind dk = rsElementGetDataKind(elem);
+ rs_data_type dt = rsElementGetDataType(elem);
+
+ if (dk == RS_KIND_USER || (dt != RS_TYPE_UNSIGNED_8 && dt != RS_TYPE_UNSIGNED_5_6_5)) {
+ float4 zero = {0.0f, 0.0f, 0.0f, 0.0f};
+ return zero;
+ }
//rsDebug("*****************************************", 0);
rs_sampler_value wrapS = rsgSamplerGetWrapS(s);
rs_sampler_value wrapT = rsgSamplerGetWrapT(s);
@@ -78,29 +152,20 @@
rs_sampler_value sampleMin = rsgSamplerGetMinification(s);
rs_sampler_value sampleMag = rsgSamplerGetMagnification(s);
- uv = wrap(wrapS, wrapT, uv);
-
int32_t sourceW = rsAllocationGetDimX(a);
int32_t sourceH = rsAllocationGetDimY(a);
- /*rsDebug("uv", uv);
- rsDebug("sourceW", sourceW);
- rsDebug("sourceH", sourceH);*/
-
float2 dimF;
dimF.x = (float)(sourceW);
dimF.y = (float)(sourceH);
float2 pixelUV = uv * dimF;
int2 iPixel = convert_int2(pixelUV);
- /*rsDebug("iPixelX initial", iPixel.x);
- rsDebug("iPixelY initial", iPixel.y);*/
if (sampleMin == RS_SAMPLER_NEAREST ||
sampleMag == RS_SAMPLER_NEAREST) {
iPixel.x = wrapI(wrapS, iPixel.x, sourceW);
iPixel.y = wrapI(wrapT, iPixel.y, sourceH);
- uchar4 *nearestSample = (uchar4*)rsGetElementAt(a, iPixel.x, iPixel.y);
- return convert_float4(*nearestSample);
+ return getNearestSample(a, iPixel, vecSize, dt);
}
float2 frac = pixelUV - convert_float2(iPixel);
@@ -125,36 +190,12 @@
weights.z = oneMinusFrac.x * frac.y;
weights.w = frac.x * frac.y;
- uint32_t nextX = wrapI(wrapS, iPixel.x + 1, sourceW);
- uint32_t nextY = wrapI(wrapT, iPixel.y + 1, sourceH);
+ int32_t nextX = wrapI(wrapS, iPixel.x + 1, sourceW);
+ int32_t nextY = wrapI(wrapT, iPixel.y + 1, sourceH);
iPixel.x = wrapI(wrapS, iPixel.x, sourceW);
iPixel.y = wrapI(wrapT, iPixel.y, sourceH);
- /*rsDebug("iPixelX wrapped", iPixel.x);
- rsDebug("iPixelY wrapped", iPixel.y);*/
- uchar4 *p0c = (uchar4*)rsGetElementAt(a, iPixel.x, iPixel.y);
- uchar4 *p1c = (uchar4*)rsGetElementAt(a, nextX, iPixel.y);
- uchar4 *p2c = (uchar4*)rsGetElementAt(a, iPixel.x, nextY);
- uchar4 *p3c = (uchar4*)rsGetElementAt(a, nextX, nextY);
-
- float4 p0 = convert_float4(*p0c);
- float4 p1 = convert_float4(*p1c);
- float4 p2 = convert_float4(*p2c);
- float4 p3 = convert_float4(*p3c);
-
- float4 result = p0 * weights.x + p1 * weights.y + p2 * weights.z + p3 * weights.w;
-
- /*rsDebug("pixelUV", pixelUV);
- rsDebug("frac", frac);
- rsDebug("oneMinusFrac", oneMinusFrac);
- rsDebug("p0", p0);
- rsDebug("p1", p1);
- rsDebug("p2", p2);
- rsDebug("p3", p3);
- rsDebug("w", weights);
- rsDebug("result", result);*/
-
- return result;
+ return getBilinearSample(a, weights, iPixel, nextX, nextY, vecSize, dt);
}
void root(uchar4 *out, uint32_t x, uint32_t y) {
diff --git a/wifi/java/android/net/wifi/WifiStateMachine.java b/wifi/java/android/net/wifi/WifiStateMachine.java
index 843620c..05a8ca7 100644
--- a/wifi/java/android/net/wifi/WifiStateMachine.java
+++ b/wifi/java/android/net/wifi/WifiStateMachine.java
@@ -1852,6 +1852,9 @@
replyToMessage(message, WifiManager.DISABLE_NETWORK_FAILED,
WifiManager.BUSY);
break;
+ case WifiWatchdogStateMachine.RSSI_FETCH:
+ replyToMessage(message, WifiWatchdogStateMachine.RSSI_FETCH_FAILED);
+ break;
default:
loge("Error! unhandled message" + message);
break;
@@ -2998,6 +3001,12 @@
mRssiPollToken, 0), POLL_RSSI_INTERVAL_MSECS);
}
break;
+ case WifiWatchdogStateMachine.RSSI_FETCH:
+ eventLoggingEnabled = false;
+ fetchRssiAndLinkSpeedNative();
+ replyToMessage(message, WifiWatchdogStateMachine.RSSI_FETCH_SUCCEEDED,
+ mWifiInfo.getRssi());
+ break;
default:
return NOT_HANDLED;
}
diff --git a/wifi/java/android/net/wifi/WifiWatchdogStateMachine.java b/wifi/java/android/net/wifi/WifiWatchdogStateMachine.java
index a2f6343..5c9bef9 100644
--- a/wifi/java/android/net/wifi/WifiWatchdogStateMachine.java
+++ b/wifi/java/android/net/wifi/WifiWatchdogStateMachine.java
@@ -93,17 +93,36 @@
private static final String TAG = "WifiWatchdogStateMachine";
private static final String WALLED_GARDEN_NOTIFICATION_ID = "WifiWatchdog.walledgarden";
+ /* RSSI Levels as used by notification icon
+ Level 4 -55 <= RSSI
+ Level 3 -66 <= RSSI < -55
+ Level 2 -77 <= RSSI < -67
+ Level 1 -88 <= RSSI < -78
+ Level 0 RSSI < -88 */
+
/* Wi-fi connection is considered poor below this
RSSI level threshold and the watchdog report it
to the WifiStateMachine */
- private static final int RSSI_LEVEL_CUTOFF = 1;
+ private static final int RSSI_LEVEL_CUTOFF = 0;
/* Wi-fi connection is monitored actively below this
threshold */
- private static final int RSSI_LEVEL_MONITOR = 2;
+ private static final int RSSI_LEVEL_MONITOR = 1;
+ /* RSSI threshold during monitoring below which network is avoided */
+ private static final int RSSI_MONITOR_THRESHOLD = -84;
+ /* Number of times RSSI is measured to be low before being avoided */
+ private static final int RSSI_MONITOR_COUNT = 5;
+ private int mRssiMonitorCount = 0;
+
+ /* Avoid flapping */
+ private static final int MIN_INTERVAL_AVOID_BSSID_MS = 60 * 1000;
+ private String mLastAvoidedBssid;
+ /* a -ve interval to allow avoidance at boot */
+ private long mLastBssidAvoidedTime = -MIN_INTERVAL_AVOID_BSSID_MS;
private int mCurrentSignalLevel;
private static final long DEFAULT_ARP_CHECK_INTERVAL_MS = 2 * 60 * 1000;
+ private static final long DEFAULT_RSSI_FETCH_INTERVAL_MS = 1000;
private static final long DEFAULT_WALLED_GARDEN_INTERVAL_MS = 30 * 60 * 1000;
private static final int DEFAULT_NUM_ARP_PINGS = 5;
@@ -143,10 +162,14 @@
/* Internal messages */
private static final int CMD_ARP_CHECK = BASE + 11;
private static final int CMD_DELAYED_WALLED_GARDEN_CHECK = BASE + 12;
+ private static final int CMD_RSSI_FETCH = BASE + 13;
/* Notifications to WifiStateMachine */
static final int POOR_LINK_DETECTED = BASE + 21;
static final int GOOD_LINK_DETECTED = BASE + 22;
+ static final int RSSI_FETCH = BASE + 23;
+ static final int RSSI_FETCH_SUCCEEDED = BASE + 24;
+ static final int RSSI_FETCH_FAILED = BASE + 25;
private static final int SINGLE_ARP_CHECK = 0;
private static final int FULL_ARP_CHECK = 1;
@@ -167,11 +190,15 @@
private WalledGardenCheckState mWalledGardenCheckState = new WalledGardenCheckState();
/* Online and watching link connectivity */
private OnlineWatchState mOnlineWatchState = new OnlineWatchState();
+ /* RSSI level is at RSSI_LEVEL_MONITOR and needs close monitoring */
+ private RssiMonitoringState mRssiMonitoringState = new RssiMonitoringState();
/* Online and doing nothing */
private OnlineState mOnlineState = new OnlineState();
private int mArpToken = 0;
private long mArpCheckIntervalMs;
+ private int mRssiFetchToken = 0;
+ private long mRssiFetchIntervalMs;
private long mWalledGardenIntervalMs;
private int mNumArpPings;
private int mMinArpResponses;
@@ -219,6 +246,7 @@
addState(mConnectedState, mWatchdogEnabledState);
addState(mWalledGardenCheckState, mConnectedState);
addState(mOnlineWatchState, mConnectedState);
+ addState(mRssiMonitoringState, mOnlineWatchState);
addState(mOnlineState, mConnectedState);
if (isWatchdogEnabled()) {
@@ -239,6 +267,7 @@
// Disable for wifi only devices.
if (Settings.Secure.getString(contentResolver, Settings.Secure.WIFI_WATCHDOG_ON) == null
&& sWifiOnly) {
+ log("Disabling watchog for wi-fi only device");
putSettingsBoolean(contentResolver, Settings.Secure.WIFI_WATCHDOG_ON, false);
}
WifiWatchdogStateMachine wwsm = new WifiWatchdogStateMachine(context);
@@ -361,6 +390,7 @@
pw.println("mLinkProperties: [" + mLinkProperties + "]");
pw.println("mCurrentSignalLevel: [" + mCurrentSignalLevel + "]");
pw.println("mArpCheckIntervalMs: [" + mArpCheckIntervalMs+ "]");
+ pw.println("mRssiFetchIntervalMs: [" + mRssiFetchIntervalMs + "]");
pw.println("mWalledGardenIntervalMs: [" + mWalledGardenIntervalMs + "]");
pw.println("mNumArpPings: [" + mNumArpPings + "]");
pw.println("mMinArpResponses: [" + mMinArpResponses + "]");
@@ -371,7 +401,9 @@
}
private boolean isWatchdogEnabled() {
- return getSettingsBoolean(mContentResolver, Settings.Secure.WIFI_WATCHDOG_ON, true);
+ boolean ret = getSettingsBoolean(mContentResolver, Settings.Secure.WIFI_WATCHDOG_ON, true);
+ if (DBG) log("watchdog enabled " + ret);
+ return ret;
}
private void updateSettings() {
@@ -380,6 +412,9 @@
mArpCheckIntervalMs = Secure.getLong(mContentResolver,
Secure.WIFI_WATCHDOG_ARP_CHECK_INTERVAL_MS,
DEFAULT_ARP_CHECK_INTERVAL_MS);
+ mRssiFetchIntervalMs = Secure.getLong(mContentResolver,
+ Secure.WIFI_WATCHDOG_RSSI_FETCH_INTERVAL_MS,
+ DEFAULT_RSSI_FETCH_INTERVAL_MS);
mNumArpPings = Secure.getInt(mContentResolver,
Secure.WIFI_WATCHDOG_NUM_ARP_PINGS,
DEFAULT_NUM_ARP_PINGS);
@@ -436,6 +471,11 @@
class DefaultState extends State {
@Override
+ public void enter() {
+ if (DBG) log(getName() + "\n");
+ }
+
+ @Override
public boolean processMessage(Message msg) {
switch (msg.what) {
case EVENT_WATCHDOG_SETTINGS_CHANGE:
@@ -445,13 +485,15 @@
}
break;
case EVENT_RSSI_CHANGE:
- mCurrentSignalLevel = WifiManager.calculateSignalLevel(msg.arg1,
- WifiManager.RSSI_LEVELS);
+ mCurrentSignalLevel = calculateSignalLevel(msg.arg1);
break;
case EVENT_WIFI_RADIO_STATE_CHANGE:
case EVENT_NETWORK_STATE_CHANGE:
case CMD_ARP_CHECK:
case CMD_DELAYED_WALLED_GARDEN_CHECK:
+ case CMD_RSSI_FETCH:
+ case RSSI_FETCH_SUCCEEDED:
+ case RSSI_FETCH_FAILED:
//ignore
break;
default:
@@ -464,6 +506,11 @@
class WatchdogDisabledState extends State {
@Override
+ public void enter() {
+ if (DBG) log(getName() + "\n");
+ }
+
+ @Override
public boolean processMessage(Message msg) {
switch (msg.what) {
case EVENT_WATCHDOG_TOGGLED:
@@ -493,7 +540,7 @@
@Override
public void enter() {
if (DBG) log("WifiWatchdogService enabled");
- }
+ }
@Override
public boolean processMessage(Message msg) {
@@ -507,6 +554,8 @@
NetworkInfo networkInfo = (NetworkInfo)
intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);
+ if (DBG) log("network state change " + networkInfo.getDetailedState());
+
switch (networkInfo.getDetailedState()) {
case VERIFYING_POOR_LINK:
mLinkProperties = (LinkProperties) intent.getParcelableExtra(
@@ -557,6 +606,10 @@
}
class NotConnectedState extends State {
+ @Override
+ public void enter() {
+ if (DBG) log(getName() + "\n");
+ }
}
class VerifyingLinkState extends State {
@@ -568,7 +621,7 @@
}
private void handleRssiChange() {
- if (mCurrentSignalLevel <= RSSI_LEVEL_CUTOFF) {
+ if (mCurrentSignalLevel <= RSSI_LEVEL_MONITOR) {
//stay here
if (DBG) log("enter VerifyingLinkState, stay level: " + mCurrentSignalLevel);
} else {
@@ -587,11 +640,7 @@
}
break;
case EVENT_RSSI_CHANGE:
- int signalLevel = WifiManager.calculateSignalLevel(msg.arg1,
- WifiManager.RSSI_LEVELS);
- if (DBG) log("RSSI change old: " + mCurrentSignalLevel + "new: " + signalLevel);
- mCurrentSignalLevel = signalLevel;
-
+ mCurrentSignalLevel = calculateSignalLevel(msg.arg1);
handleRssiChange();
break;
case CMD_ARP_CHECK:
@@ -680,11 +729,11 @@
private void handleRssiChange() {
if (mCurrentSignalLevel <= RSSI_LEVEL_CUTOFF) {
- if (DBG) log("Transition out, below cut off level: " + mCurrentSignalLevel);
- mWsmChannel.sendMessage(POOR_LINK_DETECTED);
+ sendPoorLinkDetected();
} else if (mCurrentSignalLevel <= RSSI_LEVEL_MONITOR) {
- if (DBG) log("Start monitoring, level: " + mCurrentSignalLevel);
- sendMessage(obtainMessage(CMD_ARP_CHECK, ++mArpToken, 0));
+ transitionTo(mRssiMonitoringState);
+ } else {
+ //stay here
}
}
@@ -692,30 +741,14 @@
public boolean processMessage(Message msg) {
switch (msg.what) {
case EVENT_RSSI_CHANGE:
- int signalLevel = WifiManager.calculateSignalLevel(msg.arg1,
- WifiManager.RSSI_LEVELS);
- if (DBG) log("RSSI change old: " + mCurrentSignalLevel + "new: " + signalLevel);
- mCurrentSignalLevel = signalLevel;
-
- handleRssiChange();
-
- break;
- case CMD_ARP_CHECK:
- if (msg.arg1 == mArpToken) {
- if (doArpTest(SINGLE_ARP_CHECK) != true) {
- if (DBG) log("single ARP fail, full ARP check");
- //do a full test
- if (doArpTest(FULL_ARP_CHECK) != true) {
- if (DBG) log("notify full ARP fail, level: " + mCurrentSignalLevel);
- mWsmChannel.sendMessage(POOR_LINK_DETECTED);
- }
- }
-
- if (mCurrentSignalLevel <= RSSI_LEVEL_MONITOR) {
- if (DBG) log("Continue ARP check, rssi level: " + mCurrentSignalLevel);
- sendMessageDelayed(obtainMessage(CMD_ARP_CHECK, ++mArpToken, 0),
- mArpCheckIntervalMs);
- }
+ mCurrentSignalLevel = calculateSignalLevel(msg.arg1);
+ //Ready to avoid bssid again ?
+ long time = android.os.SystemClock.elapsedRealtime();
+ if (time - mLastBssidAvoidedTime > MIN_INTERVAL_AVOID_BSSID_MS) {
+ handleRssiChange();
+ } else {
+ if (DBG) log("Early to avoid " + mWifiInfo + " time: " + time +
+ " last avoided: " + mLastBssidAvoidedTime);
}
break;
default:
@@ -725,10 +758,65 @@
}
}
+ class RssiMonitoringState extends State {
+ public void enter() {
+ if (DBG) log(getName() + "\n");
+ sendMessage(obtainMessage(CMD_RSSI_FETCH, ++mRssiFetchToken, 0));
+ }
+
+ public boolean processMessage(Message msg) {
+ switch (msg.what) {
+ case EVENT_RSSI_CHANGE:
+ mCurrentSignalLevel = calculateSignalLevel(msg.arg1);
+ if (mCurrentSignalLevel <= RSSI_LEVEL_CUTOFF) {
+ sendPoorLinkDetected();
+ } else if (mCurrentSignalLevel <= RSSI_LEVEL_MONITOR) {
+ //stay here;
+ } else {
+ //We dont need frequent RSSI monitoring any more
+ transitionTo(mOnlineWatchState);
+ }
+ break;
+ case CMD_RSSI_FETCH:
+ if (msg.arg1 == mRssiFetchToken) {
+ mWsmChannel.sendMessage(RSSI_FETCH);
+ sendMessageDelayed(obtainMessage(CMD_RSSI_FETCH, ++mRssiFetchToken, 0),
+ mRssiFetchIntervalMs);
+ }
+ break;
+ case RSSI_FETCH_SUCCEEDED:
+ int rssi = msg.arg1;
+ if (DBG) log("RSSI_FETCH_SUCCEEDED: " + rssi);
+ if (msg.arg1 < RSSI_MONITOR_THRESHOLD) {
+ mRssiMonitorCount++;
+ } else {
+ mRssiMonitorCount = 0;
+ }
+
+ if (mRssiMonitorCount > RSSI_MONITOR_COUNT) {
+ sendPoorLinkDetected();
+ ++mRssiFetchToken;
+ }
+ break;
+ case RSSI_FETCH_FAILED:
+ //can happen if we are waiting to get a disconnect notification
+ if (DBG) log("RSSI_FETCH_FAILED");
+ break;
+ default:
+ return NOT_HANDLED;
+ }
+ return HANDLED;
+ }
+ }
+
/* Child state of ConnectedState indicating that we are online
* and there is nothing to do
*/
class OnlineState extends State {
+ @Override
+ public void enter() {
+ if (DBG) log(getName() + "\n");
+ }
}
private boolean shouldCheckWalledGarden() {
@@ -794,6 +882,20 @@
return success;
}
+ private int calculateSignalLevel(int rssi) {
+ int signalLevel = WifiManager.calculateSignalLevel(rssi,
+ WifiManager.RSSI_LEVELS);
+ if (DBG) log("RSSI current: " + mCurrentSignalLevel + "new: " + rssi + ", " + signalLevel);
+ return signalLevel;
+ }
+
+ private void sendPoorLinkDetected() {
+ if (DBG) log("send POOR_LINK_DETECTED " + mWifiInfo);
+ mWsmChannel.sendMessage(POOR_LINK_DETECTED);
+ mLastAvoidedBssid = mWifiInfo.getBSSID();
+ mLastBssidAvoidedTime = android.os.SystemClock.elapsedRealtime();
+ }
+
/**
* Convenience function for retrieving a single secure settings value
* as a string with a default value.
@@ -844,11 +946,11 @@
return Settings.Secure.putInt(cr, name, value ? 1 : 0);
}
- private void log(String s) {
+ private static void log(String s) {
Log.d(TAG, s);
}
- private void loge(String s) {
+ private static void loge(String s) {
Log.e(TAG, s);
}
}