summaryrefslogtreecommitdiffstats
path: root/core/java/android
diff options
context:
space:
mode:
Diffstat (limited to 'core/java/android')
-rw-r--r--core/java/android/accessibilityservice/AccessibilityService.java2
-rw-r--r--core/java/android/accessibilityservice/AccessibilityServiceInfo.java214
-rw-r--r--core/java/android/accounts/AccountManager.java17
-rw-r--r--core/java/android/accounts/ChooseTypeAndAccountActivity.java5
-rw-r--r--core/java/android/accounts/IAccountManager.aidl1
-rw-r--r--core/java/android/app/Activity.java4
-rw-r--r--core/java/android/app/Application.java19
-rw-r--r--core/java/android/app/admin/DevicePolicyManager.java27
-rw-r--r--core/java/android/bluetooth/BluetoothAdapter.java422
-rw-r--r--core/java/android/bluetooth/BluetoothAdapterCallback.java57
-rw-r--r--core/java/android/bluetooth/BluetoothManager.java6
-rw-r--r--core/java/android/content/Intent.java4
-rw-r--r--core/java/android/content/res/Resources.java36
-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/Environment.java31
-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
-rw-r--r--core/java/android/os/StatFs.java34
-rw-r--r--core/java/android/provider/Settings.java11
-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
31 files changed, 777 insertions, 688 deletions
diff --git a/core/java/android/accessibilityservice/AccessibilityService.java b/core/java/android/accessibilityservice/AccessibilityService.java
index 31de98d..1e3d5be 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 d82b9a3..40f45b7 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/accounts/AccountManager.java b/core/java/android/accounts/AccountManager.java
index 241a64a..b4a12c4 100644
--- a/core/java/android/accounts/AccountManager.java
+++ b/core/java/android/accounts/AccountManager.java
@@ -405,6 +405,23 @@ public class AccountManager {
}
/**
+ * Returns the accounts visible to the specified package, in an environment where some apps
+ * are not authorized to view all accounts. This method can only be called by system apps.
+ * @param type The type of accounts to return, null to retrieve all accounts
+ * @param packageName The package name of the app for which the accounts are to be returned
+ * @return An array of {@link Account}, one per matching account. Empty
+ * (never null) if no accounts of the specified type have been added.
+ */
+ public Account[] getAccountsByTypeForPackage(String type, String packageName) {
+ try {
+ return mService.getAccountsByTypeForPackage(type, packageName);
+ } catch (RemoteException re) {
+ // possible security exception
+ throw new RuntimeException(re);
+ }
+ }
+
+ /**
* Lists all accounts of a particular type. The account type is a
* string token corresponding to the authenticator and useful domain
* of the account. For example, there are types corresponding to Google
diff --git a/core/java/android/accounts/ChooseTypeAndAccountActivity.java b/core/java/android/accounts/ChooseTypeAndAccountActivity.java
index 2aba163..58eb66f 100644
--- a/core/java/android/accounts/ChooseTypeAndAccountActivity.java
+++ b/core/java/android/accounts/ChooseTypeAndAccountActivity.java
@@ -34,13 +34,11 @@ import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.TextView;
-import android.widget.Toast;
import com.android.internal.R;
import java.io.IOException;
import java.util.ArrayList;
-import java.util.HashMap;
import java.util.HashSet;
import java.util.Set;
@@ -110,6 +108,7 @@ public class ChooseTypeAndAccountActivity extends Activity
private static final String KEY_INSTANCE_STATE_EXISTING_ACCOUNTS = "existingAccounts";
private static final String KEY_INSTANCE_STATE_SELECTED_ACCOUNT_NAME = "selectedAccountName";
private static final String KEY_INSTANCE_STATE_SELECTED_ADD_ACCOUNT = "selectedAddAccount";
+ private static final String KEY_INSTANCE_STATE_ACCOUNT_LIST = "accountList";
private static final int SELECTED_ITEM_NONE = -1;
@@ -169,6 +168,7 @@ public class ChooseTypeAndAccountActivity extends Activity
mSelectedAddNewAccount = savedInstanceState.getBoolean(
KEY_INSTANCE_STATE_SELECTED_ADD_ACCOUNT, false);
+ mAccounts = savedInstanceState.getParcelableArrayList(KEY_INSTANCE_STATE_ACCOUNT_LIST);
} else {
mPendingRequest = REQUEST_NULL;
mExistingAccounts = null;
@@ -266,6 +266,7 @@ public class ChooseTypeAndAccountActivity extends Activity
mAccounts.get(mSelectedItemIndex).name);
}
}
+ outState.putParcelableArrayList(KEY_INSTANCE_STATE_ACCOUNT_LIST, mAccounts);
}
public void onCancelButtonClicked(View view) {
diff --git a/core/java/android/accounts/IAccountManager.aidl b/core/java/android/accounts/IAccountManager.aidl
index 8141813..86e279f 100644
--- a/core/java/android/accounts/IAccountManager.aidl
+++ b/core/java/android/accounts/IAccountManager.aidl
@@ -32,6 +32,7 @@ interface IAccountManager {
AuthenticatorDescription[] getAuthenticatorTypes();
Account[] getAccounts(String accountType);
Account[] getAccountsForPackage(String packageName, int uid);
+ Account[] getAccountsByTypeForPackage(String type, String packageName);
Account[] getAccountsAsUser(String accountType, int userId);
void hasFeatures(in IAccountManagerResponse response, in Account account, in String[] features);
void getAccountsByFeatures(in IAccountManagerResponse response, String accountType, in String[] features);
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index a26bdbc..6b5df7f 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 0d7f0a7..75e4bab 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/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 8284b2c..17e8dd9 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -1537,14 +1537,21 @@ public class DevicePolicyManager {
return false;
}
+
/**
- * Used to determine if a particular package has been registered as a Device Owner admin.
- * Device Owner admins cannot be deactivated by the user unless the Device Owner itself allows
- * it. And Device Owner packages cannot be uninstalled, once registered.
- * @param packageName the package name to check against the registered device owner.
- * @return whether or not the package is registered as the Device Owner.
+ * Used to determine if a particular package has been registered as a Device Owner app.
+ * A device owner app is a special device admin that cannot be deactivated by the user, once
+ * activated as a device admin. It also cannot be uninstalled. To check if a particular
+ * package is currently registered as the device owner app, pass in the package name from
+ * {@link Context#getPackageName()} to this method.<p/>This is useful for device
+ * admin apps that want to check if they are also registered as the device owner app. The
+ * exact mechanism by which a device admin app is registered as a device owner app is defined by
+ * the setup process.
+ * @param packageName the package name of the app, to compare with the registered device owner
+ * app, if any.
+ * @return whether or not the package is registered as the device owner app.
*/
- public boolean isDeviceOwner(String packageName) {
+ public boolean isDeviceOwnerApp(String packageName) {
if (mService != null) {
try {
return mService.isDeviceOwner(packageName);
@@ -1555,6 +1562,14 @@ public class DevicePolicyManager {
return false;
}
+ /**
+ * @hide
+ * Redirect to isDeviceOwnerApp.
+ */
+ public boolean isDeviceOwner(String packageName) {
+ return isDeviceOwnerApp(packageName);
+ }
+
/** @hide */
public String getDeviceOwner() {
if (mService != null) {
diff --git a/core/java/android/bluetooth/BluetoothAdapter.java b/core/java/android/bluetooth/BluetoothAdapter.java
index 2e9c9e3..3498bb8 100644
--- a/core/java/android/bluetooth/BluetoothAdapter.java
+++ b/core/java/android/bluetooth/BluetoothAdapter.java
@@ -20,7 +20,6 @@ import android.annotation.SdkConstant;
import android.annotation.SdkConstant.SdkConstantType;
import android.content.Context;
import android.os.Binder;
-import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.ParcelUuid;
@@ -30,11 +29,14 @@ import android.util.Log;
import android.util.Pair;
import java.io.IOException;
+import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
+import java.util.HashMap;
import java.util.LinkedList;
+import java.util.Map;
import java.util.Random;
import java.util.Set;
import java.util.UUID;
@@ -357,9 +359,7 @@ public final class BluetoothAdapter {
private final IBluetoothManager mManagerService;
private IBluetooth mService;
- private Handler mServiceRecordHandler;
- private BluetoothAdapterCallback mCallback;
- private int mClientIf;
+ private final Map<LeScanCallback, GattCallbackWrapper> mLeScanClients;
/**
* Get a handle to the default local Bluetooth adapter.
@@ -394,7 +394,7 @@ public final class BluetoothAdapter {
mService = managerService.registerAdapter(mManagerCallback);
} catch (RemoteException e) {Log.e(TAG, "", e);}
mManagerService = managerService;
- mServiceRecordHandler = null;
+ mLeScanClients = new HashMap<LeScanCallback, GattCallbackWrapper>();
}
/**
@@ -1409,72 +1409,38 @@ public final class BluetoothAdapter {
}
/**
- * Register an callback to receive async results, such as LE scan result.
+ * Callback interface used to deliver LE scan results.
*
- * <p>This is an asynchronous call. The callback
- * {@link BluetoothAdapterCallback#onCallbackRegistration}
- * is used to notify success or failure if the function returns true.
- *
- * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
- *
- * @param callback BluetootAdapter callback handler that will receive asynchronous callbacks.
- * @return If true, the callback will be called to notify success or failure,
- * false on immediate error
- */
- public boolean registerCallback(BluetoothAdapterCallback callback) {
- try {
- IBluetoothGatt iGatt = (IBluetoothGatt) mManagerService.getBluetoothGatt();
- mCallback = callback;
- UUID uuid = UUID.randomUUID();
- if (DBG) Log.d(TAG, "registerCallback() - UUID=" + uuid);
-
- iGatt.registerClient(new ParcelUuid(uuid), mBluetoothGattCallback);
- return true;
- } catch (RemoteException e) {
- Log.e(TAG,"",e);
- return false;
- }
- }
-
- /**
- * Unregister the registered callback.
- */
- public boolean unRegisterCallback(BluetoothAdapterCallback callback) {
- if (callback != mCallback) return false;
- try {
- IBluetoothGatt iGatt = (IBluetoothGatt) mManagerService.getBluetoothGatt();
-
- iGatt.unregisterClient(mClientIf);
- return true;
- } catch (RemoteException e) {
- Log.e(TAG,"",e);
- return false;
- }
+ * @see #startLeScan(LeScanCallback)
+ * @see #startLeScan(UUID[], LeScanCallback)
+ */
+ public interface LeScanCallback {
+ /**
+ * Callback reporting an LE device found during a device scan initiated
+ * by the {@link BluetoothAdapter#startLeScan} function.
+ *
+ * @param device Identifies the remote device
+ * @param rssi The RSSI value for the remote device as reported by the
+ * Bluetooth hardware. 0 if no RSSI value is available.
+ * @param scanRecord The content of the advertisement record offered by
+ * the remote device.
+ */
+ public void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord);
}
/**
* Starts a scan for Bluetooth LE devices.
*
* <p>Results of the scan are reported using the
- * {@link BluetoothAdapterCallback#onLeScan} callback.
+ * {@link LeScanCallback#onLeScan} callback.
*
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
*
+ * @param callback the callback LE scan results are delivered
* @return true, if the scan was started successfully
*/
- public boolean startLeScan() {
- if (DBG) Log.d(TAG, "startLeScan()");
- if (mClientIf == 0) return false;
-
- try {
- IBluetoothGatt iGatt = (IBluetoothGatt) mManagerService.getBluetoothGatt();
- iGatt.startScan(mClientIf, false);
- } catch (RemoteException e) {
- Log.e(TAG,"",e);
- return false;
- }
-
- return true;
+ public boolean startLeScan(LeScanCallback callback) {
+ return startLeScan(null, callback);
}
/**
@@ -1482,155 +1448,281 @@ public final class BluetoothAdapter {
* advertise given services.
*
* <p>Devices which advertise all specified services are reported using the
- * {@link BluetoothAdapterCallback#onLeScan} callback.
+ * {@link LeScanCallback#onLeScan} callback.
*
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
*
* @param serviceUuids Array of services to look for
+ * @param callback the callback LE scan results are delivered
* @return true, if the scan was started successfully
*/
- public boolean startLeScan(UUID[] serviceUuids) {
- if (DBG) Log.d(TAG, "startLeScan() - with UUIDs");
- if (mClientIf == 0) return false;
+ public boolean startLeScan(UUID[] serviceUuids, LeScanCallback callback) {
+ if (DBG) Log.d(TAG, "startLeScan(): " + serviceUuids);
- try {
- IBluetoothGatt iGatt = (IBluetoothGatt) mManagerService.getBluetoothGatt();
- ParcelUuid[] uuids = new ParcelUuid[serviceUuids.length];
- for(int i = 0; i != uuids.length; ++i) {
- uuids[i] = new ParcelUuid(serviceUuids[i]);
- }
- iGatt.startScanWithUuids(mClientIf, false, uuids);
- } catch (RemoteException e) {
- Log.e(TAG,"",e);
+ if (callback == null) {
+ if (DBG) Log.e(TAG, "startLeScan: null callback");
return false;
}
- return true;
+ synchronized(mLeScanClients) {
+ if (mLeScanClients.containsKey(callback)) {
+ if (DBG) Log.e(TAG, "LE Scan has already started");
+ return false;
+ }
+
+ try {
+ IBluetoothGatt iGatt = mManagerService.getBluetoothGatt();
+ UUID uuid = UUID.randomUUID();
+ GattCallbackWrapper wrapper = new GattCallbackWrapper(this, callback, serviceUuids);
+
+ iGatt.registerClient(new ParcelUuid(uuid), wrapper);
+ if (wrapper.scanStarted()) {
+ mLeScanClients.put(callback, wrapper);
+ return true;
+ }
+ } catch (RemoteException e) {
+ Log.e(TAG,"",e);
+ }
+ }
+ return false;
}
/**
* Stops an ongoing Bluetooth LE device scan.
*
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
- */
- public void stopLeScan() {
- if (DBG) Log.d(TAG, "stopScan()");
- if (mClientIf == 0) return;
-
- try {
- IBluetoothGatt iGatt = (IBluetoothGatt) mManagerService.getBluetoothGatt();
- iGatt.stopScan(mClientIf, false);
- } catch (RemoteException e) {
- Log.e(TAG,"",e);
+ *
+ * @param callback used to identify which scan to stop
+ * must be the same handle used to start the scan
+ */
+ public void stopLeScan(LeScanCallback callback) {
+ if (DBG) Log.d(TAG, "stopLeScan()");
+ GattCallbackWrapper wrapper;
+ synchronized(mLeScanClients) {
+ wrapper = mLeScanClients.remove(callback);
+ if (wrapper == null) return;
}
+ wrapper.stopLeScan();
}
/**
* Bluetooth GATT interface callbacks
*/
- private final IBluetoothGattCallback mBluetoothGattCallback =
- new IBluetoothGattCallback.Stub() {
- /**
- * Application interface registered - app is ready to go
- */
- public void onClientRegistered(int status, int clientIf) {
- if (DBG) Log.d(TAG, "onClientRegistered() - status=" + status
- + " clientIf=" + clientIf);
- mClientIf = clientIf;
- mCallback.onCallbackRegistration(status == BluetoothGatt.GATT_SUCCESS ?
- BluetoothAdapterCallback.CALLBACK_REGISTERED :
- BluetoothAdapterCallback.CALLBACK_REGISTRATION_FAILURE);
- }
+ private static class GattCallbackWrapper extends IBluetoothGattCallback.Stub {
+ private static final int LE_CALLBACK_REG_TIMEOUT = 2000;
+ private static final int LE_CALLBACK_REG_WAIT_COUNT = 5;
+
+ private final LeScanCallback mLeScanCb;
+ // mLeHandle 0: not registered
+ // -1: scan stopped
+ // >0: registered and scan started
+ private int mLeHandle;
+ private final UUID[] mScanFilter;
+ private WeakReference<BluetoothAdapter> mBluetoothAdapter;
+
+ public GattCallbackWrapper(BluetoothAdapter bluetoothAdapter,
+ LeScanCallback leScanCb, UUID[] uuid) {
+ mBluetoothAdapter = new WeakReference<BluetoothAdapter>(bluetoothAdapter);
+ mLeScanCb = leScanCb;
+ mScanFilter = uuid;
+ mLeHandle = 0;
+ }
- public void onClientConnectionState(int status, int clientIf,
- boolean connected, String address) {
- // no op
+ public boolean scanStarted() {
+ boolean started = false;
+ synchronized(this) {
+ if (mLeHandle == -1) return false;
+
+ int count = 0;
+ // wait for callback registration and LE scan to start
+ while (mLeHandle == 0 && count < LE_CALLBACK_REG_WAIT_COUNT) {
+ try {
+ wait(LE_CALLBACK_REG_TIMEOUT);
+ } catch (InterruptedException e) {
+ Log.e(TAG, "Callback reg wait interrupted: " + e);
+ }
+ count++;
+ }
+ started = (mLeHandle > 0);
}
+ return started;
+ }
- /**
- * Callback reporting an LE scan result.
- * @hide
- */
- public void onScanResult(String address, int rssi, byte[] advData) {
- if (DBG) Log.d(TAG, "onScanResult() - Device=" + address + " RSSI=" +rssi);
-
- try {
- mCallback.onLeScan(getRemoteDevice(address), rssi, advData);
- } catch (Exception ex) {
- Log.w(TAG, "Unhandled exception: " + ex);
+ public void stopLeScan() {
+ synchronized(this) {
+ if (mLeHandle <= 0) {
+ Log.e(TAG, "Error state, mLeHandle: " + mLeHandle);
+ return;
+ }
+ BluetoothAdapter adapter = mBluetoothAdapter.get();
+ if (adapter != null) {
+ try {
+ IBluetoothGatt iGatt = adapter.getBluetoothManager().getBluetoothGatt();
+ iGatt.stopScan(mLeHandle, false);
+ iGatt.unregisterClient(mLeHandle);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Failed to stop scan and unregister" + e);
+ }
+ } else {
+ Log.e(TAG, "stopLeScan, BluetoothAdapter is null");
}
+ mLeHandle = -1;
+ notifyAll();
}
+ }
- public void onGetService(String address, int srvcType,
- int srvcInstId, ParcelUuid srvcUuid) {
- // no op
- }
+ /**
+ * Application interface registered - app is ready to go
+ */
+ public void onClientRegistered(int status, int clientIf) {
+ if (DBG) Log.d(TAG, "onClientRegistered() - status=" + status +
+ " clientIf=" + clientIf);
+ synchronized(this) {
+ if (mLeHandle == -1) {
+ if (DBG) Log.d(TAG, "onClientRegistered LE scan canceled");
+ }
- public void onGetIncludedService(String address, int srvcType,
- int srvcInstId, ParcelUuid srvcUuid,
- int inclSrvcType, int inclSrvcInstId,
- ParcelUuid inclSrvcUuid) {
- // no op
+ if (status == BluetoothGatt.GATT_SUCCESS) {
+ mLeHandle = clientIf;
+ IBluetoothGatt iGatt = null;
+ try {
+ BluetoothAdapter adapter = mBluetoothAdapter.get();
+ if (adapter != null) {
+ iGatt = adapter.getBluetoothManager().getBluetoothGatt();
+ if (mScanFilter == null) {
+ iGatt.startScan(mLeHandle, false);
+ } else {
+ ParcelUuid[] uuids = new ParcelUuid[mScanFilter.length];
+ for(int i = 0; i != uuids.length; ++i) {
+ uuids[i] = new ParcelUuid(mScanFilter[i]);
+ }
+ iGatt.startScanWithUuids(mLeHandle, false, uuids);
+ }
+ } else {
+ Log.e(TAG, "onClientRegistered, BluetoothAdapter null");
+ mLeHandle = -1;
+ }
+ } catch (RemoteException e) {
+ Log.e(TAG, "fail to start le scan: " + e);
+ mLeHandle = -1;
+ }
+ if (mLeHandle == -1) {
+ // registration succeeded but start scan failed
+ if (iGatt != null) {
+ try {
+ iGatt.unregisterClient(mLeHandle);
+ } catch (RemoteException e) {
+ Log.e(TAG, "fail to unregister callback: " + mLeHandle +
+ " error: " + e);
+ }
+ }
+ }
+ } else {
+ // registration failed
+ mLeHandle = -1;
+ }
+ notifyAll();
}
+ }
- public void onGetCharacteristic(String address, int srvcType,
- int srvcInstId, ParcelUuid srvcUuid,
- int charInstId, ParcelUuid charUuid,
- int charProps) {
- // no op
- }
+ public void onClientConnectionState(int status, int clientIf,
+ boolean connected, String address) {
+ // no op
+ }
- public void onGetDescriptor(String address, int srvcType,
- int srvcInstId, ParcelUuid srvcUuid,
- int charInstId, ParcelUuid charUuid,
- ParcelUuid descUuid) {
- // no op
- }
+ /**
+ * Callback reporting an LE scan result.
+ * @hide
+ */
+ public void onScanResult(String address, int rssi, byte[] advData) {
+ if (DBG) Log.d(TAG, "onScanResult() - Device=" + address + " RSSI=" +rssi);
- public void onSearchComplete(String address, int status) {
- // no op
+ // Check null in case the scan has been stopped
+ synchronized(this) {
+ if (mLeHandle <= 0) return;
}
-
- public void onCharacteristicRead(String address, int status, int srvcType,
- int srvcInstId, ParcelUuid srvcUuid,
- int charInstId, ParcelUuid charUuid, byte[] value) {
- // no op
+ try {
+ BluetoothAdapter adapter = mBluetoothAdapter.get();
+ if (adapter == null) {
+ Log.d(TAG, "onScanResult, BluetoothAdapter null");
+ return;
+ }
+ mLeScanCb.onLeScan(adapter.getRemoteDevice(address), rssi, advData);
+ } catch (Exception ex) {
+ Log.w(TAG, "Unhandled exception: " + ex);
}
+ }
- public void onCharacteristicWrite(String address, int status, int srvcType,
- int srvcInstId, ParcelUuid srvcUuid,
- int charInstId, ParcelUuid charUuid) {
- // no op
- }
+ public void onGetService(String address, int srvcType,
+ int srvcInstId, ParcelUuid srvcUuid) {
+ // no op
+ }
+
+ public void onGetIncludedService(String address, int srvcType,
+ int srvcInstId, ParcelUuid srvcUuid,
+ int inclSrvcType, int inclSrvcInstId,
+ ParcelUuid inclSrvcUuid) {
+ // no op
+ }
- public void onNotify(String address, int srvcType,
+ public void onGetCharacteristic(String address, int srvcType,
+ int srvcInstId, ParcelUuid srvcUuid,
+ int charInstId, ParcelUuid charUuid,
+ int charProps) {
+ // no op
+ }
+
+ public void onGetDescriptor(String address, int srvcType,
+ int srvcInstId, ParcelUuid srvcUuid,
+ int charInstId, ParcelUuid charUuid,
+ ParcelUuid descUuid) {
+ // no op
+ }
+
+ public void onSearchComplete(String address, int status) {
+ // no op
+ }
+
+ public void onCharacteristicRead(String address, int status, int srvcType,
+ int srvcInstId, ParcelUuid srvcUuid,
+ int charInstId, ParcelUuid charUuid, byte[] value) {
+ // no op
+ }
+
+ public void onCharacteristicWrite(String address, int status, int srvcType,
+ int srvcInstId, ParcelUuid srvcUuid,
+ int charInstId, ParcelUuid charUuid) {
+ // no op
+ }
+
+ public void onNotify(String address, int srvcType,
int srvcInstId, ParcelUuid srvcUuid,
int charInstId, ParcelUuid charUuid,
byte[] value) {
- // no op
- }
+ // no op
+ }
- public void onDescriptorRead(String address, int status, int srvcType,
- int srvcInstId, ParcelUuid srvcUuid,
- int charInstId, ParcelUuid charUuid,
- ParcelUuid descrUuid, byte[] value) {
- // no op
- }
+ public void onDescriptorRead(String address, int status, int srvcType,
+ int srvcInstId, ParcelUuid srvcUuid,
+ int charInstId, ParcelUuid charUuid,
+ ParcelUuid descrUuid, byte[] value) {
+ // no op
+ }
- public void onDescriptorWrite(String address, int status, int srvcType,
- int srvcInstId, ParcelUuid srvcUuid,
- int charInstId, ParcelUuid charUuid,
- ParcelUuid descrUuid) {
- // no op
- }
+ public void onDescriptorWrite(String address, int status, int srvcType,
+ int srvcInstId, ParcelUuid srvcUuid,
+ int charInstId, ParcelUuid charUuid,
+ ParcelUuid descrUuid) {
+ // no op
+ }
- public void onExecuteWrite(String address, int status) {
- // no op
- }
+ public void onExecuteWrite(String address, int status) {
+ // no op
+ }
- public void onReadRemoteRssi(String address, int rssi, int status) {
- // no op
- }
- };
+ public void onReadRemoteRssi(String address, int rssi, int status) {
+ // no op
+ }
+ }
}
diff --git a/core/java/android/bluetooth/BluetoothAdapterCallback.java b/core/java/android/bluetooth/BluetoothAdapterCallback.java
deleted file mode 100644
index a726bc9..0000000
--- a/core/java/android/bluetooth/BluetoothAdapterCallback.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.bluetooth;
-
-import android.bluetooth.BluetoothDevice;
-
-/**
- * This abstract class is used to implement {@link BluetoothAdapter} callbacks.
- */
-public abstract class BluetoothAdapterCallback {
-
- /**
- * Indicates the callback has been registered successfully
- */
- public static final int CALLBACK_REGISTERED = 0;
-
- /**
- * Indicates the callback registration has failed
- */
- public static final int CALLBACK_REGISTRATION_FAILURE = 1;
-
- /**
- * Callback to inform change in registration state of the application.
- *
- * @param status Returns {@link #CALLBACK_REGISTERED} if the application
- * was successfully registered.
- */
- public void onCallbackRegistration(int status) {
- }
-
- /**
- * Callback reporting an LE device found during a device scan initiated
- * by the {@link BluetoothAdapter#startLeScan} function.
- *
- * @param device Identifies the remote device
- * @param rssi The RSSI value for the remote device as reported by the
- * Bluetooth hardware. 0 if no RSSI value is available.
- * @param scanRecord The content of the advertisement record offered by
- * the remote device.
- */
- public void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord) {
- }
-}
diff --git a/core/java/android/bluetooth/BluetoothManager.java b/core/java/android/bluetooth/BluetoothManager.java
index 19083b5..172f3bc 100644
--- a/core/java/android/bluetooth/BluetoothManager.java
+++ b/core/java/android/bluetooth/BluetoothManager.java
@@ -127,7 +127,7 @@ public final class BluetoothManager {
try {
IBluetoothManager managerService = mAdapter.getBluetoothManager();
- IBluetoothGatt iGatt = (IBluetoothGatt) managerService.getBluetoothGatt();
+ IBluetoothGatt iGatt = managerService.getBluetoothGatt();
if (iGatt == null) return connectedDevices;
connectedDevices = iGatt.getDevicesMatchingConnectionStates(
@@ -172,7 +172,7 @@ public final class BluetoothManager {
try {
IBluetoothManager managerService = mAdapter.getBluetoothManager();
- IBluetoothGatt iGatt = (IBluetoothGatt) managerService.getBluetoothGatt();
+ IBluetoothGatt iGatt = managerService.getBluetoothGatt();
if (iGatt == null) return devices;
devices = iGatt.getDevicesMatchingConnectionStates(states);
} catch (RemoteException e) {
@@ -203,7 +203,7 @@ public final class BluetoothManager {
try {
IBluetoothManager managerService = mAdapter.getBluetoothManager();
- IBluetoothGatt iGatt = (IBluetoothGatt) managerService.getBluetoothGatt();
+ IBluetoothGatt iGatt = managerService.getBluetoothGatt();
if (iGatt == null) {
Log.e(TAG, "Fail to get GATT Server connection");
return null;
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 1ab1eb8..67bd952 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -2425,8 +2425,8 @@ public class Intent implements Parcelable, Cloneable {
* which is of type <code>ArrayList&lt;RestrictionEntry&gt;</code>. It can also
* contain an extra {@link #EXTRA_RESTRICTIONS_INTENT}, which is of type <code>Intent</code>.
* The activity specified by that intent will be launched for a result which must contain
- * the extra {@link #EXTRA_RESTRICTIONS_LIST}. The keys and values of the returned restrictions
- * will be persisted.
+ * one of the extras {@link #EXTRA_RESTRICTIONS_LIST} or {@link #EXTRA_RESTRICTIONS_BUNDLE}.
+ * The keys and values of the returned restrictions will be persisted.
* @see RestrictionEntry
*/
public static final String ACTION_GET_RESTRICTION_ENTRIES =
diff --git a/core/java/android/content/res/Resources.java b/core/java/android/content/res/Resources.java
index d64bff9..d8d5f2b 100644
--- a/core/java/android/content/res/Resources.java
+++ b/core/java/android/content/res/Resources.java
@@ -17,6 +17,7 @@
package android.content.res;
import android.os.Trace;
+import android.view.View;
import com.android.internal.util.XmlUtils;
import org.xmlpull.v1.XmlPullParser;
@@ -80,16 +81,16 @@ public class Resources {
private static final Object sSync = new Object();
/*package*/ static Resources mSystem = null;
-
+
// Information about preloaded resources. Note that they are not
// protected by a lock, because while preloading in zygote we are all
// single-threaded, and after that these are immutable.
- private static final LongSparseArray<Drawable.ConstantState> sPreloadedDrawables
+ private static final LongSparseArray<Drawable.ConstantState>[] sPreloadedDrawables;
+ private static final LongSparseArray<Drawable.ConstantState> sPreloadedColorDrawables
= new LongSparseArray<Drawable.ConstantState>();
private static final LongSparseArray<ColorStateList> sPreloadedColorStateLists
= new LongSparseArray<ColorStateList>();
- private static final LongSparseArray<Drawable.ConstantState> sPreloadedColorDrawables
- = new LongSparseArray<Drawable.ConstantState>();
+
private static boolean sPreloaded;
private static int sPreloadedDensity;
@@ -120,6 +121,12 @@ public class Resources {
private CompatibilityInfo mCompatibilityInfo;
+ static {
+ sPreloadedDrawables = new LongSparseArray[2];
+ sPreloadedDrawables[0] = new LongSparseArray<Drawable.ConstantState>();
+ sPreloadedDrawables[1] = new LongSparseArray<Drawable.ConstantState>();
+ }
+
/** @hide */
public static int selectDefaultTheme(int curTheme, int targetSdkVersion) {
return selectSystemTheme(curTheme, targetSdkVersion,
@@ -1982,6 +1989,7 @@ public class Resources {
ActivityInfo.CONFIG_LAYOUT_DIRECTION);
private boolean verifyPreloadConfig(int changingConfigurations, int resourceId, String name) {
+ // We dont want to preloadd a Drawable when there is both a LTR and RTL version of it
if (((changingConfigurations&~(ActivityInfo.CONFIG_FONT_SCALE |
ActivityInfo.CONFIG_DENSITY)) & VARYING_CONFIGS) != 0) {
String resName;
@@ -1995,6 +2003,17 @@ public class Resources {
+ " (" + resName + ") that varies with configuration!!");
return false;
}
+ if (TRACE_FOR_PRELOAD) {
+ String resName;
+ try {
+ resName = getResourceName(resourceId);
+ } catch (NotFoundException e) {
+ resName = "?";
+ }
+ Log.w(TAG, "Preloading " + name + " resource #0x"
+ + Integer.toHexString(resourceId)
+ + " (" + resName + ")");
+ }
return true;
}
@@ -2022,11 +2041,11 @@ public class Resources {
if (dr != null) {
return dr;
}
-
+ final int layoutDirection = mConfiguration.getLayoutDirection();
Drawable.ConstantState cs = isColorDrawable
? sPreloadedColorDrawables.get(key)
: (sPreloadedDensity == mConfiguration.densityDpi
- ? sPreloadedDrawables.get(key) : null);
+ ? sPreloadedDrawables[layoutDirection].get(key) : null);
if (cs != null) {
dr = cs.newDrawable(this);
} else {
@@ -2100,11 +2119,12 @@ public class Resources {
cs = dr.getConstantState();
if (cs != null) {
if (mPreloading) {
- if (verifyPreloadConfig(cs.getChangingConfigurations(), value.resourceId, "drawable")) {
+ if (verifyPreloadConfig(cs.getChangingConfigurations(), value.resourceId,
+ "drawable")) {
if (isColorDrawable) {
sPreloadedColorDrawables.put(key, cs);
} else {
- sPreloadedDrawables.put(key, cs);
+ sPreloadedDrawables[layoutDirection].put(key, cs);
}
}
} else {
diff --git a/core/java/android/hardware/usb/UsbDeviceConnection.java b/core/java/android/hardware/usb/UsbDeviceConnection.java
index 0856e27..b2034b2 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 2b359eb..ab4cd9b 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/Environment.java b/core/java/android/os/Environment.java
index d9846ec..61eef1f 100644
--- a/core/java/android/os/Environment.java
+++ b/core/java/android/os/Environment.java
@@ -51,6 +51,7 @@ public class Environment {
private static final String SYSTEM_PROPERTY_EFS_ENABLED = "persist.security.efs.enabled";
private static UserEnvironment sCurrentUser;
+ private static boolean sUserRequired;
private static final Object sLock = new Object();
@@ -223,7 +224,7 @@ public class Environment {
* @hide
*/
public static File getMediaStorageDirectory() {
- throwIfSystem();
+ throwIfUserRequired();
return sCurrentUser.getMediaStorageDirectory();
}
@@ -318,7 +319,7 @@ public class Environment {
* @see #isExternalStorageRemovable()
*/
public static File getExternalStorageDirectory() {
- throwIfSystem();
+ throwIfUserRequired();
return sCurrentUser.getExternalStorageDirectory();
}
@@ -465,7 +466,7 @@ public class Environment {
* using it such as with {@link File#mkdirs File.mkdirs()}.
*/
public static File getExternalStoragePublicDirectory(String type) {
- throwIfSystem();
+ throwIfUserRequired();
return sCurrentUser.getExternalStoragePublicDirectory(type);
}
@@ -474,7 +475,7 @@ public class Environment {
* @hide
*/
public static File getExternalStorageAndroidDataDir() {
- throwIfSystem();
+ throwIfUserRequired();
return sCurrentUser.getExternalStorageAndroidDataDir();
}
@@ -483,7 +484,7 @@ public class Environment {
* @hide
*/
public static File getExternalStorageAppDataDirectory(String packageName) {
- throwIfSystem();
+ throwIfUserRequired();
return sCurrentUser.getExternalStorageAppDataDirectory(packageName);
}
@@ -492,7 +493,7 @@ public class Environment {
* @hide
*/
public static File getExternalStorageAppMediaDirectory(String packageName) {
- throwIfSystem();
+ throwIfUserRequired();
return sCurrentUser.getExternalStorageAppMediaDirectory(packageName);
}
@@ -501,7 +502,7 @@ public class Environment {
* @hide
*/
public static File getExternalStorageAppObbDirectory(String packageName) {
- throwIfSystem();
+ throwIfUserRequired();
return sCurrentUser.getExternalStorageAppObbDirectory(packageName);
}
@@ -510,7 +511,7 @@ public class Environment {
* @hide
*/
public static File getExternalStorageAppFilesDirectory(String packageName) {
- throwIfSystem();
+ throwIfUserRequired();
return sCurrentUser.getExternalStorageAppFilesDirectory(packageName);
}
@@ -519,7 +520,7 @@ public class Environment {
* @hide
*/
public static File getExternalStorageAppCacheDirectory(String packageName) {
- throwIfSystem();
+ throwIfUserRequired();
return sCurrentUser.getExternalStorageAppCacheDirectory(packageName);
}
@@ -650,9 +651,15 @@ public class Environment {
}
}
- private static void throwIfSystem() {
- if (Process.myUid() == Process.SYSTEM_UID) {
- Log.wtf(TAG, "Static storage paths aren't available from AID_SYSTEM", new Throwable());
+ /** {@hide} */
+ public static void setUserRequired(boolean userRequired) {
+ sUserRequired = userRequired;
+ }
+
+ private static void throwIfUserRequired() {
+ if (sUserRequired) {
+ Log.wtf(TAG, "Path requests must specify a user by using UserEnvironment",
+ new Throwable());
}
}
diff --git a/core/java/android/os/Handler.java b/core/java/android/os/Handler.java
index 94de448..14d8f07 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 daf1f59..2904105 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 fa28765..d5cf771 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 c058bfc..bf7e5ca 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/os/StatFs.java b/core/java/android/os/StatFs.java
index 60ec0d7..2314057 100644
--- a/core/java/android/os/StatFs.java
+++ b/core/java/android/os/StatFs.java
@@ -57,9 +57,9 @@ public class StatFs {
}
/**
- * The size, in bytes, of a block on the file system. This corresponds to
- * the Unix {@code statfs.f_bsize} field.
+ * @deprecated Use {@link #getBlockSizeLong()} instead.
*/
+ @Deprecated
public int getBlockSize() {
return (int) mStat.f_bsize;
}
@@ -73,27 +73,25 @@ public class StatFs {
}
/**
- * The total number of blocks on the file system. This corresponds to the
- * Unix {@code statfs.f_blocks} field.
+ * @deprecated Use {@link #getBlockCountLong()} instead.
*/
+ @Deprecated
public int getBlockCount() {
return (int) mStat.f_blocks;
}
/**
- * The size, in bytes, of a block on the file system. This corresponds to
- * the Unix {@code statfs.f_bsize} field.
+ * The total number of blocks on the file system. This corresponds to the
+ * Unix {@code statfs.f_blocks} field.
*/
public long getBlockCountLong() {
return mStat.f_blocks;
}
/**
- * The total number of blocks that are free on the file system, including
- * reserved blocks (that are not available to normal applications). This
- * corresponds to the Unix {@code statfs.f_bfree} field. Most applications
- * will want to use {@link #getAvailableBlocks()} instead.
+ * @deprecated Use {@link #getFreeBlocksLong()} instead.
*/
+ @Deprecated
public int getFreeBlocks() {
return (int) mStat.f_bfree;
}
@@ -109,17 +107,18 @@ public class StatFs {
}
/**
- * The number of bytes that are free on the file system, including
- * reserved blocks (that are not available to normal applications).
+ * The number of bytes that are free on the file system, including reserved
+ * blocks (that are not available to normal applications). Most applications
+ * will want to use {@link #getAvailableBytes()} instead.
*/
public long getFreeBytes() {
return mStat.f_bfree * mStat.f_bsize;
}
/**
- * The number of blocks that are free on the file system and available to
- * applications. This corresponds to the Unix {@code statfs.f_bavail} field.
+ * @deprecated Use {@link #getAvailableBlocksLong()} instead.
*/
+ @Deprecated
public int getAvailableBlocks() {
return (int) mStat.f_bavail;
}
@@ -139,4 +138,11 @@ public class StatFs {
public long getAvailableBytes() {
return mStat.f_bavail * mStat.f_bsize;
}
+
+ /**
+ * The total number of bytes supported by the file system.
+ */
+ public long getTotalBytes() {
+ return mStat.f_blocks * mStat.f_bsize;
+ }
}
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 3df4e99..4de5933 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -714,6 +714,17 @@ public final class Settings {
*/
public static final String EXTRA_AUTHORITIES = "authorities";
+ /**
+ * Activity Extra: Limit available options in launched activity based on the given account
+ * types.
+ * <p>
+ * This can be passed as an extra field in an Activity Intent with one or more account types
+ * as a String[]. This field is used by some intents to alter the behavior of the called
+ * activity.
+ * <p>
+ * Example: The {@link #ACTION_ADD_ACCOUNT} intent restricts the account types to the specified
+ * list.
+ */
public static final String EXTRA_ACCOUNT_TYPES = "account_types";
public static final String EXTRA_INPUT_METHOD_ID = "input_method_id";
diff --git a/core/java/android/util/PropertyValueModel.java b/core/java/android/util/PropertyValueModel.java
deleted file mode 100755
index eb9c47d..0000000
--- 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 4789682..0000000
--- 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 be26d20..a0a63a6 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 9c1b7a0..d52b1f3 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 41ab5f2..f1804f8 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 ec81214..57e51c2 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 c7914f3..f42999d 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 a6486a8..2737f94 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 2b91abf..0000000
--- 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);
-}