summaryrefslogtreecommitdiffstats
path: root/core/java/android
diff options
context:
space:
mode:
Diffstat (limited to 'core/java/android')
-rw-r--r--core/java/android/accessibilityservice/AccessibilityService.java130
-rw-r--r--core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl8
-rw-r--r--core/java/android/app/Activity.java2
-rw-r--r--core/java/android/app/DownloadManager.java31
-rw-r--r--core/java/android/app/INotificationManager.aidl3
-rw-r--r--core/java/android/app/Notification.java95
-rw-r--r--core/java/android/hardware/Camera.java76
-rw-r--r--core/java/android/os/Environment.java17
-rw-r--r--core/java/android/provider/Downloads.java19
-rw-r--r--core/java/android/provider/MediaStore.java2
-rw-r--r--core/java/android/view/AccessibilityInteractionController.java9
-rw-r--r--core/java/android/view/KeyCharacterMap.java278
-rw-r--r--core/java/android/view/View.java26
-rw-r--r--core/java/android/view/ViewGroup.java30
-rw-r--r--core/java/android/view/ViewRootImpl.java8
-rw-r--r--core/java/android/view/accessibility/AccessibilityNodeInfo.java23
-rw-r--r--core/java/android/webkit/WebCoreThreadWatchdog.java2
17 files changed, 353 insertions, 406 deletions
diff --git a/core/java/android/accessibilityservice/AccessibilityService.java b/core/java/android/accessibilityservice/AccessibilityService.java
index 3da35d3..4e340c0 100644
--- a/core/java/android/accessibilityservice/AccessibilityService.java
+++ b/core/java/android/accessibilityservice/AccessibilityService.java
@@ -259,13 +259,51 @@ public abstract class AccessibilityService extends Service {
public static final int GESTURE_COUNTER_CLOCKWISE_CIRCLE = 10;
/**
+ * The user has performed a left and up gesture on the touch screen.
+ */
+ public static final int GESTURE_SWIPE_LEFT_AND_UP = 11;
+
+ /**
+ * The user has performed a left and down gesture on the touch screen.
+ */
+ public static final int GESTURE_SWIPE_LEFT_AND_DOWN = 12;
+
+ /**
+ * The user has performed a right and up gesture on the touch screen.
+ */
+ public static final int GESTURE_SWIPE_RIGHT_AND_UP = 13;
+
+ /**
+ * The user has performed a right and down gesture on the touch screen.
+ */
+ public static final int GESTURE_SWIPE_RIGHT_AND_DOWN = 14;
+
+ /**
+ * The user has performed an up and left gesture on the touch screen.
+ */
+ public static final int GESTURE_SWIPE_UP_AND_LEFT = 15;
+
+ /**
+ * The user has performed an up and right gesture on the touch screen.
+ */
+ public static final int GESTURE_SWIPE_UP_AND_RIGHT = 16;
+
+ /**
+ * The user has performed an down and left gesture on the touch screen.
+ */
+ public static final int GESTURE_SWIPE_DOWN_AND_LEFT = 17;
+
+ /**
+ * The user has performed an down and right gesture on the touch screen.
+ */
+ public static final int GESTURE_SWIPE_DOWN_AND_RIGHT = 18;
+
+ /**
* The {@link Intent} that must be declared as handled by the service.
*/
public static final String SERVICE_INTERFACE =
"android.accessibilityservice.AccessibilityService";
- private static final int UNDEFINED = -1;
-
/**
* Name under which an AccessibilityService component publishes information
* about itself. This meta-data must reference an XML resource containing an
@@ -284,6 +322,28 @@ public abstract class AccessibilityService extends Service {
*/
public static final String SERVICE_META_DATA = "android.accessibilityservice";
+ /**
+ * Action to go back.
+ */
+ public static final int GLOBAL_ACTION_BACK = 1;
+
+ /**
+ * Action to go home.
+ */
+ public static final int GLOBAL_ACTION_HOME = 2;
+
+ /**
+ * Action to open the recents.
+ */
+ public static final int GLOBAL_ACTION_RECENTS = 3;
+
+ /**
+ * Action to open the notifications.
+ */
+ public static final int GLOBAL_ACTION_NOTIFICATIONS = 4;
+
+ private static final int UNDEFINED = -1;
+
private static final String LOG_TAG = "AccessibilityService";
interface Callbacks {
@@ -344,23 +404,39 @@ public abstract class AccessibilityService extends Service {
protected void 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 = AccessibilityInteractionClient.getInstance()
- .findAccessibilityNodeInfoByAccessibilityId(connectionId,
- AccessibilityNodeInfo.ACTIVE_WINDOW_ID, AccessibilityNodeInfo.ROOT_NODE_ID,
- AccessibilityNodeInfo.FLAG_PREFETCH_DESCENDANTS);
+ AccessibilityNodeInfo root = getRootInActiveWindow();
if (root == null) {
return;
}
- AccessibilityNodeInfo current = root.findFocus(View.FOCUS_ACCESSIBILITY);
+
+ AccessibilityNodeInfo current = root.findFocus(AccessibilityNodeInfo.FOCUS_ACCESSIBILITY);
if (current == null) {
current = root;
}
+
+ // Local actions.
AccessibilityNodeInfo next = null;
switch (gestureId) {
case GESTURE_SWIPE_UP: {
@@ -402,6 +478,46 @@ public abstract class AccessibilityService extends Service {
}
/**
+ * Gets the root node in the currently active window if this service
+ * can retrieve window content.
+ *
+ * @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);
+ }
+
+ /**
+ * Performs a global action. Such an action can be performed
+ * at any moment regardless of the current application or user
+ * location in that application. For example going back, going
+ * home, opening recents, etc.
+ *
+ * @param action The action to perform.
+ * @return Whether the action was successfully performed.
+ *
+ * @see #GLOBAL_ACTION_BACK
+ * @see #GLOBAL_ACTION_HOME
+ * @see #GLOBAL_ACTION_NOTIFICATIONS
+ * @see #GLOBAL_ACTION_RECENTS
+ */
+ public final boolean performGlobalAction(int action) {
+ IAccessibilityServiceConnection connection =
+ AccessibilityInteractionClient.getInstance().getConnection(mConnectionId);
+ if (connection != null) {
+ try {
+ return connection.perfromGlobalAction(action);
+ } catch (RemoteException re) {
+ Log.w(LOG_TAG, "Error while calling performGlobalAction", re);
+ }
+ }
+ return false;
+ }
+
+ /**
* Gets the an {@link AccessibilityServiceInfo} describing this
* {@link AccessibilityService}. This method is useful if one wants
* to change some of the dynamically configurable properties at
diff --git a/core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl b/core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl
index 30da9db..1bd5387 100644
--- a/core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl
+++ b/core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl
@@ -160,4 +160,12 @@ interface IAccessibilityServiceConnection {
* @return The associated accessibility service info.
*/
AccessibilityServiceInfo getServiceInfo();
+
+ /**
+ * Performs a global action, such as going home, going back, etc.
+ *
+ * @param action The action to perform.
+ * @return Whether the action was performed.
+ */
+ boolean perfromGlobalAction(int action);
}
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 1c820dc..35bc7ff 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -549,7 +549,7 @@ import java.util.HashMap;
* super.onCreate(savedInstanceState);
*
* SharedPreferences mPrefs = getSharedPreferences();
- * mCurViewMode = mPrefs.getInt("view_mode" DAY_VIEW_MODE);
+ * mCurViewMode = mPrefs.getInt("view_mode", DAY_VIEW_MODE);
* }
*
* protected void onPause() {
diff --git a/core/java/android/app/DownloadManager.java b/core/java/android/app/DownloadManager.java
index 55f29e6..0713127 100644
--- a/core/java/android/app/DownloadManager.java
+++ b/core/java/android/app/DownloadManager.java
@@ -347,9 +347,9 @@ public class DownloadManager {
private CharSequence mTitle;
private CharSequence mDescription;
private String mMimeType;
- private boolean mRoamingAllowed = true;
private int mAllowedNetworkTypes = ~0; // default to all network types allowed
- private boolean mAllowedOverMetered = true;
+ private boolean mRoamingAllowed = true;
+ private boolean mMeteredAllowed = true;
private boolean mIsVisibleInDownloadsUi = true;
private boolean mScannable = false;
private boolean mUseSystemCache = false;
@@ -624,17 +624,6 @@ public class DownloadManager {
}
/**
- * Set whether this download may proceed over a metered network
- * connection. By default, metered networks are allowed.
- *
- * @see ConnectivityManager#isActiveNetworkMetered()
- */
- public Request setAllowedOverMetered(boolean allow) {
- mAllowedOverMetered = allow;
- return this;
- }
-
- /**
* Set whether this download may proceed over a roaming connection. By default, roaming is
* allowed.
* @param allowed whether to allow a roaming connection to be used
@@ -646,6 +635,17 @@ public class DownloadManager {
}
/**
+ * Set whether this download may proceed over a metered network
+ * connection. By default, metered networks are allowed.
+ *
+ * @see ConnectivityManager#isActiveNetworkMetered()
+ */
+ public Request setAllowedOverMetered(boolean allow) {
+ mMeteredAllowed = allow;
+ return this;
+ }
+
+ /**
* Set whether this download should be displayed in the system's Downloads UI. True by
* default.
* @param isVisible whether to display this download in the Downloads UI
@@ -687,10 +687,10 @@ public class DownloadManager {
putIfNonNull(values, Downloads.Impl.COLUMN_DESCRIPTION, mDescription);
putIfNonNull(values, Downloads.Impl.COLUMN_MIME_TYPE, mMimeType);
- // TODO: add COLUMN_ALLOW_METERED and persist
values.put(Downloads.Impl.COLUMN_VISIBILITY, mNotificationVisibility);
values.put(Downloads.Impl.COLUMN_ALLOWED_NETWORK_TYPES, mAllowedNetworkTypes);
values.put(Downloads.Impl.COLUMN_ALLOW_ROAMING, mRoamingAllowed);
+ values.put(Downloads.Impl.COLUMN_ALLOW_METERED, mMeteredAllowed);
values.put(Downloads.Impl.COLUMN_IS_VISIBLE_IN_DOWNLOADS_UI, mIsVisibleInDownloadsUi);
return values;
@@ -1340,9 +1340,6 @@ public class DownloadManager {
case Downloads.Impl.STATUS_FILE_ALREADY_EXISTS_ERROR:
return ERROR_FILE_ALREADY_EXISTS;
- case Downloads.Impl.STATUS_BLOCKED:
- return ERROR_BLOCKED;
-
default:
return ERROR_UNKNOWN;
}
diff --git a/core/java/android/app/INotificationManager.aidl b/core/java/android/app/INotificationManager.aidl
index 4d5238c..6f95e26 100644
--- a/core/java/android/app/INotificationManager.aidl
+++ b/core/java/android/app/INotificationManager.aidl
@@ -34,5 +34,8 @@ interface INotificationManager
void cancelToast(String pkg, ITransientNotification callback);
void enqueueNotificationWithTag(String pkg, String tag, int id, in Notification notification, inout int[] idReceived);
void cancelNotificationWithTag(String pkg, String tag, int id);
+
+ void setNotificationsEnabledForPackage(String pkg, boolean enabled);
+ boolean areNotificationsEnabledForPackage(String pkg);
}
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index 22d84f0..b581f99 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -190,12 +190,6 @@ public class Notification implements Parcelable
public RemoteViews contentView;
/**
- * The view that will represent this notification in the pop-up "intruder alert" dialog.
- * @hide
- */
- public RemoteViews intruderView;
-
- /**
* A large-format version of {@link #contentView}, giving the Notification an
* opportunity to show more detail. The system UI may choose to show this
* instead of the normal content view at its discretion.
@@ -590,9 +584,6 @@ public class Notification implements Parcelable
actions = parcel.createTypedArray(Action.CREATOR);
if (parcel.readInt() != 0) {
- intruderView = RemoteViews.CREATOR.createFromParcel(parcel);
- }
- if (parcel.readInt() != 0) {
bigContentView = RemoteViews.CREATOR.createFromParcel(parcel);
}
}
@@ -658,9 +649,6 @@ public class Notification implements Parcelable
for(int i=0; i<this.actions.length; i++) {
that.actions[i] = this.actions[i].clone();
}
- if (this.intruderView != null) {
- that.intruderView = this.intruderView.clone();
- }
if (this.bigContentView != null) {
that.bigContentView = this.bigContentView.clone();
}
@@ -755,13 +743,6 @@ public class Notification implements Parcelable
parcel.writeTypedArray(actions, 0);
- if (intruderView != null) {
- parcel.writeInt(1);
- intruderView.writeToParcel(parcel, 0);
- } else {
- parcel.writeInt(0);
- }
-
if (bigContentView != null) {
parcel.writeInt(1);
bigContentView.writeToParcel(parcel, 0);
@@ -942,8 +923,6 @@ public class Notification implements Parcelable
private Bundle mExtras;
private int mPriority;
private ArrayList<Action> mActions = new ArrayList<Action>(3);
- private boolean mCanHasIntruder;
- private boolean mIntruderActionsShowText;
private boolean mUseChronometer;
/**
@@ -1349,38 +1328,6 @@ public class Notification implements Parcelable
return this;
}
- /**
- * Specify whether this notification should pop up as an
- * "intruder alert" (a small window that shares the screen with the
- * current activity). This sort of notification is (as the name implies)
- * very intrusive, so use it sparingly for notifications that require
- * the user's attention.
- *
- * Notes:
- * <ul>
- * <li>Intruder alerts only show when the screen is on.</li>
- * <li>Intruder alerts take precedence over fullScreenIntents.</li>
- * </ul>
- *
- * @param intrude Whether to pop up an intruder alert (default false).
- */
- public Builder setUsesIntruderAlert(boolean intrude) {
- mCanHasIntruder = intrude;
- return this;
- }
-
- /**
- * Control text on intruder alert action buttons. By default, action
- * buttons in intruders do not show textual labels.
- *
- * @param showActionText Whether to show text labels beneath action
- * icons (default false).
- */
- public Builder setIntruderActionsShowText(boolean showActionText) {
- mIntruderActionsShowText = showActionText;
- return this;
- }
-
private void setFlag(int mask, boolean value) {
if (value) {
mFlags |= mask;
@@ -1506,45 +1453,6 @@ public class Notification implements Parcelable
return applyStandardTemplateWithActions(R.layout.notification_template_base);
}
- private RemoteViews makeIntruderView(boolean showLabels) {
- RemoteViews intruderView = new RemoteViews(mContext.getPackageName(),
- R.layout.notification_intruder_content);
- if (mLargeIcon != null) {
- intruderView.setImageViewBitmap(R.id.icon, mLargeIcon);
- intruderView.setViewVisibility(R.id.icon, View.VISIBLE);
- } else if (mSmallIcon != 0) {
- intruderView.setImageViewResource(R.id.icon, mSmallIcon);
- intruderView.setViewVisibility(R.id.icon, View.VISIBLE);
- } else {
- intruderView.setViewVisibility(R.id.icon, View.GONE);
- }
- if (mContentTitle != null) {
- intruderView.setTextViewText(R.id.title, mContentTitle);
- }
- if (mContentText != null) {
- intruderView.setTextViewText(R.id.text, mContentText);
- }
- if (mActions.size() > 0) {
- intruderView.setViewVisibility(R.id.actions, View.VISIBLE);
- int N = mActions.size();
- if (N>3) N=3;
- final int[] BUTTONS = { R.id.action0, R.id.action1, R.id.action2 };
- for (int i=0; i<N; i++) {
- final Action action = mActions.get(i);
- final int buttonId = BUTTONS[i];
-
- intruderView.setViewVisibility(buttonId, View.VISIBLE);
- intruderView.setTextViewText(buttonId, showLabels ? action.title : null);
- intruderView.setTextViewCompoundDrawables(buttonId, 0, action.icon, 0, 0);
- intruderView.setContentDescription(buttonId, action.title);
- intruderView.setOnClickPendingIntent(buttonId, action.actionIntent);
- }
- } else {
- intruderView.setViewVisibility(R.id.actions, View.GONE);
- }
- return intruderView;
- }
-
private RemoteViews generateActionButton(Action action) {
RemoteViews button = new RemoteViews(mContext.getPackageName(), R.layout.notification_action);
button.setTextViewCompoundDrawables(R.id.action0, action.icon, 0, 0, 0);
@@ -1579,9 +1487,6 @@ public class Notification implements Parcelable
n.ledOffMS = mLedOffMs;
n.defaults = mDefaults;
n.flags = mFlags;
- if (mCanHasIntruder) {
- n.intruderView = makeIntruderView(mIntruderActionsShowText);
- }
n.bigContentView = makeBigContentView();
if (mLedOnMs != 0 && mLedOffMs != 0) {
n.flags |= FLAG_SHOW_LIGHTS;
diff --git a/core/java/android/hardware/Camera.java b/core/java/android/hardware/Camera.java
index 640b47b..4fb710e 100644
--- a/core/java/android/hardware/Camera.java
+++ b/core/java/android/hardware/Camera.java
@@ -234,48 +234,6 @@ public class Camera {
};
/**
- * Creates a new Camera object to access a particular hardware camera.
- *
- * <p>When <code>force</code> is set to false, this will throw an exception
- * if the same camera is already opened by other clients. If true, the other
- * client will be disconnected from the camera they opened. If the device
- * can only support one camera running at a time, all camera-using clients
- * will be disconnected from their cameras.
- *
- * <p>A camera being held by an application can be taken away by other
- * applications at any time. Before the camera is taken, applications will
- * get {@link #CAMERA_ERROR_RELEASED} and have some time to clean up. Apps
- * receiving this callback must immediately stop video recording and then
- * call {@link #release()} on their camera object. Otherwise, it will be
- * released by the frameworks in a short time. After receiving
- * CAMERA_ERROR_RELEASED, apps should not call any method except <code>
- * release</code> and {@link #isReleased()}. After a camera is taken away,
- * all methods will throw exceptions except <code>isReleased</code> and
- * <code>release</code>. Apps can use <code>isReleased</code> to see if the
- * camera has been taken away. If the camera is taken away, the apps can
- * silently finish themselves or show a dialog.
- *
- * <p>Applications with android.permission.KEEP_CAMERA can request to keep
- * the camera. That is, the camera will not be taken by other applications
- * while it is opened. The permission can only be obtained by trusted
- * platform applications, such as those implementing lock screen security
- * features.
- *
- * @param cameraId the hardware camera to access, between 0 and
- * {@link #getNumberOfCameras()}-1.
- * @param force true to take the ownership from the existing client if the
- * camera has been opened by other clients.
- * @param keep true if the applications do not want other apps to take the
- * camera. Only the apps with android.permission.KEEP_CAMERA can keep
- * the camera.
- * @return a new Camera object, connected, locked and ready for use.
- * @hide
- */
- public static Camera open(int cameraId, boolean force, boolean keep) {
- return new Camera(cameraId, force, keep);
- }
-
- /**
* Creates a new Camera object to access a particular hardware camera. If
* the same camera is opened by other applications, this will throw a
* RuntimeException.
@@ -305,7 +263,7 @@ public class Camera {
* @see android.app.admin.DevicePolicyManager#getCameraDisabled(android.content.ComponentName)
*/
public static Camera open(int cameraId) {
- return new Camera(cameraId, false, false);
+ return new Camera(cameraId);
}
/**
@@ -320,13 +278,13 @@ public class Camera {
for (int i = 0; i < numberOfCameras; i++) {
getCameraInfo(i, cameraInfo);
if (cameraInfo.facing == CameraInfo.CAMERA_FACING_BACK) {
- return new Camera(i, false, false);
+ return new Camera(i);
}
}
return null;
}
- Camera(int cameraId, boolean force, boolean keep) {
+ Camera(int cameraId) {
mShutterCallback = null;
mRawImageCallback = null;
mJpegCallback = null;
@@ -343,7 +301,7 @@ public class Camera {
mEventHandler = null;
}
- native_setup(new WeakReference<Camera>(this), cameraId, force, keep);
+ native_setup(new WeakReference<Camera>(this), cameraId);
}
/**
@@ -356,8 +314,7 @@ public class Camera {
release();
}
- private native final void native_setup(Object camera_this, int cameraId,
- boolean force, boolean keep);
+ private native final void native_setup(Object camera_this, int cameraId);
private native final void native_release();
@@ -372,18 +329,6 @@ public class Camera {
}
/**
- * Whether the camera is released. When any camera method throws an
- * exception, applications can use this to check whether the camera has been
- * taken by other clients. If true, it means other clients have taken the
- * camera. The applications can silently finish themselves or show a dialog.
- *
- * @return whether the camera is released.
- * @see #open(int, boolean, boolean)
- * @hide
- */
- public native final boolean isReleased();
-
- /**
* Unlocks the camera to allow another process to access it.
* Normally, the camera is locked to the process with an active Camera
* object until {@link #release()} is called. To allow rapid handoff
@@ -1377,17 +1322,6 @@ public class Camera {
public static final int CAMERA_ERROR_UNKNOWN = 1;
/**
- * Camera was released because another client has opened the camera. The
- * application should call {@link #release()} after getting this. The apps
- * should not call any method except <code>release</code> and {@link #isReleased()}
- * after this.
- *
- * @see Camera.ErrorCallback
- * @hide
- */
- public static final int CAMERA_ERROR_RELEASED = 2;
-
- /**
* Media server died. In this case, the application must release the
* Camera object and instantiate a new one.
* @see Camera.ErrorCallback
diff --git a/core/java/android/os/Environment.java b/core/java/android/os/Environment.java
index 11f9445..f7f0263 100644
--- a/core/java/android/os/Environment.java
+++ b/core/java/android/os/Environment.java
@@ -113,19 +113,16 @@ public class Environment {
= getDirectory("ANDROID_SECURE_DATA", "/data/secure");
private static final File EXTERNAL_STORAGE_DIRECTORY
- = getDirectory("EXTERNAL_STORAGE", "/mnt/sdcard");
+ = getDirectory("EXTERNAL_STORAGE", "/storage/sdcard0");
- private static final File EXTERNAL_STORAGE_ANDROID_DATA_DIRECTORY
- = new File (new File(getDirectory("EXTERNAL_STORAGE", "/mnt/sdcard"),
- "Android"), "data");
+ private static final File EXTERNAL_STORAGE_ANDROID_DATA_DIRECTORY = new File(new File(
+ getDirectory("EXTERNAL_STORAGE", "/storage/sdcard0"), "Android"), "data");
- private static final File EXTERNAL_STORAGE_ANDROID_MEDIA_DIRECTORY
- = new File (new File(getDirectory("EXTERNAL_STORAGE", "/mnt/sdcard"),
- "Android"), "media");
+ private static final File EXTERNAL_STORAGE_ANDROID_MEDIA_DIRECTORY = new File(new File(
+ getDirectory("EXTERNAL_STORAGE", "/storage/sdcard0"), "Android"), "media");
- private static final File EXTERNAL_STORAGE_ANDROID_OBB_DIRECTORY
- = new File (new File(getDirectory("EXTERNAL_STORAGE", "/mnt/sdcard"),
- "Android"), "obb");
+ private static final File EXTERNAL_STORAGE_ANDROID_OBB_DIRECTORY = new File(new File(
+ getDirectory("EXTERNAL_STORAGE", "/storage/sdcard0"), "Android"), "obb");
private static final File DOWNLOAD_CACHE_DIRECTORY
= getDirectory("DOWNLOAD_CACHE", "/cache");
diff --git a/core/java/android/provider/Downloads.java b/core/java/android/provider/Downloads.java
index cd8d51f..31ad12b 100644
--- a/core/java/android/provider/Downloads.java
+++ b/core/java/android/provider/Downloads.java
@@ -329,6 +329,14 @@ public final class Downloads {
public static final String COLUMN_IS_PUBLIC_API = "is_public_api";
/**
+ * The name of the column holding a bitmask of allowed network types. This is only used for
+ * public API downloads.
+ * <P>Type: INTEGER</P>
+ * <P>Owner can Init/Read</P>
+ */
+ public static final String COLUMN_ALLOWED_NETWORK_TYPES = "allowed_network_types";
+
+ /**
* The name of the column indicating whether roaming connections can be used. This is only
* used for public API downloads.
* <P>Type: BOOLEAN</P>
@@ -337,12 +345,12 @@ public final class Downloads {
public static final String COLUMN_ALLOW_ROAMING = "allow_roaming";
/**
- * The name of the column holding a bitmask of allowed network types. This is only used for
- * public API downloads.
- * <P>Type: INTEGER</P>
+ * The name of the column indicating whether metered connections can be used. This is only
+ * used for public API downloads.
+ * <P>Type: BOOLEAN</P>
* <P>Owner can Init/Read</P>
*/
- public static final String COLUMN_ALLOWED_NETWORK_TYPES = "allowed_network_types";
+ public static final String COLUMN_ALLOW_METERED = "allow_metered";
/**
* Whether or not this download should be displayed in the system's Downloads UI. Defaults
@@ -701,7 +709,10 @@ public final class Downloads {
* blocked by {@link NetworkPolicyManager}.
*
* @hide
+ * @deprecated since behavior now uses
+ * {@link #STATUS_WAITING_FOR_NETWORK}
*/
+ @Deprecated
public static final int STATUS_BLOCKED = 498;
/** {@hide} */
diff --git a/core/java/android/provider/MediaStore.java b/core/java/android/provider/MediaStore.java
index 38945c2..79d0144 100644
--- a/core/java/android/provider/MediaStore.java
+++ b/core/java/android/provider/MediaStore.java
@@ -306,13 +306,11 @@ public final class MediaStore {
/**
* The width of the image/video in pixels.
- * @hide
*/
public static final String WIDTH = "width";
/**
* The height of the image/video in pixels.
- * @hide
*/
public static final String HEIGHT = "height";
}
diff --git a/core/java/android/view/AccessibilityInteractionController.java b/core/java/android/view/AccessibilityInteractionController.java
index 6c1a6bf..54c62ee 100644
--- a/core/java/android/view/AccessibilityInteractionController.java
+++ b/core/java/android/view/AccessibilityInteractionController.java
@@ -52,13 +52,16 @@ final class AccessibilityInteractionController {
private ArrayList<AccessibilityNodeInfo> mTempAccessibilityNodeInfoList =
new ArrayList<AccessibilityNodeInfo>();
- private final Handler mHandler = new PrivateHandler();
+ private final Handler mHandler;
private final ViewRootImpl mViewRootImpl;
private final AccessibilityNodePrefetcher mPrefetcher;
public AccessibilityInteractionController(ViewRootImpl viewRootImpl) {
+ // mView is never null - the caller has already checked.
+ Looper looper = viewRootImpl.mView.mContext.getMainLooper();
+ mHandler = new PrivateHandler(looper);
mViewRootImpl = viewRootImpl;
mPrefetcher = new AccessibilityNodePrefetcher();
}
@@ -846,8 +849,8 @@ final class AccessibilityInteractionController {
private final static int MSG_FIND_FOCUS = 5;
private final static int MSG_FOCUS_SEARCH = 6;
- public PrivateHandler() {
- super(Looper.getMainLooper());
+ public PrivateHandler(Looper looper) {
+ super(looper);
}
@Override
diff --git a/core/java/android/view/KeyCharacterMap.java b/core/java/android/view/KeyCharacterMap.java
index 12d7b12..1c61c6c 100644
--- a/core/java/android/view/KeyCharacterMap.java
+++ b/core/java/android/view/KeyCharacterMap.java
@@ -24,6 +24,7 @@ import android.util.SparseIntArray;
import android.hardware.input.InputManager;
import java.lang.Character;
+import java.text.Normalizer;
/**
* Describes the keys provided by a keyboard device and their associated labels.
@@ -135,6 +136,106 @@ public class KeyCharacterMap implements Parcelable {
*/
public static final int MODIFIER_BEHAVIOR_CHORDED_OR_TOGGLED = 1;
+ /*
+ * This bit will be set in the return value of {@link #get(int, int)} if the
+ * key is a "dead key."
+ */
+ public static final int COMBINING_ACCENT = 0x80000000;
+
+ /**
+ * Mask the return value from {@link #get(int, int)} with this value to get
+ * a printable representation of the accent character of a "dead key."
+ */
+ public static final int COMBINING_ACCENT_MASK = 0x7FFFFFFF;
+
+ /* Characters used to display placeholders for dead keys. */
+ private static final int ACCENT_ACUTE = '\u00B4';
+ private static final int ACCENT_BREVE = '\u02D8';
+ private static final int ACCENT_CARON = '\u02C7';
+ private static final int ACCENT_CEDILLA = '\u00B8';
+ private static final int ACCENT_COMMA_ABOVE = '\u1FBD';
+ private static final int ACCENT_COMMA_ABOVE_RIGHT = '\u02BC';
+ private static final int ACCENT_DOT_ABOVE = '\u02D9';
+ private static final int ACCENT_DOUBLE_ACUTE = '\u02DD';
+ private static final int ACCENT_GRAVE = '\u02CB';
+ private static final int ACCENT_CIRCUMFLEX = '\u02C6';
+ private static final int ACCENT_MACRON = '\u00AF';
+ private static final int ACCENT_MACRON_BELOW = '\u02CD';
+ private static final int ACCENT_OGONEK = '\u02DB';
+ private static final int ACCENT_REVERSED_COMMA_ABOVE = '\u02BD';
+ private static final int ACCENT_RING_ABOVE = '\u02DA';
+ private static final int ACCENT_TILDE = '\u02DC';
+ private static final int ACCENT_TURNED_COMMA_ABOVE = '\u02BB';
+ private static final int ACCENT_UMLAUT = '\u00A8';
+
+ /* Legacy dead key display characters used in previous versions of the API.
+ * We still support these characters by mapping them to their non-legacy version. */
+ private static final int ACCENT_GRAVE_LEGACY = '`';
+ private static final int ACCENT_CIRCUMFLEX_LEGACY = '^';
+ private static final int ACCENT_TILDE_LEGACY = '~';
+
+ /**
+ * Maps Unicode combining diacritical to display-form dead key.
+ */
+ private static final SparseIntArray sCombiningToAccent = new SparseIntArray();
+ private static final SparseIntArray sAccentToCombining = new SparseIntArray();
+ static {
+ addCombining('\u0300', ACCENT_GRAVE);
+ addCombining('\u0301', ACCENT_ACUTE);
+ addCombining('\u0302', ACCENT_CIRCUMFLEX);
+ addCombining('\u0303', ACCENT_TILDE);
+ addCombining('\u0304', ACCENT_MACRON);
+ addCombining('\u0306', ACCENT_BREVE);
+ addCombining('\u0307', ACCENT_DOT_ABOVE);
+ addCombining('\u0308', ACCENT_UMLAUT);
+ //addCombining('\u0309', ACCENT_HOOK_ABOVE);
+ addCombining('\u030A', ACCENT_RING_ABOVE);
+ addCombining('\u030B', ACCENT_DOUBLE_ACUTE);
+ addCombining('\u030C', ACCENT_CARON);
+ //addCombining('\u030D', ACCENT_VERTICAL_LINE_ABOVE);
+ //addCombining('\u030E', ACCENT_DOUBLE_VERTICAL_LINE_ABOVE);
+ //addCombining('\u030F', ACCENT_DOUBLE_GRAVE);
+ //addCombining('\u0310', ACCENT_CANDRABINDU);
+ //addCombining('\u0311', ACCENT_INVERTED_BREVE);
+ addCombining('\u0312', ACCENT_TURNED_COMMA_ABOVE);
+ addCombining('\u0313', ACCENT_COMMA_ABOVE);
+ addCombining('\u0314', ACCENT_REVERSED_COMMA_ABOVE);
+ addCombining('\u0315', ACCENT_COMMA_ABOVE_RIGHT);
+ //addCombining('\u031B', ACCENT_HORN);
+ //addCombining('\u0323', ACCENT_DOT_BELOW);
+ //addCombining('\u0326', ACCENT_COMMA_BELOW);
+ addCombining('\u0327', ACCENT_CEDILLA);
+ addCombining('\u0328', ACCENT_OGONEK);
+ //addCombining('\u0329', ACCENT_VERTICAL_LINE_BELOW);
+ addCombining('\u0331', ACCENT_MACRON_BELOW);
+ //addCombining('\u0342', ACCENT_PERISPOMENI);
+ //addCombining('\u0344', ACCENT_DIALYTIKA_TONOS);
+ //addCombining('\u0345', ACCENT_YPOGEGRAMMENI);
+
+ // One-way mappings to equivalent preferred accents.
+ sCombiningToAccent.append('\u0340', ACCENT_GRAVE);
+ sCombiningToAccent.append('\u0341', ACCENT_ACUTE);
+ sCombiningToAccent.append('\u0343', ACCENT_COMMA_ABOVE);
+
+ // One-way legacy mappings to preserve compatibility with older applications.
+ sAccentToCombining.append(ACCENT_GRAVE_LEGACY, '\u0300');
+ sAccentToCombining.append(ACCENT_CIRCUMFLEX_LEGACY, '\u0302');
+ sAccentToCombining.append(ACCENT_TILDE_LEGACY, '\u0303');
+ }
+
+ private static void addCombining(int combining, int accent) {
+ sCombiningToAccent.append(combining, accent);
+ sAccentToCombining.append(accent, combining);
+ }
+
+ /**
+ * Maps combinations of (display-form) combining key and second character
+ * to combined output character.
+ * These mappings are derived from the Unicode NFC tables as needed.
+ */
+ private static final SparseIntArray sDeadKeyCache = new SparseIntArray();
+ private static final StringBuilder sDeadKeyBuilder = new StringBuilder();
+
public static final Parcelable.Creator<KeyCharacterMap> CREATOR =
new Parcelable.Creator<KeyCharacterMap>() {
public KeyCharacterMap createFromParcel(Parcel in) {
@@ -230,9 +331,9 @@ public class KeyCharacterMap implements Parcelable {
metaState = KeyEvent.normalizeMetaState(metaState);
char ch = nativeGetCharacter(mPtr, keyCode, metaState);
- int map = COMBINING.get(ch);
+ int map = sCombiningToAccent.get(ch);
if (map != 0) {
- return map;
+ return map | COMBINING_ACCENT;
} else {
return ch;
}
@@ -346,7 +447,25 @@ public class KeyCharacterMap implements Parcelable {
* @return The combined character, or 0 if the characters cannot be combined.
*/
public static int getDeadChar(int accent, int c) {
- return DEAD.get((accent << 16) | c);
+ int combining = sAccentToCombining.get(accent);
+ if (combining == 0) {
+ return 0;
+ }
+
+ final int combination = (combining << 16) | c;
+ int combined;
+ synchronized (sDeadKeyCache) {
+ combined = sDeadKeyCache.get(combination, -1);
+ if (combined == -1) {
+ sDeadKeyBuilder.setLength(0);
+ sDeadKeyBuilder.append((char)c);
+ sDeadKeyBuilder.append((char)combining);
+ String result = Normalizer.normalize(sDeadKeyBuilder, Normalizer.Form.NFC);
+ combined = result.length() == 1 ? result.charAt(0) : 0;
+ sDeadKeyCache.put(combination, combined);
+ }
+ }
+ return combined;
}
/**
@@ -560,159 +679,6 @@ public class KeyCharacterMap implements Parcelable {
}
/**
- * Maps Unicode combining diacritical to display-form dead key
- * (display character shifted left 16 bits).
- */
- private static SparseIntArray COMBINING = new SparseIntArray();
-
- /**
- * Maps combinations of (display-form) dead key and second character
- * to combined output character.
- */
- private static SparseIntArray DEAD = new SparseIntArray();
-
- /*
- * TODO: Change the table format to support full 21-bit-wide
- * accent characters and combined characters if ever necessary.
- */
- private static final int ACUTE = '\u00B4' << 16;
- private static final int GRAVE = '`' << 16;
- private static final int CIRCUMFLEX = '^' << 16;
- private static final int TILDE = '~' << 16;
- private static final int UMLAUT = '\u00A8' << 16;
-
- /*
- * This bit will be set in the return value of {@link #get(int, int)} if the
- * key is a "dead key."
- */
- public static final int COMBINING_ACCENT = 0x80000000;
- /**
- * Mask the return value from {@link #get(int, int)} with this value to get
- * a printable representation of the accent character of a "dead key."
- */
- public static final int COMBINING_ACCENT_MASK = 0x7FFFFFFF;
-
- static {
- COMBINING.put('\u0300', (GRAVE >> 16) | COMBINING_ACCENT);
- COMBINING.put('\u0301', (ACUTE >> 16) | COMBINING_ACCENT);
- COMBINING.put('\u0302', (CIRCUMFLEX >> 16) | COMBINING_ACCENT);
- COMBINING.put('\u0303', (TILDE >> 16) | COMBINING_ACCENT);
- COMBINING.put('\u0308', (UMLAUT >> 16) | COMBINING_ACCENT);
-
- DEAD.put(ACUTE | 'A', '\u00C1');
- DEAD.put(ACUTE | 'C', '\u0106');
- DEAD.put(ACUTE | 'E', '\u00C9');
- DEAD.put(ACUTE | 'G', '\u01F4');
- DEAD.put(ACUTE | 'I', '\u00CD');
- DEAD.put(ACUTE | 'K', '\u1E30');
- DEAD.put(ACUTE | 'L', '\u0139');
- DEAD.put(ACUTE | 'M', '\u1E3E');
- DEAD.put(ACUTE | 'N', '\u0143');
- DEAD.put(ACUTE | 'O', '\u00D3');
- DEAD.put(ACUTE | 'P', '\u1E54');
- DEAD.put(ACUTE | 'R', '\u0154');
- DEAD.put(ACUTE | 'S', '\u015A');
- DEAD.put(ACUTE | 'U', '\u00DA');
- DEAD.put(ACUTE | 'W', '\u1E82');
- DEAD.put(ACUTE | 'Y', '\u00DD');
- DEAD.put(ACUTE | 'Z', '\u0179');
- DEAD.put(ACUTE | 'a', '\u00E1');
- DEAD.put(ACUTE | 'c', '\u0107');
- DEAD.put(ACUTE | 'e', '\u00E9');
- DEAD.put(ACUTE | 'g', '\u01F5');
- DEAD.put(ACUTE | 'i', '\u00ED');
- DEAD.put(ACUTE | 'k', '\u1E31');
- DEAD.put(ACUTE | 'l', '\u013A');
- DEAD.put(ACUTE | 'm', '\u1E3F');
- DEAD.put(ACUTE | 'n', '\u0144');
- DEAD.put(ACUTE | 'o', '\u00F3');
- DEAD.put(ACUTE | 'p', '\u1E55');
- DEAD.put(ACUTE | 'r', '\u0155');
- DEAD.put(ACUTE | 's', '\u015B');
- DEAD.put(ACUTE | 'u', '\u00FA');
- DEAD.put(ACUTE | 'w', '\u1E83');
- DEAD.put(ACUTE | 'y', '\u00FD');
- DEAD.put(ACUTE | 'z', '\u017A');
- DEAD.put(CIRCUMFLEX | 'A', '\u00C2');
- DEAD.put(CIRCUMFLEX | 'C', '\u0108');
- DEAD.put(CIRCUMFLEX | 'E', '\u00CA');
- DEAD.put(CIRCUMFLEX | 'G', '\u011C');
- DEAD.put(CIRCUMFLEX | 'H', '\u0124');
- DEAD.put(CIRCUMFLEX | 'I', '\u00CE');
- DEAD.put(CIRCUMFLEX | 'J', '\u0134');
- DEAD.put(CIRCUMFLEX | 'O', '\u00D4');
- DEAD.put(CIRCUMFLEX | 'S', '\u015C');
- DEAD.put(CIRCUMFLEX | 'U', '\u00DB');
- DEAD.put(CIRCUMFLEX | 'W', '\u0174');
- DEAD.put(CIRCUMFLEX | 'Y', '\u0176');
- DEAD.put(CIRCUMFLEX | 'Z', '\u1E90');
- DEAD.put(CIRCUMFLEX | 'a', '\u00E2');
- DEAD.put(CIRCUMFLEX | 'c', '\u0109');
- DEAD.put(CIRCUMFLEX | 'e', '\u00EA');
- DEAD.put(CIRCUMFLEX | 'g', '\u011D');
- DEAD.put(CIRCUMFLEX | 'h', '\u0125');
- DEAD.put(CIRCUMFLEX | 'i', '\u00EE');
- DEAD.put(CIRCUMFLEX | 'j', '\u0135');
- DEAD.put(CIRCUMFLEX | 'o', '\u00F4');
- DEAD.put(CIRCUMFLEX | 's', '\u015D');
- DEAD.put(CIRCUMFLEX | 'u', '\u00FB');
- DEAD.put(CIRCUMFLEX | 'w', '\u0175');
- DEAD.put(CIRCUMFLEX | 'y', '\u0177');
- DEAD.put(CIRCUMFLEX | 'z', '\u1E91');
- DEAD.put(GRAVE | 'A', '\u00C0');
- DEAD.put(GRAVE | 'E', '\u00C8');
- DEAD.put(GRAVE | 'I', '\u00CC');
- DEAD.put(GRAVE | 'N', '\u01F8');
- DEAD.put(GRAVE | 'O', '\u00D2');
- DEAD.put(GRAVE | 'U', '\u00D9');
- DEAD.put(GRAVE | 'W', '\u1E80');
- DEAD.put(GRAVE | 'Y', '\u1EF2');
- DEAD.put(GRAVE | 'a', '\u00E0');
- DEAD.put(GRAVE | 'e', '\u00E8');
- DEAD.put(GRAVE | 'i', '\u00EC');
- DEAD.put(GRAVE | 'n', '\u01F9');
- DEAD.put(GRAVE | 'o', '\u00F2');
- DEAD.put(GRAVE | 'u', '\u00F9');
- DEAD.put(GRAVE | 'w', '\u1E81');
- DEAD.put(GRAVE | 'y', '\u1EF3');
- DEAD.put(TILDE | 'A', '\u00C3');
- DEAD.put(TILDE | 'E', '\u1EBC');
- DEAD.put(TILDE | 'I', '\u0128');
- DEAD.put(TILDE | 'N', '\u00D1');
- DEAD.put(TILDE | 'O', '\u00D5');
- DEAD.put(TILDE | 'U', '\u0168');
- DEAD.put(TILDE | 'V', '\u1E7C');
- DEAD.put(TILDE | 'Y', '\u1EF8');
- DEAD.put(TILDE | 'a', '\u00E3');
- DEAD.put(TILDE | 'e', '\u1EBD');
- DEAD.put(TILDE | 'i', '\u0129');
- DEAD.put(TILDE | 'n', '\u00F1');
- DEAD.put(TILDE | 'o', '\u00F5');
- DEAD.put(TILDE | 'u', '\u0169');
- DEAD.put(TILDE | 'v', '\u1E7D');
- DEAD.put(TILDE | 'y', '\u1EF9');
- DEAD.put(UMLAUT | 'A', '\u00C4');
- DEAD.put(UMLAUT | 'E', '\u00CB');
- DEAD.put(UMLAUT | 'H', '\u1E26');
- DEAD.put(UMLAUT | 'I', '\u00CF');
- DEAD.put(UMLAUT | 'O', '\u00D6');
- DEAD.put(UMLAUT | 'U', '\u00DC');
- DEAD.put(UMLAUT | 'W', '\u1E84');
- DEAD.put(UMLAUT | 'X', '\u1E8C');
- DEAD.put(UMLAUT | 'Y', '\u0178');
- DEAD.put(UMLAUT | 'a', '\u00E4');
- DEAD.put(UMLAUT | 'e', '\u00EB');
- DEAD.put(UMLAUT | 'h', '\u1E27');
- DEAD.put(UMLAUT | 'i', '\u00EF');
- DEAD.put(UMLAUT | 'o', '\u00F6');
- DEAD.put(UMLAUT | 't', '\u1E97');
- DEAD.put(UMLAUT | 'u', '\u00FC');
- DEAD.put(UMLAUT | 'w', '\u1E85');
- DEAD.put(UMLAUT | 'x', '\u1E8D');
- DEAD.put(UMLAUT | 'y', '\u00FF');
- }
-
- /**
* Thrown by {@link KeyCharacterMap#load} when a key character map could not be loaded.
*/
public static class UnavailableException extends AndroidRuntimeException {
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 0ded5f9..bd054bc 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -6359,16 +6359,14 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
public boolean performAccessibilityAction(int action) {
switch (action) {
case AccessibilityNodeInfo.ACTION_CLICK: {
- final long now = SystemClock.uptimeMillis();
- // Send down.
- MotionEvent event = MotionEvent.obtain(now, now, MotionEvent.ACTION_DOWN,
- getWidth() / 2, getHeight() / 2, 0);
- onTouchEvent(event);
- // Send up.
- event.setAction(MotionEvent.ACTION_UP);
- onTouchEvent(event);
- // Clean up.
- event.recycle();
+ if (isClickable()) {
+ performClick();
+ }
+ } break;
+ case AccessibilityNodeInfo.ACTION_LONG_CLICK: {
+ if (isLongClickable()) {
+ performLongClick();
+ }
} break;
case AccessibilityNodeInfo.ACTION_FOCUS: {
if (!hasFocus()) {
@@ -13846,13 +13844,7 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
*/
public Insets getLayoutInsets() {
if (mLayoutInsets == null) {
- if (mBackground == null) {
- mLayoutInsets = Insets.NONE;
- } else {
- Rect insetRect = new Rect();
- boolean hasInsets = mBackground.getLayoutInsets(insetRect);
- mLayoutInsets = hasInsets ? Insets.of(insetRect) : Insets.NONE;
- }
+ mLayoutInsets = (mBackground == null) ? Insets.NONE : mBackground.getLayoutInsets();
}
return mLayoutInsets;
}
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index 6371963..91e945b 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -5792,11 +5792,13 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
throw new IllegalStateException("Instance already recycled.");
}
clear();
- if (sPoolSize < MAX_POOL_SIZE) {
- mNext = sPool;
- mIsPooled = true;
- sPool = this;
- sPoolSize++;
+ synchronized (sPoolLock) {
+ if (sPoolSize < MAX_POOL_SIZE) {
+ mNext = sPool;
+ mIsPooled = true;
+ sPool = this;
+ sPoolSize++;
+ }
}
}
@@ -5889,11 +5891,13 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
throw new IllegalStateException("Instance already recycled.");
}
clear();
- if (sPoolSize < MAX_POOL_SIZE) {
- mNext = sPool;
- mIsPooled = true;
- sPool = this;
- sPoolSize++;
+ synchronized (sPoolLock) {
+ if (sPoolSize < MAX_POOL_SIZE) {
+ mNext = sPool;
+ mIsPooled = true;
+ sPool = this;
+ sPoolSize++;
+ }
}
}
@@ -5943,9 +5947,9 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
if (widthDiference != 0) {
return -widthDiference;
}
- // Return nondeterministically one of them since we do
- // not want to ignore any views.
- return 1;
+ // Just break the tie somehow. The accessibliity ids are unique
+ // and stable, hence this is deterministic tie breaking.
+ return mView.getAccessibilityViewId() - another.mView.getAccessibilityViewId();
}
private void init(ViewGroup root, View view) {
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 1472993..3d40b2f 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -2665,6 +2665,7 @@ public final class ViewRootImpl implements ViewParent,
private final static int MSG_PROCESS_INPUT_EVENTS = 19;
private final static int MSG_DISPATCH_SCREEN_STATE = 20;
private final static int MSG_INVALIDATE_DISPLAY_LIST = 21;
+ private final static int MSG_CLEAR_ACCESSIBILITY_FOCUS_HOST = 22;
final class ViewRootHandler extends Handler {
@Override
@@ -2712,6 +2713,8 @@ public final class ViewRootImpl implements ViewParent,
return "MSG_DISPATCH_SCREEN_STATE";
case MSG_INVALIDATE_DISPLAY_LIST:
return "MSG_INVALIDATE_DISPLAY_LIST";
+ case MSG_CLEAR_ACCESSIBILITY_FOCUS_HOST:
+ return "MSG_CLEAR_ACCESSIBILITY_FOCUS_HOST";
}
return super.getMessageName(message);
}
@@ -2921,6 +2924,9 @@ public final class ViewRootImpl implements ViewParent,
case MSG_INVALIDATE_DISPLAY_LIST: {
invalidateDisplayLists();
} break;
+ case MSG_CLEAR_ACCESSIBILITY_FOCUS_HOST: {
+ setAccessibilityFocusedHost(null);
+ } break;
}
}
}
@@ -5066,7 +5072,7 @@ public final class ViewRootImpl implements ViewParent,
}
} else {
ensureNoConnection();
- setAccessibilityFocusedHost(null);
+ mHandler.obtainMessage(MSG_CLEAR_ACCESSIBILITY_FOCUS_HOST).sendToTarget();
}
}
diff --git a/core/java/android/view/accessibility/AccessibilityNodeInfo.java b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
index 1071c65..c5f2062 100644
--- a/core/java/android/view/accessibility/AccessibilityNodeInfo.java
+++ b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
@@ -84,7 +84,7 @@ public class AccessibilityNodeInfo implements Parcelable {
/**
* Action that gives input focus to the node.
*/
- public static final int ACTION_FOCUS = 0x00000001;
+ public static final int ACTION_FOCUS = 0x00000001;
/**
* Action that clears input focus of the node.
@@ -102,19 +102,24 @@ public class AccessibilityNodeInfo implements Parcelable {
public static final int ACTION_CLEAR_SELECTION = 0x00000008;
/**
- * Action that gives accessibility focus to the node.
+ * Action that clicks on the node info.
*/
- public static final int ACTION_ACCESSIBILITY_FOCUS = 0x00000010;
+ public static final int ACTION_CLICK = 0x00000010;
/**
- * Action that clears accessibility focus of the node.
+ * Action that clicks on the node.
+ */
+ public static final int ACTION_LONG_CLICK = 0x00000020;
+
+ /**
+ * Action that gives accessibility focus to the node.
*/
- public static final int ACTION_CLEAR_ACCESSIBILITY_FOCUS = 0x00000020;
+ public static final int ACTION_ACCESSIBILITY_FOCUS = 0x00000040;
/**
- * Action that clicks on the node info./AccessibilityNodeInfoCache.java
+ * Action that clears accessibility focus of the node.
*/
- public static final int ACTION_CLICK = 0x00000040;
+ public static final int ACTION_CLEAR_ACCESSIBILITY_FOCUS = 0x00000080;
/**
* The input focus.
@@ -278,9 +283,9 @@ public class AccessibilityNodeInfo implements Parcelable {
(root != null) ? root.getAccessibilityViewId() : UNDEFINED;
mSourceNodeId = makeNodeId(rootAccessibilityViewId, virtualDescendantId);
}
-
+
/**
- * Find the view that has the input focus. The search starts from
+ * Find the view that has the specified focus type. The search starts from
* the view represented by this node info.
*
* @param focus The focus to find. One of {@link #FOCUS_INPUT} or
diff --git a/core/java/android/webkit/WebCoreThreadWatchdog.java b/core/java/android/webkit/WebCoreThreadWatchdog.java
index 0541d5d..655db31 100644
--- a/core/java/android/webkit/WebCoreThreadWatchdog.java
+++ b/core/java/android/webkit/WebCoreThreadWatchdog.java
@@ -16,6 +16,7 @@
package android.webkit;
+import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
@@ -146,6 +147,7 @@ class WebCoreThreadWatchdog implements Runnable {
break;
case TIMED_OUT:
+ if ((mContext == null) || !(mContext instanceof Activity)) return;
new AlertDialog.Builder(mContext)
.setMessage(com.android.internal.R.string.webpage_unresponsive)
.setPositiveButton(com.android.internal.R.string.force_close,