summaryrefslogtreecommitdiffstats
path: root/core/java/android
diff options
context:
space:
mode:
Diffstat (limited to 'core/java/android')
-rw-r--r--core/java/android/app/Activity.java11
-rw-r--r--core/java/android/content/ContentProvider.java10
-rw-r--r--core/java/android/content/res/Resources.java37
-rw-r--r--core/java/android/hardware/camera2/legacy/SurfaceTextureRenderer.java100
-rw-r--r--core/java/android/midi/MidiDevice.java22
-rw-r--r--core/java/android/midi/MidiDeviceInfo.java7
-rw-r--r--core/java/android/midi/MidiInputPort.java9
-rw-r--r--core/java/android/midi/MidiManager.java56
-rw-r--r--core/java/android/midi/MidiOutputPort.java15
-rw-r--r--core/java/android/midi/MidiPort.java7
-rw-r--r--core/java/android/midi/MidiReceiver.java15
-rw-r--r--core/java/android/midi/MidiSender.java11
-rw-r--r--core/java/android/midi/MidiUtils.java2
-rw-r--r--core/java/android/net/NetworkFactory.java8
-rw-r--r--core/java/android/text/StaticLayout.java4
-rw-r--r--core/java/android/view/View.java4
-rw-r--r--core/java/android/view/ViewGroup.java9
-rw-r--r--core/java/android/view/ViewStub.java25
-rw-r--r--core/java/android/view/WindowManagerGlobal.java8
-rw-r--r--core/java/android/webkit/CookieManager.java5
-rw-r--r--core/java/android/webkit/WebView.java28
-rw-r--r--core/java/android/widget/DatePickerCalendarDelegate.java19
-rw-r--r--core/java/android/widget/RadialTimePickerView.java26
-rw-r--r--core/java/android/widget/TextView.java12
-rw-r--r--core/java/android/widget/TimePickerClockDelegate.java22
25 files changed, 388 insertions, 84 deletions
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index fab88a2..8cee587 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -6068,6 +6068,17 @@ public class Activity extends ContextThemeWrapper
" did not call through to super.onResume()");
}
+ // invisible activities must be finished before onResume() completes
+ if (!mVisibleFromClient && !mFinished) {
+ Log.w(TAG, "An activity without a UI must call finish() before onResume() completes");
+ if (getApplicationInfo().targetSdkVersion
+ > android.os.Build.VERSION_CODES.LOLLIPOP_MR1) {
+ throw new IllegalStateException(
+ "Activity " + mComponent.toShortString() +
+ " did not call finish() prior to onResume() completing");
+ }
+ }
+
// Now really resume, and install the current status bar and menu.
mCalled = false;
diff --git a/core/java/android/content/ContentProvider.java b/core/java/android/content/ContentProvider.java
index 360f308..0cff4c0 100644
--- a/core/java/android/content/ContentProvider.java
+++ b/core/java/android/content/ContentProvider.java
@@ -286,10 +286,12 @@ public abstract class ContentProvider implements ComponentCallbacks2 {
final String original = setCallingPackage(callingPkg);
try {
ContentProviderResult[] results = ContentProvider.this.applyBatch(operations);
- for (int i = 0; i < results.length ; i++) {
- if (userIds[i] != UserHandle.USER_CURRENT) {
- // Adding the userId to the uri.
- results[i] = new ContentProviderResult(results[i], userIds[i]);
+ if (results != null) {
+ for (int i = 0; i < results.length ; i++) {
+ if (userIds[i] != UserHandle.USER_CURRENT) {
+ // Adding the userId to the uri.
+ results[i] = new ContentProviderResult(results[i], userIds[i]);
+ }
}
}
return results;
diff --git a/core/java/android/content/res/Resources.java b/core/java/android/content/res/Resources.java
index 73913b6..ab0dad7 100644
--- a/core/java/android/content/res/Resources.java
+++ b/core/java/android/content/res/Resources.java
@@ -2425,6 +2425,9 @@ public class Resources {
final String themeKey = theme == null ? "" : theme.mKey;
LongSparseArray<WeakReference<ConstantState>> themedCache = caches.get(themeKey);
if (themedCache == null) {
+ // Clean out the caches before we add more. This shouldn't
+ // happen very often.
+ pruneCaches(caches);
themedCache = new LongSparseArray<WeakReference<ConstantState>>(1);
caches.put(themeKey, themedCache);
}
@@ -2434,6 +2437,40 @@ public class Resources {
}
/**
+ * Prunes empty caches from the cache map.
+ *
+ * @param caches The map of caches to prune.
+ */
+ private void pruneCaches(ArrayMap<String,
+ LongSparseArray<WeakReference<ConstantState>>> caches) {
+ final int N = caches.size();
+ for (int i = N - 1; i >= 0; i--) {
+ final LongSparseArray<WeakReference<ConstantState>> cache = caches.get(i);
+ if (pruneCache(cache)) {
+ caches.removeAt(i);
+ }
+ }
+ }
+
+ /**
+ * Prunes obsolete weak references from a cache, returning {@code true} if
+ * the cache is empty and should be removed.
+ *
+ * @param cache The cache of weak references to prune.
+ * @return {@code true} if the cache is empty and should be removed.
+ */
+ private boolean pruneCache(LongSparseArray<WeakReference<ConstantState>> cache) {
+ final int N = cache.size();
+ for (int i = N - 1; i >= 0; i--) {
+ final WeakReference entry = cache.valueAt(i);
+ if (entry.get() == null) {
+ cache.removeAt(i);
+ }
+ }
+ return cache.size() == 0;
+ }
+
+ /**
* Loads a drawable from XML or resources stream.
*/
private Drawable loadDrawableForCookie(TypedValue value, int id, Theme theme) {
diff --git a/core/java/android/hardware/camera2/legacy/SurfaceTextureRenderer.java b/core/java/android/hardware/camera2/legacy/SurfaceTextureRenderer.java
index 4853b81..a0a0716 100644
--- a/core/java/android/hardware/camera2/legacy/SurfaceTextureRenderer.java
+++ b/core/java/android/hardware/camera2/legacy/SurfaceTextureRenderer.java
@@ -58,6 +58,11 @@ public class SurfaceTextureRenderer {
private static final int GLES_VERSION = 2;
private static final int PBUFFER_PIXEL_BYTES = 4;
+ private static final int FLIP_TYPE_NONE = 0;
+ private static final int FLIP_TYPE_HORIZONTAL = 1;
+ private static final int FLIP_TYPE_VERTICAL = 2;
+ private static final int FLIP_TYPE_BOTH = FLIP_TYPE_HORIZONTAL | FLIP_TYPE_VERTICAL;
+
private EGLDisplay mEGLDisplay = EGL14.EGL_NO_DISPLAY;
private EGLContext mEGLContext = EGL14.EGL_NO_CONTEXT;
private EGLConfig mConfigs;
@@ -82,8 +87,8 @@ public class SurfaceTextureRenderer {
private static final int TRIANGLE_VERTICES_DATA_POS_OFFSET = 0;
private static final int TRIANGLE_VERTICES_DATA_UV_OFFSET = 3;
- // Sampling is mirrored across the vertical axis to undo horizontal flip from the front camera
- private static final float[] sFrontCameraTriangleVertices = {
+ // Sampling is mirrored across the horizontal axis
+ private static final float[] sHorizontalFlipTriangleVertices = {
// X, Y, Z, U, V
-1.0f, -1.0f, 0, 1.f, 0.f,
1.0f, -1.0f, 0, 0.f, 0.f,
@@ -91,8 +96,26 @@ public class SurfaceTextureRenderer {
1.0f, 1.0f, 0, 0.f, 1.f,
};
+ // Sampling is mirrored across the vertical axis
+ private static final float[] sVerticalFlipTriangleVertices = {
+ // X, Y, Z, U, V
+ -1.0f, -1.0f, 0, 0.f, 1.f,
+ 1.0f, -1.0f, 0, 1.f, 1.f,
+ -1.0f, 1.0f, 0, 0.f, 0.f,
+ 1.0f, 1.0f, 0, 1.f, 0.f,
+ };
+
+ // Sampling is mirrored across the both axes
+ private static final float[] sBothFlipTriangleVertices = {
+ // X, Y, Z, U, V
+ -1.0f, -1.0f, 0, 1.f, 1.f,
+ 1.0f, -1.0f, 0, 0.f, 1.f,
+ -1.0f, 1.0f, 0, 1.f, 0.f,
+ 1.0f, 1.0f, 0, 0.f, 0.f,
+ };
+
// Sampling is 1:1 for a straight copy for the back camera
- private static final float[] sBackCameraTriangleVertices = {
+ private static final float[] sRegularTriangleVertices = {
// X, Y, Z, U, V
-1.0f, -1.0f, 0, 0.f, 0.f,
1.0f, -1.0f, 0, 1.f, 0.f,
@@ -100,7 +123,11 @@ public class SurfaceTextureRenderer {
1.0f, 1.0f, 0, 1.f, 1.f,
};
- private FloatBuffer mTriangleVertices;
+ private FloatBuffer mRegularTriangleVertices;
+ private FloatBuffer mHorizontalFlipTriangleVertices;
+ private FloatBuffer mVerticalFlipTriangleVertices;
+ private FloatBuffer mBothFlipTriangleVertices;
+ private final int mFacing;
/**
* As used in this file, this vertex shader maps a unit square to the view, and
@@ -148,15 +175,27 @@ public class SurfaceTextureRenderer {
private static final String LEGACY_PERF_PROPERTY = "persist.camera.legacy_perf";
public SurfaceTextureRenderer(int facing) {
- if (facing == CameraCharacteristics.LENS_FACING_BACK) {
- mTriangleVertices = ByteBuffer.allocateDirect(sBackCameraTriangleVertices.length *
- FLOAT_SIZE_BYTES).order(ByteOrder.nativeOrder()).asFloatBuffer();
- mTriangleVertices.put(sBackCameraTriangleVertices).position(0);
- } else {
- mTriangleVertices = ByteBuffer.allocateDirect(sFrontCameraTriangleVertices.length *
- FLOAT_SIZE_BYTES).order(ByteOrder.nativeOrder()).asFloatBuffer();
- mTriangleVertices.put(sFrontCameraTriangleVertices).position(0);
- }
+ mFacing = facing;
+
+ mRegularTriangleVertices = ByteBuffer.allocateDirect(sRegularTriangleVertices.length *
+ FLOAT_SIZE_BYTES).order(ByteOrder.nativeOrder()).asFloatBuffer();
+ mRegularTriangleVertices.put(sRegularTriangleVertices).position(0);
+
+ mHorizontalFlipTriangleVertices = ByteBuffer.allocateDirect(
+ sHorizontalFlipTriangleVertices.length * FLOAT_SIZE_BYTES).
+ order(ByteOrder.nativeOrder()).asFloatBuffer();
+ mHorizontalFlipTriangleVertices.put(sHorizontalFlipTriangleVertices).position(0);
+
+ mVerticalFlipTriangleVertices = ByteBuffer.allocateDirect(
+ sVerticalFlipTriangleVertices.length * FLOAT_SIZE_BYTES).
+ order(ByteOrder.nativeOrder()).asFloatBuffer();
+ mVerticalFlipTriangleVertices.put(sVerticalFlipTriangleVertices).position(0);
+
+ mBothFlipTriangleVertices = ByteBuffer.allocateDirect(
+ sBothFlipTriangleVertices.length * FLOAT_SIZE_BYTES).
+ order(ByteOrder.nativeOrder()).asFloatBuffer();
+ mBothFlipTriangleVertices.put(sBothFlipTriangleVertices).position(0);
+
Matrix.setIdentityM(mSTMatrix, 0);
}
@@ -209,7 +248,7 @@ public class SurfaceTextureRenderer {
return program;
}
- private void drawFrame(SurfaceTexture st, int width, int height) {
+ private void drawFrame(SurfaceTexture st, int width, int height, int flipType) {
checkGlError("onDrawFrame start");
st.getTransformMatrix(mSTMatrix);
@@ -266,16 +305,32 @@ public class SurfaceTextureRenderer {
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, mTextureID);
- mTriangleVertices.position(TRIANGLE_VERTICES_DATA_POS_OFFSET);
+ FloatBuffer triangleVertices;
+ switch(flipType) {
+ case FLIP_TYPE_HORIZONTAL:
+ triangleVertices = mHorizontalFlipTriangleVertices;
+ break;
+ case FLIP_TYPE_VERTICAL:
+ triangleVertices = mVerticalFlipTriangleVertices;
+ break;
+ case FLIP_TYPE_BOTH:
+ triangleVertices = mBothFlipTriangleVertices;
+ break;
+ default:
+ triangleVertices = mRegularTriangleVertices;
+ break;
+ }
+
+ triangleVertices.position(TRIANGLE_VERTICES_DATA_POS_OFFSET);
GLES20.glVertexAttribPointer(maPositionHandle, VERTEX_POS_SIZE, GLES20.GL_FLOAT,
- /*normalized*/ false, TRIANGLE_VERTICES_DATA_STRIDE_BYTES, mTriangleVertices);
+ /*normalized*/ false, TRIANGLE_VERTICES_DATA_STRIDE_BYTES, triangleVertices);
checkGlError("glVertexAttribPointer maPosition");
GLES20.glEnableVertexAttribArray(maPositionHandle);
checkGlError("glEnableVertexAttribArray maPositionHandle");
- mTriangleVertices.position(TRIANGLE_VERTICES_DATA_UV_OFFSET);
+ triangleVertices.position(TRIANGLE_VERTICES_DATA_UV_OFFSET);
GLES20.glVertexAttribPointer(maTextureHandle, VERTEX_UV_SIZE, GLES20.GL_FLOAT,
- /*normalized*/ false, TRIANGLE_VERTICES_DATA_STRIDE_BYTES, mTriangleVertices);
+ /*normalized*/ false, TRIANGLE_VERTICES_DATA_STRIDE_BYTES, triangleVertices);
checkGlError("glVertexAttribPointer maTextureHandle");
GLES20.glEnableVertexAttribArray(maTextureHandle);
checkGlError("glEnableVertexAttribArray maTextureHandle");
@@ -666,7 +721,9 @@ public class SurfaceTextureRenderer {
makeCurrent(holder.eglSurface);
LegacyCameraDevice.setNextTimestamp(holder.surface, captureHolder.second);
- drawFrame(mSurfaceTexture, holder.width, holder.height);
+ drawFrame(mSurfaceTexture, holder.width, holder.height,
+ (mFacing == CameraCharacteristics.LENS_FACING_FRONT) ?
+ FLIP_TYPE_HORIZONTAL : FLIP_TYPE_NONE);
swapBuffers(holder.eglSurface);
} catch (LegacyExceptionUtils.BufferQueueAbandonedException e) {
Log.w(TAG, "Surface abandoned, dropping frame. ", e);
@@ -676,7 +733,10 @@ public class SurfaceTextureRenderer {
for (EGLSurfaceHolder holder : mConversionSurfaces) {
if (LegacyCameraDevice.containsSurfaceId(holder.surface, targetSurfaceIds)) {
makeCurrent(holder.eglSurface);
- drawFrame(mSurfaceTexture, holder.width, holder.height);
+ // glReadPixels reads from the bottom of the buffer, so add an extra vertical flip
+ drawFrame(mSurfaceTexture, holder.width, holder.height,
+ (mFacing == CameraCharacteristics.LENS_FACING_FRONT) ?
+ FLIP_TYPE_BOTH : FLIP_TYPE_VERTICAL);
mPBufferPixels.clear();
GLES20.glReadPixels(/*x*/ 0, /*y*/ 0, holder.width, holder.height,
GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, mPBufferPixels);
diff --git a/core/java/android/midi/MidiDevice.java b/core/java/android/midi/MidiDevice.java
index e704ea0..7f83896 100644
--- a/core/java/android/midi/MidiDevice.java
+++ b/core/java/android/midi/MidiDevice.java
@@ -140,6 +140,12 @@ public final class MidiDevice implements Parcelable {
mReceivers = new ArrayList[outputPorts];
}
+ /**
+ * Called to open a {@link MidiInputPort} for the specified port number.
+ *
+ * @param portNumber the number of the input port to open
+ * @return the {@link MidiInputPort}
+ */
public MidiInputPort openInputPort(int portNumber) {
if (portNumber < 0 || portNumber >= mDeviceInfo.getInputPortCount()) {
throw new IllegalArgumentException("input port number out of range");
@@ -152,6 +158,12 @@ public final class MidiDevice implements Parcelable {
}
}
+ /**
+ * Called to open a {@link MidiOutputPort} for the specified port number.
+ *
+ * @param portNumber the number of the output port to open
+ * @return the {@link MidiOutputPort}
+ */
public MidiOutputPort openOutputPort(int portNumber) {
if (portNumber < 0 || portNumber >= mDeviceInfo.getOutputPortCount()) {
throw new IllegalArgumentException("output port number out of range");
@@ -203,7 +215,7 @@ public final class MidiDevice implements Parcelable {
return true;
}
- void close() {
+ /* package */ void close() {
try {
if (mInputStream != null) {
mInputStream.close();
@@ -216,7 +228,11 @@ public final class MidiDevice implements Parcelable {
}
}
- // returns our MidiDeviceInfo object, which describes this device
+ /**
+ * Returns a {@link MidiDeviceInfo} object, which describes this device.
+ *
+ * @return the {@link MidiDeviceInfo} object
+ */
public MidiDeviceInfo getInfo() {
return mDeviceInfo;
}
@@ -239,10 +255,12 @@ public final class MidiDevice implements Parcelable {
}
};
+ @Override
public int describeContents() {
return 0;
}
+ @Override
public void writeToParcel(Parcel parcel, int flags) {
parcel.writeParcelable(mDeviceInfo, flags);
parcel.writeParcelable(mParcelFileDescriptor, flags);
diff --git a/core/java/android/midi/MidiDeviceInfo.java b/core/java/android/midi/MidiDeviceInfo.java
index 239481b..5b57696 100644
--- a/core/java/android/midi/MidiDeviceInfo.java
+++ b/core/java/android/midi/MidiDeviceInfo.java
@@ -34,7 +34,14 @@ public class MidiDeviceInfo implements Parcelable {
private static final String TAG = "MidiDeviceInfo";
+ /**
+ * Constant representing USB MIDI devices for {@link #getType}
+ */
public static final int TYPE_USB = 1;
+
+ /**
+ * Constant representing virtual (software based) MIDI devices for {@link #getType}
+ */
public static final int TYPE_VIRTUAL = 2;
private final int mType; // USB or virtual
diff --git a/core/java/android/midi/MidiInputPort.java b/core/java/android/midi/MidiInputPort.java
index 583c367..31449a5 100644
--- a/core/java/android/midi/MidiInputPort.java
+++ b/core/java/android/midi/MidiInputPort.java
@@ -38,14 +38,15 @@ public final class MidiInputPort extends MidiPort implements MidiReceiver {
/**
* Writes a MIDI message to the input port
*
- * @param msg message bytes
- * @param offset offset of first byte of the message in msg array
+ * @param msg byte array containing the message
+ * @param offset offset of first byte of the message in msg byte array
* @param count size of the message in bytes
- * @param timestamp future time to post the message
+ * @param timestamp future time to post the message (based on
+ * {@link java.lang.System#nanoTime}
*/
public void onPost(byte[] msg, int offset, int count, long timestamp) throws IOException {
synchronized (mBuffer) {
- int length = MidiDevice.packMessage(msg, offset, count, timestamp, mPortNumber,
+ int length = MidiDevice.packMessage(msg, offset, count, timestamp, getPortNumber(),
mBuffer);
mOutputStream.write(mBuffer, 0, length);
}
diff --git a/core/java/android/midi/MidiManager.java b/core/java/android/midi/MidiManager.java
index f4d1918..64cd4fe 100644
--- a/core/java/android/midi/MidiManager.java
+++ b/core/java/android/midi/MidiManager.java
@@ -35,6 +35,7 @@ import java.util.HashMap;
*
* {@samplecode
* MidiManager manager = (MidiManager) getSystemService(Context.MIDI_SERVICE);}
+ *
* @hide
*/
public class MidiManager {
@@ -64,9 +65,22 @@ public class MidiManager {
}
}
- // Callback interface clients to receive Device added and removed notifications
+ /**
+ * Callback interface used for clients to receive MIDI device added and removed notifications
+ */
public interface DeviceCallback {
+ /**
+ * Called to notify when a new MIDI device has been added
+ *
+ * @param device a {@link MidiDeviceInfo} for the newly added device
+ */
void onDeviceAdded(MidiDeviceInfo device);
+
+ /**
+ * Called to notify when a MIDI device has been removed
+ *
+ * @param device a {@link MidiDeviceInfo} for the removed device
+ */
void onDeviceRemoved(MidiDeviceInfo device);
}
@@ -78,7 +92,11 @@ public class MidiManager {
mService = service;
}
- // Used by clients to register for Device added and removed notifications
+ /**
+ * Registers a callback to receive notifications when MIDI devices are added and removed.
+ *
+ * @param callback a {@link DeviceCallback} for MIDI device notifications
+ */
public void registerDeviceCallback(DeviceCallback callback) {
DeviceListener deviceListener = new DeviceListener(callback);
try {
@@ -90,7 +108,11 @@ public class MidiManager {
mDeviceListeners.put(callback, deviceListener);
}
- // Used by clients to unregister for device added and removed notifications
+ /**
+ * Unregisters a {@link DeviceCallback}.
+ *
+ * @param callback a {@link DeviceCallback} to unregister
+ */
public void unregisterDeviceCallback(DeviceCallback callback) {
DeviceListener deviceListener = mDeviceListeners.remove(callback);
if (deviceListener != null) {
@@ -102,6 +124,11 @@ public class MidiManager {
}
}
+ /**
+ * Gets the list of all connected MIDI devices.
+ *
+ * @return an array of all MIDI devices
+ */
public MidiDeviceInfo[] getDeviceList() {
try {
return mService.getDeviceList();
@@ -111,7 +138,12 @@ public class MidiManager {
}
}
- // Use this if you want to communicate with a MIDI device.
+ /**
+ * Opens a MIDI device for reading and writing.
+ *
+ * @param deviceInfo a {@link android.midi.MidiDeviceInfo} to open
+ * @return a {@link MidiDevice} object for the device
+ */
public MidiDevice openDevice(MidiDeviceInfo deviceInfo) {
try {
ParcelFileDescriptor pfd = mService.openDevice(mToken, deviceInfo);
@@ -130,8 +162,15 @@ public class MidiManager {
return null;
}
- // Use this if you want to register and implement a virtual device.
- // The MidiDevice returned by this method is the proxy you use to implement the device.
+ /**
+ * Creates a new MIDI virtual device.
+ * NOTE: The method for creating virtual devices is likely to change before release.
+ *
+ * @param numInputPorts number of input ports for the virtual device
+ * @param numOutputPorts number of output ports for the virtual device
+ * @param properties a {@link android.os.Bundle} containing properties describing the device
+ * @return a {@link MidiDevice} object to locally represent the device
+ */
public MidiDevice createVirtualDevice(int numInputPorts, int numOutputPorts,
Bundle properties) {
try {
@@ -147,6 +186,11 @@ public class MidiManager {
}
}
+ /**
+ * Removes a MIDI virtual device.
+ *
+ * @param device the {@link MidiDevice} for the virtual device to remove
+ */
public void closeVirtualDevice(MidiDevice device) {
try {
device.close();
diff --git a/core/java/android/midi/MidiOutputPort.java b/core/java/android/midi/MidiOutputPort.java
index 69a33cb..7ce286b 100644
--- a/core/java/android/midi/MidiOutputPort.java
+++ b/core/java/android/midi/MidiOutputPort.java
@@ -32,11 +32,22 @@ public final class MidiOutputPort extends MidiPort implements MidiSender {
mDevice = device;
}
+ /**
+ * Connects a {@link MidiReceiver} to the output port to allow receiving
+ * MIDI messages from the port.
+ *
+ * @param receiver the receiver to connect
+ */
public void connect(MidiReceiver receiver) {
- mDevice.connect(receiver, mPortNumber);
+ mDevice.connect(receiver, getPortNumber());
}
+ /**
+ * Disconnects a {@link MidiReceiver} from the output port.
+ *
+ * @param receiver the receiver to connect
+ */
public void disconnect(MidiReceiver receiver) {
- mDevice.disconnect(receiver, mPortNumber);
+ mDevice.disconnect(receiver, getPortNumber());
}
}
diff --git a/core/java/android/midi/MidiPort.java b/core/java/android/midi/MidiPort.java
index e94f62d..fdd0233 100644
--- a/core/java/android/midi/MidiPort.java
+++ b/core/java/android/midi/MidiPort.java
@@ -20,13 +20,14 @@ import java.io.FileOutputStream;
import java.io.IOException;
/**
- * This class represents a MIDI input or output port
+ * This class represents a MIDI input or output port.
+ * Base class for {@link MidiInputPort} and {@link MidiOutputPort}
*
* @hide
*/
public class MidiPort {
- protected final int mPortNumber;
+ private final int mPortNumber;
/* package */ MidiPort(int portNumber) {
mPortNumber = portNumber;
@@ -37,7 +38,7 @@ public class MidiPort {
*
* @return the port's port number
*/
- public int getPortNumber() {
+ public final int getPortNumber() {
return mPortNumber;
}
}
diff --git a/core/java/android/midi/MidiReceiver.java b/core/java/android/midi/MidiReceiver.java
index 1101105..0b183cc 100644
--- a/core/java/android/midi/MidiReceiver.java
+++ b/core/java/android/midi/MidiReceiver.java
@@ -24,7 +24,18 @@ import java.io.IOException;
* @hide
*/
public interface MidiReceiver {
- // NOTE: the msg array is only valid within the context of this call.
- // the byte array may get reused by the MIDI device for the next message.
+ /**
+ * Called to pass a MIDI event to the receiver.
+ *
+ * NOTE: the msg array parameter is only valid within the context of this call.
+ * The msg bytes should be copied by the receiver rather than retaining a reference
+ * to this parameter.
+ *
+ * @param msg a byte array containing the MIDI message
+ * @param offset the offset of the first byte of the message in the byte array
+ * @param count the number of bytes in the message
+ * @param timestamp the timestamp of the message (based on {@link java.lang.System#nanoTime}
+ * @throws IOException
+ */
public void onPost(byte[] msg, int offset, int count, long timestamp) throws IOException;
}
diff --git a/core/java/android/midi/MidiSender.java b/core/java/android/midi/MidiSender.java
index cba7079..7958a06 100644
--- a/core/java/android/midi/MidiSender.java
+++ b/core/java/android/midi/MidiSender.java
@@ -23,6 +23,17 @@ package android.midi;
* @hide
*/
public interface MidiSender {
+ /**
+ * Called to connect a {@link MidiReceiver} to the sender
+ *
+ * @param receiver the receiver to connect
+ */
public void connect(MidiReceiver receiver);
+
+ /**
+ * Called to disconnect a {@link MidiReceiver} from the sender
+ *
+ * @param receiver the receiver to disconnect
+ */
public void disconnect(MidiReceiver receiver);
}
diff --git a/core/java/android/midi/MidiUtils.java b/core/java/android/midi/MidiUtils.java
index f80e83a..e60e2db 100644
--- a/core/java/android/midi/MidiUtils.java
+++ b/core/java/android/midi/MidiUtils.java
@@ -26,6 +26,8 @@ import android.util.Log;
public final class MidiUtils {
private static final String TAG = "MidiUtils";
+ private MidiUtils() { }
+
/**
* Returns data size of a MIDI message based on the message's command byte
* @param b the message command byte
diff --git a/core/java/android/net/NetworkFactory.java b/core/java/android/net/NetworkFactory.java
index 6ddd8b3..9b80e74 100644
--- a/core/java/android/net/NetworkFactory.java
+++ b/core/java/android/net/NetworkFactory.java
@@ -274,4 +274,12 @@ public class NetworkFactory extends Handler {
protected void log(String s) {
Log.d(LOG_TAG, s);
}
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder("{").append(LOG_TAG).append(" - ScoreFilter=").
+ append(mScore).append(", Filter=").append(mCapabilityFilter).append(", requests=").
+ append(mNetworkRequests.size()).append("}");
+ return sb.toString();
+ }
}
diff --git a/core/java/android/text/StaticLayout.java b/core/java/android/text/StaticLayout.java
index 9fdf88d..5b07397 100644
--- a/core/java/android/text/StaticLayout.java
+++ b/core/java/android/text/StaticLayout.java
@@ -354,12 +354,14 @@ public class StaticLayout extends Layout {
while (breakIndex < breakCount && paraStart + breaks[breakIndex] <= spanEnd) {
int endPos = paraStart + breaks[breakIndex];
+ boolean moreChars = (endPos < paraEnd); // XXX is this the right way to calculate this?
+
v = out(source, here, endPos,
fmAscent, fmDescent, fmTop, fmBottom,
v, spacingmult, spacingadd, chooseHt,chooseHtv, fm, flags[breakIndex],
needMultiply, chdirs, dir, easy, bufEnd, includepad, trackpad,
chs, widths, paraStart, ellipsize, ellipsizedWidth,
- lineWidths[breakIndex], paint, true);
+ lineWidths[breakIndex], paint, moreChars);
if (endPos < spanEnd) {
// preserve metrics for current span
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 753a4e7..143aa24 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -8185,8 +8185,10 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
* @see #performAccessibilityAction(int, Bundle)
*
* Note: Called from the default {@link AccessibilityDelegate}.
+ *
+ * @hide Until we've refactored all accessibility delegation methods.
*/
- boolean performAccessibilityActionInternal(int action, Bundle arguments) {
+ public boolean performAccessibilityActionInternal(int action, Bundle arguments) {
switch (action) {
case AccessibilityNodeInfo.ACTION_CLICK: {
if (isClickable()) {
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index 277e445..10af0c3 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -825,6 +825,12 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
return false;
}
+ // Clip the bounds by our bounds.
+ bounds.left = Math.max(bounds.left, 0);
+ bounds.top = Math.max(bounds.top, 0);
+ bounds.right = Math.min(bounds.right, mRight);
+ bounds.bottom = Math.min(bounds.bottom, mBottom);
+
Iterator<View> iterator = obtainOrderedChildIterator();
while (iterator.hasNext()) {
View sibling = iterator.next();
@@ -5113,7 +5119,8 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
final int height = mBottom - mTop;
boolean rectIsVisible = true;
- if (mParent instanceof ViewGroup && ((ViewGroup)mParent).getClipChildren()) {
+ if (mParent == null ||
+ (mParent instanceof ViewGroup && ((ViewGroup) mParent).getClipChildren())) {
// Clip to bounds.
rectIsVisible = rect.intersect(0, 0, width, height);
}
diff --git a/core/java/android/view/ViewStub.java b/core/java/android/view/ViewStub.java
index d68a860..9f9ed5b 100644
--- a/core/java/android/view/ViewStub.java
+++ b/core/java/android/view/ViewStub.java
@@ -69,8 +69,8 @@ import java.lang.ref.WeakReference;
*/
@RemoteView
public final class ViewStub extends View {
- private int mLayoutResource = 0;
private int mInflatedId;
+ private int mLayoutResource;
private WeakReference<View> mInflatedViewRef;
@@ -78,7 +78,7 @@ public final class ViewStub extends View {
private OnInflateListener mInflateListener;
public ViewStub(Context context) {
- initialize(context);
+ this(context, 0);
}
/**
@@ -88,38 +88,29 @@ public final class ViewStub extends View {
* @param layoutResource The reference to a layout resource that will be inflated.
*/
public ViewStub(Context context, int layoutResource) {
+ this(context, null);
+
mLayoutResource = layoutResource;
- initialize(context);
}
public ViewStub(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
- @SuppressWarnings({"UnusedDeclaration"})
public ViewStub(Context context, AttributeSet attrs, int defStyleAttr) {
this(context, attrs, defStyleAttr, 0);
}
public ViewStub(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
- TypedArray a = context.obtainStyledAttributes(
- attrs, com.android.internal.R.styleable.ViewStub, defStyleAttr, defStyleRes);
+ super(context);
+ final TypedArray a = context.obtainStyledAttributes(attrs,
+ R.styleable.ViewStub, defStyleAttr, defStyleRes);
mInflatedId = a.getResourceId(R.styleable.ViewStub_inflatedId, NO_ID);
mLayoutResource = a.getResourceId(R.styleable.ViewStub_layout, 0);
-
- a.recycle();
-
- a = context.obtainStyledAttributes(
- attrs, com.android.internal.R.styleable.View, defStyleAttr, defStyleRes);
- mID = a.getResourceId(R.styleable.View_id, NO_ID);
+ mID = a.getResourceId(R.styleable.ViewStub_id, NO_ID);
a.recycle();
- initialize(context);
- }
-
- private void initialize(Context context) {
- mContext = context;
setVisibility(GONE);
setWillNotDraw(true);
}
diff --git a/core/java/android/view/WindowManagerGlobal.java b/core/java/android/view/WindowManagerGlobal.java
index 0d82087..0d3727b 100644
--- a/core/java/android/view/WindowManagerGlobal.java
+++ b/core/java/android/view/WindowManagerGlobal.java
@@ -212,15 +212,15 @@ public final class WindowManagerGlobal {
throw new IllegalArgumentException("Params must be WindowManager.LayoutParams");
}
- final WindowManager.LayoutParams wparams = (WindowManager.LayoutParams)params;
+ final WindowManager.LayoutParams wparams = (WindowManager.LayoutParams) params;
if (parentWindow != null) {
parentWindow.adjustLayoutParamsForSubWindow(wparams);
- } else {
+ } else if (ActivityManager.isHighEndGfx()) {
// If there's no parent and we're running on L or above (or in the
// system context), assume we want hardware acceleration.
final Context context = view.getContext();
- if (context != null
- && context.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.LOLLIPOP) {
+ if (context != null && context.getApplicationInfo().targetSdkVersion
+ >= Build.VERSION_CODES.LOLLIPOP) {
wparams.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
}
}
diff --git a/core/java/android/webkit/CookieManager.java b/core/java/android/webkit/CookieManager.java
index eca96f9..6d5fac1 100644
--- a/core/java/android/webkit/CookieManager.java
+++ b/core/java/android/webkit/CookieManager.java
@@ -31,10 +31,7 @@ public abstract class CookieManager {
}
/**
- * Gets the singleton CookieManager instance. If this method is used
- * before the application instantiates a {@link WebView} instance,
- * {@link CookieSyncManager#createInstance CookieSyncManager.createInstance(Context)}
- * must be called first.
+ * Gets the singleton CookieManager instance.
*
* @return the singleton CookieManager instance
*/
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 6793634..3694863 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -239,6 +239,34 @@ import java.util.Map;
* and {@link WebChromeClient#onHideCustomView()} are required,
* {@link WebChromeClient#getVideoLoadingProgressView()} is optional.
* </p>
+ *
+ * <h3>Layout size</h3>
+ * <p>
+ * It is recommended to set the WebView layout height to a fixed value or to
+ * {@link android.view.ViewGroup.LayoutParams#MATCH_PARENT} instead of using
+ * {@link android.view.ViewGroup.LayoutParams#WRAP_CONTENT}.
+ * When using {@link android.view.ViewGroup.LayoutParams#MATCH_PARENT}
+ * for the height none of the WebView's parents should use a
+ * {@link android.view.ViewGroup.LayoutParams#WRAP_CONTENT} layout height since that could result in
+ * incorrect sizing of the views.
+ * </p>
+ *
+ * <p>Setting the WebView's height to {@link android.view.ViewGroup.LayoutParams#WRAP_CONTENT}
+ * enables the following behaviors:
+ * <ul>
+ * <li>The HTML body layout height is set to a fixed value. This means that elements with a height
+ * relative to the HTML body may not be sized correctly. </li>
+ * <li>For applications targetting {@link android.os.Build.VERSION_CODES#KITKAT} and earlier SDKs the
+ * HTML viewport meta tag will be ignored in order to preserve backwards compatibility. </li>
+ * </ul>
+ * </p>
+ *
+ * <p>
+ * Using a layout width of {@link android.view.ViewGroup.LayoutParams#WRAP_CONTENT} is not
+ * supported. If such a width is used the WebView will attempt to use the width of the parent
+ * instead.
+ * </p>
+ *
*/
// Implementation notes.
// The WebView is a thin API class that delegates its public API to a backend WebViewProvider
diff --git a/core/java/android/widget/DatePickerCalendarDelegate.java b/core/java/android/widget/DatePickerCalendarDelegate.java
index 54c4505..e75643ab 100644
--- a/core/java/android/widget/DatePickerCalendarDelegate.java
+++ b/core/java/android/widget/DatePickerCalendarDelegate.java
@@ -372,10 +372,9 @@ class DatePickerCalendarDelegate extends DatePicker.AbstractDatePickerDelegate i
mCurrentDate.set(Calendar.MONTH, monthOfYear);
mCurrentDate.set(Calendar.DAY_OF_MONTH, dayOfMonth);
- onDateChanged(false);
-
- // Set the listener last so that we don't call it.
mDateChangedListener = callBack;
+
+ onDateChanged(false, false);
}
@Override
@@ -384,11 +383,11 @@ class DatePickerCalendarDelegate extends DatePicker.AbstractDatePickerDelegate i
mCurrentDate.set(Calendar.MONTH, month);
mCurrentDate.set(Calendar.DAY_OF_MONTH, dayOfMonth);
- onDateChanged(false);
+ onDateChanged(false, true);
}
- private void onDateChanged(boolean fromUser) {
- if (mDateChangedListener != null) {
+ private void onDateChanged(boolean fromUser, boolean callbackToClient) {
+ if (callbackToClient && mDateChangedListener != null) {
final int year = mCurrentDate.get(Calendar.YEAR);
final int monthOfYear = mCurrentDate.get(Calendar.MONTH);
final int dayOfMonth = mCurrentDate.get(Calendar.DAY_OF_MONTH);
@@ -432,7 +431,7 @@ class DatePickerCalendarDelegate extends DatePicker.AbstractDatePickerDelegate i
}
if (mCurrentDate.before(mTempDate)) {
mCurrentDate.setTimeInMillis(minDate);
- onDateChanged(false);
+ onDateChanged(false, true);
}
mMinDate.setTimeInMillis(minDate);
mDayPickerView.setMinDate(minDate);
@@ -453,7 +452,7 @@ class DatePickerCalendarDelegate extends DatePicker.AbstractDatePickerDelegate i
}
if (mCurrentDate.after(mTempDate)) {
mCurrentDate.setTimeInMillis(maxDate);
- onDateChanged(false);
+ onDateChanged(false, true);
}
mMaxDate.setTimeInMillis(maxDate);
mDayPickerView.setMaxDate(maxDate);
@@ -592,7 +591,7 @@ class DatePickerCalendarDelegate extends DatePicker.AbstractDatePickerDelegate i
public void onYearSelected(int year) {
adjustDayInMonthIfNeeded(mCurrentDate.get(Calendar.MONTH), year);
mCurrentDate.set(Calendar.YEAR, year);
- onDateChanged(true);
+ onDateChanged(true, true);
// Auto-advance to month and day view.
setCurrentView(MONTH_AND_DAY_VIEW);
@@ -665,7 +664,7 @@ class DatePickerCalendarDelegate extends DatePicker.AbstractDatePickerDelegate i
@Override
public void onDaySelected(DayPickerView view, Calendar day) {
mCurrentDate.setTimeInMillis(day.getTimeInMillis());
- onDateChanged(true);
+ onDateChanged(true, true);
}
};
diff --git a/core/java/android/widget/RadialTimePickerView.java b/core/java/android/widget/RadialTimePickerView.java
index 75c6184..7b64cf5 100644
--- a/core/java/android/widget/RadialTimePickerView.java
+++ b/core/java/android/widget/RadialTimePickerView.java
@@ -1456,6 +1456,32 @@ public class RadialTimePickerView extends View implements View.OnTouchListener {
final boolean selected = isVirtualViewSelected(type, value);
node.setSelected(selected);
+
+ final int nextId = getVirtualViewIdAfter(type, value);
+ if (nextId != INVALID_ID) {
+ node.setTraversalBefore(RadialTimePickerView.this, nextId);
+ }
+ }
+
+ private int getVirtualViewIdAfter(int type, int value) {
+ if (type == TYPE_HOUR) {
+ final int nextValue = value + 1;
+ final int max = mIs24HourMode ? 23 : 12;
+ if (nextValue <= max) {
+ return makeId(type, nextValue);
+ }
+ } else if (type == TYPE_MINUTE) {
+ final int current = getCurrentMinute();
+ final int snapValue = value - (value % MINUTE_INCREMENT);
+ final int nextValue = snapValue + MINUTE_INCREMENT;
+ if (value < current && nextValue > current) {
+ // The current value is between two snap values.
+ return makeId(type, current);
+ } else if (nextValue < 60) {
+ return makeId(type, nextValue);
+ }
+ }
+ return INVALID_ID;
}
@Override
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 597de1e..edba9f5 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -8476,8 +8476,14 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
}
}
+ /**
+ * Performs an accessibility action after it has been offered to the
+ * delegate.
+ *
+ * @hide
+ */
@Override
- public boolean performAccessibilityAction(int action, Bundle arguments) {
+ public boolean performAccessibilityActionInternal(int action, Bundle arguments) {
switch (action) {
case AccessibilityNodeInfo.ACTION_CLICK: {
boolean handled = false;
@@ -8558,10 +8564,10 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
case AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY:
case AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY: {
ensureIterableTextForAccessibilitySelectable();
- return super.performAccessibilityAction(action, arguments);
+ return super.performAccessibilityActionInternal(action, arguments);
}
default: {
- return super.performAccessibilityAction(action, arguments);
+ return super.performAccessibilityActionInternal(action, arguments);
}
}
}
diff --git a/core/java/android/widget/TimePickerClockDelegate.java b/core/java/android/widget/TimePickerClockDelegate.java
index d61b6fc..8d475a7 100644
--- a/core/java/android/widget/TimePickerClockDelegate.java
+++ b/core/java/android/widget/TimePickerClockDelegate.java
@@ -33,9 +33,11 @@ import android.view.KeyCharacterMap;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
+import android.view.View.AccessibilityDelegate;
import android.view.ViewGroup;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityNodeInfo;
+import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction;
import com.android.internal.R;
@@ -136,9 +138,13 @@ class TimePickerClockDelegate extends TimePicker.AbstractTimePickerDelegate impl
// Set up hour/minute labels.
mHourView = (TextView) mHeaderView.findViewById(R.id.hours);
mHourView.setOnClickListener(mClickListener);
+ mHourView.setAccessibilityDelegate(
+ new ClickActionDelegate(context, R.string.select_hours));
mSeparatorView = (TextView) mHeaderView.findViewById(R.id.separator);
mMinuteView = (TextView) mHeaderView.findViewById(R.id.minutes);
mMinuteView.setOnClickListener(mClickListener);
+ mMinuteView.setAccessibilityDelegate(
+ new ClickActionDelegate(context, R.string.select_minutes));
final int headerTimeTextAppearance = a.getResourceId(
R.styleable.TimePicker_headerTimeTextAppearance, 0);
@@ -206,6 +212,22 @@ class TimePickerClockDelegate extends TimePicker.AbstractTimePickerDelegate impl
initialize(currentHour, currentMinute, false /* 12h */, HOUR_INDEX);
}
+ private static class ClickActionDelegate extends AccessibilityDelegate {
+ private final AccessibilityAction mClickAction;
+
+ public ClickActionDelegate(Context context, int resId) {
+ mClickAction = new AccessibilityAction(
+ AccessibilityNodeInfo.ACTION_CLICK, context.getString(resId));
+ }
+
+ @Override
+ public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfo info) {
+ super.onInitializeAccessibilityNodeInfo(host, info);
+
+ info.addAction(mClickAction);
+ }
+ }
+
private int computeStableWidth(TextView v, int maxNumber) {
int maxWidth = 0;