diff options
Diffstat (limited to 'core/java')
25 files changed, 305 insertions, 131 deletions
diff --git a/core/java/android/accessibilityservice/AccessibilityServiceInfo.java b/core/java/android/accessibilityservice/AccessibilityServiceInfo.java index 40f45b7..de58a33 100644 --- a/core/java/android/accessibilityservice/AccessibilityServiceInfo.java +++ b/core/java/android/accessibilityservice/AccessibilityServiceInfo.java @@ -444,8 +444,8 @@ public class AccessibilityServiceInfo implements Parcelable { mCapabilities |= CAPABILITY_CAN_REQUEST_TOUCH_EXPLORATION; } if (asAttributes.getBoolean(com.android.internal.R.styleable - .AccessibilityService_canRequestEnhancedWebAccessibility, false)) { - mCapabilities |= CAPABILITY_CAN_REQUEST_ENHANCED_WEB_ACCESSIBILITY; + .AccessibilityService_canRequestEnhancedWebAccessibility, false)) { + mCapabilities |= CAPABILITY_CAN_REQUEST_ENHANCED_WEB_ACCESSIBILITY; } if (asAttributes.getBoolean(com.android.internal.R.styleable .AccessibilityService_canRequestFilterKeyEvents, false)) { @@ -557,6 +557,23 @@ public class AccessibilityServiceInfo implements Parcelable { } /** + * Sets the bit mask of capabilities this accessibility service has such as + * being able to retrieve the active window content, etc. + * + * @param capabilities The capability bit mask. + * + * @see #CAPABILITY_CAN_RETRIEVE_WINDOW_CONTENT + * @see #CAPABILITY_CAN_REQUEST_TOUCH_EXPLORATION + * @see #CAPABILITY_CAN_REQUEST_ENHANCED_WEB_ACCESSIBILITY + * @see #CAPABILITY_FILTER_KEY_EVENTS + * + * @hide + */ + public void setCapabilities(int capabilities) { + mCapabilities = capabilities; + } + + /** * Gets the non-localized description of the accessibility service. * <p> * <strong>Statically set from diff --git a/core/java/android/app/INotificationManager.aidl b/core/java/android/app/INotificationManager.aidl index 92ec3ad..9f933ca 100644 --- a/core/java/android/app/INotificationManager.aidl +++ b/core/java/android/app/INotificationManager.aidl @@ -44,6 +44,8 @@ interface INotificationManager void registerListener(in INotificationListener listener, in ComponentName component, int userid); void unregisterListener(in INotificationListener listener, int userid); - void clearNotificationFromListener(in INotificationListener token, String pkg, String tag, int id); - void clearAllNotificationsFromListener(in INotificationListener token); + void cancelNotificationFromListener(in INotificationListener token, String pkg, String tag, int id); + void cancelAllNotificationsFromListener(in INotificationListener token); + + StatusBarNotification[] getActiveNotificationsFromListener(in INotificationListener token); }
\ No newline at end of file diff --git a/core/java/android/app/UiAutomation.java b/core/java/android/app/UiAutomation.java index 05b79c1..498fa42 100644 --- a/core/java/android/app/UiAutomation.java +++ b/core/java/android/app/UiAutomation.java @@ -443,18 +443,25 @@ public final class UiAutomation { */ public AccessibilityEvent executeAndWaitForEvent(Runnable command, AccessibilityEventFilter filter, long timeoutMillis) throws TimeoutException { + // Acquire the lock and prepare for receiving events. synchronized (mLock) { throwIfNotConnectedLocked(); - mEventQueue.clear(); // Prepare to wait for an event. mWaitingForEventDelivery = true; + } - // We will ignore events from previous interactions. - final long executionStartTimeMillis = SystemClock.uptimeMillis(); + // Note: We have to release the lock since calling out with this lock held + // can bite. We will correctly filter out events from other interactions, + // so starting to collect events before running the action is just fine. - // Execute the command. - command.run(); + // We will ignore events from previous interactions. + final long executionStartTimeMillis = SystemClock.uptimeMillis(); + // Execute the command *without* the lock being held. + command.run(); + + // Acquire the lock and wait for the event. + synchronized (mLock) { try { // Wait for the event. final long startTimeMillis = SystemClock.uptimeMillis(); @@ -463,7 +470,7 @@ public final class UiAutomation { while (!mEventQueue.isEmpty()) { AccessibilityEvent event = mEventQueue.remove(0); // Ignore events from previous interactions. - if (event.getEventTime() <= executionStartTimeMillis) { + if (event.getEventTime() < executionStartTimeMillis) { continue; } if (filter.accept(event)) { diff --git a/core/java/android/app/UiAutomationConnection.java b/core/java/android/app/UiAutomationConnection.java index 97c7ff3..607930c 100644 --- a/core/java/android/app/UiAutomationConnection.java +++ b/core/java/android/app/UiAutomationConnection.java @@ -163,6 +163,10 @@ public final class UiAutomationConnection extends IUiAutomationConnection.Stub { info.feedbackType = AccessibilityServiceInfo.FEEDBACK_GENERIC; info.flags |= AccessibilityServiceInfo.FLAG_INCLUDE_NOT_IMPORTANT_VIEWS | AccessibilityServiceInfo.FLAG_REPORT_VIEW_IDS; + info.setCapabilities(AccessibilityServiceInfo.CAPABILITY_CAN_RETRIEVE_WINDOW_CONTENT + | AccessibilityServiceInfo.CAPABILITY_CAN_REQUEST_TOUCH_EXPLORATION + | AccessibilityServiceInfo.CAPABILITY_CAN_REQUEST_ENHANCED_WEB_ACCESSIBILITY + | AccessibilityServiceInfo.CAPABILITY_CAN_REQUEST_FILTER_KEY_EVENTS); try { // Calling out with a lock held is fine since if the system // process is gone the client calling in will be killed. diff --git a/core/java/android/bluetooth/BluetoothAdapter.java b/core/java/android/bluetooth/BluetoothAdapter.java index 3498bb8..cfbfb48 100644 --- a/core/java/android/bluetooth/BluetoothAdapter.java +++ b/core/java/android/bluetooth/BluetoothAdapter.java @@ -1434,7 +1434,7 @@ public final class BluetoothAdapter { * <p>Results of the scan are reported using the * {@link LeScanCallback#onLeScan} callback. * - * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. + * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN} permission. * * @param callback the callback LE scan results are delivered * @return true, if the scan was started successfully @@ -1450,7 +1450,7 @@ public final class BluetoothAdapter { * <p>Devices which advertise all specified services are reported using the * {@link LeScanCallback#onLeScan} callback. * - * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. + * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN} permission. * * @param serviceUuids Array of services to look for * @param callback the callback LE scan results are delivered @@ -1490,7 +1490,7 @@ public final class BluetoothAdapter { /** * Stops an ongoing Bluetooth LE device scan. * - * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. + * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN} permission. * * @param callback used to identify which scan to stop * must be the same handle used to start the scan diff --git a/core/java/android/bluetooth/BluetoothOutputStream.java b/core/java/android/bluetooth/BluetoothOutputStream.java index 62242a2..117dd47 100644 --- a/core/java/android/bluetooth/BluetoothOutputStream.java +++ b/core/java/android/bluetooth/BluetoothOutputStream.java @@ -84,4 +84,15 @@ import java.io.OutputStream; } mSocket.write(b, offset, count); } + /** + * Wait until the data in sending queue is emptied. A polling version + * for flush implementation. Use it to ensure the writing data afterwards will + * be packed in the new RFCOMM frame. + * @throws IOException + * if an i/o error occurs. + * @since Android 4.2.3 + */ + public void flush() throws IOException { + mSocket.flush(); + } } diff --git a/core/java/android/bluetooth/BluetoothSocket.java b/core/java/android/bluetooth/BluetoothSocket.java index 8029a1a..a19341c 100644 --- a/core/java/android/bluetooth/BluetoothSocket.java +++ b/core/java/android/bluetooth/BluetoothSocket.java @@ -192,6 +192,7 @@ public final class BluetoothSocket implements Closeable { if (VDBG) Log.d(TAG, "socket fd passed by stack fds: " + fds); if(fds == null || fds.length != 1) { Log.e(TAG, "socket fd passed from stack failed, fds: " + fds); + as.close(); throw new IOException("bt socket acept failed"); } as.mSocket = new LocalSocket(fds[0]); @@ -407,6 +408,17 @@ public final class BluetoothSocket implements Closeable { if (VDBG) Log.d(TAG, "available: " + mSocketIS); return mSocketIS.available(); } + /** + * Wait until the data in sending queue is emptied. A polling version + * for flush implementation. Used to ensure the writing data afterwards will + * be packed in new RFCOMM frame. + * @throws IOException + * if an i/o error occurs. + */ + /*package*/ void flush() throws IOException { + if (VDBG) Log.d(TAG, "flush: " + mSocketOS); + mSocketOS.flush(); + } /*package*/ int read(byte[] b, int offset, int length) throws IOException { diff --git a/core/java/android/content/RestrictionEntry.java b/core/java/android/content/RestrictionEntry.java index af90385..217cf76 100644 --- a/core/java/android/content/RestrictionEntry.java +++ b/core/java/android/content/RestrictionEntry.java @@ -60,6 +60,7 @@ public class RestrictionEntry implements Parcelable { * and the corresponding values, respectively. * The presentation could imply that values in lower array indices are included when a * particular value is chosen. + * @hide */ public static final int TYPE_CHOICE_LEVEL = 3; @@ -102,7 +103,7 @@ public class RestrictionEntry implements Parcelable { private String[] currentValues; /** - * Constructor for {@link #TYPE_CHOICE} and {@link #TYPE_CHOICE_LEVEL} types. + * Constructor for {@link #TYPE_CHOICE} type. * @param key the unique key for this restriction * @param selectedString the current value */ @@ -206,7 +207,7 @@ public class RestrictionEntry implements Parcelable { * shown to the user. Values will be chosen from this list as the user's selection and the * selected values can be retrieved by a call to {@link #getAllSelectedStrings()}, or * {@link #getSelectedString()}, depending on whether it is a multi-select type or choice type. - * This method is not relevant for types other than {@link #TYPE_CHOICE_LEVEL}, + * This method is not relevant for types other than * {@link #TYPE_CHOICE}, and {@link #TYPE_MULTI_SELECT}. * @param choiceValues an array of Strings which will be the selected values for the user's * selections. @@ -241,7 +242,7 @@ public class RestrictionEntry implements Parcelable { * user selects one or more of these choices, the corresponding value from the possible values * are stored as the selected strings. The size of this array must match the size of the array * set in {@link #setChoiceValues(String[])}. This method is not relevant for types other - * than {@link #TYPE_CHOICE_LEVEL}, {@link #TYPE_CHOICE}, and {@link #TYPE_MULTI_SELECT}. + * than {@link #TYPE_CHOICE}, and {@link #TYPE_MULTI_SELECT}. * @param choiceEntries the list of user-visible choices. * @see #setChoiceValues(String[]) */ diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java index 30bdfef..4266d85 100644 --- a/core/java/android/content/pm/PackageManager.java +++ b/core/java/android/content/pm/PackageManager.java @@ -870,6 +870,14 @@ public abstract class PackageManager { /** * Feature for {@link #getSystemAvailableFeatures} and + * {@link #hasSystemFeature}: The device is capable of communicating with + * other devices via Bluetooth Low Energy radio. + */ + @SdkConstant(SdkConstantType.FEATURE) + public static final String FEATURE_BLUETOOTH_LE = "android.hardware.bluetooth_le"; + + /** + * Feature for {@link #getSystemAvailableFeatures} and * {@link #hasSystemFeature}: The device has a camera facing away * from the screen. */ diff --git a/core/java/android/hardware/location/GeofenceHardwareImpl.java b/core/java/android/hardware/location/GeofenceHardwareImpl.java index a62b660..e3362a7 100644 --- a/core/java/android/hardware/location/GeofenceHardwareImpl.java +++ b/core/java/android/hardware/location/GeofenceHardwareImpl.java @@ -48,11 +48,11 @@ public final class GeofenceHardwareImpl { private final Context mContext; private static GeofenceHardwareImpl sInstance; private PowerManager.WakeLock mWakeLock; - private SparseArray<IGeofenceHardwareCallback> mGeofences = + private final SparseArray<IGeofenceHardwareCallback> mGeofences = new SparseArray<IGeofenceHardwareCallback>(); - private ArrayList<IGeofenceHardwareMonitorCallback>[] mCallbacks = + private final ArrayList<IGeofenceHardwareMonitorCallback>[] mCallbacks = new ArrayList[GeofenceHardware.NUM_MONITORS]; - private ArrayList<Reaper> mReapers = new ArrayList<Reaper>(); + private final ArrayList<Reaper> mReapers = new ArrayList<Reaper>(); private IGpsGeofenceHardware mGpsService; @@ -64,9 +64,7 @@ public final class GeofenceHardwareImpl { private static final int REMOVE_GEOFENCE_CALLBACK = 3; private static final int PAUSE_GEOFENCE_CALLBACK = 4; private static final int RESUME_GEOFENCE_CALLBACK = 5; - private static final int ADD_GEOFENCE = 6; - private static final int REMOVE_GEOFENCE = 7; - private static final int GEOFENCE_CALLBACK_BINDER_DIED = 8; + private static final int GEOFENCE_CALLBACK_BINDER_DIED = 6; // mCallbacksHandler message types private static final int GPS_GEOFENCE_STATUS = 1; @@ -186,17 +184,22 @@ public final class GeofenceHardwareImpl { // This API is not thread safe. Operations on the same geofence need to be serialized // by upper layers if (DEBUG) { - Log.d(TAG, "addCircularFence: GeofenceId: " + geofenceId + "Latitude: " + latitude + - "Longitude: " + longitude + "Radius: " + radius + "LastTransition: " - + lastTransition + "MonitorTransition: " + monitorTransitions + - "NotificationResponsiveness: " + notificationResponsivenes + - "UnKnown Timer: " + unknownTimer + "MonitoringType: " + monitoringType); + Log.d(TAG, "addCircularFence: GeofenceId: " + geofenceId + " Latitude: " + latitude + + " Longitude: " + longitude + " Radius: " + radius + " LastTransition: " + + lastTransition + " MonitorTransition: " + monitorTransitions + + " NotificationResponsiveness: " + notificationResponsivenes + + " UnKnown Timer: " + unknownTimer + " MonitoringType: " + monitoringType); } boolean result; - Message m = mGeofenceHandler.obtainMessage(ADD_GEOFENCE, callback); - m.arg1 = geofenceId; - mGeofenceHandler.sendMessage(m); + + // The callback must be added before addCircularHardwareGeofence is called otherwise the + // callback might not be called after the geofence is added in the geofence hardware. + // This also means that the callback must be removed if the addCircularHardwareGeofence + // operations is not called or fails. + synchronized (mGeofences) { + mGeofences.put(geofenceId, callback); + } switch (monitoringType) { case GeofenceHardware.MONITORING_TYPE_GPS_HARDWARE: @@ -214,13 +217,13 @@ public final class GeofenceHardwareImpl { result = false; } if (result) { - m = mReaperHandler.obtainMessage(REAPER_GEOFENCE_ADDED, callback); + Message m = mReaperHandler.obtainMessage(REAPER_GEOFENCE_ADDED, callback); m.arg1 = monitoringType; mReaperHandler.sendMessage(m); } else { - m = mGeofenceHandler.obtainMessage(REMOVE_GEOFENCE); - m.arg1 = geofenceId; - mGeofenceHandler.sendMessage(m); + synchronized (mGeofences) { + mGeofences.remove(geofenceId); + } } if (DEBUG) Log.d(TAG, "addCircularFence: Result is: " + result); @@ -232,6 +235,12 @@ public final class GeofenceHardwareImpl { // by upper layers if (DEBUG) Log.d(TAG, "Remove Geofence: GeofenceId: " + geofenceId); boolean result = false; + + synchronized (mGeofences) { + if (mGeofences.get(geofenceId) == null) { + throw new IllegalArgumentException("Geofence " + geofenceId + " not registered."); + } + } switch (monitoringType) { case GeofenceHardware.MONITORING_TYPE_GPS_HARDWARE: if (mGpsService == null) return false; @@ -254,6 +263,11 @@ public final class GeofenceHardwareImpl { // by upper layers if (DEBUG) Log.d(TAG, "Pause Geofence: GeofenceId: " + geofenceId); boolean result; + synchronized (mGeofences) { + if (mGeofences.get(geofenceId) == null) { + throw new IllegalArgumentException("Geofence " + geofenceId + " not registered."); + } + } switch (monitoringType) { case GeofenceHardware.MONITORING_TYPE_GPS_HARDWARE: if (mGpsService == null) return false; @@ -277,6 +291,11 @@ public final class GeofenceHardwareImpl { // by upper layers if (DEBUG) Log.d(TAG, "Resume Geofence: GeofenceId: " + geofenceId); boolean result; + synchronized (mGeofences) { + if (mGeofences.get(geofenceId) == null) { + throw new IllegalArgumentException("Geofence " + geofenceId + " not registered."); + } + } switch (monitoringType) { case GeofenceHardware.MONITORING_TYPE_GPS_HARDWARE: if (mGpsService == null) return false; @@ -446,18 +465,11 @@ public final class GeofenceHardwareImpl { int status; IGeofenceHardwareCallback callback; switch (msg.what) { - case ADD_GEOFENCE: - geofenceId = msg.arg1; - callback = (IGeofenceHardwareCallback) msg.obj; - mGeofences.put(geofenceId, callback); - break; - case REMOVE_GEOFENCE: - geofenceId = msg.arg1; - mGeofences.remove(geofenceId); - break; case ADD_GEOFENCE_CALLBACK: geofenceId = msg.arg1; - callback = mGeofences.get(geofenceId); + synchronized (mGeofences) { + callback = mGeofences.get(geofenceId); + } if (callback == null) return; try { @@ -467,19 +479,25 @@ public final class GeofenceHardwareImpl { break; case REMOVE_GEOFENCE_CALLBACK: geofenceId = msg.arg1; - callback = mGeofences.get(geofenceId); + synchronized (mGeofences) { + callback = mGeofences.get(geofenceId); + } if (callback == null) return; try { callback.onGeofenceRemove(geofenceId, msg.arg2); } catch (RemoteException e) {} - mGeofences.remove(geofenceId); + synchronized (mGeofences) { + mGeofences.remove(geofenceId); + } releaseWakeLock(); break; case PAUSE_GEOFENCE_CALLBACK: geofenceId = msg.arg1; - callback = mGeofences.get(geofenceId); + synchronized (mGeofences) { + callback = mGeofences.get(geofenceId); + } if (callback == null) return; try { @@ -490,7 +508,9 @@ public final class GeofenceHardwareImpl { case RESUME_GEOFENCE_CALLBACK: geofenceId = msg.arg1; - callback = mGeofences.get(geofenceId); + synchronized (mGeofences) { + callback = mGeofences.get(geofenceId); + } if (callback == null) return; try { @@ -501,12 +521,14 @@ public final class GeofenceHardwareImpl { case GEOFENCE_TRANSITION_CALLBACK: GeofenceTransition geofenceTransition = (GeofenceTransition)(msg.obj); - callback = mGeofences.get(geofenceTransition.mGeofenceId); + synchronized (mGeofences) { + callback = mGeofences.get(geofenceTransition.mGeofenceId); + } if (DEBUG) Log.d(TAG, "GeofenceTransistionCallback: GPS : GeofenceId: " + geofenceTransition.mGeofenceId + - "Transition: " + geofenceTransition.mTransition + - "Location: " + geofenceTransition.mLocation + ":" + mGeofences); + " Transition: " + geofenceTransition.mTransition + + " Location: " + geofenceTransition.mLocation + ":" + mGeofences); try { callback.onGeofenceTransition( @@ -521,12 +543,14 @@ public final class GeofenceHardwareImpl { callback = (IGeofenceHardwareCallback) (msg.obj); if (DEBUG) Log.d(TAG, "Geofence callback reaped:" + callback); int monitoringType = msg.arg1; - for (int i = 0; i < mGeofences.size(); i++) { - if (mGeofences.valueAt(i).equals(callback)) { - geofenceId = mGeofences.keyAt(i); - removeGeofence(mGeofences.keyAt(i), monitoringType); - mGeofences.remove(geofenceId); - } + synchronized (mGeofences) { + for (int i = 0; i < mGeofences.size(); i++) { + if (mGeofences.valueAt(i).equals(callback)) { + geofenceId = mGeofences.keyAt(i); + removeGeofence(mGeofences.keyAt(i), monitoringType); + mGeofences.remove(geofenceId); + } + } } } } diff --git a/core/java/android/net/LocalSocketImpl.java b/core/java/android/net/LocalSocketImpl.java index 6c36a7d..8e129cb 100644 --- a/core/java/android/net/LocalSocketImpl.java +++ b/core/java/android/net/LocalSocketImpl.java @@ -136,8 +136,28 @@ class LocalSocketImpl write_native(b, myFd); } } + + /** + * Wait until the data in sending queue is emptied. A polling version + * for flush implementation. + * @throws IOException + * if an i/o error occurs. + */ + @Override + public void flush() throws IOException { + FileDescriptor myFd = fd; + if (myFd == null) throw new IOException("socket closed"); + while(pending_native(fd) > 0) { + try { + Thread.sleep(10); + } catch (InterruptedException ie) { + return; + } + } + } } + private native int pending_native(FileDescriptor fd) throws IOException; private native int available_native(FileDescriptor fd) throws IOException; private native void close_native(FileDescriptor fd) throws IOException; private native int read_native(FileDescriptor fd) throws IOException; diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java index df065e9..cb5ed4f 100644 --- a/core/java/android/os/UserManager.java +++ b/core/java/android/os/UserManager.java @@ -202,6 +202,7 @@ public class UserManager { * Used to check if the user making this call is linked to another user. Linked users may have * a reduced number of available apps, app restrictions and account restrictions. * @return whether the user making this call is a linked user + * @hide */ public boolean isLinkedUser() { try { diff --git a/core/java/android/service/notification/NotificationListenerService.java b/core/java/android/service/notification/NotificationListenerService.java index 8b72ca9..bfea9ca 100644 --- a/core/java/android/service/notification/NotificationListenerService.java +++ b/core/java/android/service/notification/NotificationListenerService.java @@ -25,6 +25,20 @@ import android.os.IBinder; import android.os.ServiceManager; import android.util.Log; +/** + * A service that receives calls from the system when new notifications are posted or removed. + * <p>To extend this class, you must declare the service in your manifest file with + * the {@link android.Manifest.permission#BIND_NOTIFICATION_LISTENER_SERVICE} permission + * and include an intent filter with the {@link #SERVICE_INTERFACE} action. For example:</p> + * <pre> + * <service android:name=".NotificationListener" + * android:label="@string/service_name" + * android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE"> + * <intent-filter> + * <action android:name="android.service.notification.NotificationListenerService" /> + * </intent-filter> + * </service></pre> + */ public abstract class NotificationListenerService extends Service { // TAG = "NotificationListenerService[MySubclass]" private final String TAG = NotificationListenerService.class.getSimpleName() @@ -57,7 +71,7 @@ public abstract class NotificationListenerService extends Service { * notification listener) or because the app has withdrawn the notification. * <P> * NOTE: The {@link StatusBarNotification} object you receive will be "light"; that is, the - * {@link StatusBarNotification#notification} member may be missing some heavyweight + * result from {@link StatusBarNotification#getNotification} may be missing some heavyweight * fields such as {@link android.app.Notification#contentView} and * {@link android.app.Notification#largeIcon}. However, all other fields on * {@link StatusBarNotification}, sufficient to match this call with a prior call to @@ -97,9 +111,9 @@ public abstract class NotificationListenerService extends Service { * @param id ID of the notification as specified by the notifying app in * {@link android.app.NotificationManager#notify(String, int, android.app.Notification)}. */ - public final void clearNotification(String pkg, String tag, int id) { + public final void cancelNotification(String pkg, String tag, int id) { try { - getNotificationInterface().clearNotificationFromListener(mWrapper, pkg, tag, id); + getNotificationInterface().cancelNotificationFromListener(mWrapper, pkg, tag, id); } catch (android.os.RemoteException ex) { Log.v(TAG, "Unable to contact notification manager", ex); } @@ -114,14 +128,29 @@ public abstract class NotificationListenerService extends Service { * upon being informed, the notification manager will actually remove all active notifications * and you will get multiple {@link #onNotificationRemoved(StatusBarNotification)} callbacks. * - * {@see #clearNotification(String, String, int)} + * {@see #cancelNotification(String, String, int)} + */ + public final void cancelAllNotifications() { + try { + getNotificationInterface().cancelAllNotificationsFromListener(mWrapper); + } catch (android.os.RemoteException ex) { + Log.v(TAG, "Unable to contact notification manager", ex); + } + } + + /** + * Request the list of outstanding notifications (that is, those that are visible to the + * current user). Useful when starting up and you don't know what's already been posted. + * + * @return An array of active notifications. */ - public final void clearAllNotifications() { + public StatusBarNotification[] getActiveNotifications() { try { - getNotificationInterface().clearAllNotificationsFromListener(mWrapper); + return getNotificationInterface().getActiveNotificationsFromListener(mWrapper); } catch (android.os.RemoteException ex) { Log.v(TAG, "Unable to contact notification manager", ex); } + return null; } @Override diff --git a/core/java/android/service/notification/StatusBarNotification.java b/core/java/android/service/notification/StatusBarNotification.java index 006518c..e8cc24b 100644 --- a/core/java/android/service/notification/StatusBarNotification.java +++ b/core/java/android/service/notification/StatusBarNotification.java @@ -26,35 +26,21 @@ import android.os.UserHandle; * the status bar and any {@link android.service.notification.NotificationListenerService}s. */ public class StatusBarNotification implements Parcelable { - /** The package of the app that posted the notification. */ - public final String pkg; - /** The id supplied to {@link android.app.NotificationManager#notify}. */ - public final int id; - /** The tag supplied to {@link android.app.NotificationManager#notify}, or null if no tag - * was specified. */ - public final String tag; + private final String pkg; + private final int id; + private final String tag; - /** The notifying app's calling uid. @hide */ - public final int uid; - /** The notifying app's base package. @hide */ - public final String basePkg; - /** @hide */ - public final int initialPid; + private final int uid; + private final String basePkg; + private final int initialPid; // TODO: make this field private and move callers to an accessor that // ensures sourceUser is applied. - /** The {@link android.app.Notification} supplied to - * {@link android.app.NotificationManager#notify}. */ - public final Notification notification; - /** The {@link android.os.UserHandle} for whom this notification is intended. */ - public final UserHandle user; - /** The time (in {@link System#currentTimeMillis} time) the notification was posted, - * which may be different than {@link android.app.Notification#when}. - */ - public final long postTime; + private final Notification notification; + private final UserHandle user; + private final long postTime; - /** @hide */ - public final int score; + private final int score; /** This is temporarily needed for the JB MR1 PDK. * @hide */ @@ -198,4 +184,61 @@ public class StatusBarNotification implements Parcelable { public int getUserId() { return this.user.getIdentifier(); } + + /** The package of the app that posted the notification. */ + public String getPackageName() { + return pkg; + } + + /** The id supplied to {@link android.app.NotificationManager#notify}. */ + public int getId() { + return id; + } + + /** The tag supplied to {@link android.app.NotificationManager#notify}, or null if no tag + * was specified. */ + public String getTag() { + return tag; + } + + /** The notifying app's calling uid. @hide */ + public int getUid() { + return uid; + } + + /** The notifying app's base package. @hide */ + public String getBasePkg() { + return basePkg; + } + + /** @hide */ + public int getInitialPid() { + return initialPid; + } + + /** The {@link android.app.Notification} supplied to + * {@link android.app.NotificationManager#notify}. */ + public Notification getNotification() { + return notification; + } + + /** + * The {@link android.os.UserHandle} for whom this notification is intended. + * @hide + */ + public UserHandle getUser() { + return user; + } + + /** The time (in {@link System#currentTimeMillis} time) the notification was posted, + * which may be different than {@link android.app.Notification#when}. + */ + public long getPostTime() { + return postTime; + } + + /** @hide */ + public int getScore() { + return score; + } } diff --git a/core/java/android/view/InputDevice.java b/core/java/android/view/InputDevice.java index 2595ee5..2a761c1 100644 --- a/core/java/android/view/InputDevice.java +++ b/core/java/android/view/InputDevice.java @@ -533,7 +533,6 @@ public final class InputDevice implements Parcelable { * * @see MotionEvent#AXIS_X * @see MotionEvent#AXIS_Y - * @see #getSupportedAxes() */ public MotionRange getMotionRange(int axis) { final int numRanges = mMotionRanges.size(); @@ -559,7 +558,6 @@ public final class InputDevice implements Parcelable { * * @see MotionEvent#AXIS_X * @see MotionEvent#AXIS_Y - * @see #getSupportedAxes() */ public MotionRange getMotionRange(int axis, int source) { final int numRanges = mMotionRanges.size(); diff --git a/core/java/android/view/InputEvent.java b/core/java/android/view/InputEvent.java index 24c3128..07a937c 100644 --- a/core/java/android/view/InputEvent.java +++ b/core/java/android/view/InputEvent.java @@ -70,7 +70,6 @@ public abstract class InputEvent implements Parcelable { * Gets the source of the event. * * @return The event source or {@link InputDevice#SOURCE_UNKNOWN} if unknown. - * @see InputDevice#getSourceInfo */ public abstract int getSource(); diff --git a/core/java/android/view/KeyEvent.java b/core/java/android/view/KeyEvent.java index 7d9f30a..0546d24 100644 --- a/core/java/android/view/KeyEvent.java +++ b/core/java/android/view/KeyEvent.java @@ -2822,7 +2822,7 @@ public class KeyEvent extends InputEvent implements Parcelable { * * @param symbolicName The symbolic name of the keycode. * @return The keycode or {@link #KEYCODE_UNKNOWN} if not found. - * @see #keycodeToString + * @see #keycodeToString(int) */ public static int keyCodeFromString(String symbolicName) { if (symbolicName == null) { diff --git a/core/java/android/view/MotionEvent.java b/core/java/android/view/MotionEvent.java index 78fa2d7..ee36097 100644 --- a/core/java/android/view/MotionEvent.java +++ b/core/java/android/view/MotionEvent.java @@ -1947,8 +1947,6 @@ public final class MotionEvent extends InputEvent implements Parcelable { * @see #TOOL_TYPE_FINGER * @see #TOOL_TYPE_STYLUS * @see #TOOL_TYPE_MOUSE - * @see #TOOL_TYPE_INDIRECT_FINGER - * @see #TOOL_TYPE_INDIRECT_STYLUS */ public final int getToolType(int pointerIndex) { return nativeGetToolType(mNativePtr, pointerIndex); @@ -2190,7 +2188,7 @@ public final class MotionEvent extends InputEvent implements Parcelable { * on the screen, before it had been adjusted for the containing window * and views. * - * @see getX() + * @see #getX(int) * @see #AXIS_X */ public final float getRawX() { @@ -2203,7 +2201,7 @@ public final class MotionEvent extends InputEvent implements Parcelable { * on the screen, before it had been adjusted for the containing window * and views. * - * @see getY() + * @see #getY(int) * @see #AXIS_Y */ public final float getRawY() { @@ -3063,7 +3061,7 @@ public final class MotionEvent extends InputEvent implements Parcelable { * * @param symbolicName The symbolic name of the axis. * @return The axis or -1 if not found. - * @see #keycodeToString + * @see KeyEvent#keycodeToString(int) */ public static int axisFromString(String symbolicName) { if (symbolicName == null) { diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index 11e392d..0938bb3 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -6617,12 +6617,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * @hide */ public void clearAccessibilityFocus() { - if ((mPrivateFlags2 & PFLAG2_ACCESSIBILITY_FOCUSED) != 0) { - mPrivateFlags2 &= ~PFLAG2_ACCESSIBILITY_FOCUSED; - invalidate(); - sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED); - notifyAccessibilityStateChanged(); - } + clearAccessibilityFocusNoCallbacks(); // Clear the global reference of accessibility focus if this // view or any of its descendants had accessibility focus. ViewRootImpl viewRootImpl = getViewRootImpl(); @@ -6669,6 +6664,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback, if ((mPrivateFlags2 & PFLAG2_ACCESSIBILITY_FOCUSED) != 0) { mPrivateFlags2 &= ~PFLAG2_ACCESSIBILITY_FOCUSED; invalidate(); + sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED); + notifyAccessibilityStateChanged(); } } @@ -8231,7 +8228,10 @@ public class View implements Drawable.Callback, KeyEvent.Callback, // in onHoverEvent. // Note that onGenericMotionEvent will be called by default when // onHoverEvent returns false (refer to dispatchGenericMotionEvent). - return dispatchGenericMotionEventInternal(event); + dispatchGenericMotionEventInternal(event); + // The event was already handled by calling setHovered(), so always + // return true. + return true; } return false; @@ -8696,7 +8696,12 @@ public class View implements Drawable.Callback, KeyEvent.Callback, /** * Change the view's z order in the tree, so it's on top of other sibling - * views + * views. This ordering change may affect layout, if the parent container + * uses an order-dependent layout scheme (e.g., LinearLayout). This + * method should be followed by calls to {@link #requestLayout()} and + * {@link View#invalidate()} on the parent. + * + * @see ViewGroup#bringChildToFront(View) */ public void bringToFront() { if (mParent != null) { @@ -13785,7 +13790,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } if ((flags & ViewGroup.FLAG_CLIP_CHILDREN) == ViewGroup.FLAG_CLIP_CHILDREN && - !useDisplayListProperties && layerType == LAYER_TYPE_NONE) { + !useDisplayListProperties && cache == null) { if (offsetForScroll) { canvas.clipRect(sx, sy, sx + (mRight - mLeft), sy + (mBottom - mTop)); } else { diff --git a/core/java/android/view/ViewParent.java b/core/java/android/view/ViewParent.java index 4b70bc0..d79aa7e 100644 --- a/core/java/android/view/ViewParent.java +++ b/core/java/android/view/ViewParent.java @@ -146,9 +146,13 @@ public interface ViewParent { public View focusSearch(View v, int direction); /** - * Change the z order of the child so it's on top of all other children + * Change the z order of the child so it's on top of all other children. + * This ordering change may affect layout, if this container + * uses an order-dependent layout scheme (e.g., LinearLayout). This + * method should be followed by calls to {@link #requestLayout()} and + * {@link View#invalidate()} on this parent. * - * @param child + * @param child The child to bring to the top of the z order */ public void bringChildToFront(View child); diff --git a/core/java/android/view/accessibility/AccessibilityNodeInfoCache.java b/core/java/android/view/accessibility/AccessibilityNodeInfoCache.java index 14954be..28518aa 100644 --- a/core/java/android/view/accessibility/AccessibilityNodeInfoCache.java +++ b/core/java/android/view/accessibility/AccessibilityNodeInfoCache.java @@ -83,6 +83,7 @@ public class AccessibilityNodeInfoCache { } break; case AccessibilityEvent.TYPE_VIEW_FOCUSED: case AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED: + case AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED: case AccessibilityEvent.TYPE_VIEW_SELECTED: case AccessibilityEvent.TYPE_VIEW_TEXT_CHANGED: case AccessibilityEvent.TYPE_VIEW_TEXT_SELECTION_CHANGED: { diff --git a/core/java/android/webkit/BrowserFrame.java b/core/java/android/webkit/BrowserFrame.java index c111a52..ce886f2 100644 --- a/core/java/android/webkit/BrowserFrame.java +++ b/core/java/android/webkit/BrowserFrame.java @@ -757,13 +757,16 @@ class BrowserFrame extends Handler { return null; } } else if (url.startsWith(ANDROID_ASSET)) { - url = url.replaceFirst(ANDROID_ASSET, ""); + String assetUrl = url.replaceFirst(ANDROID_ASSET, ""); try { AssetManager assets = mContext.getAssets(); - Uri uri = Uri.parse(url); + Uri uri = Uri.parse(assetUrl); return assets.open(uri.getPath(), AssetManager.ACCESS_STREAMING); } catch (IOException e) { return null; + } catch (Exception e) { + Log.w(LOGTAG, "Problem loading url: " + url, e); + return null; } } else if (mSettings.getAllowContentAccess() && url.startsWith(ANDROID_CONTENT)) { diff --git a/core/java/android/widget/ProgressBar.java b/core/java/android/widget/ProgressBar.java index d816200..5392a96 100644 --- a/core/java/android/widget/ProgressBar.java +++ b/core/java/android/widget/ProgressBar.java @@ -184,6 +184,7 @@ import java.util.ArrayList; * @attr ref android.R.styleable#ProgressBar_maxWidth * @attr ref android.R.styleable#ProgressBar_minHeight * @attr ref android.R.styleable#ProgressBar_minWidth + * @attr ref android.R.styleable#ProgressBar_mirrorForRtl * @attr ref android.R.styleable#ProgressBar_progress * @attr ref android.R.styleable#ProgressBar_progressDrawable * @attr ref android.R.styleable#ProgressBar_secondaryProgress diff --git a/core/java/android/widget/RelativeLayout.java b/core/java/android/widget/RelativeLayout.java index 906f02d..f940226 100644 --- a/core/java/android/widget/RelativeLayout.java +++ b/core/java/android/widget/RelativeLayout.java @@ -231,7 +231,7 @@ public class RelativeLayout extends ViewGroup { * {@link View#MEASURED_SIZE_MASK}. * {@link View#MEASURED_STATE_TOO_SMALL}. **/ - private static final int DEFAULT_WIDTH = 0x008000000; + private static final int DEFAULT_WIDTH = 0x00010000; public RelativeLayout(Context context) { super(context); diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java index 1246051..9e3f87f 100644 --- a/core/java/android/widget/TextView.java +++ b/core/java/android/widget/TextView.java @@ -8042,7 +8042,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener info.setEditable(true); } - if (TextUtils.isEmpty(getContentDescription()) && !TextUtils.isEmpty(mText)) { + if (!TextUtils.isEmpty(mText)) { info.addAction(AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY); info.addAction(AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY); info.setMovementGranularities(AccessibilityNodeInfo.MOVEMENT_GRANULARITY_CHARACTER @@ -8051,6 +8051,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PARAGRAPH | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PAGE); } + if (isFocused()) { if (canSelectText()) { info.addAction(AccessibilityNodeInfo.ACTION_SET_SELECTION); @@ -8655,13 +8656,10 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener */ @Override public CharSequence getIterableTextForAccessibility() { - if (!TextUtils.isEmpty(mText)) { - if (!(mText instanceof Spannable)) { - setText(mText, BufferType.SPANNABLE); - } - return mText; + if (!(mText instanceof Spannable)) { + setText(mText, BufferType.SPANNABLE); } - return super.getIterableTextForAccessibility(); + return mText; } /** @@ -8697,13 +8695,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener */ @Override public int getAccessibilitySelectionStart() { - if (TextUtils.isEmpty(getContentDescription())) { - final int selectionStart = getSelectionStart(); - if (selectionStart >= 0) { - return selectionStart; - } - } - return ACCESSIBILITY_CURSOR_POSITION_UNDEFINED; + return getSelectionStart(); } /** @@ -8718,13 +8710,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener */ @Override public int getAccessibilitySelectionEnd() { - if (TextUtils.isEmpty(getContentDescription())) { - final int selectionEnd = getSelectionEnd(); - if (selectionEnd >= 0) { - return selectionEnd; - } - } - return ACCESSIBILITY_CURSOR_POSITION_UNDEFINED; + return getSelectionEnd(); } /** |
