summaryrefslogtreecommitdiffstats
path: root/core/java
diff options
context:
space:
mode:
Diffstat (limited to 'core/java')
-rw-r--r--core/java/android/accessibilityservice/AccessibilityService.java162
-rw-r--r--core/java/android/accessibilityservice/AccessibilityServiceInfo.java21
-rw-r--r--core/java/android/accessibilityservice/IAccessibilityServiceClient.aidl3
-rw-r--r--core/java/android/accessibilityservice/IAccessibilityServiceClientCallback.aidl30
-rw-r--r--core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl2
-rw-r--r--core/java/android/accessibilityservice/UiTestAutomationBridge.java4
-rw-r--r--core/java/android/appwidget/AppWidgetHostView.java40
-rw-r--r--core/java/android/appwidget/AppWidgetManager.java75
-rwxr-xr-xcore/java/android/appwidget/AppWidgetProvider.java33
-rw-r--r--core/java/android/hardware/Camera.java14
-rwxr-xr-xcore/java/android/hardware/input/InputManager.java2
-rw-r--r--core/java/android/nfc/INfcAdapter.aidl2
-rw-r--r--core/java/android/nfc/NfcAdapter.java3
-rw-r--r--core/java/android/text/DynamicLayout.java52
-rw-r--r--core/java/android/view/ViewRootImpl.java28
-rw-r--r--core/java/android/view/accessibility/AccessibilityInteractionClient.java14
-rw-r--r--core/java/android/webkit/WebViewClassic.java97
-rw-r--r--core/java/android/webkit/WebViewClient.java5
-rw-r--r--core/java/android/widget/AbsListView.java74
-rw-r--r--core/java/android/widget/Editor.java43
-rw-r--r--core/java/android/widget/GridView.java7
-rw-r--r--core/java/android/widget/ListView.java7
-rw-r--r--core/java/com/android/internal/app/ShutdownThread.java37
-rw-r--r--core/java/com/android/internal/appwidget/IAppWidgetService.aidl3
-rw-r--r--core/java/com/android/internal/widget/SizeAdaptiveLayout.java13
25 files changed, 534 insertions, 237 deletions
diff --git a/core/java/android/accessibilityservice/AccessibilityService.java b/core/java/android/accessibilityservice/AccessibilityService.java
index 4e340c0..c858e3c 100644
--- a/core/java/android/accessibilityservice/AccessibilityService.java
+++ b/core/java/android/accessibilityservice/AccessibilityService.java
@@ -19,22 +19,17 @@ package android.accessibilityservice;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
-import android.content.res.Configuration;
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
import android.os.RemoteException;
-import android.util.LocaleUtil;
import android.util.Log;
-import android.view.View;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityInteractionClient;
import android.view.accessibility.AccessibilityNodeInfo;
import com.android.internal.os.HandlerCaller;
-import java.util.Locale;
-
/**
* An accessibility service runs in the background and receives callbacks by the system
* when {@link AccessibilityEvent}s are fired. Such events denote some state transition
@@ -299,6 +294,16 @@ public abstract class AccessibilityService extends Service {
public static final int GESTURE_SWIPE_DOWN_AND_RIGHT = 18;
/**
+ * The user has performed a two finger tap gesture on the touch screen.
+ */
+ public static final int GESTURE_TWO_FINGER_TAP = 19;
+
+ /**
+ * The user has performed a two finger long press gesture on the touch screen.
+ */
+ public static final int GESTURE_TWO_FINGER_LONG_PRESS = 20;
+
+ /**
* The {@link Intent} that must be declared as handled by the service.
*/
public static final String SERVICE_INTERFACE =
@@ -342,8 +347,6 @@ public abstract class AccessibilityService extends Service {
*/
public static final int GLOBAL_ACTION_NOTIFICATIONS = 4;
- private static final int UNDEFINED = -1;
-
private static final String LOG_TAG = "AccessibilityService";
interface Callbacks {
@@ -351,15 +354,13 @@ public abstract class AccessibilityService extends Service {
public void onInterrupt();
public void onServiceConnected();
public void onSetConnectionId(int connectionId);
- public void onGesture(int gestureId);
+ public boolean onGesture(int gestureId);
}
private int mConnectionId;
private AccessibilityServiceInfo mInfo;
- private int mLayoutDirection;
-
/**
* Callback for {@link android.view.accessibility.AccessibilityEvent}s.
*
@@ -386,95 +387,43 @@ public abstract class AccessibilityService extends Service {
/**
* Called by the system when the user performs a specific gesture on the
- * touch screen.
+ * touch screen. If the gesture is not handled in this callback the system
+ * may provide default handing. Therefore, one should return true from this
+ * function if overriding of default behavior is desired.
+ *
+ * <strong>Note:</strong> To receive gestures an accessibility service
+ * must declare that it can handle such by specifying the
+ * <code>&lt;{@link android.R.styleable#AccessibilityService_canHandleGestures
+ * canHandleGestures}&gt;</code> attribute.
*
* @param gestureId The unique id of the performed gesture.
*
+ * @return Whether the gesture was handled.
+ *
* @see #GESTURE_SWIPE_UP
- * @see #GESTURE_SWIPE_DOWN
- * @see #GESTURE_SWIPE_LEFT
- * @see #GESTURE_SWIPE_RIGHT
+ * @see #GESTURE_SWIPE_UP_AND_LEFT
* @see #GESTURE_SWIPE_UP_AND_DOWN
+ * @see #GESTURE_SWIPE_UP_AND_RIGHT
+ * @see #GESTURE_SWIPE_DOWN
+ * @see #GESTURE_SWIPE_DOWN_AND_LEFT
* @see #GESTURE_SWIPE_DOWN_AND_UP
+ * @see #GESTURE_SWIPE_DOWN_AND_RIGHT
+ * @see #GESTURE_SWIPE_LEFT
+ * @see #GESTURE_SWIPE_LEFT_AND_UP
* @see #GESTURE_SWIPE_LEFT_AND_RIGHT
+ * @see #GESTURE_SWIPE_LEFT_AND_DOWN
+ * @see #GESTURE_SWIPE_RIGHT
+ * @see #GESTURE_SWIPE_RIGHT_AND_UP
* @see #GESTURE_SWIPE_RIGHT_AND_LEFT
+ * @see #GESTURE_SWIPE_RIGHT_AND_DOWN
* @see #GESTURE_CLOCKWISE_CIRCLE
* @see #GESTURE_COUNTER_CLOCKWISE_CIRCLE
+ * @see #GESTURE_TWO_FINGER_TAP
+ * @see #GESTURE_TWO_FINGER_LONG_PRESS
*/
- protected void onGesture(int gestureId) {
+ protected boolean onGesture(int gestureId) {
// TODO: Describe the default gesture processing in the javaDoc once it is finalized.
-
- // Global actions.
- switch (gestureId) {
- case GESTURE_SWIPE_DOWN_AND_LEFT: {
- performGlobalAction(GLOBAL_ACTION_BACK);
- } return;
- case GESTURE_SWIPE_DOWN_AND_RIGHT: {
- performGlobalAction(GLOBAL_ACTION_HOME);
- } return;
- case GESTURE_SWIPE_UP_AND_LEFT: {
- performGlobalAction(GLOBAL_ACTION_RECENTS);
- } return;
- case GESTURE_SWIPE_UP_AND_RIGHT: {
- performGlobalAction(GLOBAL_ACTION_NOTIFICATIONS);
- } return;
- }
-
- // Cache the id to avoid locking
- final int connectionId = mConnectionId;
- if (connectionId == UNDEFINED) {
- throw new IllegalStateException("AccessibilityService not connected."
- + " Did you receive a call of onServiceConnected()?");
- }
- AccessibilityNodeInfo root = getRootInActiveWindow();
- if (root == null) {
- return;
- }
-
- AccessibilityNodeInfo current = root.findFocus(AccessibilityNodeInfo.FOCUS_ACCESSIBILITY);
- if (current == null) {
- current = root;
- }
-
- // Local actions.
- AccessibilityNodeInfo next = null;
- switch (gestureId) {
- case GESTURE_SWIPE_UP: {
- next = current.focusSearch(View.ACCESSIBILITY_FOCUS_OUT);
- } break;
- case GESTURE_SWIPE_DOWN: {
- next = current.focusSearch(View.ACCESSIBILITY_FOCUS_IN);
- } break;
- case GESTURE_SWIPE_LEFT: {
- if (mLayoutDirection == View.LAYOUT_DIRECTION_LTR) {
- next = current.focusSearch(View.ACCESSIBILITY_FOCUS_BACKWARD);
- } else { // LAYOUT_DIRECTION_RTL
- next = current.focusSearch(View.ACCESSIBILITY_FOCUS_FORWARD);
- }
- } break;
- case GESTURE_SWIPE_RIGHT: {
- if (mLayoutDirection == View.LAYOUT_DIRECTION_LTR) {
- next = current.focusSearch(View.ACCESSIBILITY_FOCUS_FORWARD);
- } else { // LAYOUT_DIRECTION_RTL
- next = current.focusSearch(View.ACCESSIBILITY_FOCUS_BACKWARD);
- }
- } break;
- case GESTURE_SWIPE_UP_AND_DOWN: {
- next = current.focusSearch(View.ACCESSIBILITY_FOCUS_UP);
- } break;
- case GESTURE_SWIPE_DOWN_AND_UP: {
- next = current.focusSearch(View.ACCESSIBILITY_FOCUS_DOWN);
- } break;
- case GESTURE_SWIPE_LEFT_AND_RIGHT: {
- next = current.focusSearch(View.ACCESSIBILITY_FOCUS_LEFT);
- } break;
- case GESTURE_SWIPE_RIGHT_AND_LEFT: {
- next = current.focusSearch(View.ACCESSIBILITY_FOCUS_RIGHT);
- } break;
- }
- if (next != null && !next.equals(current)) {
- next.performAction(AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS);
- }
+ return false;
}
/**
@@ -484,10 +433,7 @@ public abstract class AccessibilityService extends Service {
* @return The root node if this service can retrieve window content.
*/
public AccessibilityNodeInfo getRootInActiveWindow() {
- return AccessibilityInteractionClient.getInstance()
- .findAccessibilityNodeInfoByAccessibilityId(mConnectionId,
- AccessibilityNodeInfo.ACTIVE_WINDOW_ID, AccessibilityNodeInfo.ROOT_NODE_ID,
- AccessibilityNodeInfo.FLAG_PREFETCH_DESCENDANTS);
+ return AccessibilityInteractionClient.getInstance().getRootInActiveWindow(mConnectionId);
}
/**
@@ -509,7 +455,7 @@ public abstract class AccessibilityService extends Service {
AccessibilityInteractionClient.getInstance().getConnection(mConnectionId);
if (connection != null) {
try {
- return connection.perfromGlobalAction(action);
+ return connection.performGlobalAction(action);
} catch (RemoteException re) {
Log.w(LOG_TAG, "Error while calling performGlobalAction", re);
}
@@ -572,18 +518,6 @@ public abstract class AccessibilityService extends Service {
}
}
- @Override
- public void onCreate() {
- Locale locale = getResources().getConfiguration().locale;
- mLayoutDirection = LocaleUtil.getLayoutDirectionFromLocale(locale);
- }
-
- @Override
- public void onConfigurationChanged(Configuration configuration) {
- super.onConfigurationChanged(configuration);
- mLayoutDirection = LocaleUtil.getLayoutDirectionFromLocale(configuration.locale);
- }
-
/**
* Implement to return the implementation of the internal accessibility
* service interface.
@@ -612,8 +546,8 @@ public abstract class AccessibilityService extends Service {
}
@Override
- public void onGesture(int gestureId) {
- AccessibilityService.this.onGesture(gestureId);
+ public boolean onGesture(int gestureId) {
+ return AccessibilityService.this.onGesture(gestureId);
}
});
}
@@ -658,8 +592,10 @@ public abstract class AccessibilityService extends Service {
mCaller.sendMessage(message);
}
- public void onGesture(int gestureId) {
- Message message = mCaller.obtainMessageI(DO_ON_GESTURE, gestureId);
+ public void onGesture(int gestureId, IAccessibilityServiceClientCallback callback,
+ int interactionId) {
+ Message message = mCaller.obtainMessageIIO(DO_ON_GESTURE, gestureId, interactionId,
+ callback);
mCaller.sendMessage(message);
}
@@ -692,7 +628,15 @@ public abstract class AccessibilityService extends Service {
return;
case DO_ON_GESTURE :
final int gestureId = message.arg1;
- mCallback.onGesture(gestureId);
+ final int interactionId = message.arg2;
+ IAccessibilityServiceClientCallback callback =
+ (IAccessibilityServiceClientCallback) message.obj;
+ final boolean handled = mCallback.onGesture(gestureId);
+ try {
+ callback.setGestureResult(gestureId, handled, interactionId);
+ } catch (RemoteException re) {
+ Log.e(LOG_TAG, "Error calling back with the gesture resut.", re);
+ }
return;
default :
Log.w(LOG_TAG, "Unknown message type " + message.what);
diff --git a/core/java/android/accessibilityservice/AccessibilityServiceInfo.java b/core/java/android/accessibilityservice/AccessibilityServiceInfo.java
index e77ed9a..7e6786b 100644
--- a/core/java/android/accessibilityservice/AccessibilityServiceInfo.java
+++ b/core/java/android/accessibilityservice/AccessibilityServiceInfo.java
@@ -224,6 +224,11 @@ public class AccessibilityServiceInfo implements Parcelable {
private boolean mCanRetrieveWindowContent;
/**
+ * Flag whether this accessibility service can handle gestures.
+ */
+ private boolean mCanHandleGestures;
+
+ /**
* Resource id of the description of the accessibility service.
*/
private int mDescriptionResId;
@@ -303,6 +308,8 @@ public class AccessibilityServiceInfo implements Parcelable {
mCanRetrieveWindowContent = asAttributes.getBoolean(
com.android.internal.R.styleable.AccessibilityService_canRetrieveWindowContent,
false);
+ mCanHandleGestures = asAttributes.getBoolean(
+ com.android.internal.R.styleable.AccessibilityService_canHandleGestures, false);
TypedValue peekedValue = asAttributes.peekValue(
com.android.internal.R.styleable.AccessibilityService_description);
if (peekedValue != null) {
@@ -378,13 +385,25 @@ public class AccessibilityServiceInfo implements Parcelable {
* <strong>Statically set from
* {@link AccessibilityService#SERVICE_META_DATA meta-data}.</strong>
* </p>
- * @return True window content can be retrieved.
+ * @return True if window content can be retrieved.
*/
public boolean getCanRetrieveWindowContent() {
return mCanRetrieveWindowContent;
}
/**
+ * Whether this service can handle gestures.
+ * <p>
+ * <strong>Statically set from
+ * {@link AccessibilityService#SERVICE_META_DATA meta-data}.</strong>
+ * </p>
+ * @return True if the service can handle gestures.
+ */
+ public boolean getCanHandleGestures() {
+ return mCanHandleGestures;
+ }
+
+ /**
* Gets the non-localized description of the accessibility service.
* <p>
* <strong>Statically set from
diff --git a/core/java/android/accessibilityservice/IAccessibilityServiceClient.aidl b/core/java/android/accessibilityservice/IAccessibilityServiceClient.aidl
index 588728c..0257aa4 100644
--- a/core/java/android/accessibilityservice/IAccessibilityServiceClient.aidl
+++ b/core/java/android/accessibilityservice/IAccessibilityServiceClient.aidl
@@ -16,6 +16,7 @@
package android.accessibilityservice;
+import android.accessibilityservice.IAccessibilityServiceClientCallback;
import android.accessibilityservice.IAccessibilityServiceConnection;
import android.view.accessibility.AccessibilityEvent;
@@ -32,5 +33,5 @@ import android.view.accessibility.AccessibilityEvent;
void onInterrupt();
- void onGesture(int gestureId);
+ void onGesture(int gesture, in IAccessibilityServiceClientCallback callback, int interactionId);
}
diff --git a/core/java/android/accessibilityservice/IAccessibilityServiceClientCallback.aidl b/core/java/android/accessibilityservice/IAccessibilityServiceClientCallback.aidl
new file mode 100644
index 0000000..9061398
--- /dev/null
+++ b/core/java/android/accessibilityservice/IAccessibilityServiceClientCallback.aidl
@@ -0,0 +1,30 @@
+/*
+** Copyright 2012, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+package android.accessibilityservice;
+
+import android.accessibilityservice.IAccessibilityServiceConnection;
+import android.view.accessibility.AccessibilityEvent;
+
+/**
+ * Callback for IAccessibilityServiceClient.
+ *
+ * @hide
+ */
+ oneway interface IAccessibilityServiceClientCallback {
+
+ void setGestureResult(int gestureId, boolean handled, int interactionId);
+}
diff --git a/core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl b/core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl
index 1bd5387..6e85665 100644
--- a/core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl
+++ b/core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl
@@ -167,5 +167,5 @@ interface IAccessibilityServiceConnection {
* @param action The action to perform.
* @return Whether the action was performed.
*/
- boolean perfromGlobalAction(int action);
+ boolean performGlobalAction(int action);
}
diff --git a/core/java/android/accessibilityservice/UiTestAutomationBridge.java b/core/java/android/accessibilityservice/UiTestAutomationBridge.java
index c840bd6..1697df0 100644
--- a/core/java/android/accessibilityservice/UiTestAutomationBridge.java
+++ b/core/java/android/accessibilityservice/UiTestAutomationBridge.java
@@ -177,8 +177,8 @@ public class UiTestAutomationBridge {
}
@Override
- public void onGesture(int gestureId) {
- /* do nothing */
+ public boolean onGesture(int gestureId) {
+ return false;
}
});
diff --git a/core/java/android/appwidget/AppWidgetHostView.java b/core/java/android/appwidget/AppWidgetHostView.java
index 61a9dce..c1b8e7c 100644
--- a/core/java/android/appwidget/AppWidgetHostView.java
+++ b/core/java/android/appwidget/AppWidgetHostView.java
@@ -28,6 +28,7 @@ import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.os.Build;
+import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.SystemClock;
@@ -206,6 +207,45 @@ public class AppWidgetHostView extends FrameLayout {
super.dispatchRestoreInstanceState(jail);
}
+ @Override
+ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ int oldWidth = getMeasuredWidth();
+ int oldHeight = getMeasuredHeight();
+ super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+ int newWidth = getMeasuredWidth();
+ int newHeight = getMeasuredHeight();
+
+ // TODO: this is just a hack for now -- we actually have the AppWidgetHost
+ // be responsible for updating the size of the widget.
+ if (oldWidth != newWidth || oldHeight != newHeight) {
+ final float density = mContext.getResources().getDisplayMetrics().density;
+ final int newWidthDips = (int) (newWidth / density);
+ final int newHeightDips = (int) (newHeight / density);
+ updateAppWidgetSize(null, newWidthDips, newHeightDips, newWidthDips, newHeightDips);
+ }
+ }
+
+ /**
+ * Provide guidance about the size of this widget to the AppWidgetManager. This information
+ * gets embedded into the AppWidgetExtras and causes a callback to the AppWidgetProvider.
+ *
+ * @see AppWidgetProvider#onAppWidgetExtrasChanged(Context, AppWidgetManager, int, Bundle)
+ */
+ public void updateAppWidgetSize(Bundle extras, int minWidth, int minHeight, int maxWidth, int maxHeight) {
+ if (extras == null) {
+ extras = new Bundle();
+ }
+ extras.putInt(AppWidgetManager.EXTRA_APPWIDGET_MIN_WIDTH, minWidth);
+ extras.putInt(AppWidgetManager.EXTRA_APPWIDGET_MIN_HEIGHT, minHeight);
+ extras.putInt(AppWidgetManager.EXTRA_APPWIDGET_MAX_WIDTH, maxWidth);
+ extras.putInt(AppWidgetManager.EXTRA_APPWIDGET_MAX_HEIGHT, maxHeight);
+ updateAppWidgetExtras(extras);
+ }
+
+ public void updateAppWidgetExtras(Bundle extras) {
+ AppWidgetManager.getInstance(mContext).updateAppWidgetExtras(mAppWidgetId, extras);
+ }
+
/** {@inheritDoc} */
@Override
public LayoutParams generateLayoutParams(AttributeSet attrs) {
diff --git a/core/java/android/appwidget/AppWidgetManager.java b/core/java/android/appwidget/AppWidgetManager.java
index a7f7792..83ab817 100644
--- a/core/java/android/appwidget/AppWidgetManager.java
+++ b/core/java/android/appwidget/AppWidgetManager.java
@@ -19,6 +19,7 @@ package android.appwidget;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
+import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.os.ServiceManager;
@@ -109,6 +110,32 @@ public class AppWidgetManager {
public static final String EXTRA_APPWIDGET_ID = "appWidgetId";
/**
+ * An bundle extra that contains the lower bound on the current width, in dips, of a widget instance.
+ */
+ public static final String EXTRA_APPWIDGET_MIN_WIDTH = "appWidgetMinWidth";
+
+ /**
+ * An bundle extra that contains the lower bound on the current height, in dips, of a widget instance.
+ */
+ public static final String EXTRA_APPWIDGET_MIN_HEIGHT = "appWidgetMinHeight";
+
+ /**
+ * An bundle extra that contains the upper bound on the current width, in dips, of a widget instance.
+ */
+ public static final String EXTRA_APPWIDGET_MAX_WIDTH = "appWidgetMaxWidth";
+
+ /**
+ * An bundle extra that contains the upper bound on the current width, in dips, of a widget instance.
+ */
+ public static final String EXTRA_APPWIDGET_MAX_HEIGHT = "appWidgetMaxHeight";
+
+ /**
+ * An intent extra which points to a bundle of extra information for a particular widget id.
+ * In particular this bundle can contain EXTRA_APPWIDGET_WIDTH and EXTRA_APPWIDGET_HEIGHT.
+ */
+ public static final String EXTRA_APPWIDGET_EXTRAS = "appWidgetExtras";
+
+ /**
* An intent extra that contains multiple appWidgetIds.
* <p>
* The value will be an int array that can be retrieved like this:
@@ -161,6 +188,14 @@ public class AppWidgetManager {
public static final String ACTION_APPWIDGET_UPDATE = "android.appwidget.action.APPWIDGET_UPDATE";
/**
+ * Sent when the custom extras for an AppWidget change.
+ *
+ * @see AppWidgetProvider#onAppWidgetExtrasChanged AppWidgetProvider#onAppWidgetExtrasChanged(
+ * Context context, AppWidgetManager appWidgetManager, int appWidgetId, Bundle newExtras)
+ */
+ public static final String ACTION_APPWIDGET_EXTRAS_CHANGED = "android.appwidget.action.APPWIDGET_UPDATE_EXTRAS";
+
+ /**
* Sent when an instance of an AppWidget is deleted from its host.
*
* @see AppWidgetProvider#onDeleted AppWidgetProvider.onDeleted(Context context, int[] appWidgetIds)
@@ -252,6 +287,46 @@ public class AppWidgetManager {
}
/**
+ * Update the extras for a given widget instance.
+ *
+ * The extras can be used to embed additional information about this widget to be accessed
+ * by the associated widget's AppWidgetProvider.
+ *
+ * @see #getAppWidgetExtras(int)
+ *
+ * @param appWidgetId The AppWidget instances for which to set the RemoteViews.
+ * @param extras The extras to associate with this widget
+ */
+ public void updateAppWidgetExtras(int appWidgetId, Bundle extras) {
+ try {
+ sService.updateAppWidgetExtras(appWidgetId, extras);
+ }
+ catch (RemoteException e) {
+ throw new RuntimeException("system server dead?", e);
+ }
+ }
+
+ /**
+ * Get the extras associated with a given widget instance.
+ *
+ * The extras can be used to embed additional information about this widget to be accessed
+ * by the associated widget's AppWidgetProvider.
+ *
+ * @see #updateAppWidgetExtras(int, Bundle)
+ *
+ * @param appWidgetId The AppWidget instances for which to set the RemoteViews.
+ * @return The extras associated with the given widget instance.
+ */
+ public Bundle getAppWidgetExtras(int appWidgetId) {
+ try {
+ return sService.getAppWidgetExtras(appWidgetId);
+ }
+ catch (RemoteException e) {
+ throw new RuntimeException("system server dead?", e);
+ }
+ }
+
+ /**
* Set the RemoteViews to use for the specified appWidgetId.
*
* Note that the RemoteViews parameter will be cached by the AppWidgetService, and hence should
diff --git a/core/java/android/appwidget/AppWidgetProvider.java b/core/java/android/appwidget/AppWidgetProvider.java
index 00a5f0c..3cf40ae 100755
--- a/core/java/android/appwidget/AppWidgetProvider.java
+++ b/core/java/android/appwidget/AppWidgetProvider.java
@@ -74,6 +74,16 @@ public class AppWidgetProvider extends BroadcastReceiver {
this.onDeleted(context, new int[] { appWidgetId });
}
}
+ else if (AppWidgetManager.ACTION_APPWIDGET_EXTRAS_CHANGED.equals(action)) {
+ Bundle extras = intent.getExtras();
+ if (extras != null && extras.containsKey(AppWidgetManager.EXTRA_APPWIDGET_ID)
+ && extras.containsKey(AppWidgetManager.EXTRA_APPWIDGET_EXTRAS)) {
+ int appWidgetId = extras.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID);
+ Bundle widgetExtras = extras.getBundle(AppWidgetManager.EXTRA_APPWIDGET_EXTRAS);
+ this.onAppWidgetExtrasChanged(context, AppWidgetManager.getInstance(context),
+ appWidgetId, widgetExtras);
+ }
+ }
else if (AppWidgetManager.ACTION_APPWIDGET_ENABLED.equals(action)) {
this.onEnabled(context);
}
@@ -82,7 +92,7 @@ public class AppWidgetProvider extends BroadcastReceiver {
}
}
// END_INCLUDE(onReceive)
-
+
/**
* Called in response to the {@link AppWidgetManager#ACTION_APPWIDGET_UPDATE} broadcast when
* this AppWidget provider is being asked to provide {@link android.widget.RemoteViews RemoteViews}
@@ -102,7 +112,26 @@ public class AppWidgetProvider extends BroadcastReceiver {
*/
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
}
-
+
+ /**
+ * Called in response to the {@link AppWidgetManager#ACTION_APPWIDGET_EXTRAS_CHANGED}
+ * broadcast when this widget has been layed out at a new size.
+ *
+ * {@more}
+ *
+ * @param context The {@link android.content.Context Context} in which this receiver is
+ * running.
+ * @param appWidgetManager A {@link AppWidgetManager} object you can call {@link
+ * AppWidgetManager#updateAppWidget} on.
+ * @param appWidgetId The appWidgetId of the widget who's size changed.
+ * @param newExtras The appWidgetId of the widget who's size changed.
+ *
+ * @see AppWidgetManager#ACTION_APPWIDGET_EXTRAS_CHANGED
+ */
+ public void onAppWidgetExtrasChanged(Context context, AppWidgetManager appWidgetManager,
+ int appWidgetId, Bundle newExtras) {
+ }
+
/**
* Called in response to the {@link AppWidgetManager#ACTION_APPWIDGET_DELETED} broadcast when
* one or more AppWidget instances have been deleted. Override this method to implement
diff --git a/core/java/android/hardware/Camera.java b/core/java/android/hardware/Camera.java
index 4fb710e..eb0a0c6 100644
--- a/core/java/android/hardware/Camera.java
+++ b/core/java/android/hardware/Camera.java
@@ -2442,13 +2442,13 @@ public class Camera {
}
/**
- * Sets the rotation angle in degrees relative to the orientation of
- * the camera. This affects the pictures returned from JPEG {@link
- * PictureCallback}. The camera driver may set orientation in the
- * EXIF header without rotating the picture. Or the driver may rotate
- * the picture and the EXIF thumbnail. If the Jpeg picture is rotated,
- * the orientation in the EXIF header will be missing or 1 (row #0 is
- * top and column #0 is left side).
+ * Sets the clockwise rotation angle in degrees relative to the
+ * orientation of the camera. This affects the pictures returned from
+ * JPEG {@link PictureCallback}. The camera driver may set orientation
+ * in the EXIF header without rotating the picture. Or the driver may
+ * rotate the picture and the EXIF thumbnail. If the Jpeg picture is
+ * rotated, the orientation in the EXIF header will be missing or 1
+ * (row #0 is top and column #0 is left side).
*
* <p>If applications want to rotate the picture to match the orientation
* of what users see, apps should use {@link
diff --git a/core/java/android/hardware/input/InputManager.java b/core/java/android/hardware/input/InputManager.java
index b39b823..5ba1850 100755
--- a/core/java/android/hardware/input/InputManager.java
+++ b/core/java/android/hardware/input/InputManager.java
@@ -268,6 +268,8 @@ public final class InputManager {
synchronized (mInputDevicesLock) {
int index = findInputDeviceListenerLocked(listener);
if (index >= 0) {
+ InputDeviceListenerDelegate d = mInputDeviceListeners.get(index);
+ d.removeCallbacksAndMessages(null);
mInputDeviceListeners.remove(index);
}
}
diff --git a/core/java/android/nfc/INfcAdapter.aidl b/core/java/android/nfc/INfcAdapter.aidl
index ddd00a4..39810ba 100644
--- a/core/java/android/nfc/INfcAdapter.aidl
+++ b/core/java/android/nfc/INfcAdapter.aidl
@@ -34,7 +34,7 @@ interface INfcAdapter
INfcAdapterExtras getNfcAdapterExtrasInterface(in String pkg);
int getState();
- boolean disable();
+ boolean disable(boolean saveState);
boolean enable();
boolean enableNdefPush();
boolean disableNdefPush();
diff --git a/core/java/android/nfc/NfcAdapter.java b/core/java/android/nfc/NfcAdapter.java
index 90f5bef..7bf9feb 100644
--- a/core/java/android/nfc/NfcAdapter.java
+++ b/core/java/android/nfc/NfcAdapter.java
@@ -574,9 +574,10 @@ public final class NfcAdapter {
*
* @hide
*/
+
public boolean disable() {
try {
- return sService.disable();
+ return sService.disable(true);
} catch (RemoteException e) {
attemptDeadServiceRecovery(e);
return false;
diff --git a/core/java/android/text/DynamicLayout.java b/core/java/android/text/DynamicLayout.java
index ff5a467..dc58ef2 100644
--- a/core/java/android/text/DynamicLayout.java
+++ b/core/java/android/text/DynamicLayout.java
@@ -117,7 +117,7 @@ public class DynamicLayout extends Layout
mObjects = new PackedObjectVector<Directions>(1);
- mBlockEnds = new int[] { 0 };
+ mBlockEndLines = new int[] { 0 };
mBlockIndices = new int[] { INVALID_BLOCK_INDEX };
mNumberOfBlocks = 1;
@@ -391,23 +391,23 @@ public class DynamicLayout extends Layout
int firstBlock = -1;
int lastBlock = -1;
for (int i = 0; i < mNumberOfBlocks; i++) {
- if (mBlockEnds[i] >= startLine) {
+ if (mBlockEndLines[i] >= startLine) {
firstBlock = i;
break;
}
}
for (int i = firstBlock; i < mNumberOfBlocks; i++) {
- if (mBlockEnds[i] >= endLine) {
+ if (mBlockEndLines[i] >= endLine) {
lastBlock = i;
break;
}
}
- final int lastBlockEndLine = mBlockEnds[lastBlock];
+ final int lastBlockEndLine = mBlockEndLines[lastBlock];
boolean createBlockBefore = startLine > (firstBlock == 0 ? 0 :
- mBlockEnds[firstBlock - 1] + 1);
+ mBlockEndLines[firstBlock - 1] + 1);
boolean createBlock = newLineCount > 0;
- boolean createBlockAfter = endLine < mBlockEnds[lastBlock];
+ boolean createBlockAfter = endLine < mBlockEndLines[lastBlock];
int numAddedBlocks = 0;
if (createBlockBefore) numAddedBlocks++;
@@ -419,27 +419,27 @@ public class DynamicLayout extends Layout
if (newNumberOfBlocks == 0) {
// Even when text is empty, there is actually one line and hence one block
- mBlockEnds[0] = 0;
+ mBlockEndLines[0] = 0;
mBlockIndices[0] = INVALID_BLOCK_INDEX;
mNumberOfBlocks = 1;
return;
}
- if (newNumberOfBlocks > mBlockEnds.length) {
+ if (newNumberOfBlocks > mBlockEndLines.length) {
final int newSize = ArrayUtils.idealIntArraySize(newNumberOfBlocks);
- int[] blockEnds = new int[newSize];
+ int[] blockEndLines = new int[newSize];
int[] blockIndices = new int[newSize];
- System.arraycopy(mBlockEnds, 0, blockEnds, 0, firstBlock);
+ System.arraycopy(mBlockEndLines, 0, blockEndLines, 0, firstBlock);
System.arraycopy(mBlockIndices, 0, blockIndices, 0, firstBlock);
- System.arraycopy(mBlockEnds, lastBlock + 1,
- blockEnds, firstBlock + numAddedBlocks, mNumberOfBlocks - lastBlock - 1);
+ System.arraycopy(mBlockEndLines, lastBlock + 1,
+ blockEndLines, firstBlock + numAddedBlocks, mNumberOfBlocks - lastBlock - 1);
System.arraycopy(mBlockIndices, lastBlock + 1,
blockIndices, firstBlock + numAddedBlocks, mNumberOfBlocks - lastBlock - 1);
- mBlockEnds = blockEnds;
+ mBlockEndLines = blockEndLines;
mBlockIndices = blockIndices;
} else {
- System.arraycopy(mBlockEnds, lastBlock + 1,
- mBlockEnds, firstBlock + numAddedBlocks, mNumberOfBlocks - lastBlock - 1);
+ System.arraycopy(mBlockEndLines, lastBlock + 1,
+ mBlockEndLines, firstBlock + numAddedBlocks, mNumberOfBlocks - lastBlock - 1);
System.arraycopy(mBlockIndices, lastBlock + 1,
mBlockIndices, firstBlock + numAddedBlocks, mNumberOfBlocks - lastBlock - 1);
}
@@ -447,24 +447,24 @@ public class DynamicLayout extends Layout
mNumberOfBlocks = newNumberOfBlocks;
final int deltaLines = newLineCount - (endLine - startLine + 1);
for (int i = firstBlock + numAddedBlocks; i < mNumberOfBlocks; i++) {
- mBlockEnds[i] += deltaLines;
+ mBlockEndLines[i] += deltaLines;
}
int blockIndex = firstBlock;
if (createBlockBefore) {
- mBlockEnds[blockIndex] = startLine - 1;
+ mBlockEndLines[blockIndex] = startLine - 1;
mBlockIndices[blockIndex] = INVALID_BLOCK_INDEX;
blockIndex++;
}
if (createBlock) {
- mBlockEnds[blockIndex] = startLine + newLineCount - 1;
+ mBlockEndLines[blockIndex] = startLine + newLineCount - 1;
mBlockIndices[blockIndex] = INVALID_BLOCK_INDEX;
blockIndex++;
}
if (createBlockAfter) {
- mBlockEnds[blockIndex] = lastBlockEndLine + deltaLines;
+ mBlockEndLines[blockIndex] = lastBlockEndLine + deltaLines;
mBlockIndices[blockIndex] = INVALID_BLOCK_INDEX;
}
}
@@ -473,10 +473,10 @@ public class DynamicLayout extends Layout
* This package private method is used for test purposes only
* @hide
*/
- void setBlocksDataForTest(int[] blockEnds, int[] blockIndices, int numberOfBlocks) {
- mBlockEnds = new int[blockEnds.length];
+ void setBlocksDataForTest(int[] blockEndLines, int[] blockIndices, int numberOfBlocks) {
+ mBlockEndLines = new int[blockEndLines.length];
mBlockIndices = new int[blockIndices.length];
- System.arraycopy(blockEnds, 0, mBlockEnds, 0, blockEnds.length);
+ System.arraycopy(blockEndLines, 0, mBlockEndLines, 0, blockEndLines.length);
System.arraycopy(blockIndices, 0, mBlockIndices, 0, blockIndices.length);
mNumberOfBlocks = numberOfBlocks;
}
@@ -484,8 +484,8 @@ public class DynamicLayout extends Layout
/**
* @hide
*/
- public int[] getBlockEnds() {
- return mBlockEnds;
+ public int[] getBlockEndLines() {
+ return mBlockEndLines;
}
/**
@@ -633,8 +633,8 @@ public class DynamicLayout extends Layout
* @hide
*/
public static final int INVALID_BLOCK_INDEX = -1;
- // Stores the line numbers of the last line of each block
- private int[] mBlockEnds;
+ // Stores the line numbers of the last line of each block (inclusive)
+ private int[] mBlockEndLines;
// The indices of this block's display list in TextView's internal display list array or
// INVALID_BLOCK_INDEX if this block has been invalidated during an edition
private int[] mBlockIndices;
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 247f673..da1f64b 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -59,6 +59,7 @@ import android.util.EventLog;
import android.util.Log;
import android.util.Slog;
import android.util.TypedValue;
+import android.view.KeyCharacterMap.FallbackAction;
import android.view.View.AttachInfo;
import android.view.View.MeasureSpec;
import android.view.accessibility.AccessibilityEvent;
@@ -323,6 +324,8 @@ public final class ViewRootImpl implements ViewParent,
private final int mDensity;
+ final KeyCharacterMap.FallbackAction mFallbackAction = new KeyCharacterMap.FallbackAction();
+
/**
* Consistency verifier for debugging purposes.
*/
@@ -4383,6 +4386,31 @@ public final class ViewRootImpl implements ViewParent,
mHandler.sendMessage(msg);
}
+ public void dispatchUnhandledKey(KeyEvent event) {
+ if ((event.getFlags() & KeyEvent.FLAG_FALLBACK) == 0) {
+ final KeyCharacterMap kcm = event.getKeyCharacterMap();
+ final int keyCode = event.getKeyCode();
+ final int metaState = event.getMetaState();
+
+ KeyEvent fallbackEvent = null;
+ synchronized (mFallbackAction) {
+ // Check for fallback actions specified by the key character map.
+ if (kcm.getFallbackAction(keyCode, metaState, mFallbackAction)) {
+ int flags = event.getFlags() | KeyEvent.FLAG_FALLBACK;
+ fallbackEvent = KeyEvent.obtain(
+ event.getDownTime(), event.getEventTime(),
+ event.getAction(), mFallbackAction.keyCode,
+ event.getRepeatCount(), mFallbackAction.metaState,
+ event.getDeviceId(), event.getScanCode(),
+ flags, event.getSource(), null);
+ }
+ }
+ if (fallbackEvent != null) {
+ dispatchKey(fallbackEvent);
+ }
+ }
+ }
+
public void dispatchAppVisibility(boolean visible) {
Message msg = mHandler.obtainMessage(MSG_DISPATCH_APP_VISIBILITY);
msg.arg1 = visible ? 1 : 0;
diff --git a/core/java/android/view/accessibility/AccessibilityInteractionClient.java b/core/java/android/view/accessibility/AccessibilityInteractionClient.java
index 35f0d9d..f73faf3 100644
--- a/core/java/android/view/accessibility/AccessibilityInteractionClient.java
+++ b/core/java/android/view/accessibility/AccessibilityInteractionClient.java
@@ -84,7 +84,7 @@ public final class AccessibilityInteractionClient
private final Object mInstanceLock = new Object();
- private int mInteractionId = -1;
+ private volatile int mInteractionId = -1;
private AccessibilityNodeInfo mFindAccessibilityNodeInfoResult;
@@ -150,6 +150,18 @@ public final class AccessibilityInteractionClient
}
/**
+ * Gets the root {@link AccessibilityNodeInfo} in the currently active window.
+ *
+ * @param connectionId The id of a connection for interacting with the system.
+ * @return The root {@link AccessibilityNodeInfo} if found, null otherwise.
+ */
+ public AccessibilityNodeInfo getRootInActiveWindow(int connectionId) {
+ return findAccessibilityNodeInfoByAccessibilityId(connectionId,
+ AccessibilityNodeInfo.ACTIVE_WINDOW_ID, AccessibilityNodeInfo.ROOT_NODE_ID,
+ AccessibilityNodeInfo.FLAG_PREFETCH_DESCENDANTS);
+ }
+
+ /**
* Finds an {@link AccessibilityNodeInfo} by accessibility id.
*
* @param connectionId The id of a connection for interacting with the system.
diff --git a/core/java/android/webkit/WebViewClassic.java b/core/java/android/webkit/WebViewClassic.java
index f429e09..2793081 100644
--- a/core/java/android/webkit/WebViewClassic.java
+++ b/core/java/android/webkit/WebViewClassic.java
@@ -3925,6 +3925,9 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc
mSelectCursorExtent.offset(dx, dy);
mSelectCursorExtentTextQuad.offset(dx, dy);
}
+ } else if (mHandleAlpha.getAlpha() > 0) {
+ // stop fading as we're not going to move with the layer.
+ mHandleAlphaAnimator.end();
}
if (mAutoCompletePopup != null &&
mCurrentScrollingLayerId == mEditTextLayerId) {
@@ -4418,9 +4421,7 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc
}
canvas.restoreToCount(saveCount);
- if (mSelectingText) {
- drawTextSelectionHandles(canvas);
- }
+ drawTextSelectionHandles(canvas);
if (extras == DRAW_EXTRAS_CURSOR_RING) {
if (mTouchMode == TOUCH_SHORTPRESS_START_MODE) {
@@ -4658,6 +4659,9 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc
}
private void onZoomAnimationStart() {
+ if (!mSelectingText && mHandleAlpha.getAlpha() > 0) {
+ mHandleAlphaAnimator.end();
+ }
}
private void onZoomAnimationEnd() {
@@ -4688,6 +4692,36 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc
private final DrawFilter mScrollFilter =
new PaintFlagsDrawFilter(SCROLL_BITS, 0);
+ private class SelectionHandleAlpha {
+ private int mAlpha = 0;
+ public void setAlpha(int alpha) {
+ mAlpha = alpha;
+ if (mSelectHandleCenter != null) {
+ mSelectHandleCenter.setAlpha(alpha);
+ mSelectHandleLeft.setAlpha(alpha);
+ mSelectHandleRight.setAlpha(alpha);
+ // TODO: Use partial invalidate
+ invalidate();
+ }
+ }
+
+ public int getAlpha() {
+ return mAlpha;
+ }
+
+ }
+
+ private void startSelectingText() {
+ mSelectingText = true;
+ mHandleAlphaAnimator.setIntValues(255);
+ mHandleAlphaAnimator.start();
+ }
+ private void endSelectingText() {
+ mSelectingText = false;
+ mHandleAlphaAnimator.setIntValues(0);
+ mHandleAlphaAnimator.start();
+ }
+
private void ensureSelectionHandles() {
if (mSelectHandleCenter == null) {
mSelectHandleCenter = mContext.getResources().getDrawable(
@@ -4696,6 +4730,7 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc
com.android.internal.R.drawable.text_select_handle_left);
mSelectHandleRight = mContext.getResources().getDrawable(
com.android.internal.R.drawable.text_select_handle_right);
+ mHandleAlpha.setAlpha(mHandleAlpha.getAlpha());
mSelectHandleCenterOffset = new Point(0,
-mSelectHandleCenter.getIntrinsicHeight());
mSelectHandleLeftOffset = new Point(0,
@@ -4707,31 +4742,40 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc
}
private void drawTextSelectionHandles(Canvas canvas) {
+ if (mHandleAlpha.getAlpha() == 0) {
+ return;
+ }
ensureSelectionHandles();
- int[] handles = new int[4];
- getSelectionHandles(handles);
- int start_x = contentToViewDimension(handles[0]);
- int start_y = contentToViewDimension(handles[1]);
- int end_x = contentToViewDimension(handles[2]);
- int end_y = contentToViewDimension(handles[3]);
+ if (mSelectingText) {
+ int[] handles = new int[4];
+ getSelectionHandles(handles);
+ int start_x = contentToViewDimension(handles[0]);
+ int start_y = contentToViewDimension(handles[1]);
+ int end_x = contentToViewDimension(handles[2]);
+ int end_y = contentToViewDimension(handles[3]);
+
+ if (mIsCaretSelection) {
+ // Caret handle is centered
+ start_x -= (mSelectHandleCenter.getIntrinsicWidth() / 2);
+ mSelectHandleCenter.setBounds(start_x, start_y,
+ start_x + mSelectHandleCenter.getIntrinsicWidth(),
+ start_y + mSelectHandleCenter.getIntrinsicHeight());
+ } else {
+ // Magic formula copied from TextView
+ start_x -= (mSelectHandleLeft.getIntrinsicWidth() * 3) / 4;
+ mSelectHandleLeft.setBounds(start_x, start_y,
+ start_x + mSelectHandleLeft.getIntrinsicWidth(),
+ start_y + mSelectHandleLeft.getIntrinsicHeight());
+ end_x -= mSelectHandleRight.getIntrinsicWidth() / 4;
+ mSelectHandleRight.setBounds(end_x, end_y,
+ end_x + mSelectHandleRight.getIntrinsicWidth(),
+ end_y + mSelectHandleRight.getIntrinsicHeight());
+ }
+ }
if (mIsCaretSelection) {
- // Caret handle is centered
- start_x -= (mSelectHandleCenter.getIntrinsicWidth() / 2);
- mSelectHandleCenter.setBounds(start_x, start_y,
- start_x + mSelectHandleCenter.getIntrinsicWidth(),
- start_y + mSelectHandleCenter.getIntrinsicHeight());
mSelectHandleCenter.draw(canvas);
} else {
- // Magic formula copied from TextView
- start_x -= (mSelectHandleLeft.getIntrinsicWidth() * 3) / 4;
- mSelectHandleLeft.setBounds(start_x, start_y,
- start_x + mSelectHandleLeft.getIntrinsicWidth(),
- start_y + mSelectHandleLeft.getIntrinsicHeight());
- end_x -= mSelectHandleRight.getIntrinsicWidth() / 4;
- mSelectHandleRight.setBounds(end_x, end_y,
- end_x + mSelectHandleRight.getIntrinsicWidth(),
- end_y + mSelectHandleRight.getIntrinsicHeight());
mSelectHandleLeft.draw(canvas);
mSelectHandleRight.draw(canvas);
}
@@ -5385,7 +5429,7 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc
selectionDone();
return false;
}
- mSelectingText = true;
+ startSelectingText();
mTouchMode = TOUCH_DRAG_MODE;
return true;
}
@@ -5439,7 +5483,7 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc
void selectionDone() {
if (mSelectingText) {
hidePasteButton();
- mSelectingText = false;
+ endSelectingText();
// finish is idempotent, so this is fine even if selectionDone was
// called by mSelectCallback.onDestroyActionMode
if (mSelectCallback != null) {
@@ -6571,6 +6615,9 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc
private long mTrackballUpTime = 0;
private long mLastCursorTime = 0;
private Rect mLastCursorBounds;
+ private SelectionHandleAlpha mHandleAlpha = new SelectionHandleAlpha();
+ private ObjectAnimator mHandleAlphaAnimator =
+ ObjectAnimator.ofInt(mHandleAlpha, "alpha", 0);
// Set by default; BrowserActivity clears to interpret trackball data
// directly for movement. Currently, the framework only passes
diff --git a/core/java/android/webkit/WebViewClient.java b/core/java/android/webkit/WebViewClient.java
index 0c34037..6aff10a 100644
--- a/core/java/android/webkit/WebViewClient.java
+++ b/core/java/android/webkit/WebViewClient.java
@@ -20,6 +20,7 @@ import android.graphics.Bitmap;
import android.net.http.SslError;
import android.os.Message;
import android.view.KeyEvent;
+import android.view.ViewRootImpl;
public class WebViewClient {
@@ -273,6 +274,10 @@ public class WebViewClient {
* @param event The key event.
*/
public void onUnhandledKeyEvent(WebView view, KeyEvent event) {
+ ViewRootImpl root = view.getViewRootImpl();
+ if (root != null) {
+ root.dispatchUnhandledKey(event);
+ }
}
/**
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index e68049c..53d5e0b 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -403,7 +403,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
/**
* Handles scrolling between positions within the list.
*/
- private PositionScroller mPositionScroller;
+ PositionScroller mPositionScroller;
/**
* The offset in pixels form the top of the AdapterView to the top
@@ -3080,6 +3080,10 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
return isClickable() || isLongClickable();
}
+ if (mPositionScroller != null) {
+ mPositionScroller.stop();
+ }
+
if (mFastScroller != null) {
boolean intercepted = mFastScroller.onTouchEvent(ev);
if (intercepted) {
@@ -3564,6 +3568,10 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
int action = ev.getAction();
View v;
+ if (mPositionScroller != null) {
+ mPositionScroller.stop();
+ }
+
if (mFastScroller != null) {
boolean intercepted = mFastScroller.onInterceptTouchEvent(ev);
if (intercepted) {
@@ -3748,7 +3756,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
mScroller.fling(0, initialY, 0, initialVelocity,
0, Integer.MAX_VALUE, 0, Integer.MAX_VALUE);
mTouchMode = TOUCH_MODE_FLING;
- post(this);
+ postOnAnimation(this);
if (PROFILE_FLINGING) {
if (!mFlingProfilingStarted) {
@@ -3766,7 +3774,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
if (mScroller.springBack(0, mScrollY, 0, 0, 0, 0)) {
mTouchMode = TOUCH_MODE_OVERFLING;
invalidate();
- post(this);
+ postOnAnimation(this);
} else {
mTouchMode = TOUCH_MODE_REST;
reportScrollStateChange(OnScrollListener.SCROLL_STATE_IDLE);
@@ -3778,7 +3786,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
Integer.MIN_VALUE, Integer.MAX_VALUE, 0, getHeight());
mTouchMode = TOUCH_MODE_OVERFLING;
invalidate();
- post(this);
+ postOnAnimation(this);
}
void edgeReached(int delta) {
@@ -3800,7 +3808,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
}
}
invalidate();
- post(this);
+ postOnAnimation(this);
}
void startScroll(int distance, int duration) {
@@ -3808,7 +3816,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
mLastFlingY = initialY;
mScroller.startScroll(0, initialY, 0, distance, duration);
mTouchMode = TOUCH_MODE_FLING;
- post(this);
+ postOnAnimation(this);
}
void endFling() {
@@ -3907,7 +3915,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
if (more && !atEnd) {
if (atEdge) invalidate();
mLastFlingY = y;
- post(this);
+ postOnAnimation(this);
} else {
endFling();
@@ -3948,7 +3956,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
}
} else {
invalidate();
- post(this);
+ postOnAnimation(this);
}
} else {
endFling();
@@ -3959,7 +3967,6 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
}
}
-
class PositionScroller implements Runnable {
private static final int SCROLL_DURATION = 400;
@@ -4009,7 +4016,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
mBoundPos = INVALID_POSITION;
mLastSeenPos = INVALID_POSITION;
- post(this);
+ postOnAnimation(this);
}
void start(int position, int boundPosition) {
@@ -4070,7 +4077,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
mBoundPos = boundPosition;
mLastSeenPos = INVALID_POSITION;
- post(this);
+ postOnAnimation(this);
}
void startWithOffset(int position, int offset) {
@@ -4080,6 +4087,8 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
void startWithOffset(int position, int offset, int duration) {
stop();
+ offset += getPaddingTop();
+
mTargetPos = position;
mOffsetFromTop = offset;
mBoundPos = INVALID_POSITION;
@@ -4108,7 +4117,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
(int) (duration / screenTravelCount);
mLastSeenPos = INVALID_POSITION;
- post(this);
+ postOnAnimation(this);
}
void stop() {
@@ -4116,10 +4125,6 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
}
public void run() {
- if (mTouchMode != TOUCH_MODE_FLING && mLastSeenPos != INVALID_POSITION) {
- return;
- }
-
final int listHeight = getHeight();
final int firstPos = mFirstPosition;
@@ -4134,7 +4139,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
if (lastPos == mLastSeenPos) {
// No new views, let things keep going.
- post(this);
+ postOnAnimation(this);
return;
}
@@ -4142,14 +4147,15 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
final int lastViewHeight = lastView.getHeight();
final int lastViewTop = lastView.getTop();
final int lastViewPixelsShowing = listHeight - lastViewTop;
- final int extraScroll = lastPos < mItemCount - 1 ? mExtraScroll : mListPadding.bottom;
+ final int extraScroll = lastPos < mItemCount - 1 ?
+ Math.max(mListPadding.bottom, mExtraScroll) : mListPadding.bottom;
- smoothScrollBy(lastViewHeight - lastViewPixelsShowing + extraScroll,
- mScrollDuration);
+ final int scrollBy = lastViewHeight - lastViewPixelsShowing + extraScroll;
+ smoothScrollBy(scrollBy, mScrollDuration);
mLastSeenPos = lastPos;
if (lastPos < mTargetPos) {
- post(this);
+ postOnAnimation(this);
}
break;
}
@@ -4166,21 +4172,21 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
if (nextPos == mLastSeenPos) {
// No new views, let things keep going.
- post(this);
+ postOnAnimation(this);
return;
}
final View nextView = getChildAt(nextViewIndex);
final int nextViewHeight = nextView.getHeight();
final int nextViewTop = nextView.getTop();
- final int extraScroll = mExtraScroll;
+ final int extraScroll = Math.max(mListPadding.bottom, mExtraScroll);
if (nextPos < mBoundPos) {
smoothScrollBy(Math.max(0, nextViewHeight + nextViewTop - extraScroll),
mScrollDuration);
mLastSeenPos = nextPos;
- post(this);
+ postOnAnimation(this);
} else {
if (nextViewTop > extraScroll) {
smoothScrollBy(nextViewTop - extraScroll, mScrollDuration);
@@ -4192,7 +4198,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
case MOVE_UP_POS: {
if (firstPos == mLastSeenPos) {
// No new views, let things keep going.
- post(this);
+ postOnAnimation(this);
return;
}
@@ -4201,14 +4207,15 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
return;
}
final int firstViewTop = firstView.getTop();
- final int extraScroll = firstPos > 0 ? mExtraScroll : mListPadding.top;
+ final int extraScroll = firstPos > 0 ?
+ Math.max(mExtraScroll, mListPadding.top) : mListPadding.top;
smoothScrollBy(firstViewTop - extraScroll, mScrollDuration);
mLastSeenPos = firstPos;
if (firstPos > mTargetPos) {
- post(this);
+ postOnAnimation(this);
}
break;
}
@@ -4230,12 +4237,13 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
final int lastViewHeight = lastView.getHeight();
final int lastViewTop = lastView.getTop();
final int lastViewPixelsShowing = listHeight - lastViewTop;
+ final int extraScroll = Math.max(mListPadding.top, mExtraScroll);
mLastSeenPos = lastPos;
if (lastPos > mBoundPos) {
- smoothScrollBy(-(lastViewPixelsShowing - mExtraScroll), mScrollDuration);
- post(this);
+ smoothScrollBy(-(lastViewPixelsShowing - extraScroll), mScrollDuration);
+ postOnAnimation(this);
} else {
- final int bottom = listHeight - mExtraScroll;
+ final int bottom = listHeight - extraScroll;
final int lastViewBottom = lastViewTop + lastViewHeight;
if (bottom > lastViewBottom) {
smoothScrollBy(-(bottom - lastViewBottom), mScrollDuration);
@@ -4270,10 +4278,10 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
final float modifier = Math.min(Math.abs(screenTravelCount), 1.f);
if (position < firstPos) {
smoothScrollBy((int) (-getHeight() * modifier), mScrollDuration);
- post(this);
+ postOnAnimation(this);
} else if (position > lastPos) {
smoothScrollBy((int) (getHeight() * modifier), mScrollDuration);
- post(this);
+ postOnAnimation(this);
} else {
// On-screen, just scroll.
final int targetTop = getChildAt(position - firstPos).getTop();
@@ -4620,7 +4628,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
// invalidate before moving the children to avoid unnecessary invalidate
// calls to bubble up from the children all the way to the top
if (!awakenScrollBars()) {
- invalidate();
+ invalidate();
}
offsetChildrenTopAndBottom(incrementalDeltaY);
diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java
index 040a385..900f0d3 100644
--- a/core/java/android/widget/Editor.java
+++ b/core/java/android/widget/Editor.java
@@ -1241,24 +1241,21 @@ public class Editor {
}
DynamicLayout dynamicLayout = (DynamicLayout) layout;
- int[] blockEnds = dynamicLayout.getBlockEnds();
+ int[] blockEndLines = dynamicLayout.getBlockEndLines();
int[] blockIndices = dynamicLayout.getBlockIndices();
final int numberOfBlocks = dynamicLayout.getNumberOfBlocks();
- final int mScrollX = mTextView.getScrollX();
- final int mScrollY = mTextView.getScrollY();
- canvas.translate(mScrollX, mScrollY);
int endOfPreviousBlock = -1;
int searchStartIndex = 0;
for (int i = 0; i < numberOfBlocks; i++) {
- int blockEnd = blockEnds[i];
+ int blockEndLine = blockEndLines[i];
int blockIndex = blockIndices[i];
final boolean blockIsInvalid = blockIndex == DynamicLayout.INVALID_BLOCK_INDEX;
if (blockIsInvalid) {
blockIndex = getAvailableDisplayListIndex(blockIndices, numberOfBlocks,
searchStartIndex);
- // Dynamic layout internal block indices structure is updated from Editor
+ // Note how dynamic layout's internal block indices get updated from Editor
blockIndices[i] = blockIndex;
searchStartIndex = blockIndex + 1;
}
@@ -1272,28 +1269,38 @@ public class Editor {
}
if (!blockDisplayList.isValid()) {
+ final int blockBeginLine = endOfPreviousBlock + 1;
+ final int top = layout.getLineTop(blockBeginLine);
+ final int bottom = layout.getLineBottom(blockEndLine);
+
final HardwareCanvas hardwareCanvas = blockDisplayList.start();
try {
- hardwareCanvas.setViewport(width, height);
+ hardwareCanvas.setViewport(width, bottom - top);
// The dirty rect should always be null for a display list
hardwareCanvas.onPreDraw(null);
- hardwareCanvas.translate(-mScrollX, -mScrollY);
- layout.drawText(hardwareCanvas, endOfPreviousBlock + 1, blockEnd);
- hardwareCanvas.translate(mScrollX, mScrollY);
+ // drawText is always relative to TextView's origin, this translation brings
+ // this range of text back to the top of the viewport
+ hardwareCanvas.translate(0, -top);
+ layout.drawText(hardwareCanvas, blockBeginLine, blockEndLine);
+ hardwareCanvas.translate(0, top);
} finally {
hardwareCanvas.onPostDraw();
blockDisplayList.end();
if (View.USE_DISPLAY_LIST_PROPERTIES) {
- blockDisplayList.setLeftTopRightBottom(0, 0, width, height);
+ blockDisplayList.setLeftTopRightBottom(0, top, width, bottom);
+ // Same as drawDisplayList below, handled by our TextView's parent
+ blockDisplayList.setClipChildren(false);
}
}
}
+ // TODO When View.USE_DISPLAY_LIST_PROPERTIES is the only code path, the
+ // width and height parameters should be removed and the bounds set above in
+ // setLeftTopRightBottom should be used instead for quick rejection.
((HardwareCanvas) canvas).drawDisplayList(blockDisplayList, width, height, null,
- DisplayList.FLAG_CLIP_CHILDREN);
- endOfPreviousBlock = blockEnd;
+ 0 /* no child clipping, our TextView parent enforces it */);
+ endOfPreviousBlock = blockEndLine;
}
- canvas.translate(-mScrollX, -mScrollY);
} else {
// Boring layout is used for empty and hint text
layout.drawText(canvas, firstLine, lastLine);
@@ -1572,11 +1579,9 @@ public class Editor {
}
void onScrollChanged() {
- if (mPositionListener != null) {
- mPositionListener.onScrollChanged();
- }
- // Internal scroll affects the clip boundaries
- invalidateTextDisplayList();
+ if (mPositionListener != null) {
+ mPositionListener.onScrollChanged();
+ }
}
/**
diff --git a/core/java/android/widget/GridView.java b/core/java/android/widget/GridView.java
index 0f1dab5..0a40d5e 100644
--- a/core/java/android/widget/GridView.java
+++ b/core/java/android/widget/GridView.java
@@ -1463,6 +1463,9 @@ public class GridView extends AbsListView {
mResurrectToPosition = position;
}
mLayoutMode = LAYOUT_SET_SELECTION;
+ if (mPositionScroller != null) {
+ mPositionScroller.stop();
+ }
requestLayout();
}
@@ -1475,6 +1478,10 @@ public class GridView extends AbsListView {
void setSelectionInt(int position) {
int previousSelectedPosition = mNextSelectedPosition;
+ if (mPositionScroller != null) {
+ mPositionScroller.stop();
+ }
+
setNextSelectedPositionInt(position);
layoutChildren();
diff --git a/core/java/android/widget/ListView.java b/core/java/android/widget/ListView.java
index 71700b3..5098523 100644
--- a/core/java/android/widget/ListView.java
+++ b/core/java/android/widget/ListView.java
@@ -1926,6 +1926,9 @@ public class ListView extends AbsListView {
mSyncRowId = mAdapter.getItemId(position);
}
+ if (mPositionScroller != null) {
+ mPositionScroller.stop();
+ }
requestLayout();
}
}
@@ -1950,6 +1953,10 @@ public class ListView extends AbsListView {
}
}
+ if (mPositionScroller != null) {
+ mPositionScroller.stop();
+ }
+
layoutChildren();
if (awakeScrollbars) {
diff --git a/core/java/com/android/internal/app/ShutdownThread.java b/core/java/com/android/internal/app/ShutdownThread.java
index 6a46929..c03694f 100644
--- a/core/java/com/android/internal/app/ShutdownThread.java
+++ b/core/java/com/android/internal/app/ShutdownThread.java
@@ -24,6 +24,8 @@ import android.app.IActivityManager;
import android.app.ProgressDialog;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.IBluetooth;
+import android.nfc.NfcAdapter;
+import android.nfc.INfcAdapter;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
@@ -48,7 +50,7 @@ import android.view.WindowManager;
public final class ShutdownThread extends Thread {
// constants
private static final String TAG = "ShutdownThread";
- private static final int MAX_NUM_PHONE_STATE_READS = 16;
+ private static final int MAX_NUM_PHONE_STATE_READS = 24;
private static final int PHONE_STATE_POLL_SLEEP_MSEC = 500;
// maximum time we wait for the shutdown broadcast before going on.
private static final int MAX_BROADCAST_TIME = 10*1000;
@@ -231,6 +233,7 @@ public final class ShutdownThread extends Thread {
* Shuts off power regardless of radio and bluetooth state if the alloted time has passed.
*/
public void run() {
+ boolean nfcOff;
boolean bluetoothOff;
boolean radioOff;
@@ -284,16 +287,29 @@ public final class ShutdownThread extends Thread {
}
}
+ final INfcAdapter nfc =
+ INfcAdapter.Stub.asInterface(ServiceManager.checkService("nfc"));
final ITelephony phone =
ITelephony.Stub.asInterface(ServiceManager.checkService("phone"));
final IBluetooth bluetooth =
IBluetooth.Stub.asInterface(ServiceManager.checkService(
BluetoothAdapter.BLUETOOTH_SERVICE));
-
final IMountService mount =
IMountService.Stub.asInterface(
ServiceManager.checkService("mount"));
-
+
+ try {
+ nfcOff = nfc == null ||
+ nfc.getState() == NfcAdapter.STATE_OFF;
+ if (!nfcOff) {
+ Log.w(TAG, "Turning off NFC...");
+ nfc.disable(false); // Don't persist new state
+ }
+ } catch (RemoteException ex) {
+ Log.e(TAG, "RemoteException during NFC shutdown", ex);
+ nfcOff = true;
+ }
+
try {
bluetoothOff = bluetooth == null ||
bluetooth.getBluetoothState() == BluetoothAdapter.STATE_OFF;
@@ -317,7 +333,7 @@ public final class ShutdownThread extends Thread {
radioOff = true;
}
- Log.i(TAG, "Waiting for Bluetooth and Radio...");
+ Log.i(TAG, "Waiting for NFC, Bluetooth and Radio...");
// Wait a max of 32 seconds for clean shutdown
for (int i = 0; i < MAX_NUM_PHONE_STATE_READS; i++) {
@@ -338,8 +354,17 @@ public final class ShutdownThread extends Thread {
radioOff = true;
}
}
- if (radioOff && bluetoothOff) {
- Log.i(TAG, "Radio and Bluetooth shutdown complete.");
+ if (!nfcOff) {
+ try {
+ nfcOff = nfc.getState() == NfcAdapter.STATE_OFF;
+ } catch (RemoteException ex) {
+ Log.e(TAG, "RemoteException during NFC shutdown", ex);
+ nfcOff = true;
+ }
+ }
+
+ if (radioOff && bluetoothOff && nfcOff) {
+ Log.i(TAG, "NFC, Radio and Bluetooth shutdown complete.");
break;
}
SystemClock.sleep(PHONE_STATE_POLL_SLEEP_MSEC);
diff --git a/core/java/com/android/internal/appwidget/IAppWidgetService.aidl b/core/java/com/android/internal/appwidget/IAppWidgetService.aidl
index fa0873d..b1b57e7 100644
--- a/core/java/com/android/internal/appwidget/IAppWidgetService.aidl
+++ b/core/java/com/android/internal/appwidget/IAppWidgetService.aidl
@@ -20,6 +20,7 @@ import android.content.ComponentName;
import android.content.Intent;
import android.appwidget.AppWidgetProviderInfo;
import com.android.internal.appwidget.IAppWidgetHost;
+import android.os.Bundle;
import android.os.IBinder;
import android.widget.RemoteViews;
@@ -42,6 +43,8 @@ interface IAppWidgetService {
// for AppWidgetManager
//
void updateAppWidgetIds(in int[] appWidgetIds, in RemoteViews views);
+ void updateAppWidgetExtras(int appWidgetId, in Bundle extras);
+ Bundle getAppWidgetExtras(int appWidgetId);
void partiallyUpdateAppWidgetIds(in int[] appWidgetIds, in RemoteViews views);
void updateAppWidgetProvider(in ComponentName provider, in RemoteViews views);
void notifyAppWidgetViewDataChanged(in int[] appWidgetIds, int viewId);
diff --git a/core/java/com/android/internal/widget/SizeAdaptiveLayout.java b/core/java/com/android/internal/widget/SizeAdaptiveLayout.java
index adfd3dc..0a99f17 100644
--- a/core/java/com/android/internal/widget/SizeAdaptiveLayout.java
+++ b/core/java/com/android/internal/widget/SizeAdaptiveLayout.java
@@ -26,8 +26,11 @@ import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
+import android.graphics.drawable.Drawable;
+import android.graphics.drawable.StateListDrawable;
import android.util.AttributeSet;
import android.util.Log;
+import android.util.StateSet;
import android.view.View;
import android.view.ViewDebug;
import android.view.ViewGroup;
@@ -90,8 +93,14 @@ public class SizeAdaptiveLayout extends ViewGroup {
private void initialize() {
mModestyPanel = new View(getContext());
// If the SizeAdaptiveLayout has a solid background, use it as a transition hint.
- if (getBackground() instanceof ColorDrawable) {
- mModestyPanel.setBackgroundDrawable(getBackground());
+ Drawable background = getBackground();
+ if (background instanceof StateListDrawable) {
+ StateListDrawable sld = (StateListDrawable) background;
+ sld.setState(StateSet.WILD_CARD);
+ background = sld.getCurrent();
+ }
+ if (background instanceof ColorDrawable) {
+ mModestyPanel.setBackgroundDrawable(background);
} else {
mModestyPanel.setBackgroundColor(Color.BLACK);
}