summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--api/current.txt80
-rw-r--r--core/java/android/accessibilityservice/AccessibilityService.java2
-rw-r--r--core/java/android/accessibilityservice/AccessibilityServiceInfo.java214
-rw-r--r--core/java/android/app/Activity.java4
-rw-r--r--core/java/android/app/Application.java19
-rw-r--r--core/java/android/hardware/usb/UsbDeviceConnection.java42
-rw-r--r--core/java/android/net/DhcpInfo.java3
-rw-r--r--core/java/android/os/Handler.java15
-rw-r--r--core/java/android/os/HandlerThread.java53
-rw-r--r--core/java/android/os/Looper.java33
-rw-r--r--core/java/android/os/MessageQueue.java46
-rwxr-xr-xcore/java/android/util/PropertyValueModel.java143
-rwxr-xr-xcore/java/android/util/ValueModel.java74
-rw-r--r--core/java/android/view/View.java26
-rw-r--r--core/java/android/view/WindowManager.java4
-rw-r--r--core/java/android/widget/CheckBox.java23
-rw-r--r--core/java/android/widget/EditText.java23
-rw-r--r--core/java/android/widget/ListView.java17
-rw-r--r--core/java/android/widget/SeekBar.java20
-rwxr-xr-xcore/java/android/widget/ValueEditor.java53
-rw-r--r--core/res/AndroidManifest.xml18
-rw-r--r--core/res/res/values/attrs.xml32
-rw-r--r--core/res/res/values/public.xml6
-rw-r--r--core/res/res/values/strings.xml39
-rw-r--r--core/res/res/values/symbols.xml8
-rw-r--r--core/res/res/values/themes.xml30
-rw-r--r--media/java/android/media/AudioManager.java8
-rw-r--r--media/java/android/media/AudioService.java58
-rw-r--r--media/java/android/media/IAudioService.aidl2
-rw-r--r--media/java/android/media/MediaCodecInfo.java14
-rw-r--r--media/java/android/media/RemoteControlClient.java119
-rw-r--r--media/jni/android_media_MediaDrm.cpp53
-rw-r--r--opengl/java/android/opengl/GLSurfaceView.java16
-rw-r--r--services/java/com/android/server/NotificationManagerService.java11
-rw-r--r--services/java/com/android/server/accessibility/AccessibilityManagerService.java51
-rw-r--r--services/java/com/android/server/wifi/WifiService.java4
-rw-r--r--wifi/java/android/net/wifi/IWifiManager.aidl2
-rw-r--r--wifi/java/android/net/wifi/WifiEnterpriseConfig.java34
-rw-r--r--wifi/java/android/net/wifi/WifiManager.java4
39 files changed, 820 insertions, 583 deletions
diff --git a/api/current.txt b/api/current.txt
index 62c90dfc6531..8de8a5ddcb6e 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -37,8 +37,6 @@ package android {
field public static final java.lang.String CALL_PHONE = "android.permission.CALL_PHONE";
field public static final java.lang.String CALL_PRIVILEGED = "android.permission.CALL_PRIVILEGED";
field public static final java.lang.String CAMERA = "android.permission.CAMERA";
- field public static final java.lang.String CAN_REQUEST_ENHANCED_WEB_ACCESSIBILITY = "android.permission.CAN_REQUEST_ENHANCED_WEB_ACCESSIBILITY";
- field public static final java.lang.String CAN_REQUEST_TOUCH_EXPLORATION_MODE = "android.permission.CAN_REQUEST_TOUCH_EXPLORATION_MODE";
field public static final java.lang.String CHANGE_COMPONENT_ENABLED_STATE = "android.permission.CHANGE_COMPONENT_ENABLED_STATE";
field public static final java.lang.String CHANGE_CONFIGURATION = "android.permission.CHANGE_CONFIGURATION";
field public static final java.lang.String CHANGE_NETWORK_STATE = "android.permission.CHANGE_NETWORK_STATE";
@@ -322,6 +320,9 @@ package android {
field public static final int cacheColorHint = 16843009; // 0x1010101
field public static final int calendarViewShown = 16843596; // 0x101034c
field public static final int calendarViewStyle = 16843613; // 0x101035d
+ field public static final int canRequestEnhancedWebAccessibility = 16843736; // 0x10103d8
+ field public static final int canRequestFilterKeyEvents = 16843737; // 0x10103d9
+ field public static final int canRequestTouchExplorationMode = 16843735; // 0x10103d7
field public static final int canRetrieveWindowContent = 16843653; // 0x1010385
field public static final int candidatesTextStyleSpans = 16843312; // 0x1010230
field public static final deprecated int capitalize = 16843113; // 0x1010169
@@ -1703,7 +1704,6 @@ package android {
field public static final int Theme_Black = 16973832; // 0x1030008
field public static final int Theme_Black_NoTitleBar = 16973833; // 0x1030009
field public static final int Theme_Black_NoTitleBar_Fullscreen = 16973834; // 0x103000a
- field public static final int Theme_Black_NoTitleBar_Overscan = 16974303; // 0x10301df
field public static final int Theme_DeviceDefault = 16974120; // 0x1030128
field public static final int Theme_DeviceDefault_Dialog = 16974126; // 0x103012e
field public static final int Theme_DeviceDefault_DialogWhenLarge = 16974134; // 0x1030136
@@ -1722,11 +1722,11 @@ package android {
field public static final int Theme_DeviceDefault_Light_Dialog_NoActionBar_MinWidth = 16974133; // 0x1030135
field public static final int Theme_DeviceDefault_Light_NoActionBar = 16974124; // 0x103012c
field public static final int Theme_DeviceDefault_Light_NoActionBar_Fullscreen = 16974125; // 0x103012d
- field public static final int Theme_DeviceDefault_Light_NoActionBar_Overscan = 16974307; // 0x10301e3
+ field public static final int Theme_DeviceDefault_Light_NoActionBar_Overscan = 16974304; // 0x10301e0
field public static final int Theme_DeviceDefault_Light_Panel = 16974139; // 0x103013b
field public static final int Theme_DeviceDefault_NoActionBar = 16974121; // 0x1030129
field public static final int Theme_DeviceDefault_NoActionBar_Fullscreen = 16974122; // 0x103012a
- field public static final int Theme_DeviceDefault_NoActionBar_Overscan = 16974306; // 0x10301e2
+ field public static final int Theme_DeviceDefault_NoActionBar_Overscan = 16974303; // 0x10301df
field public static final int Theme_DeviceDefault_Panel = 16974138; // 0x103013a
field public static final int Theme_DeviceDefault_Wallpaper = 16974140; // 0x103013c
field public static final int Theme_DeviceDefault_Wallpaper_NoTitleBar = 16974141; // 0x103013d
@@ -1749,11 +1749,11 @@ package android {
field public static final int Theme_Holo_Light_Dialog_NoActionBar_MinWidth = 16973942; // 0x1030076
field public static final int Theme_Holo_Light_NoActionBar = 16974064; // 0x10300f0
field public static final int Theme_Holo_Light_NoActionBar_Fullscreen = 16974065; // 0x10300f1
- field public static final int Theme_Holo_Light_NoActionBar_Overscan = 16974305; // 0x10301e1
+ field public static final int Theme_Holo_Light_NoActionBar_Overscan = 16974302; // 0x10301de
field public static final int Theme_Holo_Light_Panel = 16973948; // 0x103007c
field public static final int Theme_Holo_NoActionBar = 16973932; // 0x103006c
field public static final int Theme_Holo_NoActionBar_Fullscreen = 16973933; // 0x103006d
- field public static final int Theme_Holo_NoActionBar_Overscan = 16974304; // 0x10301e0
+ field public static final int Theme_Holo_NoActionBar_Overscan = 16974301; // 0x10301dd
field public static final int Theme_Holo_Panel = 16973947; // 0x103007b
field public static final int Theme_Holo_Wallpaper = 16973949; // 0x103007d
field public static final int Theme_Holo_Wallpaper_NoTitleBar = 16973950; // 0x103007e
@@ -1761,14 +1761,12 @@ package android {
field public static final int Theme_Light = 16973836; // 0x103000c
field public static final int Theme_Light_NoTitleBar = 16973837; // 0x103000d
field public static final int Theme_Light_NoTitleBar_Fullscreen = 16973838; // 0x103000e
- field public static final int Theme_Light_NoTitleBar_Overscan = 16974302; // 0x10301de
field public static final int Theme_Light_Panel = 16973914; // 0x103005a
field public static final int Theme_Light_WallpaperSettings = 16973922; // 0x1030062
field public static final int Theme_NoDisplay = 16973909; // 0x1030055
field public static final int Theme_NoTitleBar = 16973830; // 0x1030006
field public static final int Theme_NoTitleBar_Fullscreen = 16973831; // 0x1030007
field public static final int Theme_NoTitleBar_OverlayActionModes = 16973930; // 0x103006a
- field public static final int Theme_NoTitleBar_Overscan = 16974301; // 0x10301dd
field public static final int Theme_Panel = 16973913; // 0x1030059
field public static final int Theme_Translucent = 16973839; // 0x103000f
field public static final int Theme_Translucent_NoTitleBar = 16973840; // 0x1030010
@@ -2107,16 +2105,22 @@ package android.accessibilityservice {
public class AccessibilityServiceInfo implements android.os.Parcelable {
ctor public AccessibilityServiceInfo();
+ method public static java.lang.String capabilityToString(int);
method public int describeContents();
method public static java.lang.String feedbackTypeToString(int);
method public static java.lang.String flagToString(int);
- method public boolean getCanRetrieveWindowContent();
+ method public deprecated boolean getCanRetrieveWindowContent();
+ method public int getCapabilities();
method public deprecated java.lang.String getDescription();
method public java.lang.String getId();
method public android.content.pm.ResolveInfo getResolveInfo();
method public java.lang.String getSettingsActivityName();
method public java.lang.String loadDescription(android.content.pm.PackageManager);
method public void writeToParcel(android.os.Parcel, int);
+ field public static final int CAPABILITY_CAN_REQUEST_ENHANCED_WEB_ACCESSIBILITY = 4; // 0x4
+ field public static final int CAPABILITY_CAN_REQUEST_FILTER_KEY_EVENTS = 8; // 0x8
+ field public static final int CAPABILITY_CAN_REQUEST_TOUCH_EXPLORATION = 2; // 0x2
+ field public static final int CAPABILITY_CAN_RETRIEVE_WINDOW_CONTENT = 1; // 0x1
field public static final android.os.Parcelable.Creator CREATOR;
field public static final int DEFAULT = 1; // 0x1
field public static final int FEEDBACK_ALL_MASK = -1; // 0xffffffff
@@ -2129,6 +2133,7 @@ package android.accessibilityservice {
field public static final int FLAG_INCLUDE_NOT_IMPORTANT_VIEWS = 2; // 0x2
field public static final int FLAG_REPORT_VIEW_IDS = 16; // 0x10
field public static final int FLAG_REQUEST_ENHANCED_WEB_ACCESSIBILITY = 8; // 0x8
+ field public static final int FLAG_REQUEST_FILTER_KEY_EVENTS = 32; // 0x20
field public static final int FLAG_REQUEST_TOUCH_EXPLORATION_MODE = 4; // 0x4
field public int eventTypes;
field public int feedbackType;
@@ -3117,9 +3122,9 @@ package android.app {
method public void onTerminate();
method public void onTrimMemory(int);
method public void registerActivityLifecycleCallbacks(android.app.Application.ActivityLifecycleCallbacks);
- method public void registerOnProvideAssistData(android.app.Application.OnProvideAssistData);
+ method public void registerOnProvideAssistDataListener(android.app.Application.OnProvideAssistDataListener);
method public void unregisterActivityLifecycleCallbacks(android.app.Application.ActivityLifecycleCallbacks);
- method public void unregisterOnProvideAssistData(android.app.Application.OnProvideAssistData);
+ method public void unregisterOnProvideAssistDataListener(android.app.Application.OnProvideAssistDataListener);
}
public static abstract interface Application.ActivityLifecycleCallbacks {
@@ -3132,7 +3137,7 @@ package android.app {
method public abstract void onActivityStopped(android.app.Activity);
}
- public static abstract interface Application.OnProvideAssistData {
+ public static abstract interface Application.OnProvideAssistDataListener {
method public abstract void onProvideAssistData(android.app.Activity, android.os.Bundle);
}
@@ -10589,11 +10594,11 @@ package android.hardware.usb {
}
public class UsbDeviceConnection {
- method public deprecated int bulkTransfer(android.hardware.usb.UsbEndpoint, byte[], int, int);
+ method public int bulkTransfer(android.hardware.usb.UsbEndpoint, byte[], int, int);
method public int bulkTransfer(android.hardware.usb.UsbEndpoint, byte[], int, int, int);
method public boolean claimInterface(android.hardware.usb.UsbInterface, boolean);
method public void close();
- method public deprecated int controlTransfer(int, int, int, int, byte[], int, int);
+ method public int controlTransfer(int, int, int, int, byte[], int, int);
method public int controlTransfer(int, int, int, int, byte[], int, int, int);
method public int getFileDescriptor();
method public byte[] getRawDescriptors();
@@ -13926,8 +13931,11 @@ package android.net.wifi {
ctor public WifiEnterpriseConfig(android.net.wifi.WifiEnterpriseConfig);
method public int describeContents();
method public java.lang.String getAnonymousIdentity();
+ method public java.security.cert.X509Certificate getCaCertificate();
+ method public java.security.cert.X509Certificate getClientCertificate();
method public int getEapMethod();
method public java.lang.String getIdentity();
+ method public java.lang.String getPassword();
method public int getPhase2Method();
method public java.lang.String getSubjectMatch();
method public void setAnonymousIdentity(java.lang.String);
@@ -13943,7 +13951,6 @@ package android.net.wifi {
}
public static final class WifiEnterpriseConfig.Eap {
- ctor public WifiEnterpriseConfig.Eap();
field public static final int NONE = -1; // 0xffffffff
field public static final int PEAP = 0; // 0x0
field public static final int PWD = 3; // 0x3
@@ -13952,7 +13959,6 @@ package android.net.wifi {
}
public static final class WifiEnterpriseConfig.Phase2 {
- ctor public WifiEnterpriseConfig.Phase2();
field public static final int GTC = 4; // 0x4
field public static final int MSCHAP = 2; // 0x2
field public static final int MSCHAPV2 = 3; // 0x3
@@ -13991,7 +13997,7 @@ package android.net.wifi {
method public deprecated android.net.DhcpInfo getDhcpInfo();
method public java.util.List<android.net.wifi.ScanResult> getScanResults();
method public int getWifiState();
- method public boolean isScanningAlwaysAvailable();
+ method public boolean isScanAlwaysAvailable();
method public boolean isWifiEnabled();
method public boolean pingSupplicant();
method public boolean reassociate();
@@ -17116,6 +17122,7 @@ package android.os {
method public int getThreadId();
method protected void onLooperPrepared();
method public boolean quit();
+ method public boolean quitSafely();
}
public abstract interface IBinder {
@@ -17156,6 +17163,7 @@ package android.os {
method public static void prepare();
method public static void prepareMainLooper();
method public void quit();
+ method public void quitSafely();
method public void setMessageLogging(android.util.Printer);
}
@@ -24440,17 +24448,6 @@ package android.util {
method public void set(T, V);
}
- public class PropertyValueModel extends android.util.ValueModel {
- method public T get();
- method public H getHost();
- method public android.util.Property<H, T> getProperty();
- method public java.lang.Class<T> getType();
- method public static android.util.PropertyValueModel<H, T> of(H, android.util.Property<H, T>);
- method public static android.util.PropertyValueModel<H, T> of(H, java.lang.Class<T>, java.lang.String);
- method public static android.util.PropertyValueModel of(java.lang.Object, java.lang.String);
- method public void set(T);
- }
-
public class SparseArray implements java.lang.Cloneable {
ctor public SparseArray();
ctor public SparseArray(int);
@@ -24617,14 +24614,6 @@ package android.util {
field public int type;
}
- public abstract class ValueModel {
- ctor protected ValueModel();
- method public abstract T get();
- method public abstract java.lang.Class<T> getType();
- method public abstract void set(T);
- field public static final android.util.ValueModel EMPTY;
- }
-
public class Xml {
method public static android.util.AttributeSet asAttributeSet(org.xmlpull.v1.XmlPullParser);
method public static android.util.Xml.Encoding findEncodingByName(java.lang.String) throws java.io.UnsupportedEncodingException;
@@ -29090,12 +29079,10 @@ package android.widget {
method public abstract void onSelectedDayChange(android.widget.CalendarView, int, int, int);
}
- public class CheckBox extends android.widget.CompoundButton implements android.widget.ValueEditor {
+ public class CheckBox extends android.widget.CompoundButton {
ctor public CheckBox(android.content.Context);
ctor public CheckBox(android.content.Context, android.util.AttributeSet);
ctor public CheckBox(android.content.Context, android.util.AttributeSet, int);
- method public android.util.ValueModel<java.lang.Boolean> getValueModel();
- method public void setValueModel(android.util.ValueModel<java.lang.Boolean>);
}
public abstract interface Checkable {
@@ -29268,16 +29255,14 @@ package android.widget {
method public void setSize(int, int);
}
- public class EditText extends android.widget.TextView implements android.widget.ValueEditor {
+ public class EditText extends android.widget.TextView {
ctor public EditText(android.content.Context);
ctor public EditText(android.content.Context, android.util.AttributeSet);
ctor public EditText(android.content.Context, android.util.AttributeSet, int);
method public void extendSelection(int);
- method public android.util.ValueModel<java.lang.CharSequence> getValueModel();
method public void selectAll();
method public void setSelection(int, int);
method public void setSelection(int);
- method public void setValueModel(android.util.ValueModel<java.lang.CharSequence>);
}
public abstract interface ExpandableListAdapter {
@@ -30306,13 +30291,11 @@ package android.widget {
method public abstract java.lang.Object[] getSections();
}
- public class SeekBar extends android.widget.AbsSeekBar implements android.widget.ValueEditor {
+ public class SeekBar extends android.widget.AbsSeekBar {
ctor public SeekBar(android.content.Context);
ctor public SeekBar(android.content.Context, android.util.AttributeSet);
ctor public SeekBar(android.content.Context, android.util.AttributeSet, int);
- method public android.util.ValueModel<java.lang.Integer> getValueModel();
method public void setOnSeekBarChangeListener(android.widget.SeekBar.OnSeekBarChangeListener);
- method public void setValueModel(android.util.ValueModel<java.lang.Integer>);
}
public static abstract interface SeekBar.OnSeekBarChangeListener {
@@ -30900,11 +30883,6 @@ package android.widget {
method public android.widget.TextView getText2();
}
- public abstract interface ValueEditor {
- method public abstract android.util.ValueModel<T> getValueModel();
- method public abstract void setValueModel(android.util.ValueModel<T>);
- }
-
public class VideoView extends android.view.SurfaceView implements android.widget.MediaController.MediaPlayerControl {
ctor public VideoView(android.content.Context);
ctor public VideoView(android.content.Context, android.util.AttributeSet);
diff --git a/core/java/android/accessibilityservice/AccessibilityService.java b/core/java/android/accessibilityservice/AccessibilityService.java
index 31de98dc1593..1e3d5bea9571 100644
--- a/core/java/android/accessibilityservice/AccessibilityService.java
+++ b/core/java/android/accessibilityservice/AccessibilityService.java
@@ -308,6 +308,8 @@ public abstract class AccessibilityService extends Service {
* android:accessibilityFlags="flagDefault"
* android:settingsActivity="foo.bar.TestBackActivity"
* android:canRetrieveWindowContent="true"
+ * android:canRequestTouchExplorationMode="true"
+ * android:canRequestEnhancedWebAccessibility="true"
* . . .
* /&gt;</pre>
*/
diff --git a/core/java/android/accessibilityservice/AccessibilityServiceInfo.java b/core/java/android/accessibilityservice/AccessibilityServiceInfo.java
index d82b9a38390c..40f45b780485 100644
--- a/core/java/android/accessibilityservice/AccessibilityServiceInfo.java
+++ b/core/java/android/accessibilityservice/AccessibilityServiceInfo.java
@@ -29,6 +29,7 @@ import android.os.Build;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.AttributeSet;
+import android.util.SparseArray;
import android.util.TypedValue;
import android.util.Xml;
import android.view.View;
@@ -38,7 +39,12 @@ import android.view.accessibility.AccessibilityNodeInfo;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
+import com.android.internal.R;
+
import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
/**
* This class describes an {@link AccessibilityService}. The system notifies an
@@ -61,6 +67,49 @@ public class AccessibilityServiceInfo implements Parcelable {
private static final String TAG_ACCESSIBILITY_SERVICE = "accessibility-service";
/**
+ * Capability: This accessibility service can retrieve the active window content.
+ */
+ public static final int CAPABILITY_CAN_RETRIEVE_WINDOW_CONTENT = 0x00000001;
+
+ /**
+ * Capability: This accessibility service can request touch exploration mode in which
+ * touched items are spoken aloud and the UI can be explored via gestures.
+ */
+ public static final int CAPABILITY_CAN_REQUEST_TOUCH_EXPLORATION = 0x00000002;
+
+ /**
+ * Capability: This accessibility service can request enhanced web accessibility
+ * enhancements. For example, installing scripts to make app content more accessible.
+ */
+ public static final int CAPABILITY_CAN_REQUEST_ENHANCED_WEB_ACCESSIBILITY = 0x00000004;
+
+ /**
+ * Capability: This accessibility service can request to filter the key event stream.
+ */
+ public static final int CAPABILITY_CAN_REQUEST_FILTER_KEY_EVENTS = 0x00000008;
+
+ private static final SparseArray<CapabilityInfo> sAvailableCapabilityInfos =
+ new SparseArray<CapabilityInfo>();
+ static {
+ sAvailableCapabilityInfos.put(CAPABILITY_CAN_RETRIEVE_WINDOW_CONTENT,
+ new CapabilityInfo(CAPABILITY_CAN_RETRIEVE_WINDOW_CONTENT,
+ R.string.capability_title_canRetrieveWindowContent,
+ R.string.capability_desc_canRetrieveWindowContent));
+ sAvailableCapabilityInfos.put(CAPABILITY_CAN_REQUEST_TOUCH_EXPLORATION,
+ new CapabilityInfo(CAPABILITY_CAN_REQUEST_TOUCH_EXPLORATION,
+ R.string.capability_title_canRequestTouchExploration,
+ R.string.capability_desc_canRequestTouchExploration));
+ sAvailableCapabilityInfos.put(CAPABILITY_CAN_REQUEST_ENHANCED_WEB_ACCESSIBILITY,
+ new CapabilityInfo(CAPABILITY_CAN_REQUEST_ENHANCED_WEB_ACCESSIBILITY,
+ R.string.capability_title_canRequestEnhancedWebAccessibility,
+ R.string.capability_desc_canRequestEnhancedWebAccessibility));
+ sAvailableCapabilityInfos.put(CAPABILITY_CAN_REQUEST_FILTER_KEY_EVENTS,
+ new CapabilityInfo(CAPABILITY_CAN_REQUEST_FILTER_KEY_EVENTS,
+ R.string.capability_title_canRequestFilterKeyEvents,
+ R.string.capability_desc_canRequestFilterKeyEvents));
+ }
+
+ /**
* Denotes spoken feedback.
*/
public static final int FEEDBACK_SPOKEN = 0x0000001;
@@ -152,9 +201,11 @@ public class AccessibilityServiceInfo implements Parcelable {
* <p>
* For accessibility services targeting API version higher than
* {@link Build.VERSION_CODES#JELLY_BEAN_MR1} that want to set
- * this flag have to request the
- * {@link android.Manifest.permission#CAN_REQUEST_TOUCH_EXPLORATION_MODE}
- * permission or the flag will be ignored.
+ * this flag have to declare this capability in their meta-data by setting
+ * the attribute {@link android.R.attr#canRequestTouchExplorationMode
+ * canRequestTouchExplorationMode} to true, otherwise this flag will
+ * be ignored. For how to declare the meta-data of a service refer to
+ * {@value AccessibilityService#SERVICE_META_DATA}.
* </p>
* <p>
* Services targeting API version equal to or lower than
@@ -175,9 +226,11 @@ public class AccessibilityServiceInfo implements Parcelable {
* device will not have enhanced web accessibility enabled since there may be
* another enabled service that requested it.
* <p>
- * Clients that want to set this flag have to request the
- * {@link android.Manifest.permission#CAN_REQUEST_ENHANCED_WEB_ACCESSIBILITY}
- * permission or the flag will be ignored.
+ * Services that want to set this flag have to declare this capability
+ * in their meta-data by setting the attribute {@link android.R.attr
+ * #canRequestEnhancedWebAccessibility canRequestEnhancedWebAccessibility} to
+ * true, otherwise this flag will be ignored. For how to declare the meta-data
+ * of a service refer to {@value AccessibilityService#SERVICE_META_DATA}.
* </p>
*/
public static final int FLAG_REQUEST_ENHANCED_WEB_ACCESSIBILITY = 0x00000008;
@@ -192,6 +245,25 @@ public class AccessibilityServiceInfo implements Parcelable {
public static final int FLAG_REPORT_VIEW_IDS = 0x00000010;
/**
+ * This flag requests from the system to filter key events. If this flag
+ * is set the accessibility service will receive the key events before
+ * applications allowing it implement global shortcuts. Setting this flag
+ * does not guarantee that this service will filter key events since only
+ * one service can do so at any given time. This avoids user confusion due
+ * to behavior change in case different key filtering services are enabled.
+ * If there is already another key filtering service enabled, this one will
+ * not receive key events.
+ * <p>
+ * Services that want to set this flag have to declare this capability
+ * in their meta-data by setting the attribute {@link android.R.attr
+ * #canRequestFilterKeyEvents canRequestFilterKeyEvents} to true,
+ * otherwise this flag will be ignored. For how to declare the meta-data
+ * of a service refer to {@value AccessibilityService#SERVICE_META_DATA}.
+ * </p>
+ */
+ public static final int FLAG_REQUEST_FILTER_KEY_EVENTS = 0x00000020;
+
+ /**
* The event types an {@link AccessibilityService} is interested in.
* <p>
* <strong>Can be dynamically set at runtime.</strong>
@@ -259,6 +331,9 @@ public class AccessibilityServiceInfo implements Parcelable {
* @see #DEFAULT
* @see #FLAG_INCLUDE_NOT_IMPORTANT_VIEWS
* @see #FLAG_REQUEST_TOUCH_EXPLORATION_MODE
+ * @see #FLAG_REQUEST_ENHANCED_WEB_ACCESSIBILITY
+ * @see #FLAG_REQUEST_FILTER_KEY_EVENTS
+ * @see #FLAG_REPORT_VIEW_IDS
*/
public int flags;
@@ -279,9 +354,9 @@ public class AccessibilityServiceInfo implements Parcelable {
private String mSettingsActivityName;
/**
- * Flag whether this accessibility service can retrieve window content.
+ * Bit mask with capabilities of this service.
*/
- private boolean mCanRetrieveWindowContent;
+ private int mCapabilities;
/**
* Resource id of the description of the accessibility service.
@@ -360,9 +435,22 @@ public class AccessibilityServiceInfo implements Parcelable {
com.android.internal.R.styleable.AccessibilityService_accessibilityFlags, 0);
mSettingsActivityName = asAttributes.getString(
com.android.internal.R.styleable.AccessibilityService_settingsActivity);
- mCanRetrieveWindowContent = asAttributes.getBoolean(
- com.android.internal.R.styleable.AccessibilityService_canRetrieveWindowContent,
- false);
+ if (asAttributes.getBoolean(com.android.internal.R.styleable
+ .AccessibilityService_canRetrieveWindowContent, false)) {
+ mCapabilities |= CAPABILITY_CAN_RETRIEVE_WINDOW_CONTENT;
+ }
+ if (asAttributes.getBoolean(com.android.internal.R.styleable
+ .AccessibilityService_canRequestTouchExplorationMode, false)) {
+ mCapabilities |= CAPABILITY_CAN_REQUEST_TOUCH_EXPLORATION;
+ }
+ if (asAttributes.getBoolean(com.android.internal.R.styleable
+ .AccessibilityService_canRequestEnhancedWebAccessibility, false)) {
+ mCapabilities |= CAPABILITY_CAN_REQUEST_ENHANCED_WEB_ACCESSIBILITY;
+ }
+ if (asAttributes.getBoolean(com.android.internal.R.styleable
+ .AccessibilityService_canRequestFilterKeyEvents, false)) {
+ mCapabilities |= CAPABILITY_CAN_REQUEST_FILTER_KEY_EVENTS;
+ }
TypedValue peekedValue = asAttributes.peekValue(
com.android.internal.R.styleable.AccessibilityService_description);
if (peekedValue != null) {
@@ -446,9 +534,26 @@ public class AccessibilityServiceInfo implements Parcelable {
* {@link AccessibilityService#SERVICE_META_DATA meta-data}.</strong>
* </p>
* @return True if window content can be retrieved.
+ *
+ * @deprecated Use {@link #getCapabilities()}.
*/
public boolean getCanRetrieveWindowContent() {
- return mCanRetrieveWindowContent;
+ return (mCapabilities & CAPABILITY_CAN_RETRIEVE_WINDOW_CONTENT) != 0;
+ }
+
+ /**
+ * Returns the bit mask of capabilities this accessibility service has such as
+ * being able to retrieve the active window content, etc.
+ *
+ * @return 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
+ */
+ public int getCapabilities() {
+ return mCapabilities;
}
/**
@@ -502,7 +607,7 @@ public class AccessibilityServiceInfo implements Parcelable {
parcel.writeString(mId);
parcel.writeParcelable(mResolveInfo, 0);
parcel.writeString(mSettingsActivityName);
- parcel.writeInt(mCanRetrieveWindowContent ? 1 : 0);
+ parcel.writeInt(mCapabilities);
parcel.writeInt(mDescriptionResId);
parcel.writeString(mNonLocalizedDescription);
}
@@ -516,7 +621,7 @@ public class AccessibilityServiceInfo implements Parcelable {
mId = parcel.readString();
mResolveInfo = parcel.readParcelable(null);
mSettingsActivityName = parcel.readString();
- mCanRetrieveWindowContent = (parcel.readInt() == 1);
+ mCapabilities = parcel.readInt();
mDescriptionResId = parcel.readInt();
mNonLocalizedDescription = parcel.readString();
}
@@ -567,7 +672,7 @@ public class AccessibilityServiceInfo implements Parcelable {
stringBuilder.append(", ");
stringBuilder.append("settingsActivityName: ").append(mSettingsActivityName);
stringBuilder.append(", ");
- stringBuilder.append("retrieveScreenContent: ").append(mCanRetrieveWindowContent);
+ appendCapabilities(stringBuilder, mCapabilities);
return stringBuilder.toString();
}
@@ -628,6 +733,20 @@ public class AccessibilityServiceInfo implements Parcelable {
stringBuilder.append("]");
}
+ private static void appendCapabilities(StringBuilder stringBuilder, int capabilities) {
+ stringBuilder.append("capabilities:");
+ stringBuilder.append("[");
+ while (capabilities != 0) {
+ final int capabilityBit = (1 << Integer.numberOfTrailingZeros(capabilities));
+ stringBuilder.append(capabilityToString(capabilityBit));
+ capabilities &= ~capabilityBit;
+ if (capabilities != 0) {
+ stringBuilder.append(", ");
+ }
+ }
+ stringBuilder.append("]");
+ }
+
/**
* Returns the string representation of a feedback type. For example,
* {@link #FEEDBACK_SPOKEN} is represented by the string FEEDBACK_SPOKEN.
@@ -699,12 +818,77 @@ public class AccessibilityServiceInfo implements Parcelable {
return "FLAG_INCLUDE_NOT_IMPORTANT_VIEWS";
case FLAG_REQUEST_TOUCH_EXPLORATION_MODE:
return "FLAG_REQUEST_TOUCH_EXPLORATION_MODE";
+ case FLAG_REQUEST_ENHANCED_WEB_ACCESSIBILITY:
+ return "FLAG_REQUEST_ENHANCED_WEB_ACCESSIBILITY";
+ case FLAG_REPORT_VIEW_IDS:
+ return "FLAG_REPORT_VIEW_IDS";
+ case FLAG_REQUEST_FILTER_KEY_EVENTS:
+ return "FLAG_REQUEST_FILTER_KEY_EVENTS";
default:
return null;
}
}
/**
+ * Returns the string representation of a capability. For example,
+ * {@link #CAPABILITY_CAN_RETRIEVE_WINDOW_CONTENT} is represented
+ * by the string CAPABILITY_CAN_RETRIEVE_WINDOW_CONTENT.
+ *
+ * @param capability The capability.
+ * @return The string representation.
+ */
+ public static String capabilityToString(int capability) {
+ switch (capability) {
+ case CAPABILITY_CAN_RETRIEVE_WINDOW_CONTENT:
+ return "CAPABILITY_CAN_RETRIEVE_WINDOW_CONTENT";
+ case CAPABILITY_CAN_REQUEST_TOUCH_EXPLORATION:
+ return "CAPABILITY_CAN_REQUEST_TOUCH_EXPLORATION";
+ case CAPABILITY_CAN_REQUEST_ENHANCED_WEB_ACCESSIBILITY:
+ return "CAPABILITY_CAN_REQUEST_ENHANCED_WEB_ACCESSIBILITY";
+ case CAPABILITY_CAN_REQUEST_FILTER_KEY_EVENTS:
+ return "CAPABILITY_CAN_FILTER_KEY_EVENTS";
+ default:
+ return "UNKNOWN";
+ }
+ }
+
+ /**
+ * @hide
+ * @return The list of {@link CapabilityInfo} objects.
+ */
+ public List<CapabilityInfo> getCapabilityInfos() {
+ if (mCapabilities == 0) {
+ return Collections.emptyList();
+ }
+ int capabilities = mCapabilities;
+ List<CapabilityInfo> capabilityInfos = new ArrayList<CapabilityInfo>();
+ while (capabilities != 0) {
+ final int capabilityBit = 1 << Integer.numberOfTrailingZeros(capabilities);
+ capabilities &= ~capabilityBit;
+ CapabilityInfo capabilityInfo = sAvailableCapabilityInfos.get(capabilityBit);
+ if (capabilityInfo != null) {
+ capabilityInfos.add(capabilityInfo);
+ }
+ }
+ return capabilityInfos;
+ }
+
+ /**
+ * @hide
+ */
+ public static final class CapabilityInfo {
+ public final int capability;
+ public final int titleResId;
+ public final int descResId;
+
+ public CapabilityInfo(int capability, int titleResId, int descResId) {
+ this.capability = capability;
+ this.titleResId = titleResId;
+ this.descResId = descResId;
+ }
+ }
+
+ /**
* @see Parcelable.Creator
*/
public static final Parcelable.Creator<AccessibilityServiceInfo> CREATOR =
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index a26bdbcbfed0..6b5df7f74c70 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -1353,8 +1353,8 @@ public class Activity extends ContextThemeWrapper
* of the assist Intent. The default implementation does nothing.
*
* <p>This function will be called after any global assist callbacks that had
- * been registered with {@link Application#registerOnProvideAssistData
- * Application.registerOnProvideAssistData}.
+ * been registered with {@link Application#registerOnProvideAssistDataListener
+ * Application.registerOnProvideAssistDataListener}.
*/
public void onProvideAssistData(Bundle data) {
}
diff --git a/core/java/android/app/Application.java b/core/java/android/app/Application.java
index 0d7f0a740e53..75e4babeb524 100644
--- a/core/java/android/app/Application.java
+++ b/core/java/android/app/Application.java
@@ -17,17 +17,14 @@
package android.app;
import java.util.ArrayList;
-import java.util.List;
import android.content.ComponentCallbacks;
import android.content.ComponentCallbacks2;
import android.content.Context;
import android.content.ContextWrapper;
import android.content.Intent;
-import android.content.RestrictionEntry;
import android.content.res.Configuration;
import android.os.Bundle;
-import android.os.UserManager;
/**
* Base class for those who need to maintain global application state. You can
@@ -49,7 +46,7 @@ public class Application extends ContextWrapper implements ComponentCallbacks2 {
new ArrayList<ComponentCallbacks>();
private ArrayList<ActivityLifecycleCallbacks> mActivityLifecycleCallbacks =
new ArrayList<ActivityLifecycleCallbacks>();
- private ArrayList<OnProvideAssistData> mAssistCallbacks = null;
+ private ArrayList<OnProvideAssistDataListener> mAssistCallbacks = null;
/** @hide */
public LoadedApk mLoadedApk;
@@ -65,10 +62,10 @@ public class Application extends ContextWrapper implements ComponentCallbacks2 {
}
/**
- * Callback interface for use with {@link Application#registerOnProvideAssistData}
- * and {@link Application#unregisterOnProvideAssistData}.
+ * Callback interface for use with {@link Application#registerOnProvideAssistDataListener}
+ * and {@link Application#unregisterOnProvideAssistDataListener}.
*/
- public interface OnProvideAssistData {
+ public interface OnProvideAssistDataListener {
/**
* This is called when the user is requesting an assist, to build a full
* {@link Intent#ACTION_ASSIST} Intent with all of the context of the current
@@ -158,16 +155,16 @@ public class Application extends ContextWrapper implements ComponentCallbacks2 {
}
}
- public void registerOnProvideAssistData(OnProvideAssistData callback) {
+ public void registerOnProvideAssistDataListener(OnProvideAssistDataListener callback) {
synchronized (this) {
if (mAssistCallbacks == null) {
- mAssistCallbacks = new ArrayList<OnProvideAssistData>();
+ mAssistCallbacks = new ArrayList<OnProvideAssistDataListener>();
}
mAssistCallbacks.add(callback);
}
}
- public void unregisterOnProvideAssistData(OnProvideAssistData callback) {
+ public void unregisterOnProvideAssistDataListener(OnProvideAssistDataListener callback) {
synchronized (this) {
if (mAssistCallbacks != null) {
mAssistCallbacks.remove(callback);
@@ -280,7 +277,7 @@ public class Application extends ContextWrapper implements ComponentCallbacks2 {
}
if (callbacks != null) {
for (int i=0; i<callbacks.length; i++) {
- ((OnProvideAssistData)callbacks[i]).onProvideAssistData(activity, data);
+ ((OnProvideAssistDataListener)callbacks[i]).onProvideAssistData(activity, data);
}
}
}
diff --git a/core/java/android/hardware/usb/UsbDeviceConnection.java b/core/java/android/hardware/usb/UsbDeviceConnection.java
index 0856e2736d0a..b2034b2636c9 100644
--- a/core/java/android/hardware/usb/UsbDeviceConnection.java
+++ b/core/java/android/hardware/usb/UsbDeviceConnection.java
@@ -107,6 +107,11 @@ public class UsbDeviceConnection {
* {@link UsbConstants#USB_DIR_OUT}, then the transfer is a write,
* and if it is {@link UsbConstants#USB_DIR_IN}, then the transfer
* is a read.
+ * <p>
+ * This method transfers data starting from index 0 in the buffer.
+ * To specify a different offset, use
+ * {@link #controlTransfer(int, int, int, int, byte[], int, int, int)}.
+ * </p>
*
* @param requestType request type for this transaction
* @param request request ID for this transaction
@@ -118,11 +123,7 @@ public class UsbDeviceConnection {
* @param timeout in milliseconds
* @return length of data transferred (or zero) for success,
* or negative value for failure
- *
- * @deprecated Use {@link #controlTransfer(int, int, int, int, byte[], int, int, int)}
- * which accepts a buffer start index.
*/
- @Deprecated
public int controlTransfer(int requestType, int request, int value,
int index, byte[] buffer, int length, int timeout) {
return controlTransfer(requestType, request, value, index, buffer, 0, length, timeout);
@@ -142,22 +143,27 @@ public class UsbDeviceConnection {
* @param index index field for this transaction
* @param buffer buffer for data portion of transaction,
* or null if no data needs to be sent or received
- * @param start the index of the first byte in the buffer to send or receive
+ * @param offset the index of the first byte in the buffer to send or receive
* @param length the length of the data to send or receive
* @param timeout in milliseconds
* @return length of data transferred (or zero) for success,
* or negative value for failure
*/
public int controlTransfer(int requestType, int request, int value, int index,
- byte[] buffer, int start, int length, int timeout) {
- checkBounds(buffer, start, length);
+ byte[] buffer, int offset, int length, int timeout) {
+ checkBounds(buffer, offset, length);
return native_control_request(requestType, request, value, index,
- buffer, start, length, timeout);
+ buffer, offset, length, timeout);
}
/**
* Performs a bulk transaction on the given endpoint.
- * The direction of the transfer is determined by the direction of the endpoint
+ * The direction of the transfer is determined by the direction of the endpoint.
+ * <p>
+ * This method transfers data starting from index 0 in the buffer.
+ * To specify a different offset, use
+ * {@link #bulkTransfer(UsbEndpoint, byte[], int, int, int)}.
+ * </p>
*
* @param endpoint the endpoint for this transaction
* @param buffer buffer for data to send or receive
@@ -165,11 +171,7 @@ public class UsbDeviceConnection {
* @param timeout in milliseconds
* @return length of data transferred (or zero) for success,
* or negative value for failure
- *
- * @deprecated Use {@link #bulkTransfer(UsbEndpoint, byte[], int, int, int)}
- * which accepts a buffer start index.
*/
- @Deprecated
public int bulkTransfer(UsbEndpoint endpoint,
byte[] buffer, int length, int timeout) {
return bulkTransfer(endpoint, buffer, 0, length, timeout);
@@ -177,20 +179,20 @@ public class UsbDeviceConnection {
/**
* Performs a bulk transaction on the given endpoint.
- * The direction of the transfer is determined by the direction of the endpoint
+ * The direction of the transfer is determined by the direction of the endpoint.
*
* @param endpoint the endpoint for this transaction
* @param buffer buffer for data to send or receive
- * @param start the index of the first byte in the buffer to send or receive
+ * @param offset the index of the first byte in the buffer to send or receive
* @param length the length of the data to send or receive
* @param timeout in milliseconds
* @return length of data transferred (or zero) for success,
* or negative value for failure
*/
public int bulkTransfer(UsbEndpoint endpoint,
- byte[] buffer, int start, int length, int timeout) {
- checkBounds(buffer, start, length);
- return native_bulk_request(endpoint.getAddress(), buffer, start, length, timeout);
+ byte[] buffer, int offset, int length, int timeout) {
+ checkBounds(buffer, offset, length);
+ return native_bulk_request(endpoint.getAddress(), buffer, offset, length, timeout);
}
/**
@@ -235,9 +237,9 @@ public class UsbDeviceConnection {
private native boolean native_claim_interface(int interfaceID, boolean force);
private native boolean native_release_interface(int interfaceID);
private native int native_control_request(int requestType, int request, int value,
- int index, byte[] buffer, int start, int length, int timeout);
+ int index, byte[] buffer, int offset, int length, int timeout);
private native int native_bulk_request(int endpoint, byte[] buffer,
- int start, int length, int timeout);
+ int offset, int length, int timeout);
private native UsbRequest native_request_wait();
private native String native_get_serial();
}
diff --git a/core/java/android/net/DhcpInfo.java b/core/java/android/net/DhcpInfo.java
index 2b359ebc1156..ab4cd9b9ef76 100644
--- a/core/java/android/net/DhcpInfo.java
+++ b/core/java/android/net/DhcpInfo.java
@@ -22,8 +22,7 @@ import java.net.InetAddress;
/**
* A simple object for retrieving the results of a DHCP request.
- * @deprecated - use LinkProperties - To be removed 11/2013
- * STOPSHIP - make sure we expose LinkProperties through ConnectivityManager
+ * @deprecated - use LinkProperties - To be removed 11/2014
*/
public class DhcpInfo implements Parcelable {
public int ipAddress;
diff --git a/core/java/android/os/Handler.java b/core/java/android/os/Handler.java
index 94de4487b645..14d8f0765f9d 100644
--- a/core/java/android/os/Handler.java
+++ b/core/java/android/os/Handler.java
@@ -413,27 +413,32 @@ public class Handler {
/**
* Runs the specified task synchronously.
- *
+ * <p>
* If the current thread is the same as the handler thread, then the runnable
* runs immediately without being enqueued. Otherwise, posts the runnable
* to the handler and waits for it to complete before returning.
- *
+ * </p><p>
* This method is dangerous! Improper use can result in deadlocks.
* Never call this method while any locks are held or use it in a
* possibly re-entrant manner.
- *
+ * </p><p>
* This method is occasionally useful in situations where a background thread
* must synchronously await completion of a task that must run on the
* handler's thread. However, this problem is often a symptom of bad design.
* Consider improving the design (if possible) before resorting to this method.
- *
+ * </p><p>
* One example of where you might want to use this method is when you just
* set up a Handler thread and need to perform some initialization steps on
* it before continuing execution.
- *
+ * </p><p>
* If timeout occurs then this method returns <code>false</code> but the runnable
* will remain posted on the handler and may already be in progress or
* complete at a later time.
+ * </p><p>
+ * When using this method, be sure to use {@link Looper#quitSafely} when
+ * quitting the looper. Otherwise {@link #runWithScissors} may hang indefinitely.
+ * (TODO: We should fix this by making MessageQueue aware of blocking runnables.)
+ * </p>
*
* @param r The Runnable that will be executed synchronously.
* @param timeout The timeout in milliseconds, or 0 to wait indefinitely.
diff --git a/core/java/android/os/HandlerThread.java b/core/java/android/os/HandlerThread.java
index daf1f5933520..2904105ef782 100644
--- a/core/java/android/os/HandlerThread.java
+++ b/core/java/android/os/HandlerThread.java
@@ -48,6 +48,7 @@ public class HandlerThread extends Thread {
protected void onLooperPrepared() {
}
+ @Override
public void run() {
mTid = Process.myTid();
Looper.prepare();
@@ -83,12 +84,25 @@ public class HandlerThread extends Thread {
}
return mLooper;
}
-
+
/**
- * Ask the currently running looper to quit. If the thread has not
- * been started or has finished (that is if {@link #getLooper} returns
- * null), then false is returned. Otherwise the looper is asked to
- * quit and true is returned.
+ * Quits the handler thread's looper.
+ * <p>
+ * Causes the handler thread's looper to terminate without processing any
+ * more messages in the message queue.
+ * </p><p>
+ * Any attempt to post messages to the queue after the looper is asked to quit will fail.
+ * For example, the {@link Handler#sendMessage(Message)} method will return false.
+ * </p><p class="note">
+ * Using this method may be unsafe because some messages may not be delivered
+ * before the looper terminates. Consider using {@link #quitSafely} instead to ensure
+ * that all pending work is completed in an orderly manner.
+ * </p>
+ *
+ * @return True if the looper looper has been asked to quit or false if the
+ * thread had not yet started running.
+ *
+ * @see #quitSafely
*/
public boolean quit() {
Looper looper = getLooper();
@@ -98,7 +112,34 @@ public class HandlerThread extends Thread {
}
return false;
}
-
+
+ /**
+ * Quits the handler thread's looper safely.
+ * <p>
+ * Causes the handler thread's looper to terminate as soon as all remaining messages
+ * in the message queue that are already due to be delivered have been handled.
+ * Pending delayed messages with due times in the future will not be delivered.
+ * </p><p>
+ * Any attempt to post messages to the queue after the looper is asked to quit will fail.
+ * For example, the {@link Handler#sendMessage(Message)} method will return false.
+ * </p><p>
+ * If the thread has not been started or has finished (that is if
+ * {@link #getLooper} returns null), then false is returned.
+ * Otherwise the looper is asked to quit and true is returned.
+ * </p>
+ *
+ * @return True if the looper looper has been asked to quit or false if the
+ * thread had not yet started running.
+ */
+ public boolean quitSafely() {
+ Looper looper = getLooper();
+ if (looper != null) {
+ looper.quitSafely();
+ return true;
+ }
+ return false;
+ }
+
/**
* Returns the identifier of this thread. See Process.myTid().
*/
diff --git a/core/java/android/os/Looper.java b/core/java/android/os/Looper.java
index fa28765206f0..d5cf771a22bc 100644
--- a/core/java/android/os/Looper.java
+++ b/core/java/android/os/Looper.java
@@ -202,18 +202,37 @@ public final class Looper {
/**
* Quits the looper.
* <p>
+ * Causes the {@link #loop} method to terminate without processing any
+ * more messages in the message queue.
+ * </p><p>
+ * Any attempt to post messages to the queue after the looper is asked to quit will fail.
+ * For example, the {@link Handler#sendMessage(Message)} method will return false.
+ * </p><p class="note">
+ * Using this method may be unsafe because some messages may not be delivered
+ * before the looper terminates. Consider using {@link #quitSafely} instead to ensure
+ * that all pending work is completed in an orderly manner.
+ * </p>
+ *
+ * @see #quitSafely
+ */
+ public void quit() {
+ mQueue.quit(false);
+ }
+
+ /**
+ * Quits the looper safely.
+ * <p>
* Causes the {@link #loop} method to terminate as soon as all remaining messages
* in the message queue that are already due to be delivered have been handled.
- * However delayed messages with due times in the future may not be handled before
- * the loop terminates.
+ * However pending delayed messages with due times in the future will not be
+ * delivered before the loop terminates.
* </p><p>
- * Any attempt to post messages to the queue after {@link #quit} has been called
- * will fail. For example, the {@link Handler#sendMessage(Message)} method will
- * return false when the looper is being terminated.
+ * Any attempt to post messages to the queue after the looper is asked to quit will fail.
+ * For example, the {@link Handler#sendMessage(Message)} method will return false.
* </p>
*/
- public void quit() {
- mQueue.quit();
+ public void quitSafely() {
+ mQueue.quit(true);
}
/**
diff --git a/core/java/android/os/MessageQueue.java b/core/java/android/os/MessageQueue.java
index c058bfce28e6..bf7e5caf7024 100644
--- a/core/java/android/os/MessageQueue.java
+++ b/core/java/android/os/MessageQueue.java
@@ -219,7 +219,7 @@ public final class MessageQueue {
}
}
- void quit() {
+ void quit(boolean safe) {
if (!mQuitAllowed) {
throw new RuntimeException("Main thread not allowed to quit.");
}
@@ -229,6 +229,12 @@ public final class MessageQueue {
return;
}
mQuiting = true;
+
+ if (safe) {
+ removeAllFutureMessagesLocked();
+ } else {
+ removeAllMessagesLocked();
+ }
}
nativeWake(mPtr);
}
@@ -473,4 +479,42 @@ public final class MessageQueue {
}
}
}
+
+ private void removeAllMessagesLocked() {
+ Message p = mMessages;
+ while (p != null) {
+ Message n = p.next;
+ p.recycle();
+ p = n;
+ }
+ mMessages = null;
+ }
+
+ private void removeAllFutureMessagesLocked() {
+ final long now = SystemClock.uptimeMillis();
+ Message p = mMessages;
+ if (p != null) {
+ if (p.when > now) {
+ removeAllMessagesLocked();
+ } else {
+ Message n;
+ for (;;) {
+ n = p.next;
+ if (n == null) {
+ return;
+ }
+ if (n.when > now) {
+ break;
+ }
+ p = n;
+ }
+ p.next = null;
+ do {
+ p = n;
+ n = p.next;
+ p.recycle();
+ } while (n != null);
+ }
+ }
+ }
}
diff --git a/core/java/android/util/PropertyValueModel.java b/core/java/android/util/PropertyValueModel.java
deleted file mode 100755
index eb9c47d0c379..000000000000
--- a/core/java/android/util/PropertyValueModel.java
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * Copyright (C) 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.util;
-
-/**
- * A value model for a {@link Property property} of a host object. This class can be used for
- * both reflective and non-reflective property implementations.
- *
- * @param <H> the host type, where the host is the object that holds this property
- * @param <T> the value type
- *
- * @see Property
- * @see ValueModel
- */
-public class PropertyValueModel<H, T> extends ValueModel<T> {
- private final H mHost;
- private final Property<H, T> mProperty;
-
- private PropertyValueModel(H host, Property<H, T> property) {
- mProperty = property;
- mHost = host;
- }
-
- /**
- * Returns the host.
- *
- * @return the host
- */
- public H getHost() {
- return mHost;
- }
-
- /**
- * Returns the property.
- *
- * @return the property
- */
- public Property<H, T> getProperty() {
- return mProperty;
- }
-
- @Override
- public Class<T> getType() {
- return mProperty.getType();
- }
-
- @Override
- public T get() {
- return mProperty.get(mHost);
- }
-
- @Override
- public void set(T value) {
- mProperty.set(mHost, value);
- }
-
- /**
- * Return an appropriate PropertyValueModel for this host and property.
- *
- * @param host the host
- * @param property the property
- * @return the value model
- */
- public static <H, T> PropertyValueModel<H, T> of(H host, Property<H, T> property) {
- return new PropertyValueModel<H, T>(host, property);
- }
-
- /**
- * Return a PropertyValueModel for this {@code host} and a
- * reflective property, constructed from this {@code propertyType} and {@code propertyName}.
- *
- * @param host
- * @param propertyType the property type
- * @param propertyName the property name
- * @return a value model with this host and a reflective property with this type and name
- *
- * @see Property#of
- */
- public static <H, T> PropertyValueModel<H, T> of(H host, Class<T> propertyType,
- String propertyName) {
- return of(host, Property.of((Class<H>) host.getClass(), propertyType, propertyName));
- }
-
- private static Class getNullaryMethodReturnType(Class c, String name) {
- try {
- return c.getMethod(name).getReturnType();
- } catch (NoSuchMethodException e) {
- return null;
- }
- }
-
- private static Class getFieldType(Class c, String name) {
- try {
- return c.getField(name).getType();
- } catch (NoSuchFieldException e) {
- return null;
- }
- }
-
- private static String capitalize(String name) {
- if (name.isEmpty()) {
- return name;
- }
- return Character.toUpperCase(name.charAt(0)) + name.substring(1);
- }
-
- /**
- * Return a PropertyValueModel for this {@code host} and and {@code propertyName}.
- *
- * @param host the host
- * @param propertyName the property name
- * @return a value model with this host and a reflective property with this name
- */
- public static PropertyValueModel of(Object host, String propertyName) {
- Class clazz = host.getClass();
- String suffix = capitalize(propertyName);
- Class propertyType = getNullaryMethodReturnType(clazz, "get" + suffix);
- if (propertyType == null) {
- propertyType = getNullaryMethodReturnType(clazz, "is" + suffix);
- }
- if (propertyType == null) {
- propertyType = getFieldType(clazz, propertyName);
- }
- if (propertyType == null) {
- throw new NoSuchPropertyException(propertyName);
- }
- return of(host, propertyType, propertyName);
- }
-}
diff --git a/core/java/android/util/ValueModel.java b/core/java/android/util/ValueModel.java
deleted file mode 100755
index 4789682ea496..000000000000
--- a/core/java/android/util/ValueModel.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright (C) 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.util;
-
-/**
- * A ValueModel is an abstraction for a 'slot' or place in memory in which a value
- * may be stored and retrieved. A common implementation of ValueModel is a regular property of
- * an object, whose value may be retrieved by calling the appropriate <em>getter</em>
- * method and set by calling the corresponding <em>setter</em> method.
- *
- * @param <T> the value type
- *
- * @see PropertyValueModel
- */
-public abstract class ValueModel<T> {
- /**
- * The empty model should be used in place of {@code null} to indicate that a
- * model has not been set. The empty model has no value and does nothing when it is set.
- */
- public static final ValueModel EMPTY = new ValueModel() {
- @Override
- public Class getType() {
- return Object.class;
- }
-
- @Override
- public Object get() {
- return null;
- }
-
- @Override
- public void set(Object value) {
-
- }
- };
-
- protected ValueModel() {
- }
-
- /**
- * Returns the type of this property.
- *
- * @return the property type
- */
- public abstract Class<T> getType();
-
- /**
- * Returns the value of this property.
- *
- * @return the property value
- */
- public abstract T get();
-
- /**
- * Sets the value of this property.
- *
- * @param value the new value for this property
- */
- public abstract void set(T value);
-} \ No newline at end of file
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index be26d20d5350..a0a63a619ac7 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -2915,14 +2915,14 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
*
* @hide
*/
- int mUserPaddingLeftInitial = 0;
+ int mUserPaddingLeftInitial;
/**
* Cache initial right padding.
*
* @hide
*/
- int mUserPaddingRightInitial = 0;
+ int mUserPaddingRightInitial;
/**
* Default undefined padding
@@ -3388,11 +3388,11 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
break;
case com.android.internal.R.styleable.View_paddingStart:
startPadding = a.getDimensionPixelSize(attr, UNDEFINED_PADDING);
- startPaddingDefined = true;
+ startPaddingDefined = (startPadding != UNDEFINED_PADDING);
break;
case com.android.internal.R.styleable.View_paddingEnd:
endPadding = a.getDimensionPixelSize(attr, UNDEFINED_PADDING);
- endPaddingDefined = true;
+ endPaddingDefined = (endPadding != UNDEFINED_PADDING);
break;
case com.android.internal.R.styleable.View_scrollX:
x = a.getDimensionPixelOffset(attr, 0);
@@ -3712,10 +3712,12 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
// Padding from the background drawable is stored at this point in mUserPaddingLeftInitial
// and mUserPaddingRightInitial) so drawable padding will be used as ultimate default if
// defined.
- if (leftPaddingDefined) {
+ final boolean hasRelativePadding = startPaddingDefined || endPaddingDefined;
+
+ if (leftPaddingDefined && !hasRelativePadding) {
mUserPaddingLeftInitial = leftPadding;
}
- if (rightPaddingDefined) {
+ if (rightPaddingDefined && !hasRelativePadding) {
mUserPaddingRightInitial = rightPadding;
}
}
@@ -11952,26 +11954,30 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
// left / right or right / left depending on the resolved layout direction.
// If start / end padding are not defined, use the left / right ones.
int resolvedLayoutDirection = getLayoutDirection();
- // Set user padding to initial values ...
- mUserPaddingLeft = mUserPaddingLeftInitial;
- mUserPaddingRight = mUserPaddingRightInitial;
- // ... then resolve it.
switch (resolvedLayoutDirection) {
case LAYOUT_DIRECTION_RTL:
if (mUserPaddingStart != UNDEFINED_PADDING) {
mUserPaddingRight = mUserPaddingStart;
+ } else {
+ mUserPaddingRight = mUserPaddingRightInitial;
}
if (mUserPaddingEnd != UNDEFINED_PADDING) {
mUserPaddingLeft = mUserPaddingEnd;
+ } else {
+ mUserPaddingLeft = mUserPaddingLeftInitial;
}
break;
case LAYOUT_DIRECTION_LTR:
default:
if (mUserPaddingStart != UNDEFINED_PADDING) {
mUserPaddingLeft = mUserPaddingStart;
+ } else {
+ mUserPaddingLeft = mUserPaddingLeftInitial;
}
if (mUserPaddingEnd != UNDEFINED_PADDING) {
mUserPaddingRight = mUserPaddingEnd;
+ } else {
+ mUserPaddingRight = mUserPaddingRightInitial;
}
}
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index 48630a4156ed..0212482f8961 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -795,9 +795,7 @@ public interface WindowManager extends ViewManager {
* <p>This flag can be controlled in your theme through the
* {@link android.R.attr#windowOverscan} attribute; this attribute
* is automatically set for you in the standard overscan themes
- * such as {@link android.R.style#Theme_NoTitleBar_Overscan},
- * {@link android.R.style#Theme_Black_NoTitleBar_Overscan},
- * {@link android.R.style#Theme_Light_NoTitleBar_Overscan},
+ * such as
* {@link android.R.style#Theme_Holo_NoActionBar_Overscan},
* {@link android.R.style#Theme_Holo_Light_NoActionBar_Overscan},
* {@link android.R.style#Theme_DeviceDefault_NoActionBar_Overscan}, and
diff --git a/core/java/android/widget/CheckBox.java b/core/java/android/widget/CheckBox.java
index 41ab5f25f6db..f1804f8b97b2 100644
--- a/core/java/android/widget/CheckBox.java
+++ b/core/java/android/widget/CheckBox.java
@@ -20,7 +20,6 @@ import android.content.Context;
import android.util.AttributeSet;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityNodeInfo;
-import android.util.ValueModel;
/**
@@ -56,9 +55,7 @@ import android.util.ValueModel;
* {@link android.R.styleable#View View Attributes}
* </p>
*/
-public class CheckBox extends CompoundButton implements ValueEditor<Boolean> {
- private ValueModel<Boolean> mValueModel = ValueModel.EMPTY;
-
+public class CheckBox extends CompoundButton {
public CheckBox(Context context) {
this(context, null);
}
@@ -82,22 +79,4 @@ public class CheckBox extends CompoundButton implements ValueEditor<Boolean> {
super.onInitializeAccessibilityNodeInfo(info);
info.setClassName(CheckBox.class.getName());
}
-
- @Override
- public ValueModel<Boolean> getValueModel() {
- return mValueModel;
- }
-
- @Override
- public void setValueModel(ValueModel<Boolean> valueModel) {
- mValueModel = valueModel;
- setChecked(mValueModel.get());
- }
-
- @Override
- public boolean performClick() {
- boolean handled = super.performClick();
- mValueModel.set(isChecked());
- return handled;
- }
}
diff --git a/core/java/android/widget/EditText.java b/core/java/android/widget/EditText.java
index ec812143e15e..57e51c259251 100644
--- a/core/java/android/widget/EditText.java
+++ b/core/java/android/widget/EditText.java
@@ -17,7 +17,6 @@
package android.widget;
import android.content.Context;
-import android.graphics.Rect;
import android.text.Editable;
import android.text.Selection;
import android.text.Spannable;
@@ -25,7 +24,6 @@ import android.text.TextUtils;
import android.text.method.ArrowKeyMovementMethod;
import android.text.method.MovementMethod;
import android.util.AttributeSet;
-import android.util.ValueModel;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityNodeInfo;
@@ -49,9 +47,7 @@ import android.view.accessibility.AccessibilityNodeInfo;
* {@link android.R.styleable#TextView TextView Attributes},
* {@link android.R.styleable#View View Attributes}
*/
-public class EditText extends TextView implements ValueEditor<CharSequence> {
- private ValueModel<CharSequence> mValueModel = ValueModel.EMPTY;
-
+public class EditText extends TextView {
public EditText(Context context) {
this(context, null);
}
@@ -132,21 +128,4 @@ public class EditText extends TextView implements ValueEditor<CharSequence> {
super.onInitializeAccessibilityNodeInfo(info);
info.setClassName(EditText.class.getName());
}
-
- @Override
- public ValueModel<CharSequence> getValueModel() {
- return mValueModel;
- }
-
- @Override
- public void setValueModel(ValueModel<CharSequence> valueModel) {
- mValueModel = valueModel;
- setText(mValueModel.get());
- }
-
- @Override
- void sendAfterTextChanged(Editable text) {
- super.sendAfterTextChanged(text);
- mValueModel.set(text);
- }
}
diff --git a/core/java/android/widget/ListView.java b/core/java/android/widget/ListView.java
index c7914f3ffc46..f42999d283cb 100644
--- a/core/java/android/widget/ListView.java
+++ b/core/java/android/widget/ListView.java
@@ -41,6 +41,7 @@ import android.view.ViewParent;
import android.view.ViewRootImpl;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityNodeInfo;
+import android.view.accessibility.AccessibilityNodeProvider;
import android.widget.RemoteViews.RemoteView;
import java.util.ArrayList;
@@ -1715,11 +1716,17 @@ public class ListView extends AbsListView {
}
// Attempt to restore accessibility focus.
- if (accessibilityFocusLayoutRestoreNode != null) {
- accessibilityFocusLayoutRestoreNode.performAction(
- AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS);
- } else if (accessibilityFocusLayoutRestoreView != null) {
- accessibilityFocusLayoutRestoreView.requestAccessibilityFocus();
+ if (accessibilityFocusLayoutRestoreView != null) {
+ final AccessibilityNodeProvider provider =
+ accessibilityFocusLayoutRestoreView.getAccessibilityNodeProvider();
+ if ((accessibilityFocusLayoutRestoreNode != null) && (provider != null)) {
+ final int virtualViewId = AccessibilityNodeInfo.getVirtualDescendantId(
+ accessibilityFocusLayoutRestoreNode.getSourceNodeId());
+ provider.performAction(virtualViewId,
+ AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS, null);
+ } else {
+ accessibilityFocusLayoutRestoreView.requestAccessibilityFocus();
+ }
} else if (accessibilityFocusPosition != INVALID_POSITION) {
// Bound the position within the visible children.
final int position = MathUtils.constrain(
diff --git a/core/java/android/widget/SeekBar.java b/core/java/android/widget/SeekBar.java
index a6486a827af5..2737f9414c46 100644
--- a/core/java/android/widget/SeekBar.java
+++ b/core/java/android/widget/SeekBar.java
@@ -18,7 +18,6 @@ package android.widget;
import android.content.Context;
import android.util.AttributeSet;
-import android.util.ValueModel;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityNodeInfo;
@@ -34,7 +33,7 @@ import android.view.accessibility.AccessibilityNodeInfo;
*
* @attr ref android.R.styleable#SeekBar_thumb
*/
-public class SeekBar extends AbsSeekBar implements ValueEditor<Integer> {
+public class SeekBar extends AbsSeekBar {
/**
* A callback that notifies clients when the progress level has been
@@ -70,9 +69,8 @@ public class SeekBar extends AbsSeekBar implements ValueEditor<Integer> {
void onStopTrackingTouch(SeekBar seekBar);
}
- private ValueModel<Integer> mValueModel = ValueModel.EMPTY;
private OnSeekBarChangeListener mOnSeekBarChangeListener;
-
+
public SeekBar(Context context) {
this(context, null);
}
@@ -91,23 +89,9 @@ public class SeekBar extends AbsSeekBar implements ValueEditor<Integer> {
if (mOnSeekBarChangeListener != null) {
mOnSeekBarChangeListener.onProgressChanged(this, getProgress(), fromUser);
- if (fromUser) {
- mValueModel.set(getProgress());
- }
}
}
- @Override
- public ValueModel<Integer> getValueModel() {
- return mValueModel;
- }
-
- @Override
- public void setValueModel(ValueModel<Integer> valueModel) {
- mValueModel = valueModel;
- setProgress(mValueModel.get());
- }
-
/**
* Sets a listener to receive notifications of changes to the SeekBar's progress level. Also
* provides notifications of when the user starts and stops a touch gesture within the SeekBar.
diff --git a/core/java/android/widget/ValueEditor.java b/core/java/android/widget/ValueEditor.java
deleted file mode 100755
index 2b91abf9b8ff..000000000000
--- a/core/java/android/widget/ValueEditor.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (C) 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.widget;
-
-import android.util.ValueModel;
-
-/**
- * An interface for editors of simple values. Classes implementing this interface are normally
- * UI controls (subclasses of {@link android.view.View View}) that can provide a suitable
- * user interface to display and edit values of the specified type. This interface is
- * intended to describe editors for simple types, like {@code boolean}, {@code int} or
- * {@code String}, where the values themselves are immutable.
- * <p>
- * For example, {@link android.widget.CheckBox CheckBox} implements
- * this interface for the Boolean type as it is capable of providing an appropriate
- * mechanism for displaying and changing the value of a Boolean property.
- *
- * @param <T> the value type that this editor supports
- */
-public interface ValueEditor<T> {
- /**
- * Return the last value model that was set. If no value model has been set, the editor
- * should return the value {@link android.util.ValueModel#EMPTY}.
- *
- * @return the value model
- */
- public ValueModel<T> getValueModel();
-
- /**
- * Sets the value model for this editor. When the value model is set, the editor should
- * retrieve the value from the value model, using {@link android.util.ValueModel#get()},
- * and set its internal state accordingly. Likewise, when the editor's internal state changes
- * it should update the value model by calling {@link android.util.ValueModel#set(T)}
- * with the appropriate value.
- *
- * @param valueModel the new value model for this editor.
- */
- public void setValueModel(ValueModel<T> valueModel);
-}
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 104cc91cdac7..cb14374f13ab 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -545,6 +545,7 @@
<!-- =============================================== -->
<!-- Permissions for enabling accessibility features -->
<!-- =============================================== -->
+ <eat-comment />
<!-- Used for permissions that allow requesting certain accessibility features. -->
<permission-group android:name="android.permission-group.ACCESSIBILITY_FEATURES"
@@ -553,20 +554,6 @@
android:description="@string/permgroupdesc_accessibilityFeatures"
android:priority="380" />
- <!-- Allows an accessibility service to request touch exploration mode. -->
- <permission android:name="android.permission.CAN_REQUEST_TOUCH_EXPLORATION_MODE"
- android:permissionGroup="android.permission-group.ACCESSIBILITY_FEATURES"
- android:label="@string/permlab_canRequestTouchExplorationMode"
- android:description="@string/permdesc_canRequestTouchExplorationMode"
- android:protectionLevel="dangerous" />
-
- <!-- Allows an accessibility service to request enhanced web accessibility. -->
- <permission android:name="android.permission.CAN_REQUEST_ENHANCED_WEB_ACCESSIBILITY"
- android:permissionGroup="android.permission-group.ACCESSIBILITY_FEATURES"
- android:label="@string/permlab_canRequestEnahncedWebAccessibility"
- android:description="@string/permdesc_canRequestEnahncedWebAccessibility"
- android:protectionLevel="dangerous" />
-
<!-- ======================================= -->
<!-- Permissions for accessing location info -->
<!-- ======================================= -->
@@ -837,6 +824,7 @@
<!-- ==================================================== -->
<!-- Permissions related to changing audio settings -->
<!-- ==================================================== -->
+ <eat-comment />
<!-- Used for permissions that provide direct access to speaker settings
the device. -->
@@ -1276,6 +1264,7 @@
<!-- ==================================================== -->
<!-- Permissions related to changing status bar -->
<!-- ==================================================== -->
+ <eat-comment />
<!-- Used for permissions that change the status bar -->
<permission-group android:name="android.permission-group.STATUS_BAR"
@@ -1294,6 +1283,7 @@
<!-- ==================================================== -->
<!-- Permissions related to accessing sync settings -->
<!-- ==================================================== -->
+ <eat-comment />
<!-- Used for permissions that access the sync settings or sync
related information. -->
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 8c7a37462c31..60f3f3250c79 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -2521,13 +2521,43 @@
<flag name="flagRequestTouchExplorationMode" value="0x00000004" />
<!-- Has flag {@link android.accessibilityservice.AccessibilityServiceInfo#FLAG_REQUEST_ENHANCED_WEB_ACCESSIBILITY} -->
<flag name="flagRequestEnhancedWebAccessibility" value="0x00000008" />
+ <!-- Has flag {@link android.accessibilityservice.AccessibilityServiceInfo#FLAG_REPORT_VIEW_IDS} -->
+ <flag name="flagReportViewIds" value="0x00000010" />
+ <!-- Has flag {@link android.accessibilityservice.AccessibilityServiceInfo#FLAG_REQUEST_FILTER_KEY_EVENTS} -->
+ <flag name="flagRequestFilterKeyEvents" value="0x00000020" />
</attr>
<!-- Component name of an activity that allows the user to modify
the settings for this service. This setting cannot be changed at runtime. -->
<attr name="settingsActivity" />
- <!-- Flag whether the accessibility service wants to be able to retrieve the
+ <!-- Attribute whether the accessibility service wants to be able to retrieve the
active window content. This setting cannot be changed at runtime. -->
<attr name="canRetrieveWindowContent" format="boolean" />
+ <!-- Attribute whether the accessibility service wants to be able to request touch
+ exploration mode in which touched items are spoken aloud and the UI can be
+ explored via gestures.
+ <p>
+ Required to allow setting the {@link android.accessibilityservice
+ #AccessibilityServiceInfo#FLAG_REQUEST_TOUCH_EXPLORATION_MODE} flag.
+ </p>
+ -->
+ <attr name="canRequestTouchExplorationMode" format="boolean" />
+ <!-- Attribute whether the accessibility service wants to be able to request enhanced
+ web accessibility enhancements. For example, installing scripts to make app
+ content more accessible.
+ <p>
+ Required to allow setting the {@link android.accessibilityservice
+ #AccessibilityServiceInfo#FLAG_REQUEST_ENHANCED_WEB_ACCESSIBILITY} flag.
+ </p>
+ -->
+ <attr name="canRequestEnhancedWebAccessibility" format="boolean" />
+ <!-- Attribute whether the accessibility service wants to be able to request to
+ filter key events.
+ <p>
+ Required to allow setting the {@link android.accessibilityservice
+ #AccessibilityServiceInfo#FLAG_REQUEST_FILTER_KEY_EVENTS} flag.
+ </p>
+ -->
+ <attr name="canRequestFilterKeyEvents" format="boolean" />
<!-- Short description of the accessibility serivce purpose or behavior.-->
<attr name="description" />
</declare-styleable>
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 074d91f9cbb5..c150fe01c255 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -2043,10 +2043,10 @@
<public type="attr" name="childIndicatorEnd" />
<public type="attr" name="restrictedAccountType" />
<public type="attr" name="requiredAccountType" />
+ <public type="attr" name="canRequestTouchExplorationMode" />
+ <public type="attr" name="canRequestEnhancedWebAccessibility" />
+ <public type="attr" name="canRequestFilterKeyEvents" />
- <public type="style" name="Theme.NoTitleBar.Overscan" />
- <public type="style" name="Theme.Light.NoTitleBar.Overscan" />
- <public type="style" name="Theme.Black.NoTitleBar.Overscan" />
<public type="style" name="Theme.Holo.NoActionBar.Overscan" />
<public type="style" name="Theme.Holo.Light.NoActionBar.Overscan" />
<public type="style" name="Theme.DeviceDefault.NoActionBar.Overscan" />
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 3361ab7439c9..db9602a1f10d 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -545,6 +545,31 @@
<!-- Description of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permgroupdesc_accessibilityFeatures">Features that assistive technology can request.</string>
+ <!-- Title for the capability of an accessibility service to retrieve window content. -->
+ <string name="capability_title_canRetrieveWindowContent">Retrieve window content</string>
+ <!-- Description for the capability of an accessibility service to retrieve window content. -->
+ <string name="capability_desc_canRetrieveWindowContent">Inspect the content of a window you\'re
+ interacting with.</string>
+
+ <!-- Title for the capability of an accessibility service to request touch exploration. -->
+ <string name="capability_title_canRequestTouchExploration">Turn on Explore by Touch</string>
+ <!-- Description for the capability of an accessibility service to request touch exploration. -->
+ <string name="capability_desc_canRequestTouchExploration">Touched items will be spoken aloud
+ and the screen can be explored using gestures.</string>
+
+ <!-- Title for the capability of an accessibility service to request enhanced web accessibility. -->
+ <string name="capability_title_canRequestEnhancedWebAccessibility">Turn on enhanced web
+ accessibility</string>
+ <!-- Description for the capability of an accessibility service to request enhanced web accessibility. -->
+ <string name="capability_desc_canRequestEnhancedWebAccessibility">Scripts may be installed to
+ make app content more accessible.</string>
+
+ <!-- Title for the capability of an accessibility service to request to filter key events. -->
+ <string name="capability_title_canRequestFilterKeyEvents">Observe text you type</string>
+ <!-- Description for the capability of an accessibility service to request to filter key events. -->
+ <string name="capability_desc_canRequestFilterKeyEvents">Includes personal data such as credit
+ card numbers and passwords.</string>
+
<!-- Permissions -->
<!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
@@ -945,20 +970,6 @@
interface of an accessibility service. Should never be needed for normal apps.</string>
<!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
- <string name="permlab_canRequestTouchExplorationMode">request explore by touch</string>
- <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
- <string name="permdesc_canRequestTouchExplorationMode">Allows the hoder to request an
- interaction mode in which touched items are spoken aloud and the UI can be explored
- via gestures.</string>
-
- <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
- <string name="permlab_canRequestEnahncedWebAccessibility">request enhanced web accessibility</string>
- <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
- <string name="permdesc_canRequestEnahncedWebAccessibility">Allows the hoder to request
- enabling of web accessibility enhancements. For example, installing scripts to make
- app content more accessible.</string>
-
- <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permlab_bindTextService">bind to a text service</string>
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permdesc_bindTextService">Allows the holder to bind to the top-level
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 5e753900eee1..fdf7c8f65606 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -438,6 +438,14 @@
<java-symbol type="string" name="badPin" />
<java-symbol type="string" name="badPuk" />
<java-symbol type="string" name="byteShort" />
+ <java-symbol type="string" name="capability_desc_canRequestEnhancedWebAccessibility" />
+ <java-symbol type="string" name="capability_title_canRequestFilterKeyEvents" />
+ <java-symbol type="string" name="capability_desc_canRequestTouchExploration" />
+ <java-symbol type="string" name="capability_desc_canRetrieveWindowContent" />
+ <java-symbol type="string" name="capability_title_canRequestEnhancedWebAccessibility" />
+ <java-symbol type="string" name="capability_desc_canRequestFilterKeyEvents" />
+ <java-symbol type="string" name="capability_title_canRequestTouchExploration" />
+ <java-symbol type="string" name="capability_title_canRetrieveWindowContent" />
<java-symbol type="string" name="cfTemplateForwarded" />
<java-symbol type="string" name="cfTemplateForwardedTime" />
<java-symbol type="string" name="cfTemplateNotForwarded" />
diff --git a/core/res/res/values/themes.xml b/core/res/res/values/themes.xml
index e1750af3335a..80f7486f8f51 100644
--- a/core/res/res/values/themes.xml
+++ b/core/res/res/values/themes.xml
@@ -405,16 +405,6 @@ please see themes_device_defaults.xml.
<item name="android:windowContentOverlay">@null</item>
</style>
- <!-- Variant of {@link #Theme} that has no title bar and no status bar and extending
- into the display overscan region. This theme
- sets {@link android.R.attr#windowFullscreen} and {@link android.R.attr#windowOverscan}
- to true. -->
- <style name="Theme.NoTitleBar.Overscan">
- <item name="android:windowFullscreen">true</item>
- <item name="android:windowOverscan">true</item>
- <item name="android:windowContentOverlay">@null</item>
- </style>
-
<!-- Theme for a light background with dark text on top. Set your activity
to this theme if you would like such an appearance. As with the
default theme, you should try to assume little more than that the
@@ -508,16 +498,6 @@ please see themes_device_defaults.xml.
<item name="android:windowContentOverlay">@null</item>
</style>
- <!-- Variant of {@link #Theme_Light} that has no title bar and
- no status bar and extending into the display overscan region. This theme
- sets {@link android.R.attr#windowFullscreen} and {@link android.R.attr#windowOverscan}
- to true. -->
- <style name="Theme.Light.NoTitleBar.Overscan">
- <item name="android:windowFullscreen">true</item>
- <item name="android:windowOverscan">true</item>
- <item name="android:windowContentOverlay">@null</item>
- </style>
-
<!-- Variant on {@link #Theme} that ensures the background is
completely black. This is useful for things like image viewers and
media players. If you want the normal (dark background) theme
@@ -539,16 +519,6 @@ please see themes_device_defaults.xml.
<item name="android:windowFullscreen">true</item>
<item name="android:windowContentOverlay">@null</item>
</style>
-
- <!-- Variant of {@link #Theme_Black} that has no title bar and
- no status bar and extending into the display overscan region. This theme
- sets {@link android.R.attr#windowFullscreen} and {@link android.R.attr#windowOverscan}
- to true. -->
- <style name="Theme.Black.NoTitleBar.Overscan">
- <item name="android:windowFullscreen">true</item>
- <item name="android:windowOverscan">true</item>
- <item name="android:windowContentOverlay">@null</item>
- </style>
<!-- Theme for windows that want to have the user's selected
wallpaper appear behind them (for API level 10 and lower). -->
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index 917a47df52be..56e98e4a9206 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -24,6 +24,7 @@ import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.os.Binder;
+import android.os.Build;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
@@ -1205,6 +1206,11 @@ public class AudioManager {
* call {@link #stopBluetoothSco()} to clear the request and turn down the bluetooth connection.
* <p>Even if a SCO connection is established, the following restrictions apply on audio
* output streams so that they can be routed to SCO headset:
+ * <p>NOTE: up to and including API version
+ * {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR1}, this method initiates a virtual
+ * voice call to the bluetooth headset.
+ * After API version {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2} only a raw SCO audio
+ * connection is established.
* <ul>
* <li> the stream type must be {@link #STREAM_VOICE_CALL} </li>
* <li> the format must be mono </li>
@@ -1226,7 +1232,7 @@ public class AudioManager {
public void startBluetoothSco(){
IAudioService service = getService();
try {
- service.startBluetoothSco(mICallBack);
+ service.startBluetoothSco(mICallBack, mContext.getApplicationInfo().targetSdkVersion);
} catch (RemoteException e) {
Log.e(TAG, "Dead object in startBluetoothSco", e);
}
diff --git a/media/java/android/media/AudioService.java b/media/java/android/media/AudioService.java
index 637ac858fa9b..0df4f822393b 100644
--- a/media/java/android/media/AudioService.java
+++ b/media/java/android/media/AudioService.java
@@ -48,6 +48,7 @@ import android.database.ContentObserver;
import android.media.MediaPlayer.OnCompletionListener;
import android.media.MediaPlayer.OnErrorListener;
import android.os.Binder;
+import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
@@ -369,6 +370,14 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
// waiting for headset service to connect
private static final int SCO_STATE_DEACTIVATE_EXT_REQ = 4;
+ // Indicates the mode used for SCO audio connection. The mode is virtual call if the request
+ // originated from an app targeting an API version before JB MR2 and raw audio after that.
+ private int mScoAudioMode;
+ // SCO audio mode is virtual voice call (BluetoothHeadset.startScoUsingVirtualVoiceCall())
+ private static final int SCO_MODE_VIRTUAL_CALL = 0;
+ // SCO audio mode is raw audio (BluetoothHeadset.connectAudio())
+ private static final int SCO_MODE_RAW = 1;
+
// Current connection state indicated by bluetooth headset
private int mScoConnectionState;
@@ -1910,7 +1919,7 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
}
/** @see AudioManager#startBluetoothSco() */
- public void startBluetoothSco(IBinder cb){
+ public void startBluetoothSco(IBinder cb, int targetSdkVersion){
if (!checkAudioSettingsPermission("startBluetoothSco()") ||
!mBootCompleted) {
return;
@@ -1922,7 +1931,7 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
// The caller identity must be cleared after getScoClient() because it is needed if a new
// client is created.
final long ident = Binder.clearCallingIdentity();
- client.incCount();
+ client.incCount(targetSdkVersion);
Binder.restoreCallingIdentity(ident);
}
@@ -1968,9 +1977,9 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
}
}
- public void incCount() {
+ public void incCount(int targetSdkVersion) {
synchronized(mScoClients) {
- requestScoState(BluetoothHeadset.STATE_AUDIO_CONNECTED);
+ requestScoState(BluetoothHeadset.STATE_AUDIO_CONNECTED, targetSdkVersion);
if (mStartcount == 0) {
try {
mCb.linkToDeath(this, 0);
@@ -1996,7 +2005,7 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
Log.w(TAG, "decCount() going to 0 but not registered to binder");
}
}
- requestScoState(BluetoothHeadset.STATE_AUDIO_DISCONNECTED);
+ requestScoState(BluetoothHeadset.STATE_AUDIO_DISCONNECTED, 0);
}
}
}
@@ -2012,7 +2021,7 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
}
mStartcount = 0;
if (stopSco) {
- requestScoState(BluetoothHeadset.STATE_AUDIO_DISCONNECTED);
+ requestScoState(BluetoothHeadset.STATE_AUDIO_DISCONNECTED, 0);
}
}
}
@@ -2040,7 +2049,7 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
}
}
- private void requestScoState(int state) {
+ private void requestScoState(int state, int targetSdkVersion) {
checkScoAudioState();
if (totalCount() == 0) {
if (state == BluetoothHeadset.STATE_AUDIO_CONNECTED) {
@@ -2055,8 +2064,18 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
(mScoAudioState == SCO_STATE_INACTIVE ||
mScoAudioState == SCO_STATE_DEACTIVATE_REQ)) {
if (mScoAudioState == SCO_STATE_INACTIVE) {
+ mScoAudioMode =
+ (targetSdkVersion < Build.VERSION_CODES.JELLY_BEAN_MR2) ?
+ SCO_MODE_VIRTUAL_CALL : SCO_MODE_RAW;
if (mBluetoothHeadset != null && mBluetoothHeadsetDevice != null) {
- if (mBluetoothHeadset.connectAudio()) {
+ boolean status;
+ if (mScoAudioMode == SCO_MODE_RAW) {
+ status = mBluetoothHeadset.connectAudio();
+ } else {
+ status = mBluetoothHeadset.startScoUsingVirtualVoiceCall(
+ mBluetoothHeadsetDevice);
+ }
+ if (status) {
mScoAudioState = SCO_STATE_ACTIVE_INTERNAL;
} else {
broadcastScoConnectionState(
@@ -2078,7 +2097,14 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
mScoAudioState == SCO_STATE_ACTIVATE_REQ)) {
if (mScoAudioState == SCO_STATE_ACTIVE_INTERNAL) {
if (mBluetoothHeadset != null && mBluetoothHeadsetDevice != null) {
- if (!mBluetoothHeadset.disconnectAudio()) {
+ boolean status;
+ if (mScoAudioMode == SCO_MODE_RAW) {
+ status = mBluetoothHeadset.disconnectAudio();
+ } else {
+ status = mBluetoothHeadset.stopScoUsingVirtualVoiceCall(
+ mBluetoothHeadsetDevice);
+ }
+ if (!status) {
mScoAudioState = SCO_STATE_INACTIVE;
broadcastScoConnectionState(
AudioManager.SCO_AUDIO_STATE_DISCONNECTED);
@@ -2251,10 +2277,20 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
switch (mScoAudioState) {
case SCO_STATE_ACTIVATE_REQ:
mScoAudioState = SCO_STATE_ACTIVE_INTERNAL;
- status = mBluetoothHeadset.connectAudio();
+ if (mScoAudioMode == SCO_MODE_RAW) {
+ status = mBluetoothHeadset.connectAudio();
+ } else {
+ status = mBluetoothHeadset.startScoUsingVirtualVoiceCall(
+ mBluetoothHeadsetDevice);
+ }
break;
case SCO_STATE_DEACTIVATE_REQ:
- status = mBluetoothHeadset.disconnectAudio();
+ if (mScoAudioMode == SCO_MODE_RAW) {
+ status = mBluetoothHeadset.disconnectAudio();
+ } else {
+ status = mBluetoothHeadset.stopScoUsingVirtualVoiceCall(
+ mBluetoothHeadsetDevice);
+ }
break;
case SCO_STATE_DEACTIVATE_EXT_REQ:
status = mBluetoothHeadset.stopVoiceRecognition(
diff --git a/media/java/android/media/IAudioService.aidl b/media/java/android/media/IAudioService.aidl
index 13f6c021cc85..0d285fc171c2 100644
--- a/media/java/android/media/IAudioService.aidl
+++ b/media/java/android/media/IAudioService.aidl
@@ -179,7 +179,7 @@ interface IAudioService {
int getRemoteStreamVolume();
oneway void registerRemoteVolumeObserverForRcc(int rccId, in IRemoteVolumeObserver rvo);
- void startBluetoothSco(IBinder cb);
+ void startBluetoothSco(IBinder cb, int targetSdkVersion);
void stopBluetoothSco(IBinder cb);
void forceVolumeControlStream(int streamType, IBinder cb);
diff --git a/media/java/android/media/MediaCodecInfo.java b/media/java/android/media/MediaCodecInfo.java
index 1501c796727d..df87db39c2ed 100644
--- a/media/java/android/media/MediaCodecInfo.java
+++ b/media/java/android/media/MediaCodecInfo.java
@@ -44,7 +44,16 @@ public final class MediaCodecInfo {
return MediaCodecList.getSupportedTypes(mIndex);
}
+ /**
+ * Encapsulates the capabilities of a given codec component,
+ * i.e. what profile/level combinations it supports and what colorspaces
+ * it is capable of providing the decoded data in.
+ */
public static final class CodecCapabilities {
+ // Enumerates supported profile/level combinations as defined
+ // by the type of encoded data. These combinations impose restrictions
+ // on video resolution, bitrate... and limit the available encoder tools
+ // such as B-frame support, arithmetic coding...
public CodecProfileLevel[] profileLevels;
// from OMX_COLOR_FORMATTYPE
@@ -219,6 +228,11 @@ public final class MediaCodecInfo {
public int level;
};
+ /**
+ * Enumerates the capabilities of the codec component. Since a single
+ * component can support data of a variety of types, the type has to be
+ * specified to yield a meaningful result.
+ */
public final CodecCapabilities getCapabilitiesForType(
String type) {
return MediaCodecList.getCodecCapabilities(mIndex, type);
diff --git a/media/java/android/media/RemoteControlClient.java b/media/java/android/media/RemoteControlClient.java
index 61a0134e01ed..f77ddc4297f6 100644
--- a/media/java/android/media/RemoteControlClient.java
+++ b/media/java/android/media/RemoteControlClient.java
@@ -65,6 +65,7 @@ import java.util.Iterator;
public class RemoteControlClient
{
private final static String TAG = "RemoteControlClient";
+ private final static boolean DEBUG = false;
/**
* Playback state of a RemoteControlClient which is stopped.
@@ -219,7 +220,7 @@ public class RemoteControlClient
public final static int PLAYBACKINFO_USES_STREAM = 5;
//==========================================
- // Public flags for the supported transport control capabililities
+ // Public flags for the supported transport control capabilities
/**
* Flag indicating a RemoteControlClient makes use of the "previous" media key.
*
@@ -642,6 +643,57 @@ public class RemoteControlClient
sendPlaybackState_syncCacheLock();
// update AudioService
sendAudioServiceNewPlaybackState_syncCacheLock();
+
+ // handle automatic playback position refreshes
+ if (mEventHandler == null) {
+ return;
+ }
+ mEventHandler.removeMessages(MSG_POSITION_DRIFT_CHECK);
+ if (timeInMs == PLAYBACK_POSITION_INVALID) {
+ // this playback state refresh has no known playback position, it's no use
+ // trying to see if there is any drift at this point
+ // (this also bypasses this mechanism for older apps that use the old
+ // setPlaybackState(int) API)
+ return;
+ }
+ if (playbackPositionShouldMove(mPlaybackState)) {
+ // playback position moving, schedule next position drift check
+ mEventHandler.sendMessageDelayed(
+ mEventHandler.obtainMessage(MSG_POSITION_DRIFT_CHECK),
+ getCheckPeriodFromSpeed(playbackSpeed));
+ }
+ }
+ }
+ }
+
+ private void onPositionDriftCheck() {
+ if (DEBUG) { Log.d(TAG, "onPositionDriftCheck()"); }
+ synchronized(mCacheLock) {
+ if ((mEventHandler == null) || (mPositionProvider == null)) {
+ return;
+ }
+ if ((mPlaybackPositionMs == PLAYBACK_POSITION_INVALID) || (mPlaybackSpeed == 0.0f)) {
+ if (DEBUG) { Log.d(TAG, " no position or 0 speed, no check needed"); }
+ return;
+ }
+ long estPos = mPlaybackPositionMs + (long)
+ ((SystemClock.elapsedRealtime() - mPlaybackStateChangeTimeMs) / mPlaybackSpeed);
+ long actPos = mPositionProvider.onGetPlaybackPosition();
+ if (actPos >= 0) {
+ if (Math.abs(estPos - actPos) > POSITION_DRIFT_MAX_MS) {
+ // drift happened, report the new position
+ if (DEBUG) { Log.w(TAG, " drift detected: actual=" +actPos +" est=" +estPos); }
+ setPlaybackState(mPlaybackState, actPos, mPlaybackSpeed);
+ } else {
+ if (DEBUG) { Log.d(TAG, " no drift: actual=" + actPos +" est=" + estPos); }
+ // no drift, schedule the next drift check
+ mEventHandler.sendMessageDelayed(
+ mEventHandler.obtainMessage(MSG_POSITION_DRIFT_CHECK),
+ getCheckPeriodFromSpeed(mPlaybackSpeed));
+ }
+ } else {
+ // invalid position (negative value), can't check for drift
+ mEventHandler.removeMessages(MSG_POSITION_DRIFT_CHECK);
}
}
}
@@ -746,6 +798,14 @@ public class RemoteControlClient
// tell RCDs that this RCC's playback position capabilities have changed
sendTransportControlInfo_syncCacheLock();
}
+ if ((mPositionProvider != null) && (mEventHandler != null)
+ && playbackPositionShouldMove(mPlaybackState)) {
+ // playback position is already moving, but now we have a position provider,
+ // so schedule a drift check right now
+ mEventHandler.sendMessageDelayed(
+ mEventHandler.obtainMessage(MSG_POSITION_DRIFT_CHECK),
+ 0 /*check now*/);
+ }
}
}
@@ -1099,6 +1159,7 @@ public class RemoteControlClient
private final static int MSG_UNPLUG_DISPLAY = 8;
private final static int MSG_UPDATE_DISPLAY_ARTWORK_SIZE = 9;
private final static int MSG_SEEK_TO = 10;
+ private final static int MSG_POSITION_DRIFT_CHECK = 11;
private class EventHandler extends Handler {
public EventHandler(RemoteControlClient rcc, Looper looper) {
@@ -1146,6 +1207,9 @@ public class RemoteControlClient
case MSG_SEEK_TO:
onSeekTo(msg.arg1, ((Long)msg.obj).longValue());
break;
+ case MSG_POSITION_DRIFT_CHECK:
+ onPositionDriftCheck();
+ break;
default:
Log.e(TAG, "Unknown event " + msg.what + " in RemoteControlClient handler");
}
@@ -1440,4 +1504,57 @@ public class RemoteControlClient
return false;
}
}
+
+ /**
+ * Returns whether, for the given playback state, the playback position is expected to
+ * be changing.
+ * @param playstate the playback state to evaluate
+ * @return true during any form of playback, false if it's not playing anything while in this
+ * playback state
+ */
+ private static boolean playbackPositionShouldMove(int playstate) {
+ switch(playstate) {
+ case PLAYSTATE_STOPPED:
+ case PLAYSTATE_PAUSED:
+ case PLAYSTATE_BUFFERING:
+ case PLAYSTATE_ERROR:
+ case PLAYSTATE_SKIPPING_FORWARDS:
+ case PLAYSTATE_SKIPPING_BACKWARDS:
+ return false;
+ case PLAYSTATE_PLAYING:
+ case PLAYSTATE_FAST_FORWARDING:
+ case PLAYSTATE_REWINDING:
+ default:
+ return true;
+ }
+ }
+
+ /**
+ * Period for playback position drift checks, 15s when playing at 1x or slower.
+ */
+ private final static long POSITION_REFRESH_PERIOD_PLAYING_MS = 15000;
+ /**
+ * Minimum period for playback position drift checks, never more often when every 2s, when
+ * fast forwarding or rewinding.
+ */
+ private final static long POSITION_REFRESH_PERIOD_MIN_MS = 2000;
+ /**
+ * The value above which the difference between client-reported playback position and
+ * estimated position is considered a drift.
+ */
+ private final static long POSITION_DRIFT_MAX_MS = 500;
+ /**
+ * Compute the period at which the estimated playback position should be compared against the
+ * actual playback position. Is a funciton of playback speed.
+ * @param speed 1.0f is normal playback speed
+ * @return the period in ms
+ */
+ private static long getCheckPeriodFromSpeed(float speed) {
+ if (Math.abs(speed) <= 1.0f) {
+ return POSITION_REFRESH_PERIOD_PLAYING_MS;
+ } else {
+ return Math.max((long)(POSITION_REFRESH_PERIOD_PLAYING_MS / Math.abs(speed)),
+ POSITION_REFRESH_PERIOD_MIN_MS);
+ }
+ }
}
diff --git a/media/jni/android_media_MediaDrm.cpp b/media/jni/android_media_MediaDrm.cpp
index d9d466e75e6c..d1b499e8d9d0 100644
--- a/media/jni/android_media_MediaDrm.cpp
+++ b/media/jni/android_media_MediaDrm.cpp
@@ -30,6 +30,7 @@
#include <media/IDrm.h>
#include <media/IMediaPlayerService.h>
#include <media/stagefright/foundation/ADebug.h>
+#include <media/stagefright/MediaErrors.h>
namespace android {
@@ -191,10 +192,62 @@ void JNIDrmListener::notify(DrmPlugin::EventType eventType, int extra,
static bool throwExceptionAsNecessary(
JNIEnv *env, status_t err, const char *msg = NULL) {
+ const char *drmMessage = NULL;
+
+ switch(err) {
+ case ERROR_DRM_UNKNOWN:
+ drmMessage = "General DRM error";
+ break;
+ case ERROR_DRM_NO_LICENSE:
+ drmMessage = "No license";
+ break;
+ case ERROR_DRM_LICENSE_EXPIRED:
+ drmMessage = "License expired";
+ break;
+ case ERROR_DRM_SESSION_NOT_OPENED:
+ drmMessage = "Session not opened";
+ break;
+ case ERROR_DRM_DECRYPT_UNIT_NOT_INITIALIZED:
+ drmMessage = "Not initialized";
+ break;
+ case ERROR_DRM_DECRYPT:
+ drmMessage = "Decrypt error";
+ break;
+ case ERROR_DRM_CANNOT_HANDLE:
+ drmMessage = "Unsupported scheme or data format";
+ break;
+ case ERROR_DRM_TAMPER_DETECTED:
+ drmMessage = "Invalid state";
+ break;
+ case ERROR_DRM_NOT_PROVISIONED:
+ drmMessage = "Not provisioned";
+ break;
+ case ERROR_DRM_DEVICE_REVOKED:
+ drmMessage = "Device revoked";
+ break;
+ default:
+ break;
+ }
+
+ String8 vendorMessage;
+ if (err >= ERROR_DRM_VENDOR_MIN && err <= ERROR_DRM_VENDOR_MAX) {
+ vendorMessage.format("DRM vendor-defined error: %d", err);
+ drmMessage = vendorMessage.string();
+ }
+
if (err == BAD_VALUE) {
jniThrowException(env, "java/lang/IllegalArgumentException", msg);
return true;
} else if (err != OK) {
+ String8 errbuf;
+ if (drmMessage != NULL) {
+ if (msg == NULL) {
+ msg = drmMessage;
+ } else {
+ errbuf.format("%s: %s", msg, drmMessage);
+ msg = errbuf.string();
+ }
+ }
jniThrowException(env, "java/lang/IllegalStateException", msg);
return true;
}
diff --git a/opengl/java/android/opengl/GLSurfaceView.java b/opengl/java/android/opengl/GLSurfaceView.java
index 235829e6a0d4..dac3506e0923 100644
--- a/opengl/java/android/opengl/GLSurfaceView.java
+++ b/opengl/java/android/opengl/GLSurfaceView.java
@@ -245,7 +245,7 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback
if (mGLThread != null) {
// GLThread may still be running if this view was never
// attached to a window.
- mGLThread.requestExitAndWait();
+ mGLThread.quitSafely();
}
} finally {
super.finalize();
@@ -628,7 +628,11 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback
Log.d(TAG, "onDetachedFromWindow");
}
if (mGLThread != null) {
- mGLThread.requestExitAndWait();
+ mGLThread.quitSafely();
+ try {
+ mGLThread.join();
+ } catch (InterruptedException ex) {
+ }
}
mDetached = true;
super.onDetachedFromWindow();
@@ -1627,14 +1631,6 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback
mGLHandler.runWithScissors(mGetRenderModeRunnable, 0);
return mGetRenderModeRunnable.renderMode;
}
-
- public void requestExitAndWait() {
- getLooper().quit();
- try {
- this.join();
- } catch (InterruptedException e) {
- }
- }
} // class GLThread
static class LogWriter extends Writer {
diff --git a/services/java/com/android/server/NotificationManagerService.java b/services/java/com/android/server/NotificationManagerService.java
index 3bebf91a922c..9a93f637e072 100644
--- a/services/java/com/android/server/NotificationManagerService.java
+++ b/services/java/com/android/server/NotificationManagerService.java
@@ -450,11 +450,16 @@ public class NotificationManagerService extends INotificationManager.Stub
public void setNotificationsEnabledForPackage(String pkg, int uid, boolean enabled) {
checkCallerIsSystem();
- if (true||DBG) {
- Slog.v(TAG, (enabled?"en":"dis") + "abling notifications for " + pkg);
- }
+
+ Slog.v(TAG, (enabled?"en":"dis") + "abling notifications for " + pkg);
+
mAppOps.setMode(AppOpsManager.OP_POST_NOTIFICATION, uid, pkg,
enabled ? AppOpsManager.MODE_ALLOWED : AppOpsManager.MODE_IGNORED);
+
+ // Now, cancel any outstanding notifications that are part of a just-disabled app
+ if (ENABLE_BLOCKED_NOTIFICATIONS && !enabled) {
+ cancelAllNotificationsInt(pkg, 0, 0, true, UserHandle.getUserId(uid));
+ }
}
diff --git a/services/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/java/com/android/server/accessibility/AccessibilityManagerService.java
index 7a5f55a12512..2f64908e0506 100644
--- a/services/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -237,6 +237,11 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
}
// We will update when the automation service dies.
UserState userState = getCurrentUserStateLocked();
+ // We have to reload the installed services since some services may
+ // have different attributes, resolve info (does not support equals),
+ // etc. Remove them then to force reload. Do it even if automation is
+ // running since when it goes away, we will have to reload as well.
+ userState.mInstalledServices.clear();
if (userState.mUiAutomationService == null) {
if (readConfigurationForUserStateLocked(userState)) {
onUserStateChangedLocked(userState);
@@ -820,17 +825,21 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
private boolean notifyKeyEventLocked(KeyEvent event, int policyFlags, boolean isDefault) {
// TODO: Now we are giving the key events to the last enabled
- // service that can handle them which is the last one
- // in our list since we write the last enabled as the
- // last record in the enabled services setting. Ideally,
- // the user should make the call which service handles
- // key events. However, only one service should handle
- // key events to avoid user frustration when different
- // behavior is observed from different combinations of
- // enabled accessibility services.
+ // service that can handle them Ideally, the user should
+ // make the call which service handles key events. However,
+ // only one service should handle key events to avoid user
+ // frustration when different behavior is observed from
+ // different combinations of enabled accessibility services.
UserState state = getCurrentUserStateLocked();
for (int i = state.mBoundServices.size() - 1; i >= 0; i--) {
Service service = state.mBoundServices.get(i);
+ // Key events are handled only by services that declared
+ // this capability and requested to filter key events.
+ if (!service.mRequestFilterKeyEvents ||
+ (service.mAccessibilityServiceInfo.getCapabilities() & AccessibilityServiceInfo
+ .CAPABILITY_CAN_REQUEST_FILTER_KEY_EVENTS) == 0) {
+ continue;
+ }
if (service.mIsDefault == isDefault) {
service.notifyKeyEvent(event, policyFlags);
return true;
@@ -1369,11 +1378,11 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
return true;
}
} else {
- // Starting in JB-MR2 we request a permission to allow a service to enable
- // touch exploration and do not care if the service is in the white list.
- if (mContext.getPackageManager().checkPermission(
- android.Manifest.permission.CAN_REQUEST_TOUCH_EXPLORATION_MODE,
- service.mComponentName.getPackageName()) == PackageManager.PERMISSION_GRANTED) {
+ // Starting in JB-MR2 we request an accessibility service to declare
+ // certain capabilities in its meta-data to allow it to enable the
+ // corresponding features.
+ if (service.mIsAutomation || (service.mAccessibilityServiceInfo.getCapabilities()
+ & AccessibilityServiceInfo.CAPABILITY_CAN_REQUEST_TOUCH_EXPLORATION) != 0) {
userState.mIsTouchExplorationEnabled = true;
Settings.Secure.putIntForUser(mContext.getContentResolver(),
Settings.Secure.TOUCH_EXPLORATION_ENABLED, 1, service.mUserId);
@@ -1402,9 +1411,8 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
if (userState.mIsEnhancedWebAccessibilityEnabled) {
return false;
}
- if (service.mIsAutomation || mContext.getPackageManager().checkPermission(
- android.Manifest.permission.CAN_REQUEST_ENHANCED_WEB_ACCESSIBILITY,
- service.mComponentName.getPackageName()) == PackageManager.PERMISSION_GRANTED) {
+ if (service.mIsAutomation || (service.mAccessibilityServiceInfo.getCapabilities()
+ & AccessibilityServiceInfo.CAPABILITY_CAN_REQUEST_ENHANCED_WEB_ACCESSIBILITY) != 0) {
userState.mIsEnhancedWebAccessibilityEnabled = true;
Settings.Secure.putIntForUser(mContext.getContentResolver(),
Settings.Secure.ACCESSIBILITY_SCRIPT_INJECTION, 1, userState.mUserId);
@@ -1639,6 +1647,8 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
boolean mRequestEnhancedWebAccessibility;
+ boolean mRequestFilterKeyEvents;
+
int mFetchFlags;
long mNotificationTimeout;
@@ -1684,7 +1694,8 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
mAccessibilityServiceInfo = accessibilityServiceInfo;
mIsAutomation = (sFakeAccessibilityServiceComponentName.equals(componentName));
if (!mIsAutomation) {
- mCanRetrieveScreenContent = accessibilityServiceInfo.getCanRetrieveWindowContent();
+ mCanRetrieveScreenContent = (accessibilityServiceInfo.getCapabilities()
+ & AccessibilityServiceInfo.CAPABILITY_CAN_REQUEST_TOUCH_EXPLORATION) != 0;
mIntent = new Intent().setComponent(mComponentName);
mIntent.putExtra(Intent.EXTRA_CLIENT_LABEL,
com.android.internal.R.string.accessibility_binding_label);
@@ -1723,9 +1734,11 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
if (mResolveInfo != null) {
mRequestTouchExplorationMode = (info.flags
- & AccessibilityServiceInfo.FLAG_REQUEST_TOUCH_EXPLORATION_MODE) != 0;
+ & AccessibilityServiceInfo.FLAG_REQUEST_TOUCH_EXPLORATION_MODE) != 0;
mRequestEnhancedWebAccessibility = (info.flags
- & AccessibilityServiceInfo.FLAG_REQUEST_ENHANCED_WEB_ACCESSIBILITY) != 0;
+ & AccessibilityServiceInfo.FLAG_REQUEST_ENHANCED_WEB_ACCESSIBILITY) != 0;
+ mRequestFilterKeyEvents = (info.flags
+ & AccessibilityServiceInfo.FLAG_REQUEST_FILTER_KEY_EVENTS) != 0;
}
}
diff --git a/services/java/com/android/server/wifi/WifiService.java b/services/java/com/android/server/wifi/WifiService.java
index 4d23e5cfeb60..956019951e53 100644
--- a/services/java/com/android/server/wifi/WifiService.java
+++ b/services/java/com/android/server/wifi/WifiService.java
@@ -404,7 +404,7 @@ public final class WifiService extends IWifiManager.Stub {
try {
/* Turning off Wi-Fi when scans are still available */
- if (!enable && isScanningAlwaysAvailable()) {
+ if (!enable && isScanAlwaysAvailable()) {
/* Notify if device is provisioned and user has not opted out of the notification */
if (mNotifyScanMode.get() && mDeviceProvisioned.get()) {
Intent intent = new Intent(WifiManager.ACTION_NOTIFY_SCAN_ALWAYS_AVAILABLE);
@@ -497,7 +497,7 @@ public final class WifiService extends IWifiManager.Stub {
* @return {@code true} if the enable/disable operation was
* started or is already in the queue.
*/
- public boolean isScanningAlwaysAvailable() {
+ public boolean isScanAlwaysAvailable() {
enforceAccessPermission();
return mSettingsStore.isScanAlwaysAvailable();
}
diff --git a/wifi/java/android/net/wifi/IWifiManager.aidl b/wifi/java/android/net/wifi/IWifiManager.aidl
index f093b52a1c3f..547ae9598916 100644
--- a/wifi/java/android/net/wifi/IWifiManager.aidl
+++ b/wifi/java/android/net/wifi/IWifiManager.aidl
@@ -71,7 +71,7 @@ interface IWifiManager
DhcpInfo getDhcpInfo();
- boolean isScanningAlwaysAvailable();
+ boolean isScanAlwaysAvailable();
boolean acquireWifiLock(IBinder lock, int lockType, String tag, in WorkSource ws);
diff --git a/wifi/java/android/net/wifi/WifiEnterpriseConfig.java b/wifi/java/android/net/wifi/WifiEnterpriseConfig.java
index 4e7497cb68af..e2512a424799 100644
--- a/wifi/java/android/net/wifi/WifiEnterpriseConfig.java
+++ b/wifi/java/android/net/wifi/WifiEnterpriseConfig.java
@@ -223,6 +223,9 @@ public class WifiEnterpriseConfig implements Parcelable {
public static final int PWD = 3;
/** @hide */
public static final String[] strings = { "PEAP", "TLS", "TTLS", "PWD" };
+
+ /** Prevent initialization */
+ private Eap() {}
}
/** The inner authentication method used */
@@ -239,6 +242,9 @@ public class WifiEnterpriseConfig implements Parcelable {
private static final String PREFIX = "auth=";
/** @hide */
public static final String[] strings = {EMPTY_VALUE, "PAP", "MSCHAP", "MSCHAPV2", "GTC" };
+
+ /** Prevent initialization */
+ private Phase2() {}
}
/** Internal use only */
@@ -363,6 +369,16 @@ public class WifiEnterpriseConfig implements Parcelable {
}
/**
+ * Get the password.
+ *
+ * Returns locally set password value. For networks fetched from
+ * framework, returns "*".
+ */
+ public String getPassword() {
+ return getFieldValue(PASSWORD_KEY, "");
+ }
+
+ /**
* Set CA certificate alias.
*
* <p> See the {@link android.security.KeyChain} for details on installing or choosing
@@ -404,6 +420,15 @@ public class WifiEnterpriseConfig implements Parcelable {
}
/**
+ * Get CA certificate
+ *
+ * @return X.509 CA certificate
+ */
+ public X509Certificate getCaCertificate() {
+ return mCaCert;
+ }
+
+ /**
* Set Client certificate alias.
*
* <p> See the {@link android.security.KeyChain} for details on installing or choosing
@@ -463,6 +488,15 @@ public class WifiEnterpriseConfig implements Parcelable {
mClientCertificate = clientCertificate;
}
+ /**
+ * Get client certificate
+ *
+ * @return X.509 client certificate
+ */
+ public X509Certificate getClientCertificate() {
+ return mClientCertificate;
+ }
+
boolean needsKeyStore() {
// Has no keys to be installed
if (mClientCertificate == null && mCaCert == null) return false;
diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java
index 0c0a144ae234..a7a59240683c 100644
--- a/wifi/java/android/net/wifi/WifiManager.java
+++ b/wifi/java/android/net/wifi/WifiManager.java
@@ -794,9 +794,9 @@ public class WifiManager {
*
* To change this setting, see {@link #ACTION_REQUEST_SCAN_ALWAYS_AVAILABLE}.
*/
- public boolean isScanningAlwaysAvailable() {
+ public boolean isScanAlwaysAvailable() {
try {
- return mService.isScanningAlwaysAvailable();
+ return mService.isScanAlwaysAvailable();
} catch (RemoteException e) {
return false;
}