diff options
Diffstat (limited to 'core/java')
34 files changed, 508 insertions, 437 deletions
diff --git a/core/java/android/accessibilityservice/AccessibilityServiceInfo.java b/core/java/android/accessibilityservice/AccessibilityServiceInfo.java index 40f45b7..7e21db3 100644 --- a/core/java/android/accessibilityservice/AccessibilityServiceInfo.java +++ b/core/java/android/accessibilityservice/AccessibilityServiceInfo.java @@ -378,6 +378,23 @@ public class AccessibilityServiceInfo implements Parcelable { /** * Creates a new instance. * + * @param isAutomation Whether this is a test automation service. + * + * @hide + */ + public AccessibilityServiceInfo(boolean isAutomation) { + // Automation service can do anything. + if (isAutomation) { + mCapabilities |= CAPABILITY_CAN_RETRIEVE_WINDOW_CONTENT + | CAPABILITY_CAN_REQUEST_TOUCH_EXPLORATION + | CAPABILITY_CAN_REQUEST_ENHANCED_WEB_ACCESSIBILITY + | CAPABILITY_CAN_REQUEST_FILTER_KEY_EVENTS; + } + } + + /** + * Creates a new instance. + * * @param resolveInfo The service resolve info. * @param context Context for accessing resources. * @throws XmlPullParserException If a XML parsing error occurs. diff --git a/core/java/android/app/NativeActivity.java b/core/java/android/app/NativeActivity.java index 7d8a36e..63c6acd 100644 --- a/core/java/android/app/NativeActivity.java +++ b/core/java/android/app/NativeActivity.java @@ -27,7 +27,6 @@ import android.os.Environment; import android.os.Looper; import android.os.MessageQueue; import android.util.AttributeSet; -import android.view.InputChannel; import android.view.InputQueue; import android.view.KeyEvent; import android.view.Surface; @@ -111,11 +110,9 @@ public class NativeActivity extends Activity implements SurfaceHolder.Callback2, int format, int width, int height); private native void onSurfaceRedrawNeededNative(int handle, Surface surface); private native void onSurfaceDestroyedNative(int handle); - private native void onInputChannelCreatedNative(int handle, InputChannel channel); - private native void onInputChannelDestroyedNative(int handle, InputChannel channel); + private native void onInputQueueCreatedNative(int handle, int queuePtr); + private native void onInputQueueDestroyedNative(int handle, int queuePtr); private native void onContentRectChangedNative(int handle, int x, int y, int w, int h); - private native void dispatchKeyEventNative(int handle, KeyEvent event); - private native void finishPreDispatchKeyEventNative(int handle, int seq, boolean handled); static class NativeContentView extends View { NativeActivity mActivity; @@ -197,7 +194,7 @@ public class NativeActivity extends Activity implements SurfaceHolder.Callback2, mCurSurfaceHolder = null; } if (mCurInputQueue != null) { - onInputChannelDestroyedNative(mNativeHandle, mCurInputQueue.getInputChannel()); + onInputQueueDestroyedNative(mNativeHandle, mCurInputQueue.getNativePtr()); mCurInputQueue = null; } unloadNativeCode(mNativeHandle); @@ -261,18 +258,6 @@ public class NativeActivity extends Activity implements SurfaceHolder.Callback2, } } - @Override - public boolean dispatchKeyEvent(KeyEvent event) { - if (mDispatchingUnhandledKey) { - return super.dispatchKeyEvent(event); - } else { - // Key events from the IME do not go through the input channel; - // we need to intercept them here to hand to the application. - dispatchKeyEventNative(mNativeHandle, event); - return true; - } - } - public void surfaceCreated(SurfaceHolder holder) { if (!mDestroyed) { mCurSurfaceHolder = holder; @@ -304,14 +289,14 @@ public class NativeActivity extends Activity implements SurfaceHolder.Callback2, public void onInputQueueCreated(InputQueue queue) { if (!mDestroyed) { mCurInputQueue = queue; - onInputChannelCreatedNative(mNativeHandle, queue.getInputChannel()); + onInputQueueCreatedNative(mNativeHandle, queue.getNativePtr()); } } public void onInputQueueDestroyed(InputQueue queue) { - mCurInputQueue = null; if (!mDestroyed) { - onInputChannelDestroyedNative(mNativeHandle, queue.getInputChannel()); + onInputQueueDestroyedNative(mNativeHandle, queue.getNativePtr()); + mCurInputQueue = null; } } @@ -332,25 +317,6 @@ public class NativeActivity extends Activity implements SurfaceHolder.Callback2, } } - boolean dispatchUnhandledKeyEvent(KeyEvent event) { - try { - mDispatchingUnhandledKey = true; - View decor = getWindow().getDecorView(); - if (decor != null) { - return decor.dispatchKeyEvent(event); - } else { - return false; - } - } finally { - mDispatchingUnhandledKey = false; - } - } - - void preDispatchKeyEvent(KeyEvent event, int seq) { - // FIXME: Input dispatch should be redirected back through ViewRootImpl again. - finishPreDispatchKeyEventNative(mNativeHandle, seq, false); - } - void setWindowFlags(int flags, int mask) { getWindow().setFlags(flags, mask); } diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java index 8d994c4..2e328b2 100644 --- a/core/java/android/app/Notification.java +++ b/core/java/android/app/Notification.java @@ -635,11 +635,16 @@ public class Notification implements Parcelable @Override public Notification clone() { Notification that = new Notification(); - cloneInto(that); + cloneInto(that, true); return that; } - private void cloneInto(Notification that) { + /** + * Copy all (or if heavy is false, all except Bitmaps and RemoteViews) members + * of this into that. + * @hide + */ + public void cloneInto(Notification that, boolean heavy) { that.when = this.when; that.icon = this.icon; that.number = this.number; @@ -652,13 +657,13 @@ public class Notification implements Parcelable if (this.tickerText != null) { that.tickerText = this.tickerText.toString(); } - if (this.tickerView != null) { + if (heavy && this.tickerView != null) { that.tickerView = this.tickerView.clone(); } - if (this.contentView != null) { + if (heavy && this.contentView != null) { that.contentView = this.contentView.clone(); } - if (this.largeIcon != null) { + if (heavy && this.largeIcon != null) { that.largeIcon = Bitmap.createBitmap(this.largeIcon); } that.iconLevel = this.iconLevel; @@ -690,7 +695,6 @@ public class Notification implements Parcelable if (this.extras != null) { that.extras = new Bundle(this.extras); - } if (this.actions != null) { @@ -700,9 +704,30 @@ public class Notification implements Parcelable } } - if (this.bigContentView != null) { + if (heavy && this.bigContentView != null) { that.bigContentView = this.bigContentView.clone(); } + + if (!heavy) { + that.lightenPayload(); // will clean out extras + } + } + + /** + * Removes heavyweight parts of the Notification object for archival or for sending to + * listeners when the full contents are not necessary. + * @hide + */ + public final void lightenPayload() { + tickerView = null; + contentView = null; + bigContentView = null; + largeIcon = null; + if (extras != null) { + extras.remove(Notification.EXTRA_LARGE_ICON); + extras.remove(Notification.EXTRA_LARGE_ICON_BIG); + extras.remove(Notification.EXTRA_PICTURE); + } } public int describeContents() { @@ -1706,7 +1731,7 @@ public class Notification implements Parcelable * @hide */ public Notification buildInto(Notification n) { - build().cloneInto(n); + build().cloneInto(n, true); return n; } } diff --git a/core/java/android/app/UiAutomation.java b/core/java/android/app/UiAutomation.java index 05b79c1..498fa42 100644 --- a/core/java/android/app/UiAutomation.java +++ b/core/java/android/app/UiAutomation.java @@ -443,18 +443,25 @@ public final class UiAutomation { */ public AccessibilityEvent executeAndWaitForEvent(Runnable command, AccessibilityEventFilter filter, long timeoutMillis) throws TimeoutException { + // Acquire the lock and prepare for receiving events. synchronized (mLock) { throwIfNotConnectedLocked(); - mEventQueue.clear(); // Prepare to wait for an event. mWaitingForEventDelivery = true; + } - // We will ignore events from previous interactions. - final long executionStartTimeMillis = SystemClock.uptimeMillis(); + // Note: We have to release the lock since calling out with this lock held + // can bite. We will correctly filter out events from other interactions, + // so starting to collect events before running the action is just fine. - // Execute the command. - command.run(); + // We will ignore events from previous interactions. + final long executionStartTimeMillis = SystemClock.uptimeMillis(); + // Execute the command *without* the lock being held. + command.run(); + + // Acquire the lock and wait for the event. + synchronized (mLock) { try { // Wait for the event. final long startTimeMillis = SystemClock.uptimeMillis(); @@ -463,7 +470,7 @@ public final class UiAutomation { while (!mEventQueue.isEmpty()) { AccessibilityEvent event = mEventQueue.remove(0); // Ignore events from previous interactions. - if (event.getEventTime() <= executionStartTimeMillis) { + if (event.getEventTime() < executionStartTimeMillis) { continue; } if (filter.accept(event)) { diff --git a/core/java/android/app/UiAutomationConnection.java b/core/java/android/app/UiAutomationConnection.java index 97c7ff3..5bc17fa 100644 --- a/core/java/android/app/UiAutomationConnection.java +++ b/core/java/android/app/UiAutomationConnection.java @@ -158,7 +158,7 @@ public final class UiAutomationConnection extends IUiAutomationConnection.Stub { private void registerUiTestAutomationServiceLocked(IAccessibilityServiceClient client) { IAccessibilityManager manager = IAccessibilityManager.Stub.asInterface( ServiceManager.getService(Context.ACCESSIBILITY_SERVICE)); - AccessibilityServiceInfo info = new AccessibilityServiceInfo(); + AccessibilityServiceInfo info = new AccessibilityServiceInfo(true); info.eventTypes = AccessibilityEvent.TYPES_ALL_MASK; info.feedbackType = AccessibilityServiceInfo.FEEDBACK_GENERIC; info.flags |= AccessibilityServiceInfo.FLAG_INCLUDE_NOT_IMPORTANT_VIEWS diff --git a/core/java/android/app/backup/BackupAgent.java b/core/java/android/app/backup/BackupAgent.java index 37fddcb..67c772b 100644 --- a/core/java/android/app/backup/BackupAgent.java +++ b/core/java/android/app/backup/BackupAgent.java @@ -17,12 +17,15 @@ package android.app.backup; import android.app.IBackupAgent; +import android.app.QueuedWork; import android.app.backup.IBackupManager; import android.content.Context; import android.content.ContextWrapper; import android.content.pm.ApplicationInfo; import android.os.Binder; +import android.os.Handler; import android.os.IBinder; +import android.os.Looper; import android.os.ParcelFileDescriptor; import android.os.Process; import android.os.RemoteException; @@ -33,6 +36,7 @@ import java.io.FileOutputStream; import java.io.IOException; import java.util.HashSet; import java.util.LinkedList; +import java.util.concurrent.CountDownLatch; import libcore.io.ErrnoException; import libcore.io.Libcore; @@ -122,6 +126,32 @@ public abstract class BackupAgent extends ContextWrapper { /** @hide */ public static final int TYPE_SYMLINK = 3; + Handler mHandler = null; + + class SharedPrefsSynchronizer implements Runnable { + public final CountDownLatch mLatch = new CountDownLatch(1); + + @Override + public void run() { + QueuedWork.waitToFinish(); + mLatch.countDown(); + } + }; + + // Syncing shared preferences deferred writes needs to happen on the main looper thread + private void waitForSharedPrefs() { + if (mHandler == null) { + mHandler = new Handler(Looper.getMainLooper()); + } + + final SharedPrefsSynchronizer s = new SharedPrefsSynchronizer(); + mHandler.postAtFrontOfQueue(s); + try { + s.mLatch.await(); + } catch (InterruptedException e) { /* ignored */ } + } + + public BackupAgent() { super(null); } @@ -542,6 +572,11 @@ public abstract class BackupAgent extends ContextWrapper { Log.d(TAG, "onBackup (" + BackupAgent.this.getClass().getName() + ") threw", ex); throw ex; } finally { + // Ensure that any SharedPreferences writes have landed after the backup, + // in case the app code has side effects (since apps cannot provide this + // guarantee themselves). + waitForSharedPrefs(); + Binder.restoreCallingIdentity(ident); try { callbackBinder.opComplete(token); @@ -569,6 +604,9 @@ public abstract class BackupAgent extends ContextWrapper { Log.d(TAG, "onRestore (" + BackupAgent.this.getClass().getName() + ") threw", ex); throw ex; } finally { + // Ensure that any side-effect SharedPreferences writes have landed + waitForSharedPrefs(); + Binder.restoreCallingIdentity(ident); try { callbackBinder.opComplete(token); @@ -586,6 +624,10 @@ public abstract class BackupAgent extends ContextWrapper { if (DEBUG) Log.v(TAG, "doFullBackup() invoked"); + // Ensure that any SharedPreferences writes have landed *before* + // we potentially try to back up the underlying files directly. + waitForSharedPrefs(); + try { BackupAgent.this.onFullBackup(new FullBackupDataOutput(data)); } catch (IOException ex) { @@ -595,6 +637,9 @@ public abstract class BackupAgent extends ContextWrapper { Log.d(TAG, "onBackup (" + BackupAgent.this.getClass().getName() + ") threw", ex); throw ex; } finally { + // ... and then again after, as in the doBackup() case + waitForSharedPrefs(); + // Send the EOD marker indicating that there is no more data // forthcoming from this agent. try { @@ -624,6 +669,9 @@ public abstract class BackupAgent extends ContextWrapper { } catch (IOException e) { throw new RuntimeException(e); } finally { + // Ensure that any side-effect SharedPreferences writes have landed + waitForSharedPrefs(); + Binder.restoreCallingIdentity(ident); try { callbackBinder.opComplete(token); diff --git a/core/java/android/content/ContentValues.aidl b/core/java/android/content/ContentValues.aidl new file mode 100644 index 0000000..23d51d8 --- /dev/null +++ b/core/java/android/content/ContentValues.aidl @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.content; + +parcelable ContentValues; diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java index 30bdfef..4266d85 100644 --- a/core/java/android/content/pm/PackageManager.java +++ b/core/java/android/content/pm/PackageManager.java @@ -870,6 +870,14 @@ public abstract class PackageManager { /** * Feature for {@link #getSystemAvailableFeatures} and + * {@link #hasSystemFeature}: The device is capable of communicating with + * other devices via Bluetooth Low Energy radio. + */ + @SdkConstant(SdkConstantType.FEATURE) + public static final String FEATURE_BLUETOOTH_LE = "android.hardware.bluetooth_le"; + + /** + * Feature for {@link #getSystemAvailableFeatures} and * {@link #hasSystemFeature}: The device has a camera facing away * from the screen. */ diff --git a/core/java/android/content/res/Configuration.java b/core/java/android/content/res/Configuration.java index 86d6ee7..905ae0d 100644 --- a/core/java/android/content/res/Configuration.java +++ b/core/java/android/content/res/Configuration.java @@ -1219,12 +1219,12 @@ public final class Configuration implements Parcelable, Comparable<Configuration * Return the layout direction. Will be either {@link View#LAYOUT_DIRECTION_LTR} or * {@link View#LAYOUT_DIRECTION_RTL}. * - * @return the layout direction + * @return Returns {@link View#LAYOUT_DIRECTION_RTL} if the configuration + * is {@link #SCREENLAYOUT_LAYOUTDIR_RTL}, otherwise {@link View#LAYOUT_DIRECTION_LTR}. */ public int getLayoutDirection() { - // We need to substract one here as the configuration values are using "0" as undefined thus - // having LRT set to "1" and RTL set to "2" - return ((screenLayout&SCREENLAYOUT_LAYOUTDIR_MASK) >> SCREENLAYOUT_LAYOUTDIR_SHIFT) - 1; + return (screenLayout&SCREENLAYOUT_LAYOUTDIR_MASK) == SCREENLAYOUT_LAYOUTDIR_RTL + ? View.LAYOUT_DIRECTION_RTL : View.LAYOUT_DIRECTION_LTR; } /** diff --git a/core/java/android/content/res/Resources.java b/core/java/android/content/res/Resources.java index d8d5f2b..42f4faf 100644 --- a/core/java/android/content/res/Resources.java +++ b/core/java/android/content/res/Resources.java @@ -1985,13 +1985,14 @@ public class Resources { } } - static private final int VARYING_CONFIGS = ActivityInfo.activityInfoConfigToNative( - ActivityInfo.CONFIG_LAYOUT_DIRECTION); - - private boolean verifyPreloadConfig(int changingConfigurations, int resourceId, String name) { - // We dont want to preloadd a Drawable when there is both a LTR and RTL version of it + private boolean verifyPreloadConfig(int changingConfigurations, int allowVarying, + int resourceId, String name) { + // We allow preloading of resources even if they vary by font scale (which + // doesn't impact resource selection) or density (which we handle specially by + // simply turning off all preloading), as well as any other configs specified + // by the caller. if (((changingConfigurations&~(ActivityInfo.CONFIG_FONT_SCALE | - ActivityInfo.CONFIG_DENSITY)) & VARYING_CONFIGS) != 0) { + ActivityInfo.CONFIG_DENSITY)) & ~allowVarying) != 0) { String resName; try { resName = getResourceName(resourceId); @@ -2017,6 +2018,9 @@ public class Resources { return true; } + static private final int LAYOUT_DIR_CONFIG = ActivityInfo.activityInfoConfigToNative( + ActivityInfo.CONFIG_LAYOUT_DIRECTION); + /*package*/ Drawable loadDrawable(TypedValue value, int id) throws NotFoundException { @@ -2041,11 +2045,12 @@ public class Resources { if (dr != null) { return dr; } - final int layoutDirection = mConfiguration.getLayoutDirection(); - Drawable.ConstantState cs = isColorDrawable - ? sPreloadedColorDrawables.get(key) - : (sPreloadedDensity == mConfiguration.densityDpi - ? sPreloadedDrawables[layoutDirection].get(key) : null); + Drawable.ConstantState cs; + if (isColorDrawable) { + cs = sPreloadedColorDrawables.get(key); + } else { + cs = sPreloadedDrawables[mConfiguration.getLayoutDirection()].get(key); + } if (cs != null) { dr = cs.newDrawable(this); } else { @@ -2119,12 +2124,26 @@ public class Resources { cs = dr.getConstantState(); if (cs != null) { if (mPreloading) { - if (verifyPreloadConfig(cs.getChangingConfigurations(), value.resourceId, - "drawable")) { - if (isColorDrawable) { + final int changingConfigs = cs.getChangingConfigurations(); + if (isColorDrawable) { + if (verifyPreloadConfig(changingConfigs, 0, value.resourceId, + "drawable")) { sPreloadedColorDrawables.put(key, cs); - } else { - sPreloadedDrawables[layoutDirection].put(key, cs); + } + } else { + if (verifyPreloadConfig(changingConfigs, + LAYOUT_DIR_CONFIG, value.resourceId, "drawable")) { + if ((changingConfigs&LAYOUT_DIR_CONFIG) == 0) { + // If this resource does not vary based on layout direction, + // we can put it in all of the preload maps. + sPreloadedDrawables[0].put(key, cs); + sPreloadedDrawables[1].put(key, cs); + } else { + // Otherwise, only in the layout dir we loaded it for. + final LongSparseArray<Drawable.ConstantState> preloads + = sPreloadedDrawables[mConfiguration.getLayoutDirection()]; + preloads.put(key, cs); + } } } } else { @@ -2190,7 +2209,8 @@ public class Resources { csl = ColorStateList.valueOf(value.data); if (mPreloading) { - if (verifyPreloadConfig(value.changingConfigurations, value.resourceId, "color")) { + if (verifyPreloadConfig(value.changingConfigurations, 0, value.resourceId, + "color")) { sPreloadedColorStateLists.put(key, csl); } } @@ -2239,7 +2259,8 @@ public class Resources { if (csl != null) { if (mPreloading) { - if (verifyPreloadConfig(value.changingConfigurations, value.resourceId, "color")) { + if (verifyPreloadConfig(value.changingConfigurations, 0, value.resourceId, + "color")) { sPreloadedColorStateLists.put(key, csl); } } else { diff --git a/core/java/android/database/CursorWindow.aidl b/core/java/android/database/CursorWindow.aidl new file mode 100644 index 0000000..5809355 --- /dev/null +++ b/core/java/android/database/CursorWindow.aidl @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.database; + +parcelable CursorWindow; diff --git a/core/java/android/net/IConnectivityManager.aidl b/core/java/android/net/IConnectivityManager.aidl index 9e9b43d..e5d6e51 100644 --- a/core/java/android/net/IConnectivityManager.aidl +++ b/core/java/android/net/IConnectivityManager.aidl @@ -129,4 +129,6 @@ interface IConnectivityManager void captivePortalCheckComplete(in NetworkInfo info); void supplyMessenger(int networkType, in Messenger messenger); + + int findConnectionTypeForIface(in String iface); } diff --git a/core/java/android/os/Build.java b/core/java/android/os/Build.java index bbad76a..71c3e4a 100644 --- a/core/java/android/os/Build.java +++ b/core/java/android/os/Build.java @@ -433,9 +433,9 @@ public class Build { public static final int JELLY_BEAN_MR1 = 17; /** - * Android 4.X: Jelly Bean MR2, the revenge of the beans. + * Android 4.3: Jelly Bean MR2, the revenge of the beans. */ - public static final int JELLY_BEAN_MR2 = CUR_DEVELOPMENT; + public static final int JELLY_BEAN_MR2 = 18; /** * Android X.X: Key Lime Pie, another tasty treat. diff --git a/core/java/android/os/Debug.java b/core/java/android/os/Debug.java index 2e77237..fd01da9 100644 --- a/core/java/android/os/Debug.java +++ b/core/java/android/os/Debug.java @@ -577,6 +577,7 @@ href="{@docRoot}guide/developing/tools/traceview.html">Traceview: A Graphical Lo * * @see #startAllocCounting() */ + @Deprecated public static void stopAllocCounting() { VMDebug.stopAllocCounting(); } diff --git a/core/java/android/service/notification/NotificationListenerService.java b/core/java/android/service/notification/NotificationListenerService.java index 86bab2a..8b72ca9 100644 --- a/core/java/android/service/notification/NotificationListenerService.java +++ b/core/java/android/service/notification/NotificationListenerService.java @@ -55,10 +55,17 @@ public abstract class NotificationListenerService extends Service { * <P> * This might occur because the user has dismissed the notification using system UI (or another * notification listener) or because the app has withdrawn the notification. + * <P> + * NOTE: The {@link StatusBarNotification} object you receive will be "light"; that is, the + * {@link StatusBarNotification#notification} member may be missing some heavyweight + * fields such as {@link android.app.Notification#contentView} and + * {@link android.app.Notification#largeIcon}. However, all other fields on + * {@link StatusBarNotification}, sufficient to match this call with a prior call to + * {@link #onNotificationPosted(StatusBarNotification)}, will be intact. * - * @param sbn A data structure encapsulating the original {@link android.app.Notification} - * object as well as its identifying information (tag and id) and source - * (package name). + * @param sbn A data structure encapsulating at least the original information (tag and id) + * and source (package name) used to post the {@link android.app.Notification} that + * was just removed. */ public abstract void onNotificationRemoved(StatusBarNotification sbn); diff --git a/core/java/android/service/notification/StatusBarNotification.java b/core/java/android/service/notification/StatusBarNotification.java index ef5f8c4..006518c 100644 --- a/core/java/android/service/notification/StatusBarNotification.java +++ b/core/java/android/service/notification/StatusBarNotification.java @@ -152,6 +152,17 @@ public class StatusBarNotification implements Parcelable { } }; + /** + * @hide + */ + public StatusBarNotification cloneLight() { + final Notification no = new Notification(); + this.notification.cloneInto(no, false); // light copy + return new StatusBarNotification(this.pkg, this.basePkg, + this.id, this.tag, this.uid, this.initialPid, + this.score, no, this.user, this.postTime); + } + @Override public StatusBarNotification clone() { return new StatusBarNotification(this.pkg, this.basePkg, diff --git a/core/java/android/text/bidi/BidiFormatter.java b/core/java/android/text/BidiFormatter.java index 7a08213..3fab35b 100644 --- a/core/java/android/text/bidi/BidiFormatter.java +++ b/core/java/android/text/BidiFormatter.java @@ -14,18 +14,14 @@ * limitations under the License. */ -package android.text.bidi; +package android.text; -import android.text.TextDirectionHeuristic; -import android.text.TextDirectionHeuristics; -import android.text.TextUtils; import android.view.View; import static android.text.TextDirectionHeuristics.FIRSTSTRONG_LTR; import java.util.Locale; - /** * Utility class for formatting text for display in a potentially opposite-directionality context * without garbling. The directionality of the context is set at formatter creation and the @@ -34,14 +30,12 @@ import java.util.Locale; * <p> * 1. Bidi Wrapping * When text in one language is mixed into a document in another, opposite-directionality language, - * e.g. when an English business name is embedded in a Hebrew web page, both the inserted string + * e.g. when an English business name is embedded in some Hebrew text, both the inserted string * and the text surrounding it may be displayed incorrectly unless the inserted string is explicitly * separated from the surrounding text in a "wrapper" that: * <p> - * - Declares its directionality so that the string is displayed correctly. This can be done in HTML - * markup (e.g. a 'span dir="rtl"' element) by {@link #spanWrap} and similar methods, or - only in - * contexts where markup can't be used - in Unicode bidi formatting codes by {@link #unicodeWrap} - * and similar methods. + * - Declares its directionality so that the string is displayed correctly. This can be done in + * Unicode bidi formatting codes by {@link #unicodeWrap} and similar methods. * <p> * - Isolates the string's directionality, so it does not unduly affect the surrounding content. * Currently, this can only be done using invisible Unicode characters of the same direction as @@ -80,16 +74,6 @@ import java.util.Locale; * estimated at run-time. The bidi formatter can do this automatically using the default * first-strong estimation algorithm. It can also be configured to use a custom directionality * estimation object. - * <p> - * 3. Escaping - * When wrapping plain text - i.e. text that is not already HTML or HTML-escaped - in HTML markup, - * the text must first be HTML-escaped to prevent XSS attacks and other nasty business. This of - * course is always true, but the escaping can not be done after the string has already been wrapped - * in markup, so the bidi formatter also serves as a last chance and includes escaping services. - * <p> - * Thus, in a single call, the formatter will escape the input string as specified, determine its - * directionality, and wrap it as necessary. It is then up to the caller to insert the return value - * in the output. */ public final class BidiFormatter { @@ -134,36 +118,6 @@ public final class BidiFormatter { private static final String RLM_STRING = Character.toString(RLM); /** - * "ltr" string constant. - */ - private static final String LTR_STRING = "ltr"; - - /** - * "rtl" string constant. - */ - private static final String RTL_STRING = "rtl"; - - /** - * "dir=\"ltr\"" string constant. - */ - private static final String DIR_LTR_STRING = "dir=\"ltr\""; - - /** - * "dir=\"rtl\"" string constant. - */ - private static final String DIR_RTL_STRING = "dir=\"rtl\""; - - /** - * "right" string constant. - */ - private static final String RIGHT = "right"; - - /** - * "left" string constant. - */ - private static final String LEFT = "left"; - - /** * Empty string constant. */ private static final String EMPTY_STRING = ""; @@ -325,102 +279,21 @@ public final class BidiFormatter { } /** - * Returns "rtl" if {@code str}'s estimated directionality is RTL, and "ltr" if it is LTR. - * - * @param str String whose directionality is to be estimated. - * @return "rtl" if {@code str}'s estimated directionality is RTL, and "ltr" otherwise. - */ - public String dirAttrValue(String str) { - return dirAttrValue(isRtl(str)); - } - - /** - * Operates like {@link #dirAttrValue(String)}, but uses a given heuristic to estimate the - * {@code str}'s directionality. - * - * @param str String whose directionality is to be estimated. - * @param heuristic The text direction heuristic that will be used to estimate the {@code str}'s - * directionality. - * @return "rtl" if {@code str}'s estimated directionality is RTL, and "ltr" otherwise. - */ - public String dirAttrValue(String str, TextDirectionHeuristic heuristic) { - return dirAttrValue(heuristic.isRtl(str, 0, str.length())); - } - - /** - * Returns "rtl" if the given directionality is RTL, and "ltr" if it is LTR. - * - * @param isRtl Whether the directionality is RTL or not. - * @return "rtl" if the given directionality is RTL, and "ltr" otherwise. - */ - public String dirAttrValue(boolean isRtl) { - return isRtl ? RTL_STRING : LTR_STRING; - } - - /** - * Returns "dir=\"ltr\"" or "dir=\"rtl\"", depending on {@code str}'s estimated directionality, - * if it is not the same as the context directionality. Otherwise, returns the empty string. - * - * @param str String whose directionality is to be estimated. - * @return "dir=\"rtl\"" for RTL text in non-RTL context; "dir=\"ltr\"" for LTR text in non-LTR - * context; else, the empty string. - */ - public String dirAttr(String str) { - return dirAttr(isRtl(str)); - } - - /** - * Operates like {@link #dirAttr(String)}, but uses a given heuristic to estimate the - * {@code str}'s directionality. - * - * @param str String whose directionality is to be estimated. - * @param heuristic The text direction heuristic that will be used to estimate the {@code str}'s - * directionality. - * @return "dir=\"rtl\"" for RTL text in non-RTL context; "dir=\"ltr\"" for LTR text in non-LTR - * context; else, the empty string. - */ - public String dirAttr(String str, TextDirectionHeuristic heuristic) { - return dirAttr(heuristic.isRtl(str, 0, str.length())); - } - - /** - * Returns "dir=\"ltr\"" or "dir=\"rtl\"", depending on the given directionality, if it is not - * the same as the context directionality. Otherwise, returns the empty string. - * - * @param isRtl Whether the directionality is RTL or not - * @return "dir=\"rtl\"" for RTL text in non-RTL context; "dir=\"ltr\"" for LTR text in non-LTR - * context; else, the empty string. - */ - public String dirAttr(boolean isRtl) { - return (isRtl != mIsRtlContext) ? (isRtl ? DIR_RTL_STRING : DIR_LTR_STRING) : EMPTY_STRING; - } - - /** * Returns a Unicode bidi mark matching the context directionality (LRM or RLM) if either the * overall or the exit directionality of a given string is opposite to the context directionality. * Putting this after the string (including its directionality declaration wrapping) prevents it * from "sticking" to other opposite-directionality text or a number appearing after it inline * with only neutral content in between. Otherwise returns the empty string. While the exit * directionality is determined by scanning the end of the string, the overall directionality is - * given explicitly in {@code dir}. - * - * @param str String after which the mark may need to appear. - * @return LRM for RTL text in LTR context; RLM for LTR text in RTL context; - * else, the empty string. - */ - public String markAfter(String str) { - return markAfter(str, mDefaultTextDirectionHeuristic); - } - - /** - * Operates like {@link #markAfter(String)}, but uses a given heuristic to estimate the - * {@code str}'s directionality. + * given explicitly by a heuristic to estimate the {@code str}'s directionality. * * @param str String after which the mark may need to appear. * @param heuristic The text direction heuristic that will be used to estimate the {@code str}'s * directionality. * @return LRM for RTL text in LTR context; RLM for LTR text in RTL context; * else, the empty string. + * + * @hide */ public String markAfter(String str, TextDirectionHeuristic heuristic) { final boolean isRtl = heuristic.isRtl(str, 0, str.length()); @@ -438,28 +311,18 @@ public final class BidiFormatter { * Returns a Unicode bidi mark matching the context directionality (LRM or RLM) if either the * overall or the entry directionality of a given string is opposite to the context * directionality. Putting this before the string (including its directionality declaration - * wrapping) prevents it from "sticking" to other opposite-directionality text appearing before it - * inline with only neutral content in between. Otherwise returns the empty string. While the + * wrapping) prevents it from "sticking" to other opposite-directionality text appearing before + * it inline with only neutral content in between. Otherwise returns the empty string. While the * entry directionality is determined by scanning the beginning of the string, the overall - * directionality is given explicitly in {@code dir}. - * - * @param str String before which the mark may need to appear. - * @return LRM for RTL text in LTR context; RLM for LTR text in RTL context; - * else, the empty string. - */ - public String markBefore(String str) { - return markBefore(str, mDefaultTextDirectionHeuristic); - } - - /** - * Operates like {@link #markBefore(String)}, but uses a given heuristic to estimate the - * {@code str}'s directionality. + * directionality is given explicitly by a heuristic to estimate the {@code str}'s directionality. * * @param str String before which the mark may need to appear. * @param heuristic The text direction heuristic that will be used to estimate the {@code str}'s * directionality. * @return LRM for RTL text in LTR context; RLM for LTR text in RTL context; * else, the empty string. + * + * @hide */ public String markBefore(String str, TextDirectionHeuristic heuristic) { final boolean isRtl = heuristic.isRtl(str, 0, str.length()); @@ -474,30 +337,6 @@ public final class BidiFormatter { } /** - * Returns the Unicode bidi mark matching the context directionality (LRM for LTR context - * directionality, RLM for RTL context directionality). - */ - public String mark() { - return mIsRtlContext ? RLM_STRING : LRM_STRING; - } - - /** - * Returns "right" for RTL context directionality. Otherwise for LTR context directionality - * returns "left". - */ - public String startEdge() { - return mIsRtlContext ? RIGHT : LEFT; - } - - /** - * Returns "left" for RTL context directionality. Otherwise for LTR context directionality - * returns "right". - */ - public String endEdge() { - return mIsRtlContext ? LEFT : RIGHT; - } - - /** * Estimates the directionality of a string using the default text direction heuristic. * * @param str String whose directionality is to be estimated. @@ -509,95 +348,9 @@ public final class BidiFormatter { } /** - * Formats a given string of unknown directionality for use in HTML output of the context - * directionality, so an opposite-directionality string is neither garbled nor garbles its - * surroundings. - * <p> - * The algorithm: estimates the directionality of the given string using the given heuristic. - * If the directionality is known, pass TextDirectionHeuristics.LTR or RTL for heuristic. - * In case its directionality doesn't match the context directionality, wraps it with a 'span' - * element and adds a "dir" attribute (either 'dir=\"rtl\"' or 'dir=\"ltr\"'). - * <p> - * If {@code isolate}, directionally isolates the string so that it does not garble its - * surroundings. Currently, this is done by "resetting" the directionality after the string by - * appending a trailing Unicode bidi mark matching the context directionality (LRM or RLM) when - * either the overall directionality or the exit directionality of the string is opposite to that - * of the context. If the formatter was built using {@link Builder#stereoReset(boolean)} and - * passing "true" as an argument, also prepends a Unicode bidi mark matching the context - * directionality when either the overall directionality or the entry directionality of the - * string is opposite to that of the context. - * <p> - * - * @param str The input string. - * @param heuristic The algorithm to be used to estimate the string's overall direction. - * @param isolate Whether to directionally isolate the string to prevent it from garbling the - * content around it. - * @return Input string after applying the above processing. - */ - public String spanWrap(String str, TextDirectionHeuristic heuristic, boolean isolate) { - final boolean isRtl = heuristic.isRtl(str, 0, str.length()); - String origStr = str; - str = TextUtils.htmlEncode(str); - - StringBuilder result = new StringBuilder(); - if (getStereoReset() && isolate) { - result.append(markBefore(origStr, - isRtl ? TextDirectionHeuristics.RTL : TextDirectionHeuristics.LTR)); - } - if (isRtl != mIsRtlContext) { - result.append("<span ").append(dirAttr(isRtl)).append('>').append(str).append("</span>"); - } else { - result.append(str); - } - if (isolate) { - result.append(markAfter(origStr, - isRtl ? TextDirectionHeuristics.RTL : TextDirectionHeuristics.LTR)); - } - return result.toString(); - } - - /** - * Operates like {@link #spanWrap(String, TextDirectionHeuristic, boolean)}, but assumes - * {@code isolate} is true. - * - * @param str The input string. - * @param heuristic The algorithm to be used to estimate the string's overall direction. - * @return Input string after applying the above processing. - */ - public String spanWrap(String str, TextDirectionHeuristic heuristic) { - return spanWrap(str, heuristic, true /* isolate */); - } - - /** - * Operates like {@link #spanWrap(String, TextDirectionHeuristic, boolean)}, but uses the - * formatter's default direction estimation algorithm. - * - * @param str The input string. - * @param isolate Whether to directionally isolate the string to prevent it from garbling the - * content around it - * @return Input string after applying the above processing. - */ - public String spanWrap(String str, boolean isolate) { - return spanWrap(str, mDefaultTextDirectionHeuristic, isolate); - } - - /** - * Operates like {@link #spanWrap(String, TextDirectionHeuristic, boolean)}, but uses the - * formatter's default direction estimation algorithm and assumes {@code isolate} is true. - * - * @param str The input string. - * @return Input string after applying the above processing. - */ - public String spanWrap(String str) { - return spanWrap(str, mDefaultTextDirectionHeuristic, true /* isolate */); - } - - /** * Formats a string of given directionality for use in plain-text output of the context * directionality, so an opposite-directionality string is neither garbled nor garbles its - * surroundings. As opposed to {@link #spanWrap}, this makes use of Unicode bidi - * formatting characters. In HTML, its *only* valid use is inside of elements that do not allow - * markup, e.g. the 'option' and 'title' elements. + * surroundings. This makes use of Unicode bidi formatting characters. * <p> * The algorithm: In case the given directionality doesn't match the context directionality, wraps * the string with Unicode bidi formatting characters: RLE+{@code str}+PDF for RTL text, or diff --git a/core/java/android/text/TextUtils.java b/core/java/android/text/TextUtils.java index 2ab9bf8..e2035c2 100644 --- a/core/java/android/text/TextUtils.java +++ b/core/java/android/text/TextUtils.java @@ -44,6 +44,7 @@ import android.text.style.TextAppearanceSpan; import android.text.style.TypefaceSpan; import android.text.style.URLSpan; import android.text.style.UnderlineSpan; +import android.util.Log; import android.util.Printer; import android.view.View; @@ -57,6 +58,8 @@ import java.util.Locale; import java.util.regex.Pattern; public class TextUtils { + private static final String TAG = "TextUtils"; + private TextUtils() { /* cannot be instantiated */ } @@ -550,6 +553,8 @@ public class TextUtils { /** @hide */ public static final int ALIGNMENT_SPAN = 1; /** @hide */ + public static final int FIRST_SPAN = ALIGNMENT_SPAN; + /** @hide */ public static final int FOREGROUND_COLOR_SPAN = 2; /** @hide */ public static final int RELATIVE_SIZE_SPAN = 3; @@ -593,6 +598,8 @@ public class TextUtils { public static final int EASY_EDIT_SPAN = 22; /** @hide */ public static final int LOCALE_SPAN = 23; + /** @hide */ + public static final int LAST_SPAN = LOCALE_SPAN; /** * Flatten a CharSequence and whatever styles can be copied across processes @@ -622,9 +629,16 @@ public class TextUtils { if (prop instanceof ParcelableSpan) { ParcelableSpan ps = (ParcelableSpan)prop; - p.writeInt(ps.getSpanTypeId()); - ps.writeToParcel(p, parcelableFlags); - writeWhere(p, sp, o); + int spanTypeId = ps.getSpanTypeId(); + if (spanTypeId < FIRST_SPAN || spanTypeId > LAST_SPAN) { + Log.e(TAG, "external class \"" + ps.getClass().getSimpleName() + + "\" is attempting to use the frameworks-only ParcelableSpan" + + " interface"); + } else { + p.writeInt(spanTypeId); + ps.writeToParcel(p, parcelableFlags); + writeWhere(p, sp, o); + } } } diff --git a/core/java/android/view/DisplayList.java b/core/java/android/view/DisplayList.java index 3bad98e..2d24c1e 100644 --- a/core/java/android/view/DisplayList.java +++ b/core/java/android/view/DisplayList.java @@ -285,9 +285,9 @@ public abstract class DisplayList { * Set whether the display list should clip itself to its bounds. This property is controlled by * the view's parent. * - * @param clipChildren true if the display list should clip to its bounds + * @param clipToBounds true if the display list should clip to its bounds */ - public abstract void setClipChildren(boolean clipChildren); + public abstract void setClipToBounds(boolean clipToBounds); /** * Set the static matrix on the display list. The specified matrix is combined with other diff --git a/core/java/android/view/GLES20DisplayList.java b/core/java/android/view/GLES20DisplayList.java index 9c5cdb2..3272504 100644 --- a/core/java/android/view/GLES20DisplayList.java +++ b/core/java/android/view/GLES20DisplayList.java @@ -137,9 +137,9 @@ class GLES20DisplayList extends DisplayList { } @Override - public void setClipChildren(boolean clipChildren) { + public void setClipToBounds(boolean clipToBounds) { if (hasNativeDisplayList()) { - nSetClipChildren(mFinalizer.mNativeDisplayList, clipChildren); + nSetClipToBounds(mFinalizer.mNativeDisplayList, clipToBounds); } } @@ -450,7 +450,7 @@ class GLES20DisplayList extends DisplayList { private static native void nSetPivotY(int displayList, float pivotY); private static native void nSetPivotX(int displayList, float pivotX); private static native void nSetCaching(int displayList, boolean caching); - private static native void nSetClipChildren(int displayList, boolean clipChildren); + private static native void nSetClipToBounds(int displayList, boolean clipToBounds); private static native void nSetAlpha(int displayList, float alpha); private static native void nSetHasOverlappingRendering(int displayList, boolean hasOverlappingRendering); diff --git a/core/java/android/view/InputQueue.java b/core/java/android/view/InputQueue.java index 909a3b2..e3de89d 100644 --- a/core/java/android/view/InputQueue.java +++ b/core/java/android/view/InputQueue.java @@ -16,11 +16,127 @@ package android.view; +import dalvik.system.CloseGuard; + +import android.os.Handler; +import android.os.Looper; +import android.os.MessageQueue; +import android.util.Pools.Pool; +import android.util.Pools.SimplePool; +import android.util.SparseArray; + +import java.lang.ref.WeakReference; + /** * An input queue provides a mechanism for an application to receive incoming * input events. Currently only usable from native code. */ public final class InputQueue { + private final SparseArray<ActiveInputEvent> mActiveEventArray = + new SparseArray<ActiveInputEvent>(20); + private final Pool<ActiveInputEvent> mActiveInputEventPool = + new SimplePool<ActiveInputEvent>(20); + + private final CloseGuard mCloseGuard = CloseGuard.get(); + + private int mPtr; + + private static native int nativeInit(WeakReference<InputQueue> weakQueue, + MessageQueue messageQueue); + private static native int nativeSendKeyEvent(int ptr, KeyEvent e, boolean preDispatch); + private static native int nativeSendMotionEvent(int ptr, MotionEvent e); + private static native void nativeDispose(int ptr); + + /** @hide */ + public InputQueue() { + mPtr = nativeInit(new WeakReference<InputQueue>(this), Looper.myQueue()); + + mCloseGuard.open("dispose"); + } + + @Override + protected void finalize() throws Throwable { + try { + dispose(true); + } finally { + super.finalize(); + } + } + + /** @hide */ + public void dispose() { + dispose(false); + } + + /** @hide */ + public void dispose(boolean finalized) { + if (mCloseGuard != null) { + if (finalized) { + mCloseGuard.warnIfOpen(); + } + mCloseGuard.close(); + } + + if (mPtr != 0) { + nativeDispose(mPtr); + mPtr = 0; + } + } + + /** @hide */ + public int getNativePtr() { + return mPtr; + } + + /** @hide */ + public void sendInputEvent(InputEvent e, Object token, boolean predispatch, + FinishedInputEventCallback callback) { + ActiveInputEvent event = obtainActiveInputEvent(token, callback); + int id; + if (e instanceof KeyEvent) { + id = nativeSendKeyEvent(mPtr, (KeyEvent) e, predispatch); + } else { + id = nativeSendMotionEvent(mPtr, (MotionEvent) e); + } + mActiveEventArray.put(id, event); + } + + private void finishInputEvent(int id, boolean handled) { + int index = mActiveEventArray.indexOfKey(id); + if (index >= 0) { + ActiveInputEvent e = mActiveEventArray.valueAt(index); + mActiveEventArray.removeAt(index); + e.mCallback.onFinishedInputEvent(e.mToken, handled); + recycleActiveInputEvent(e); + } + } + + private ActiveInputEvent obtainActiveInputEvent(Object token, + FinishedInputEventCallback callback) { + ActiveInputEvent e = mActiveInputEventPool.acquire(); + if (e == null) { + e = new ActiveInputEvent(); + } + e.mToken = token; + e.mCallback = callback; + return e; + } + + private void recycleActiveInputEvent(ActiveInputEvent e) { + e.recycle(); + mActiveInputEventPool.release(e); + } + + private final class ActiveInputEvent { + public Object mToken; + public FinishedInputEventCallback mCallback; + + public void recycle() { + mToken = null; + mCallback = null; + } + } + /** * Interface to receive notification of when an InputQueue is associated * and dissociated with a thread. @@ -31,7 +147,7 @@ public final class InputQueue { * thread making this call, so it can start receiving events from it. */ void onInputQueueCreated(InputQueue queue); - + /** * Called when the given InputQueue is no longer associated with * the thread and thus not dispatching events. @@ -39,15 +155,9 @@ public final class InputQueue { void onInputQueueDestroyed(InputQueue queue); } - final InputChannel mChannel; - - /** @hide */ - public InputQueue(InputChannel channel) { - mChannel = channel; - } - /** @hide */ - public InputChannel getInputChannel() { - return mChannel; + public static interface FinishedInputEventCallback { + void onFinishedInputEvent(Object token, boolean handled); } + } diff --git a/core/java/android/view/KeyEvent.java b/core/java/android/view/KeyEvent.java index bb533bf..b178ea8 100644 --- a/core/java/android/view/KeyEvent.java +++ b/core/java/android/view/KeyEvent.java @@ -634,8 +634,8 @@ public class KeyEvent extends InputEvent implements Parcelable { // NOTE: If you add a new keycode here you must also add it to: // isSystem() - // native/include/android/keycodes.h - // frameworks/base/include/ui/KeycodeLabels.h + // frameworks/native/include/android/keycodes.h + // frameworks/base/include/androidfw/KeycodeLabels.h // external/webkit/WebKit/android/plugins/ANPKeyCodes.h // frameworks/base/core/res/res/values/attrs.xml // emulator? @@ -1233,6 +1233,12 @@ public class KeyEvent extends InputEvent implements Parcelable { public static final int FLAG_FALLBACK = 0x400; /** + * Signifies that the key is being predispatched. + * @hide + */ + public static final int FLAG_PREDISPATCH = 0x20000000; + + /** * Private control to determine when an app is tracking a key sequence. * @hide */ diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index 17ef58a..d658aac 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -13515,8 +13515,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback, displayList.setLeftTopRightBottom(mLeft, mTop, mRight, mBottom); displayList.setHasOverlappingRendering(hasOverlappingRendering()); if (mParent instanceof ViewGroup) { - displayList.setClipChildren( - (((ViewGroup)mParent).mGroupFlags & ViewGroup.FLAG_CLIP_CHILDREN) != 0); + displayList.setClipToBounds( + (((ViewGroup) mParent).mGroupFlags & ViewGroup.FLAG_CLIP_CHILDREN) != 0); } float alpha = 1; if (mParent instanceof ViewGroup && (((ViewGroup) mParent).mGroupFlags & diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java index a8c83f7..dfe5f88 100644 --- a/core/java/android/view/ViewGroup.java +++ b/core/java/android/view/ViewGroup.java @@ -3119,7 +3119,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager for (int i = 0; i < mChildrenCount; ++i) { View child = getChildAt(i); if (child.mDisplayList != null) { - child.mDisplayList.setClipChildren(clipChildren); + child.mDisplayList.setClipToBounds(clipChildren); } } } @@ -4307,6 +4307,9 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager FLAG_OPTIMIZE_INVALIDATE) { dirty.offset(location[CHILD_LEFT_INDEX] - mScrollX, location[CHILD_TOP_INDEX] - mScrollY); + if ((mGroupFlags & FLAG_CLIP_CHILDREN) == 0) { + dirty.union(0, 0, mRight - mLeft, mBottom - mTop); + } final int left = mLeft; final int top = mTop; @@ -4406,6 +4409,9 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager if ((mPrivateFlags & PFLAG_DRAWN) == PFLAG_DRAWN || (mPrivateFlags & PFLAG_DRAWING_CACHE_VALID) == PFLAG_DRAWING_CACHE_VALID) { dirty.offset(left - mScrollX, top - mScrollY); + if ((mGroupFlags & FLAG_CLIP_CHILDREN) == 0) { + dirty.union(0, 0, mRight - mLeft, mBottom - mTop); + } if ((mGroupFlags & FLAG_CLIP_CHILDREN) == 0 || dirty.intersect(0, 0, mRight - mLeft, mBottom - mTop)) { diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index 3215e21..f34d390 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -600,12 +600,11 @@ public final class ViewRootImpl implements ViewParent, } if (mInputChannel != null) { if (mInputQueueCallback != null) { - mInputQueue = new InputQueue(mInputChannel); + mInputQueue = new InputQueue(); mInputQueueCallback.onInputQueueCreated(mInputQueue); - } else { - mInputEventReceiver = new WindowInputEventReceiver(mInputChannel, - Looper.myLooper()); } + mInputEventReceiver = new WindowInputEventReceiver(mInputChannel, + Looper.myLooper()); } view.assignParent(this); @@ -2825,9 +2824,11 @@ public final class ViewRootImpl implements ViewParent, if (mInputQueueCallback != null && mInputQueue != null) { mInputQueueCallback.onInputQueueDestroyed(mInputQueue); + mInputQueue.dispose(); mInputQueueCallback = null; mInputQueue = null; - } else if (mInputEventReceiver != null) { + } + if (mInputEventReceiver != null) { mInputEventReceiver.dispose(); mInputEventReceiver = null; } @@ -3350,6 +3351,15 @@ public final class ViewRootImpl implements ViewParent, if ((q.mFlags & QueuedInputEvent.FLAG_FINISHED) != 0) { forward(q); } else if (mView == null || !mAdded) { + Slog.w(TAG, "Dropping event due to root view being removed: " + q.mEvent); + finish(q, false); + } else if (!mAttachInfo.mHasWindowFocus && + !q.mEvent.isFromSource(InputDevice.SOURCE_CLASS_POINTER) && + !isTerminalInputEvent(q.mEvent)) { + // If this is a focused event and the window doesn't currently have input focus, + // then drop this event. This could be an event that came back from the previous + // stage but the window has lost focus in the meantime. + Slog.w(TAG, "Dropping event due to no window focus: " + q.mEvent); finish(q, false); } else { apply(q, onProcess(q)); @@ -3550,15 +3560,30 @@ public final class ViewRootImpl implements ViewParent, * Delivers pre-ime input events to a native activity. * Does not support pointer events. */ - final class NativePreImeInputStage extends AsyncInputStage { + final class NativePreImeInputStage extends AsyncInputStage + implements InputQueue.FinishedInputEventCallback { public NativePreImeInputStage(InputStage next, String traceCounter) { super(next, traceCounter); } @Override protected int onProcess(QueuedInputEvent q) { + if (mInputQueue != null && q.mEvent instanceof KeyEvent) { + mInputQueue.sendInputEvent(q.mEvent, q, true, this); + return DEFER; + } return FORWARD; } + + @Override + public void onFinishedInputEvent(Object token, boolean handled) { + QueuedInputEvent q = (QueuedInputEvent)token; + if (handled) { + finish(q, true); + return; + } + forward(q); + } } /** @@ -3624,16 +3649,6 @@ public final class ViewRootImpl implements ViewParent, finish(q, true); return; } - - // If the window doesn't currently have input focus, then drop - // this event. This could be an event that came back from the - // IME dispatch but the window has lost focus in the meantime. - if (!mAttachInfo.mHasWindowFocus && !isTerminalInputEvent(q.mEvent)) { - Slog.w(TAG, "Dropping event due to no window focus: " + q.mEvent); - finish(q, false); - return; - } - forward(q); } } @@ -3705,15 +3720,30 @@ public final class ViewRootImpl implements ViewParent, /** * Delivers post-ime input events to a native activity. */ - final class NativePostImeInputStage extends AsyncInputStage { + final class NativePostImeInputStage extends AsyncInputStage + implements InputQueue.FinishedInputEventCallback { public NativePostImeInputStage(InputStage next, String traceCounter) { super(next, traceCounter); } @Override protected int onProcess(QueuedInputEvent q) { + if (mInputQueue != null) { + mInputQueue.sendInputEvent(q.mEvent, q, false, this); + return DEFER; + } return FORWARD; } + + @Override + public void onFinishedInputEvent(Object token, boolean handled) { + QueuedInputEvent q = (QueuedInputEvent)token; + if (handled) { + finish(q, true); + return; + } + forward(q); + } } /** diff --git a/core/java/android/view/accessibility/AccessibilityNodeInfo.java b/core/java/android/view/accessibility/AccessibilityNodeInfo.java index ad87fcb..d9c9b69 100644 --- a/core/java/android/view/accessibility/AccessibilityNodeInfo.java +++ b/core/java/android/view/accessibility/AccessibilityNodeInfo.java @@ -473,7 +473,7 @@ public class AccessibilityNodeInfo implements Parcelable { private CharSequence mClassName; private CharSequence mText; private CharSequence mContentDescription; - private CharSequence mViewIdResourceName; + private String mViewIdResourceName; private final SparseLongArray mChildNodeIds = new SparseLongArray(); private int mActions; @@ -1541,7 +1541,7 @@ public class AccessibilityNodeInfo implements Parcelable { * * @param viewIdResName The id resource name. */ - public void setViewIdResourceName(CharSequence viewIdResName) { + public void setViewIdResourceName(String viewIdResName) { enforceNotSealed(); mViewIdResourceName = viewIdResName; } @@ -1558,7 +1558,7 @@ public class AccessibilityNodeInfo implements Parcelable { * @return The id resource name. */ - public CharSequence getViewIdResourceName() { + public String getViewIdResourceName() { return mViewIdResourceName; } @@ -1841,7 +1841,7 @@ public class AccessibilityNodeInfo implements Parcelable { parcel.writeCharSequence(mClassName); parcel.writeCharSequence(mText); parcel.writeCharSequence(mContentDescription); - parcel.writeCharSequence(mViewIdResourceName); + parcel.writeString(mViewIdResourceName); parcel.writeInt(mTextSelectionStart); parcel.writeInt(mTextSelectionEnd); @@ -1923,7 +1923,7 @@ public class AccessibilityNodeInfo implements Parcelable { mClassName = parcel.readCharSequence(); mText = parcel.readCharSequence(); mContentDescription = parcel.readCharSequence(); - mViewIdResourceName = parcel.readCharSequence(); + mViewIdResourceName = parcel.readString(); mTextSelectionStart = parcel.readInt(); mTextSelectionEnd = parcel.readInt(); diff --git a/core/java/android/view/accessibility/AccessibilityNodeInfoCache.java b/core/java/android/view/accessibility/AccessibilityNodeInfoCache.java index 14954be..28518aa 100644 --- a/core/java/android/view/accessibility/AccessibilityNodeInfoCache.java +++ b/core/java/android/view/accessibility/AccessibilityNodeInfoCache.java @@ -83,6 +83,7 @@ public class AccessibilityNodeInfoCache { } break; case AccessibilityEvent.TYPE_VIEW_FOCUSED: case AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED: + case AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED: case AccessibilityEvent.TYPE_VIEW_SELECTED: case AccessibilityEvent.TYPE_VIEW_TEXT_CHANGED: case AccessibilityEvent.TYPE_VIEW_TEXT_SELECTION_CHANGED: { diff --git a/core/java/android/webkit/BrowserFrame.java b/core/java/android/webkit/BrowserFrame.java index 33e8364..c111a52 100644 --- a/core/java/android/webkit/BrowserFrame.java +++ b/core/java/android/webkit/BrowserFrame.java @@ -70,7 +70,6 @@ class BrowserFrame extends Handler { * request's LoadListener */ private final static int MAX_OUTSTANDING_REQUESTS = 300; - private final static String SCHEME_HOST_DELIMITER = "://"; private final CallbackProxy mCallbackProxy; private final WebSettingsClassic mSettings; @@ -499,14 +498,10 @@ class BrowserFrame extends Handler { .getCurrentItem(); if (item != null) { WebAddress uri = new WebAddress(item.getUrl()); - String schemePlusHost = uri.getScheme() + SCHEME_HOST_DELIMITER + - uri.getHost(); - String[] up = mDatabase.getUsernamePassword( - schemePlusHost); - if (up == null) { // no row found, try again using the legacy method - schemePlusHost = uri.getScheme() + uri.getHost(); - up = mDatabase.getUsernamePassword(schemePlusHost); - } + String schemePlusHost = uri.getScheme() + uri.getHost(); + String[] up = + WebViewDatabaseClassic.getInstance(mContext) + .getUsernamePassword(schemePlusHost); if (up != null && up[0] != null) { setUsernamePassword(up[0], up[1]); } @@ -821,7 +816,7 @@ class BrowserFrame extends Handler { } WebAddress uri = new WebAddress(mCallbackProxy .getBackForwardList().getCurrentItem().getUrl()); - String schemePlusHost = uri.getScheme() + SCHEME_HOST_DELIMITER + uri.getHost(); + String schemePlusHost = uri.getScheme() + uri.getHost(); // Check to see if the username & password appear in // the post data (there could be another form on the // page and that was posted instead. diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java index afa4894..4998742 100644 --- a/core/java/android/webkit/WebView.java +++ b/core/java/android/webkit/WebView.java @@ -581,8 +581,7 @@ public class WebView extends AbsoluteLayout * forms. Note that this is unrelated to the credentials used for HTTP * authentication. * - * @param host the host that required the credentials. It is recommended that - * the host is given using scheme://hostname format. + * @param host the host that required the credentials * @param username the username for the given host * @param password the password for the given host * @see WebViewDatabase#clearUsernamePassword diff --git a/core/java/android/webkit/WebViewDatabaseClassic.java b/core/java/android/webkit/WebViewDatabaseClassic.java index 5ad4fa5..be01028 100644 --- a/core/java/android/webkit/WebViewDatabaseClassic.java +++ b/core/java/android/webkit/WebViewDatabaseClassic.java @@ -37,7 +37,7 @@ final class WebViewDatabaseClassic extends WebViewDatabase { private static final String DATABASE_FILE = "webview.db"; private static final String CACHE_DATABASE_FILE = "webviewCache.db"; - private static final int DATABASE_VERSION = 12; + private static final int DATABASE_VERSION = 11; // 2 -> 3 Modified Cache table to allow cache of redirects // 3 -> 4 Added Oma-Downloads table // 4 -> 5 Modified Cache table to support persistent contentLength @@ -50,7 +50,6 @@ final class WebViewDatabaseClassic extends WebViewDatabase { // 10 -> 11 Drop cookies and cache now managed by the chromium stack, // and update the form data table to use the new format // implemented for b/5265606. - // 11 -> 12 Add a delimiter between scheme and host when storing passwords private static WebViewDatabaseClassic sInstance = null; private static final Object sInstanceLock = new Object(); @@ -170,23 +169,11 @@ final class WebViewDatabaseClassic extends WebViewDatabase { private static void upgradeDatabase() { upgradeDatabaseToV10(); upgradeDatabaseFromV10ToV11(); - upgradeDatabaseFromV11ToV12(); // Add future database upgrade functions here, one version at a // time. sDatabase.setVersion(DATABASE_VERSION); } - private static void upgradeDatabaseFromV11ToV12() { - int oldVersion = sDatabase.getVersion(); - - if (oldVersion >= 12) { - // Nothing to do. - return; - } - // delete the rows in the database. - sDatabase.delete(mTableNames[TABLE_PASSWORD_ID], null, null); - } - private static void upgradeDatabaseFromV10ToV11() { int oldVersion = sDatabase.getVersion(); diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java index 0c1a80e..4312dee 100644 --- a/core/java/android/widget/Editor.java +++ b/core/java/android/widget/Editor.java @@ -1367,7 +1367,7 @@ public class Editor { } finally { blockDisplayList.end(); // Same as drawDisplayList below, handled by our TextView's parent - blockDisplayList.setClipChildren(false); + blockDisplayList.setClipToBounds(false); } } diff --git a/core/java/android/widget/RelativeLayout.java b/core/java/android/widget/RelativeLayout.java index 3df7258..f940226 100644 --- a/core/java/android/widget/RelativeLayout.java +++ b/core/java/android/widget/RelativeLayout.java @@ -226,7 +226,12 @@ public class RelativeLayout extends ViewGroup { private boolean mMeasureVerticalWithPaddingMargin = false; // A default width used for RTL measure pass - private static final int DEFAULT_WIDTH = Integer.MAX_VALUE / 2; + /** + * Value reduced so as not to interfere with View's measurement spec. flags. See: + * {@link View#MEASURED_SIZE_MASK}. + * {@link View#MEASURED_STATE_TOO_SMALL}. + **/ + private static final int DEFAULT_WIDTH = 0x00010000; public RelativeLayout(Context context) { super(context); diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java index ffb3543..698f101 100644 --- a/core/java/android/widget/TextView.java +++ b/core/java/android/widget/TextView.java @@ -8065,7 +8065,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener info.setEditable(true); } - if (TextUtils.isEmpty(getContentDescription()) && !TextUtils.isEmpty(mText)) { + if (!TextUtils.isEmpty(mText)) { info.addAction(AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY); info.addAction(AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY); info.setMovementGranularities(AccessibilityNodeInfo.MOVEMENT_GRANULARITY_CHARACTER @@ -8074,6 +8074,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PARAGRAPH | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PAGE); } + if (isFocused()) { if (canSelectText()) { info.addAction(AccessibilityNodeInfo.ACTION_SET_SELECTION); @@ -8678,13 +8679,10 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener */ @Override public CharSequence getIterableTextForAccessibility() { - if (!TextUtils.isEmpty(mText)) { - if (!(mText instanceof Spannable)) { - setText(mText, BufferType.SPANNABLE); - } - return mText; + if (!(mText instanceof Spannable)) { + setText(mText, BufferType.SPANNABLE); } - return super.getIterableTextForAccessibility(); + return mText; } /** @@ -8720,13 +8718,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener */ @Override public int getAccessibilitySelectionStart() { - if (TextUtils.isEmpty(getContentDescription())) { - final int selectionStart = getSelectionStart(); - if (selectionStart >= 0) { - return selectionStart; - } - } - return ACCESSIBILITY_CURSOR_POSITION_UNDEFINED; + return getSelectionStart(); } /** @@ -8741,13 +8733,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener */ @Override public int getAccessibilitySelectionEnd() { - if (TextUtils.isEmpty(getContentDescription())) { - final int selectionEnd = getSelectionEnd(); - if (selectionEnd >= 0) { - return selectionEnd; - } - } - return ACCESSIBILITY_CURSOR_POSITION_UNDEFINED; + return getSelectionEnd(); } /** diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java index 2184fd2..fb22df7 100644 --- a/core/java/com/android/internal/os/ZygoteInit.java +++ b/core/java/com/android/internal/os/ZygoteInit.java @@ -34,6 +34,7 @@ import dalvik.system.Zygote; import libcore.io.IoUtils; import libcore.io.Libcore; +import libcore.io.OsConstants; import java.io.BufferedReader; import java.io.FileDescriptor; @@ -472,12 +473,25 @@ public class ZygoteInit { */ private static boolean startSystemServer() throws MethodAndArgsCaller, RuntimeException { + long capabilities = posixCapabilitiesAsBits( + OsConstants.CAP_KILL, + OsConstants.CAP_NET_ADMIN, + OsConstants.CAP_NET_BIND_SERVICE, + OsConstants.CAP_NET_BROADCAST, + OsConstants.CAP_NET_RAW, + OsConstants.CAP_SYS_BOOT, + OsConstants.CAP_SYS_MODULE, + OsConstants.CAP_SYS_NICE, + OsConstants.CAP_SYS_RESOURCE, + OsConstants.CAP_SYS_TIME, + OsConstants.CAP_SYS_TTY_CONFIG + ); /* Hardcoded command line to start the system server */ String args[] = { "--setuid=1000", "--setgid=1000", "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,3001,3002,3003,3006,3007", - "--capabilities=130104352,130104352", + "--capabilities=" + capabilities + "," + capabilities, "--runtime-init", "--nice-name=system_server", "com.android.server.SystemServer", @@ -511,6 +525,20 @@ public class ZygoteInit { return true; } + /** + * Gets the bit array representation of the provided list of POSIX capabilities. + */ + private static long posixCapabilitiesAsBits(int... capabilities) { + long result = 0; + for (int capability : capabilities) { + if ((capability < 0) || (capability > OsConstants.CAP_LAST_CAP)) { + throw new IllegalArgumentException(String.valueOf(capability)); + } + result |= (1L << capability); + } + return result; + } + public static void main(String argv[]) { try { // Start profiling the zygote initialization. |
