summaryrefslogtreecommitdiffstats
path: root/core/java/android
diff options
context:
space:
mode:
Diffstat (limited to 'core/java/android')
-rw-r--r--core/java/android/accounts/AccountAuthenticatorCache.java38
-rw-r--r--core/java/android/accounts/AccountManager.java18
-rw-r--r--core/java/android/accounts/AccountManagerService.java166
-rw-r--r--core/java/android/accounts/AuthenticatorDescription.java20
-rw-r--r--core/java/android/app/ContextImpl.java16
-rw-r--r--core/java/android/app/Dialog.java2
-rw-r--r--core/java/android/content/Context.java11
-rw-r--r--core/java/android/content/SyncManager.java7
-rw-r--r--core/java/android/content/SyncStorageEngine.java26
-rw-r--r--core/java/android/content/pm/PackageManager.java7
-rw-r--r--core/java/android/content/res/AssetManager.java1
-rw-r--r--core/java/android/hardware/SensorManager.java7
-rw-r--r--core/java/android/hardware/Usb.java99
-rw-r--r--core/java/android/hardware/usb/IUsbManager.aidl58
-rw-r--r--core/java/android/hardware/usb/UsbAccessory.aidl19
-rw-r--r--core/java/android/hardware/usb/UsbAccessory.java192
-rw-r--r--core/java/android/hardware/usb/UsbManager.java295
-rw-r--r--core/java/android/net/ConnectivityManager.java4
-rw-r--r--core/java/android/net/InterfaceConfiguration.java18
-rw-r--r--core/java/android/net/MobileDataStateTracker.java4
-rw-r--r--core/java/android/net/NetworkStateTracker.java4
-rw-r--r--core/java/android/net/NetworkUtils.java12
-rw-r--r--core/java/android/net/wimax/WimaxManagerConstants.java103
-rw-r--r--[-rwxr-xr-x]core/java/android/nfc/ApduList.aidl (renamed from core/java/android/nfc/INfcSecureElement.aidl)13
-rw-r--r--core/java/android/nfc/ApduList.java68
-rw-r--r--core/java/android/nfc/INfcAdapter.aidl11
-rwxr-xr-xcore/java/android/nfc/INfcAdapterExtras.aidl34
-rw-r--r--core/java/android/nfc/NfcAdapter.java41
-rwxr-xr-xcore/java/android/nfc/NfcSecureElement.java138
-rw-r--r--core/java/android/nfc/tech/Ndef.java9
-rw-r--r--core/java/android/nfc/tech/package.html13
-rw-r--r--core/java/android/os/BatteryStats.java45
-rw-r--r--core/java/android/os/Looper.java19
-rw-r--r--core/java/android/os/Process.java2
-rw-r--r--core/java/android/os/RecoverySystem.java25
-rw-r--r--core/java/android/pim/ICalendar.java17
-rw-r--r--core/java/android/provider/Settings.java20
-rwxr-xr-xcore/java/android/provider/Telephony.java15
-rw-r--r--core/java/android/speech/RecognitionService.java14
-rwxr-xr-xcore/java/android/text/Layout.java2
-rw-r--r--core/java/android/text/TextUtils.java12
-rw-r--r--core/java/android/text/method/MultiTapKeyListener.java8
-rw-r--r--core/java/android/text/style/DrawableMarginSpan.java3
-rw-r--r--core/java/android/util/SparseArray.java11
-rwxr-xr-x[-rw-r--r--]core/java/android/view/GestureDetector.java11
-rwxr-xr-x[-rw-r--r--]core/java/android/view/ViewConfiguration.java17
-rw-r--r--core/java/android/view/ViewRoot.java9
-rw-r--r--core/java/android/webkit/FrameLoader.java3
-rw-r--r--core/java/android/webkit/WebSettings.java23
-rw-r--r--core/java/android/widget/DatePicker.java39
-rw-r--r--core/java/android/widget/PopupWindow.java4
-rw-r--r--core/java/android/widget/ScrollView.java6
-rw-r--r--core/java/android/widget/TextView.java31
53 files changed, 1329 insertions, 461 deletions
diff --git a/core/java/android/accounts/AccountAuthenticatorCache.java b/core/java/android/accounts/AccountAuthenticatorCache.java
index d2b3bc7..5ee1f60 100644
--- a/core/java/android/accounts/AccountAuthenticatorCache.java
+++ b/core/java/android/accounts/AccountAuthenticatorCache.java
@@ -18,17 +18,22 @@ package android.accounts;
import android.content.pm.PackageManager;
import android.content.pm.RegisteredServicesCache;
+import android.content.pm.ResolveInfo;
import android.content.pm.XmlSerializerAndParser;
import android.content.res.Resources;
import android.content.res.TypedArray;
+import android.content.ComponentName;
import android.content.Context;
+import android.content.Intent;
import android.util.AttributeSet;
+import android.util.Log;
import android.text.TextUtils;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlSerializer;
import org.xmlpull.v1.XmlPullParserException;
import java.io.IOException;
+import java.util.List;
/**
* A cache of services that export the {@link IAccountAuthenticator} interface. This cache
@@ -63,11 +68,40 @@ import java.io.IOException;
com.android.internal.R.styleable.AccountAuthenticator_smallIcon, 0);
final int prefId = sa.getResourceId(
com.android.internal.R.styleable.AccountAuthenticator_accountPreferences, 0);
+
+ boolean customTokens = false;
+ try {
+ // In HC this will be an attribute in authenticator.xml, this is a workaround
+ // using meta-data to avoid changes to the API.
+ // If meta-data is absent the old behavior is preserved.
+ // Authenticator will know if AccountManager supports customTokens or not.
+ PackageManager pm = mContext.getPackageManager();
+ List<ResolveInfo> resolveInfos = pm.queryIntentServices(
+ new Intent(AccountManager.ACTION_AUTHENTICATOR_INTENT),
+ PackageManager.GET_META_DATA);
+ for (ResolveInfo resolveInfo: resolveInfos) {
+ android.content.pm.ServiceInfo si = resolveInfo.serviceInfo;
+ if (!packageName.equals(si.packageName)) {
+ continue;
+ }
+ Object ctString = si.metaData.get(AccountManager.ACTION_AUTHENTICATOR_INTENT
+ + ".customTokens");
+ if (ctString != null) {
+ customTokens = true;
+ }
+ }
+ } catch (Throwable t) {
+ // Protected against invalid data in meta or unexpected
+ // conditions - the authenticator will not have the new
+ // features.
+ Log.e(TAG, "Error getting customTokens metadata " + t);
+ }
+
if (TextUtils.isEmpty(accountType)) {
return null;
}
- return new AuthenticatorDescription(accountType, packageName, labelId, iconId,
- smallIconId, prefId);
+ return new AuthenticatorDescription(accountType, packageName, labelId, iconId,
+ smallIconId, prefId, customTokens);
} finally {
sa.recycle();
}
diff --git a/core/java/android/accounts/AccountManager.java b/core/java/android/accounts/AccountManager.java
index fd3a0d0..677b959 100644
--- a/core/java/android/accounts/AccountManager.java
+++ b/core/java/android/accounts/AccountManager.java
@@ -188,6 +188,24 @@ public class AccountManager {
public static final String KEY_ERROR_CODE = "errorCode";
public static final String KEY_ERROR_MESSAGE = "errorMessage";
public static final String KEY_USERDATA = "userdata";
+ /**
+ * Authenticators using 'customTokens' option will also get the UID of the
+ * caller
+ * @hide
+ */
+ public static final String KEY_CALLER_UID = "callerUid";
+
+ /**
+ * @hide
+ */
+ public static final String KEY_CALLER_PID = "callerPid";
+
+ /**
+ * Boolean, if set and 'customTokens' the authenticator is responsible for
+ * notifications.
+ * @hide
+ */
+ public static final String KEY_NOTIFY_ON_FAILURE = "notifyOnAuthFailure";
public static final String ACTION_AUTHENTICATOR_INTENT =
"android.accounts.AccountAuthenticator";
diff --git a/core/java/android/accounts/AccountManagerService.java b/core/java/android/accounts/AccountManagerService.java
index 9a8cc15..5796042 100644
--- a/core/java/android/accounts/AccountManagerService.java
+++ b/core/java/android/accounts/AccountManagerService.java
@@ -91,6 +91,8 @@ public class AccountManagerService
private final Context mContext;
+ private final PackageManager mPackageManager;
+
private HandlerThread mMessageThread;
private final MessageHandler mMessageHandler;
@@ -99,7 +101,6 @@ public class AccountManagerService
private final AccountAuthenticatorCache mAuthenticatorCache;
private final DatabaseHelper mOpenHelper;
- private final SimWatcher mSimWatcher;
private static final String TABLE_ACCOUNTS = "accounts";
private static final String ACCOUNTS_ID = "_id";
@@ -214,6 +215,7 @@ public class AccountManagerService
public AccountManagerService(Context context) {
mContext = context;
+ mPackageManager = context.getPackageManager();
mOpenHelper = new DatabaseHelper(mContext);
@@ -224,7 +226,6 @@ public class AccountManagerService
mAuthenticatorCache = new AccountAuthenticatorCache(mContext);
mAuthenticatorCache.setListener(this, null /* Handler */);
- mSimWatcher = new SimWatcher(mContext);
sThis.set(this);
validateAccounts();
@@ -520,6 +521,18 @@ public class AccountManagerService
if (account == null) throw new IllegalArgumentException("account is null");
checkManageAccountsPermission();
long identityToken = clearCallingIdentity();
+
+ cancelNotification(getSigninRequiredNotificationId(account));
+ synchronized(mCredentialsPermissionNotificationIds) {
+ for (Pair<Pair<Account, String>, Integer> pair:
+ mCredentialsPermissionNotificationIds.keySet()) {
+ if (account.equals(pair.first.first)) {
+ int id = mCredentialsPermissionNotificationIds.get(pair);
+ cancelNotification(id);
+ }
+ }
+ }
+
try {
new RemoveAccountSession(response, account).bind();
} finally {
@@ -842,19 +855,49 @@ public class AccountManagerService
public void getAuthToken(IAccountManagerResponse response, final Account account,
final String authTokenType, final boolean notifyOnAuthFailure,
- final boolean expectActivityLaunch, final Bundle loginOptions) {
+ final boolean expectActivityLaunch, Bundle loginOptionsIn) {
+ if (Log.isLoggable(TAG, Log.VERBOSE)) {
+ Log.v(TAG, "getAuthToken: " + account
+ + ", response " + response
+ + ", authTokenType " + authTokenType
+ + ", notifyOnAuthFailure " + notifyOnAuthFailure
+ + ", expectActivityLaunch " + expectActivityLaunch
+ + ", caller's uid " + Binder.getCallingUid()
+ + ", pid " + Binder.getCallingPid());
+ }
if (response == null) throw new IllegalArgumentException("response is null");
if (account == null) throw new IllegalArgumentException("account is null");
if (authTokenType == null) throw new IllegalArgumentException("authTokenType is null");
checkBinderPermission(Manifest.permission.USE_CREDENTIALS);
final int callerUid = Binder.getCallingUid();
- final boolean permissionGranted = permissionIsGranted(account, authTokenType, callerUid);
+ final int callerPid = Binder.getCallingPid();
+
+ AccountAuthenticatorCache.ServiceInfo<AuthenticatorDescription> authenticatorInfo =
+ mAuthenticatorCache.getServiceInfo(
+ AuthenticatorDescription.newKey(account.type));
+ final boolean customTokens =
+ authenticatorInfo != null && authenticatorInfo.type.customTokens;
+
+ // skip the check if customTokens
+ final boolean permissionGranted = customTokens ||
+ permissionIsGranted(account, authTokenType, callerUid);
+
+ final Bundle loginOptions = (loginOptionsIn == null) ? new Bundle() :
+ loginOptionsIn;
+ if (customTokens) {
+ // let authenticator know the identity of the caller
+ loginOptions.putInt(AccountManager.KEY_CALLER_UID, callerUid);
+ loginOptions.putInt(AccountManager.KEY_CALLER_PID, callerPid);
+ if (notifyOnAuthFailure) {
+ loginOptions.putBoolean(AccountManager.KEY_NOTIFY_ON_FAILURE, true);
+ }
+ }
long identityToken = clearCallingIdentity();
try {
// if the caller has permission, do the peek. otherwise go the more expensive
// route of starting a Session
- if (permissionGranted) {
+ if (!customTokens && permissionGranted) {
String authToken = readAuthTokenFromDatabase(account, authTokenType);
if (authToken != null) {
Bundle result = new Bundle();
@@ -908,12 +951,14 @@ public class AccountManagerService
"the type and name should not be empty");
return;
}
- saveAuthTokenToDatabase(new Account(name, type),
- authTokenType, authToken);
+ if (!customTokens) {
+ saveAuthTokenToDatabase(new Account(name, type),
+ authTokenType, authToken);
+ }
}
Intent intent = result.getParcelable(AccountManager.KEY_INTENT);
- if (intent != null && notifyOnAuthFailure) {
+ if (intent != null && notifyOnAuthFailure && !customTokens) {
doNotification(
account, result.getString(AccountManager.KEY_AUTH_FAILED_MESSAGE),
intent);
@@ -972,6 +1017,10 @@ public class AccountManagerService
AccountAuthenticatorResponse response, String authTokenType, String authTokenLabel) {
Intent intent = new Intent(mContext, GrantCredentialsPermissionActivity.class);
+ // See FLAG_ACTIVITY_NEW_TASK docs for limitations and benefits of the flag.
+ // Since it was set in Eclair+ we can't change it without breaking apps using
+ // the intent from a non-Activity context.
+ intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.addCategory(
String.valueOf(getCredentialPermissionNotificationId(account, authTokenType, uid)));
@@ -1640,95 +1689,6 @@ public class AccountManagerService
}
}
- private class SimWatcher extends BroadcastReceiver {
- public SimWatcher(Context context) {
- // Re-scan the SIM card when the SIM state changes, and also if
- // the disk recovers from a full state (we may have failed to handle
- // things properly while the disk was full).
- final IntentFilter filter = new IntentFilter();
- filter.addAction(TelephonyIntents.ACTION_SIM_STATE_CHANGED);
- filter.addAction(Intent.ACTION_DEVICE_STORAGE_OK);
- context.registerReceiver(this, filter);
- }
-
- /**
- * Compare the IMSI to the one stored in the login service's
- * database. If they differ, erase all passwords and
- * authtokens (and store the new IMSI).
- */
- @Override
- public void onReceive(Context context, Intent intent) {
- // Check IMSI on every update; nothing happens if the IMSI
- // is missing or unchanged.
- TelephonyManager telephonyManager =
- (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
- if (telephonyManager == null) {
- Log.w(TAG, "failed to get TelephonyManager");
- return;
- }
- String imsi = telephonyManager.getSubscriberId();
-
- // If the subscriber ID is an empty string, don't do anything.
- if (TextUtils.isEmpty(imsi)) return;
-
- // If the current IMSI matches what's stored, don't do anything.
- String storedImsi = getMetaValue("imsi");
- if (Log.isLoggable(TAG, Log.VERBOSE)) {
- Log.v(TAG, "current IMSI=" + imsi + "; stored IMSI=" + storedImsi);
- }
- if (imsi.equals(storedImsi)) return;
-
- // If a CDMA phone is unprovisioned, getSubscriberId()
- // will return a different value, but we *don't* erase the
- // passwords. We only erase them if it has a different
- // subscriber ID once it's provisioned.
- if (telephonyManager.getPhoneType() == TelephonyManager.PHONE_TYPE_CDMA) {
- IBinder service = ServiceManager.checkService(Context.TELEPHONY_SERVICE);
- if (service == null) {
- Log.w(TAG, "call to checkService(TELEPHONY_SERVICE) failed");
- return;
- }
- ITelephony telephony = ITelephony.Stub.asInterface(service);
- if (telephony == null) {
- Log.w(TAG, "failed to get ITelephony interface");
- return;
- }
- boolean needsProvisioning;
- try {
- needsProvisioning = telephony.getCdmaNeedsProvisioning();
- } catch (RemoteException e) {
- Log.w(TAG, "exception while checking provisioning", e);
- // default to NOT wiping out the passwords
- needsProvisioning = true;
- }
- if (needsProvisioning) {
- // if the phone needs re-provisioning, don't do anything.
- if (Log.isLoggable(TAG, Log.VERBOSE)) {
- Log.v(TAG, "current IMSI=" + imsi + " (needs provisioning); stored IMSI=" +
- storedImsi);
- }
- return;
- }
- }
-
- if (!imsi.equals(storedImsi) && !TextUtils.isEmpty(storedImsi)) {
- Log.w(TAG, "wiping all passwords and authtokens because IMSI changed ("
- + "stored=" + storedImsi + ", current=" + imsi + ")");
- SQLiteDatabase db = mOpenHelper.getWritableDatabase();
- db.beginTransaction();
- try {
- db.execSQL("DELETE from " + TABLE_AUTHTOKENS);
- db.execSQL("UPDATE " + TABLE_ACCOUNTS + " SET " + ACCOUNTS_PASSWORD + " = ''");
- sendAccountsChangedBroadcast();
- db.setTransactionSuccessful();
- } finally {
- db.endTransaction();
- }
- }
- setMetaValue("imsi", imsi);
- }
- }
-
public IBinder onBind(Intent intent) {
return asBinder();
}
@@ -1849,12 +1809,12 @@ public class AccountManagerService
}
private boolean inSystemImage(int callerUid) {
- String[] packages = mContext.getPackageManager().getPackagesForUid(callerUid);
+ String[] packages = mPackageManager.getPackagesForUid(callerUid);
for (String name : packages) {
try {
- PackageInfo packageInfo =
- mContext.getPackageManager().getPackageInfo(name, 0 /* flags */);
- if ((packageInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
+ PackageInfo packageInfo = mPackageManager.getPackageInfo(name, 0 /* flags */);
+ if (packageInfo != null
+ && (packageInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
return true;
}
} catch (PackageManager.NameNotFoundException e) {
@@ -1872,7 +1832,7 @@ public class AccountManagerService
&& hasExplicitlyGrantedPermission(account, authTokenType);
if (Log.isLoggable(TAG, Log.VERBOSE)) {
Log.v(TAG, "checkGrantsOrCallingUidAgainstAuthenticator: caller uid "
- + callerUid + ", account " + account
+ + callerUid + ", " + account
+ ": is authenticator? " + fromAuthenticator
+ ", has explicit permission? " + hasExplicitGrants);
}
@@ -1884,7 +1844,7 @@ public class AccountManagerService
mAuthenticatorCache.getAllServices()) {
if (serviceInfo.type.type.equals(accountType)) {
return (serviceInfo.uid == callingUid) ||
- (mContext.getPackageManager().checkSignatures(serviceInfo.uid, callingUid)
+ (mPackageManager.checkSignatures(serviceInfo.uid, callingUid)
== PackageManager.SIGNATURE_MATCH);
}
}
diff --git a/core/java/android/accounts/AuthenticatorDescription.java b/core/java/android/accounts/AuthenticatorDescription.java
index c651567..4d3769a 100644
--- a/core/java/android/accounts/AuthenticatorDescription.java
+++ b/core/java/android/accounts/AuthenticatorDescription.java
@@ -44,9 +44,16 @@ public class AuthenticatorDescription implements Parcelable {
/** The package name that can be used to lookup the resources from above. */
final public String packageName;
- /** A constructor for a full AuthenticatorDescription */
+ /** Authenticator handles its own token caching and permission screen
+ * @hide
+ */
+ final public boolean customTokens;
+
+ /** A constructor for a full AuthenticatorDescription
+ * @hide
+ */
public AuthenticatorDescription(String type, String packageName, int labelId, int iconId,
- int smallIconId, int prefId) {
+ int smallIconId, int prefId, boolean customTokens) {
if (type == null) throw new IllegalArgumentException("type cannot be null");
if (packageName == null) throw new IllegalArgumentException("packageName cannot be null");
this.type = type;
@@ -55,6 +62,12 @@ public class AuthenticatorDescription implements Parcelable {
this.iconId = iconId;
this.smallIconId = smallIconId;
this.accountPreferencesId = prefId;
+ this.customTokens = customTokens;
+ }
+
+ public AuthenticatorDescription(String type, String packageName, int labelId, int iconId,
+ int smallIconId, int prefId) {
+ this(type, packageName, labelId, iconId, smallIconId, prefId, false);
}
/**
@@ -74,6 +87,7 @@ public class AuthenticatorDescription implements Parcelable {
this.iconId = 0;
this.smallIconId = 0;
this.accountPreferencesId = 0;
+ this.customTokens = false;
}
private AuthenticatorDescription(Parcel source) {
@@ -83,6 +97,7 @@ public class AuthenticatorDescription implements Parcelable {
this.iconId = source.readInt();
this.smallIconId = source.readInt();
this.accountPreferencesId = source.readInt();
+ this.customTokens = source.readByte() == 1;
}
/** @inheritDoc */
@@ -115,6 +130,7 @@ public class AuthenticatorDescription implements Parcelable {
dest.writeInt(iconId);
dest.writeInt(smallIconId);
dest.writeInt(accountPreferencesId);
+ dest.writeByte((byte) (customTokens ? 1 : 0));
}
/** Used to create the object from a parcel. */
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index f535d61..0e473c9 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -61,6 +61,8 @@ import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.graphics.Bitmap;
import android.graphics.drawable.Drawable;
import android.hardware.SensorManager;
+import android.hardware.usb.IUsbManager;
+import android.hardware.usb.UsbManager;
import android.location.ILocationManager;
import android.location.LocationManager;
import android.media.AudioManager;
@@ -188,6 +190,7 @@ class ContextImpl extends Context {
private SearchManager mSearchManager = null;
private SensorManager mSensorManager = null;
private StorageManager mStorageManager = null;
+ private UsbManager mUsbManager = null;
private Vibrator mVibrator = null;
private LayoutInflater mLayoutInflater = null;
private StatusBarManager mStatusBarManager = null;
@@ -951,6 +954,8 @@ class ContextImpl extends Context {
return getSensorManager();
} else if (STORAGE_SERVICE.equals(name)) {
return getStorageManager();
+ } else if (USB_SERVICE.equals(name)) {
+ return getUsbManager();
} else if (VIBRATOR_SERVICE.equals(name)) {
return getVibrator();
} else if (STATUS_BAR_SERVICE.equals(name)) {
@@ -1145,6 +1150,17 @@ class ContextImpl extends Context {
return mStorageManager;
}
+ private UsbManager getUsbManager() {
+ synchronized (mSync) {
+ if (mUsbManager == null) {
+ IBinder b = ServiceManager.getService(USB_SERVICE);
+ IUsbManager service = IUsbManager.Stub.asInterface(b);
+ mUsbManager = new UsbManager(this, service);
+ }
+ }
+ return mUsbManager;
+ }
+
private Vibrator getVibrator() {
synchronized (mSync) {
if (mVibrator == null) {
diff --git a/core/java/android/app/Dialog.java b/core/java/android/app/Dialog.java
index da8c9e5..d70ec0b 100644
--- a/core/java/android/app/Dialog.java
+++ b/core/java/android/app/Dialog.java
@@ -823,7 +823,7 @@ public class Dialog implements DialogInterface, Window.Callback,
// associate search with owner activity
final ComponentName appName = getAssociatedActivity();
- if (appName != null) {
+ if (appName != null && searchManager.getSearchableInfo(appName) != null) {
searchManager.startSearch(null, false, appName, null, false);
dismiss();
return true;
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 85c29b8..ec2d640 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -1567,6 +1567,17 @@ public abstract class Context {
public static final String SIP_SERVICE = "sip";
/**
+ * Use with {@link #getSystemService} to retrieve a {@link
+ * android.hardware.usb.UsbManager} for access to USB devices (as a USB host)
+ * and for controlling this device's behavior as a USB device.
+ *
+ * @see #getSystemService
+ * @see android.harware.usb.UsbManager
+ * @hide
+ */
+ public static final String USB_SERVICE = "usb";
+
+ /**
* Determine whether the given permission is allowed for a particular
* process and user ID running in the system.
*
diff --git a/core/java/android/content/SyncManager.java b/core/java/android/content/SyncManager.java
index 26b6ad7..5a83604 100644
--- a/core/java/android/content/SyncManager.java
+++ b/core/java/android/content/SyncManager.java
@@ -258,6 +258,7 @@ public class SyncManager implements OnAccountsUpdateListener {
// DISCONNECTED for GPRS in any order. if we receive the CONNECTED first, and then
// a DISCONNECTED, we want to make sure we set mDataConnectionIsConnected to true
// since we still have a WiFi connection.
+ final boolean wasConnected = mDataConnectionIsConnected;
switch (state) {
case CONNECTED:
mDataConnectionIsConnected = true;
@@ -273,6 +274,12 @@ public class SyncManager implements OnAccountsUpdateListener {
// ignore the rest of the states -- leave our boolean alone.
}
if (mDataConnectionIsConnected) {
+ if (!wasConnected) {
+ if (Log.isLoggable(TAG, Log.VERBOSE)) {
+ Log.v(TAG, "Reconnection detected: clearing all backoffs");
+ }
+ mSyncStorageEngine.clearAllBackoffs();
+ }
sendCheckAlarmsMessage();
}
}
diff --git a/core/java/android/content/SyncStorageEngine.java b/core/java/android/content/SyncStorageEngine.java
index e1a9dbb..faf1365 100644
--- a/core/java/android/content/SyncStorageEngine.java
+++ b/core/java/android/content/SyncStorageEngine.java
@@ -525,6 +525,32 @@ public class SyncStorageEngine extends Handler {
}
}
+ public void clearAllBackoffs() {
+ boolean changed = false;
+ synchronized (mAuthorities) {
+ for (AccountInfo accountInfo : mAccounts.values()) {
+ for (AuthorityInfo authorityInfo : accountInfo.authorities.values()) {
+ if (authorityInfo.backoffTime != NOT_IN_BACKOFF_MODE
+ || authorityInfo.backoffDelay != NOT_IN_BACKOFF_MODE) {
+ if (Log.isLoggable(TAG, Log.VERBOSE)) {
+ Log.v(TAG, "clearAllBackoffs:"
+ + " authority:" + authorityInfo.authority
+ + " account:" + accountInfo.account.name
+ + " backoffTime was: " + authorityInfo.backoffTime
+ + " backoffDelay was: " + authorityInfo.backoffDelay);
+ }
+ authorityInfo.backoffTime = NOT_IN_BACKOFF_MODE;
+ authorityInfo.backoffDelay = NOT_IN_BACKOFF_MODE;
+ changed = true;
+ }
+ }
+ }
+ }
+
+ if (changed) {
+ reportChange(ContentResolver.SYNC_OBSERVER_TYPE_SETTINGS);
+ }
+ }
public void setDelayUntilTime(Account account, String providerName, long delayUntil) {
if (Log.isLoggable(TAG, Log.VERBOSE)) {
Log.v(TAG, "setDelayUntil: " + account + ", provider " + providerName
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 922f8cd..a779925 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -785,6 +785,13 @@ public abstract class PackageManager {
/**
* Feature for {@link #getSystemAvailableFeatures} and
+ * {@link #hasSystemFeature}: The device supports connecting to USB accessories.
+ * @hide
+ */
+ public static final String FEATURE_USB_ACCESSORY = "android.hardware.usb.accessory";
+
+ /**
+ * Feature for {@link #getSystemAvailableFeatures} and
* {@link #hasSystemFeature}: The SIP API is enabled on the device.
*/
@SdkConstant(SdkConstantType.FEATURE)
diff --git a/core/java/android/content/res/AssetManager.java b/core/java/android/content/res/AssetManager.java
index 73d9458..4702327 100644
--- a/core/java/android/content/res/AssetManager.java
+++ b/core/java/android/content/res/AssetManager.java
@@ -234,6 +234,7 @@ public final class AssetManager {
StringBlock[] blocks = mStringBlocks;
if (blocks == null) {
ensureStringBlocks();
+ blocks = mStringBlocks;
}
outValue.string = blocks[block].get(outValue.data);
return true;
diff --git a/core/java/android/hardware/SensorManager.java b/core/java/android/hardware/SensorManager.java
index f079e42..b1a9349 100644
--- a/core/java/android/hardware/SensorManager.java
+++ b/core/java/android/hardware/SensorManager.java
@@ -1970,7 +1970,8 @@ public class SensorManager
if (rotationVector.length == 4) {
q0 = rotationVector[3];
} else {
- q0 = (float)Math.sqrt(1 - q1*q1 - q2*q2 - q3*q3);
+ q0 = 1 - q1*q1 - q2*q2 - q3*q3;
+ q0 = (q0 > 0) ? (float)Math.sqrt(q0) : 0;
}
float sq_q1 = 2 * q1 * q1;
@@ -2026,8 +2027,8 @@ public class SensorManager
if (rv.length == 4) {
Q[0] = rv[3];
} else {
- //In this case, the w component of the quaternion is known to be a positive number
- Q[0] = (float)Math.sqrt(1 - rv[0]*rv[0] - rv[1]*rv[1] - rv[2]*rv[2]);
+ Q[0] = 1 - rv[0]*rv[0] - rv[1]*rv[1] - rv[2]*rv[2];
+ Q[0] = (Q[0] > 0) ? (float)Math.sqrt(Q[0]) : 0;
}
Q[1] = rv[0];
Q[2] = rv[1];
diff --git a/core/java/android/hardware/Usb.java b/core/java/android/hardware/Usb.java
deleted file mode 100644
index 57271d4..0000000
--- a/core/java/android/hardware/Usb.java
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * Copyright (C) 2010 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.hardware;
-
-/**
- * Class for accessing USB state information.
- * @hide
- */
-public class Usb {
- /**
- * Broadcast Action: A broadcast for USB connected events.
- *
- * The extras bundle will name/value pairs with the name of the function
- * and a value of either {@link #USB_FUNCTION_ENABLED} or {@link #USB_FUNCTION_DISABLED}.
- * Possible USB function names include {@link #USB_FUNCTION_MASS_STORAGE},
- * {@link #USB_FUNCTION_ADB}, {@link #USB_FUNCTION_RNDIS} and {@link #USB_FUNCTION_MTP}.
- */
- public static final String ACTION_USB_CONNECTED =
- "android.hardware.action.USB_CONNECTED";
-
- /**
- * Broadcast Action: A broadcast for USB disconnected events.
- */
- public static final String ACTION_USB_DISCONNECTED =
- "android.hardware.action.USB_DISCONNECTED";
-
- /**
- * Broadcast Action: A sticky broadcast for USB state change events.
- *
- * This is a sticky broadcast for clients that are interested in both USB connect and
- * disconnect events. If you are only concerned with one or the other, you can use
- * {@link #ACTION_USB_CONNECTED} or {@link #ACTION_USB_DISCONNECTED} to avoid receiving
- * unnecessary broadcasts. The boolean {@link #USB_CONNECTED} extra indicates whether
- * USB is connected or disconnected.
- * The extras bundle will also contain name/value pairs with the name of the function
- * and a value of either {@link #USB_FUNCTION_ENABLED} or {@link #USB_FUNCTION_DISABLED}.
- * Possible USB function names include {@link #USB_FUNCTION_MASS_STORAGE},
- * {@link #USB_FUNCTION_ADB}, {@link #USB_FUNCTION_RNDIS} and {@link #USB_FUNCTION_MTP}.
- */
- public static final String ACTION_USB_STATE =
- "android.hardware.action.USB_STATE";
-
- /**
- * Boolean extra indicating whether USB is connected or disconnected.
- * Used in extras for the {@link #ACTION_USB_STATE} broadcast.
- */
- public static final String USB_CONNECTED = "connected";
-
- /**
- * Name of the USB mass storage USB function.
- * Used in extras for the {@link #ACTION_USB_CONNECTED} broadcast
- */
- public static final String USB_FUNCTION_MASS_STORAGE = "mass_storage";
-
- /**
- * Name of the adb USB function.
- * Used in extras for the {@link #ACTION_USB_CONNECTED} broadcast
- */
- public static final String USB_FUNCTION_ADB = "adb";
-
- /**
- * Name of the RNDIS ethernet USB function.
- * Used in extras for the {@link #ACTION_USB_CONNECTED} broadcast
- */
- public static final String USB_FUNCTION_RNDIS = "rndis";
-
- /**
- * Name of the MTP USB function.
- * Used in extras for the {@link #ACTION_USB_CONNECTED} broadcast
- */
- public static final String USB_FUNCTION_MTP = "mtp";
-
- /**
- * Value indicating that a USB function is enabled.
- * Used in extras for the {@link #ACTION_USB_CONNECTED} broadcast
- */
- public static final String USB_FUNCTION_ENABLED = "enabled";
-
- /**
- * Value indicating that a USB function is disabled.
- * Used in extras for the {@link #ACTION_USB_CONNECTED} broadcast
- */
- public static final String USB_FUNCTION_DISABLED = "disabled";
-}
diff --git a/core/java/android/hardware/usb/IUsbManager.aidl b/core/java/android/hardware/usb/IUsbManager.aidl
new file mode 100644
index 0000000..ffe557c
--- /dev/null
+++ b/core/java/android/hardware/usb/IUsbManager.aidl
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2010 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.hardware.usb;
+
+import android.app.PendingIntent;
+import android.hardware.usb.UsbAccessory;
+import android.os.Bundle;
+import android.os.ParcelFileDescriptor;
+
+/** @hide */
+interface IUsbManager
+{
+ /* Returns the currently attached USB accessory */
+ UsbAccessory getCurrentAccessory();
+
+ /* Returns a file descriptor for communicating with the USB accessory.
+ * This file descriptor can be used with standard Java file operations.
+ */
+ ParcelFileDescriptor openAccessory(in UsbAccessory accessory);
+
+ /* Sets the default package for a USB accessory
+ * (or clears it if the package name is null)
+ */
+ void setAccessoryPackage(in UsbAccessory accessory, String packageName);
+
+ /* Returns true if the caller has permission to access the accessory. */
+ boolean hasAccessoryPermission(in UsbAccessory accessory);
+
+ /* Requests permission for the given package to access the accessory.
+ * Will display a system dialog to query the user if permission
+ * had not already been given. Result is returned via pi.
+ */
+ void requestAccessoryPermission(in UsbAccessory accessory, String packageName,
+ in PendingIntent pi);
+
+ /* Grants permission for the given UID to access the accessory */
+ void grantAccessoryPermission(in UsbAccessory accessory, int uid);
+
+ /* Returns true if the USB manager has default preferences or permissions for the package */
+ boolean hasDefaults(String packageName);
+
+ /* Clears default preferences and permissions for the package */
+ void clearDefaults(String packageName);
+}
diff --git a/core/java/android/hardware/usb/UsbAccessory.aidl b/core/java/android/hardware/usb/UsbAccessory.aidl
new file mode 100644
index 0000000..1c15f1c
--- /dev/null
+++ b/core/java/android/hardware/usb/UsbAccessory.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2011, 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.hardware.usb;
+
+parcelable UsbAccessory;
diff --git a/core/java/android/hardware/usb/UsbAccessory.java b/core/java/android/hardware/usb/UsbAccessory.java
new file mode 100644
index 0000000..8938463
--- /dev/null
+++ b/core/java/android/hardware/usb/UsbAccessory.java
@@ -0,0 +1,192 @@
+/*
+ * Copyright (C) 2011 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.hardware.usb;
+
+import android.os.Bundle;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.util.Log;
+
+/**
+ * A class representing a USB accessory.
+ * @hide
+ */
+public class UsbAccessory implements Parcelable {
+
+ private static final String TAG = "UsbAccessory";
+
+ private final String mManufacturer;
+ private final String mModel;
+ private final String mDescription;
+ private final String mVersion;
+ private final String mUri;
+ private final String mSerial;
+
+ /**
+ * UsbAccessory should only be instantiated by UsbService implementation
+ * @hide
+ */
+ public UsbAccessory(String manufacturer, String model, String description,
+ String version, String uri, String serial) {
+ mManufacturer = manufacturer;
+ mModel = model;
+ mDescription = description;
+ mVersion = version;
+ mUri = uri;
+ mSerial = serial;
+ }
+
+ /**
+ * UsbAccessory should only be instantiated by UsbService implementation
+ * @hide
+ */
+ public UsbAccessory(String[] strings) {
+ mManufacturer = strings[0];
+ mModel = strings[1];
+ mDescription = strings[2];
+ mVersion = strings[3];
+ mUri = strings[4];
+ mSerial = strings[5];
+ }
+
+ /**
+ * Returns the manufacturer of the accessory.
+ *
+ * @return the accessory manufacturer
+ */
+ public String getManufacturer() {
+ return mManufacturer;
+ }
+
+ /**
+ * Returns the model name of the accessory.
+ *
+ * @return the accessory model
+ */
+ public String getModel() {
+ return mModel;
+ }
+
+ /**
+ * Returns a user visible description of the accessory.
+ *
+ * @return the accessory description
+ */
+ public String getDescription() {
+ return mDescription;
+ }
+
+ /**
+ * Returns the version of the accessory.
+ *
+ * @return the accessory version
+ */
+ public String getVersion() {
+ return mVersion;
+ }
+
+ /**
+ * Returns the URI for the accessory.
+ * This is an optional URI that might show information about the accessory
+ * or provide the option to download an application for the accessory
+ *
+ * @return the accessory URI
+ */
+ public String getUri() {
+ return mUri;
+ }
+
+ /**
+ * Returns the unique serial number for the accessory.
+ * This is an optional serial number that can be used to differentiate
+ * between individual accessories of the same model and manufacturer
+ *
+ * @return the unique serial number
+ */
+ public String getSerial() {
+ return mSerial;
+ }
+
+ private static boolean compare(String s1, String s2) {
+ if (s1 == null) return (s2 == null);
+ return s1.equals(s2);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj instanceof UsbAccessory) {
+ UsbAccessory accessory = (UsbAccessory)obj;
+ return (compare(mManufacturer, accessory.getManufacturer()) &&
+ compare(mModel, accessory.getModel()) &&
+ compare(mDescription, accessory.getDescription()) &&
+ compare(mVersion, accessory.getVersion()) &&
+ compare(mUri, accessory.getUri()) &&
+ compare(mSerial, accessory.getSerial()));
+ }
+ return false;
+ }
+
+ @Override
+ public int hashCode() {
+ return ((mManufacturer == null ? 0 : mManufacturer.hashCode()) ^
+ (mModel == null ? 0 : mModel.hashCode()) ^
+ (mDescription == null ? 0 : mDescription.hashCode()) ^
+ (mVersion == null ? 0 : mVersion.hashCode()) ^
+ (mUri == null ? 0 : mUri.hashCode()) ^
+ (mSerial == null ? 0 : mSerial.hashCode()));
+ }
+
+ @Override
+ public String toString() {
+ return "UsbAccessory[mManufacturer=" + mManufacturer +
+ ", mModel=" + mModel +
+ ", mDescription=" + mDescription +
+ ", mVersion=" + mVersion +
+ ", mUri=" + mUri +
+ ", mSerial=" + mSerial + "]";
+ }
+
+ public static final Parcelable.Creator<UsbAccessory> CREATOR =
+ new Parcelable.Creator<UsbAccessory>() {
+ public UsbAccessory createFromParcel(Parcel in) {
+ String manufacturer = in.readString();
+ String model = in.readString();
+ String description = in.readString();
+ String version = in.readString();
+ String uri = in.readString();
+ String serial = in.readString();
+ return new UsbAccessory(manufacturer, model, description, version, uri, serial);
+ }
+
+ public UsbAccessory[] newArray(int size) {
+ return new UsbAccessory[size];
+ }
+ };
+
+ public int describeContents() {
+ return 0;
+ }
+
+ public void writeToParcel(Parcel parcel, int flags) {
+ parcel.writeString(mManufacturer);
+ parcel.writeString(mModel);
+ parcel.writeString(mDescription);
+ parcel.writeString(mVersion);
+ parcel.writeString(mUri);
+ parcel.writeString(mSerial);
+ }
+}
diff --git a/core/java/android/hardware/usb/UsbManager.java b/core/java/android/hardware/usb/UsbManager.java
new file mode 100644
index 0000000..ea820f9
--- /dev/null
+++ b/core/java/android/hardware/usb/UsbManager.java
@@ -0,0 +1,295 @@
+/*
+ * Copyright (C) 2010 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.hardware.usb;
+
+import android.app.PendingIntent;
+import android.content.Context;
+import android.os.Bundle;
+import android.os.ParcelFileDescriptor;
+import android.os.RemoteException;
+import android.util.Log;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.HashMap;
+
+/**
+ * This class allows you to access the state of USB.
+ *
+ * <p>You can obtain an instance of this class by calling
+ * {@link android.content.Context#getSystemService(java.lang.String) Context.getSystemService()}.
+ *
+ * {@samplecode
+ * UsbManager manager = (UsbManager) getSystemService(Context.USB_SERVICE);
+ * }
+ * @hide
+ */
+public class UsbManager {
+ private static final String TAG = "UsbManager";
+
+ /**
+ * Broadcast Action: A sticky broadcast for USB state change events when in device mode.
+ *
+ * This is a sticky broadcast for clients that includes USB connected/disconnected state,
+ * <ul>
+ * <li> {@link #USB_CONNECTED} boolean indicating whether USB is connected or disconnected.
+ * <li> {@link #USB_CONFIGURATION} a Bundle containing name/value pairs where the name
+ * is the name of a USB function and the value is either {@link #USB_FUNCTION_ENABLED}
+ * or {@link #USB_FUNCTION_DISABLED}. The possible function names include
+ * {@link #USB_FUNCTION_MASS_STORAGE}, {@link #USB_FUNCTION_ADB}, {@link #USB_FUNCTION_RNDIS},
+ * {@link #USB_FUNCTION_MTP} and {@link #USB_FUNCTION_ACCESSORY}.
+ * </ul>
+ */
+ public static final String ACTION_USB_STATE =
+ "android.hardware.usb.action.USB_STATE";
+
+ /**
+ * Broadcast Action: A broadcast for USB accessory attached event.
+ *
+ * This intent is sent when a USB accessory is attached.
+ * <ul>
+ * <li> {@link #EXTRA_ACCESSORY} containing the {@link android.hardware.usb.UsbAccessory}
+ * for the attached accessory
+ * </ul>
+ */
+ public static final String ACTION_USB_ACCESSORY_ATTACHED =
+ "android.hardware.usb.action.USB_ACCESSORY_ATTACHED";
+
+ /**
+ * Broadcast Action: A broadcast for USB accessory detached event.
+ *
+ * This intent is sent when a USB accessory is detached.
+ * <ul>
+ * <li> {@link #EXTRA_ACCESSORY} containing the {@link UsbAccessory}
+ * for the attached accessory that was detached
+ * </ul>
+ */
+ public static final String ACTION_USB_ACCESSORY_DETACHED =
+ "android.hardware.usb.action.USB_ACCESSORY_DETACHED";
+
+ /**
+ * Boolean extra indicating whether USB is connected or disconnected.
+ * Used in extras for the {@link #ACTION_USB_STATE} broadcast.
+ */
+ public static final String USB_CONNECTED = "connected";
+
+ /**
+ * Integer extra containing currently set USB configuration.
+ * Used in extras for the {@link #ACTION_USB_STATE} broadcast.
+ */
+ public static final String USB_CONFIGURATION = "configuration";
+
+ /**
+ * Name of the USB mass storage USB function.
+ * Used in extras for the {@link #ACTION_USB_STATE} broadcast
+ */
+ public static final String USB_FUNCTION_MASS_STORAGE = "mass_storage";
+
+ /**
+ * Name of the adb USB function.
+ * Used in extras for the {@link #ACTION_USB_STATE} broadcast
+ */
+ public static final String USB_FUNCTION_ADB = "adb";
+
+ /**
+ * Name of the RNDIS ethernet USB function.
+ * Used in extras for the {@link #ACTION_USB_STATE} broadcast
+ */
+ public static final String USB_FUNCTION_RNDIS = "rndis";
+
+ /**
+ * Name of the MTP USB function.
+ * Used in extras for the {@link #ACTION_USB_STATE} broadcast
+ */
+ public static final String USB_FUNCTION_MTP = "mtp";
+
+ /**
+ * Name of the Accessory USB function.
+ * Used in extras for the {@link #ACTION_USB_STATE} broadcast
+ */
+ public static final String USB_FUNCTION_ACCESSORY = "accessory";
+
+ /**
+ * Value indicating that a USB function is enabled.
+ * Used in {@link #USB_CONFIGURATION} extras bundle for the
+ * {@link #ACTION_USB_STATE} broadcast
+ */
+ public static final String USB_FUNCTION_ENABLED = "enabled";
+
+ /**
+ * Value indicating that a USB function is disabled.
+ * Used in {@link #USB_CONFIGURATION} extras bundle for the
+ * {@link #ACTION_USB_STATE} broadcast
+ */
+ public static final String USB_FUNCTION_DISABLED = "disabled";
+
+ /**
+ * Name of extra for {@link #ACTION_USB_ACCESSORY_ATTACHED} and
+ * {@link #ACTION_USB_ACCESSORY_DETACHED} broadcasts
+ * containing the UsbAccessory object for the accessory.
+ */
+ public static final String EXTRA_ACCESSORY = "accessory";
+
+ /**
+ * Name of extra added to the {@link android.app.PendingIntent}
+ * passed into {@link #requestPermission(UsbDevice, PendingIntent)}
+ * or {@link #requestPermission(UsbAccessory, PendingIntent)}
+ * containing a boolean value indicating whether the user granted permission or not.
+ */
+ public static final String EXTRA_PERMISSION_GRANTED = "permission";
+
+ private final Context mContext;
+ private final IUsbManager mService;
+
+ /**
+ * {@hide}
+ */
+ public UsbManager(Context context, IUsbManager service) {
+ mContext = context;
+ mService = service;
+ }
+
+ /**
+ * Returns a list of currently attached USB accessories.
+ * (in the current implementation there can be at most one)
+ *
+ * @return list of USB accessories, or null if none are attached.
+ */
+ public UsbAccessory[] getAccessoryList() {
+ try {
+ UsbAccessory accessory = mService.getCurrentAccessory();
+ if (accessory == null) {
+ return null;
+ } else {
+ return new UsbAccessory[] { accessory };
+ }
+ } catch (RemoteException e) {
+ Log.e(TAG, "RemoteException in getAccessoryList", e);
+ return null;
+ }
+ }
+
+ /**
+ * Opens a file descriptor for reading and writing data to the USB accessory.
+ *
+ * @param accessory the USB accessory to open
+ * @return file descriptor, or null if the accessor could not be opened.
+ */
+ public ParcelFileDescriptor openAccessory(UsbAccessory accessory) {
+ try {
+ return mService.openAccessory(accessory);
+ } catch (RemoteException e) {
+ Log.e(TAG, "RemoteException in openAccessory", e);
+ return null;
+ }
+ }
+
+ /**
+ * Returns true if the caller has permission to access the accessory.
+ * Permission might have been granted temporarily via
+ * {@link #requestPermission(UsbAccessory, PendingIntent)} or
+ * by the user choosing the caller as the default application for the accessory.
+ *
+ * @param accessory to check permissions for
+ * @return true if caller has permission
+ */
+ public boolean hasPermission(UsbAccessory accessory) {
+ try {
+ return mService.hasAccessoryPermission(accessory);
+ } catch (RemoteException e) {
+ Log.e(TAG, "RemoteException in hasPermission", e);
+ return false;
+ }
+ }
+
+ /**
+ * Requests temporary permission for the given package to access the accessory.
+ * This may result in a system dialog being displayed to the user
+ * if permission had not already been granted.
+ * Success or failure is returned via the {@link android.app.PendingIntent} pi.
+ * If successful, this grants the caller permission to access the accessory only
+ * until the device is disconnected.
+ *
+ * The following extras will be added to pi:
+ * <ul>
+ * <li> {@link #EXTRA_ACCESSORY} containing the accessory passed into this call
+ * <li> {@link #EXTRA_PERMISSION_GRANTED} containing boolean indicating whether
+ * permission was granted by the user
+ * </ul>
+ *
+ * @param accessory to request permissions for
+ * @param pi PendingIntent for returning result
+ */
+ public void requestPermission(UsbAccessory accessory, PendingIntent pi) {
+ try {
+ mService.requestAccessoryPermission(accessory, mContext.getPackageName(), pi);
+ } catch (RemoteException e) {
+ Log.e(TAG, "RemoteException in requestPermission", e);
+ }
+ }
+
+ private static File getFunctionEnableFile(String function) {
+ return new File("/sys/class/usb_composite/" + function + "/enable");
+ }
+
+ /**
+ * Returns true if the specified USB function is supported by the kernel.
+ * Note that a USB function maybe supported but disabled.
+ *
+ * @param function name of the USB function
+ * @return true if the USB function is supported.
+ */
+ public static boolean isFunctionSupported(String function) {
+ return getFunctionEnableFile(function).exists();
+ }
+
+ /**
+ * Returns true if the specified USB function is currently enabled.
+ *
+ * @param function name of the USB function
+ * @return true if the USB function is enabled.
+ */
+ public static boolean isFunctionEnabled(String function) {
+ try {
+ FileInputStream stream = new FileInputStream(getFunctionEnableFile(function));
+ boolean enabled = (stream.read() == '1');
+ stream.close();
+ return enabled;
+ } catch (IOException e) {
+ return false;
+ }
+ }
+
+ /**
+ * Enables or disables a USB function.
+ *
+ * @hide
+ */
+ public static boolean setFunctionEnabled(String function, boolean enable) {
+ try {
+ FileOutputStream stream = new FileOutputStream(getFunctionEnableFile(function));
+ stream.write(enable ? '1' : '0');
+ stream.close();
+ return true;
+ } catch (IOException e) {
+ return false;
+ }
+ }
+}
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index a43914a..494e922 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -222,9 +222,9 @@ public class ConnectivityManager
/** {@hide} */
public static final int TYPE_ETHERNET = 9;
/** {@hide} TODO: Need to adjust this for WiMAX. */
- public static final int MAX_RADIO_TYPE = TYPE_WIFI;
+ public static final int MAX_RADIO_TYPE = TYPE_ETHERNET;
/** {@hide} TODO: Need to adjust this for WiMAX. */
- public static final int MAX_NETWORK_TYPE = TYPE_MOBILE_HIPRI;
+ public static final int MAX_NETWORK_TYPE = TYPE_ETHERNET;
public static final int DEFAULT_NETWORK_PREFERENCE = TYPE_WIFI;
diff --git a/core/java/android/net/InterfaceConfiguration.java b/core/java/android/net/InterfaceConfiguration.java
index 915c5d7..dcea3af 100644
--- a/core/java/android/net/InterfaceConfiguration.java
+++ b/core/java/android/net/InterfaceConfiguration.java
@@ -51,6 +51,24 @@ public class InterfaceConfiguration implements Parcelable {
append(addr & 0xff);
}
+ /**
+ * This function determines if the interface is up and has a valid IP
+ * configuration (IP address has a non zero octet).
+ *
+ * Note: It is supposed to be quick and hence should not initiate
+ * any network activity
+ */
+ public boolean isActive() {
+ try {
+ if(interfaceFlags.contains("up")) {
+ if (ipAddr != 0) return true;
+ }
+ } catch (NullPointerException e) {
+ return false;
+ }
+ return false;
+ }
+
/** Implement the Parcelable interface {@hide} */
public int describeContents() {
return 0;
diff --git a/core/java/android/net/MobileDataStateTracker.java b/core/java/android/net/MobileDataStateTracker.java
index 32c2d64..04b0f12 100644
--- a/core/java/android/net/MobileDataStateTracker.java
+++ b/core/java/android/net/MobileDataStateTracker.java
@@ -247,6 +247,9 @@ public class MobileDataStateTracker extends NetworkStateTracker {
Log.d(TAG, "CONNECTED event did not supply interface name.");
}
mDefaultGatewayAddr = intent.getIntExtra(Phone.DATA_GATEWAY_KEY, 0);
+ if (mDefaultGatewayAddr == 0) {
+ Log.d(TAG, "CONNECTED event did not supply a default gateway.");
+ }
setDetailedState(DetailedState.CONNECTED, reason, apnName);
break;
}
@@ -385,6 +388,7 @@ public class MobileDataStateTracker extends NetworkStateTracker {
intent.putExtra(Phone.DATA_APN_KEY, mApnName);
intent.putExtra(Phone.DATA_IFACE_NAME_KEY, mInterfaceName);
intent.putExtra(Phone.NETWORK_UNAVAILABLE_KEY, false);
+ intent.putExtra(Phone.DATA_GATEWAY_KEY, mDefaultGatewayAddr);
if (mStateReceiver != null) mStateReceiver.onReceive(mContext, intent);
break;
case Phone.APN_REQUEST_STARTED:
diff --git a/core/java/android/net/NetworkStateTracker.java b/core/java/android/net/NetworkStateTracker.java
index 9140dc9..233ad21 100644
--- a/core/java/android/net/NetworkStateTracker.java
+++ b/core/java/android/net/NetworkStateTracker.java
@@ -172,6 +172,7 @@ public abstract class NetworkStateTracker extends Handler {
if (inetAddress == null) {
if (DBG) Log.d(TAG, " Unable to add default route. mDefaultGatewayAddr Error");
} else {
+ NetworkUtils.addHostRoute(mInterfaceName, inetAddress, null);
if (!NetworkUtils.addDefaultRoute(mInterfaceName, inetAddress) && DBG) {
Log.d(TAG, " Unable to add default route.");
}
@@ -423,4 +424,7 @@ public abstract class NetworkStateTracker extends Handler {
public void interpretScanResultsAvailable() {
}
+ public String getInterfaceName() {
+ return mInterfaceName;
+ }
}
diff --git a/core/java/android/net/NetworkUtils.java b/core/java/android/net/NetworkUtils.java
index 5d4b099..8bdfdf9 100644
--- a/core/java/android/net/NetworkUtils.java
+++ b/core/java/android/net/NetworkUtils.java
@@ -209,4 +209,16 @@ public class NetworkUtils {
}
return result;
}
+
+ /**
+ * Start the DHCP renew service for wimax,
+ * This call blocks until it obtains a result (either success
+ * or failure) from the daemon.
+ * @param interfaceName the name of the interface to configure
+ * @param ipInfo if the request succeeds, this object is filled in with
+ * the IP address information.
+ * @return {@code true} for success, {@code false} for failure
+ * {@hide}
+ */
+ public native static boolean runDhcpRenew(String interfaceName, DhcpInfo ipInfo);
}
diff --git a/core/java/android/net/wimax/WimaxManagerConstants.java b/core/java/android/net/wimax/WimaxManagerConstants.java
new file mode 100644
index 0000000..5ec4e96
--- /dev/null
+++ b/core/java/android/net/wimax/WimaxManagerConstants.java
@@ -0,0 +1,103 @@
+package android.net.wimax;
+
+/**
+ * {@hide}
+ */
+public class WimaxManagerConstants
+{
+
+ /**
+ * Used by android.net.wimax.WimaxManager for handling management of
+ * Wimax access.
+ */
+ public static final String WIMAX_SERVICE = "WiMax";
+
+ /**
+ * Broadcast intent action indicating that Wimax has been enabled, disabled,
+ * enabling, disabling, or unknown. One extra provides this state as an int.
+ * Another extra provides the previous state, if available.
+ */
+ public static final String WIMAX_ENABLED_STATUS_CHANGED =
+ "android.net.wimax.WIMAX_STATUS_CHANGED";
+
+ /**
+ * The lookup key for an int that indicates whether Wimax is enabled,
+ * disabled, enabling, disabling, or unknown.
+ */
+ public static final String EXTRA_WIMAX_STATUS = "wimax_status";
+
+ /**
+ * Broadcast intent action indicating that Wimax state has been changed
+ * state could be scanning, connecting, connected, disconnecting, disconnected
+ * initializing, initialized, unknown and ready. One extra provides this state as an int.
+ * Another extra provides the previous state, if available.
+ */
+ public static final String WIMAX_STATE_CHANGED_ACTION =
+ "android.net.wimax.WIMAX_STATE_CHANGE";
+
+ /**
+ * Broadcast intent action indicating that Wimax signal level has been changed.
+ * Level varies from 0 to 3.
+ */
+ public static final String SIGNAL_LEVEL_CHANGED_ACTION =
+ "android.net.wimax.SIGNAL_LEVEL_CHANGED";
+
+ /**
+ * The lookup key for an int that indicates whether Wimax state is
+ * scanning, connecting, connected, disconnecting, disconnected
+ * initializing, initialized, unknown and ready.
+ */
+ public static final String EXTRA_WIMAX_STATE = "WimaxState";
+
+ /**
+ * The lookup key for an int that indicates whether state of Wimax
+ * is idle.
+ */
+ public static final String EXTRA_WIMAX_STATE_DETAIL = "WimaxStateDetail";
+
+ /**
+ * The lookup key for an int that indicates Wimax signal level.
+ */
+ public static final String EXTRA_NEW_SIGNAL_LEVEL = "newSignalLevel";
+
+ /**
+ * Indicatates Wimax is disabled.
+ */
+ public static final int WIMAX_STATUS_DISABLED = 1;
+
+ /**
+ * Indicatates Wimax is enabled.
+ */
+ public static final int WIMAX_STATUS_ENABLED = 3;
+
+ /**
+ * Indicatates Wimax status is known.
+ */
+ public static final int WIMAX_STATUS_UNKNOWN = 4;
+
+ /**
+ * Indicatates Wimax is in idle state.
+ */
+ public static final int WIMAX_IDLE = 6;
+
+ /**
+ * Indicatates Wimax is being deregistered.
+ */
+ public static final int WIMAX_DEREGISTRATION = 8;
+
+ /**
+ * Indicatates wimax state is unknown.
+ */
+ public static final int WIMAX_STATE_UNKNOWN = 0;
+
+ /**
+ * Indicatates wimax state is connected.
+ */
+ public static final int WIMAX_STATE_CONNECTED = 7;
+
+ /**
+ * Indicatates wimax state is disconnected.
+ */
+ public static final int WIMAX_STATE_DISCONNECTED = 9;
+
+}
diff --git a/core/java/android/nfc/INfcSecureElement.aidl b/core/java/android/nfc/ApduList.aidl
index aa98dd2..f6236b2 100755..100644
--- a/core/java/android/nfc/INfcSecureElement.aidl
+++ b/core/java/android/nfc/ApduList.aidl
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010 The Android Open Source Project
+ * Copyright (C) 2011 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.
@@ -16,13 +16,4 @@
package android.nfc;
-/**
- * {@hide}
- */
-interface INfcSecureElement {
- int openSecureElementConnection();
- int closeSecureElementConnection(int nativeHandle);
- byte[] exchangeAPDU(int nativeHandle, in byte[] data);
- int[] getSecureElementTechList(int nativeHandle);
- byte[] getSecureElementUid(int nativeHandle);
-} \ No newline at end of file
+parcelable ApduList; \ No newline at end of file
diff --git a/core/java/android/nfc/ApduList.java b/core/java/android/nfc/ApduList.java
new file mode 100644
index 0000000..85b0547
--- /dev/null
+++ b/core/java/android/nfc/ApduList.java
@@ -0,0 +1,68 @@
+package android.nfc;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @hide
+ */
+public class ApduList implements Parcelable {
+
+ private ArrayList<byte[]> commands = new ArrayList<byte[]>();
+
+ public ApduList() {
+ }
+
+ public void add(byte[] command) {
+ commands.add(command);
+ }
+
+ public List<byte[]> get() {
+ return commands;
+ }
+
+ public static final Parcelable.Creator<ApduList> CREATOR =
+ new Parcelable.Creator<ApduList>() {
+ @Override
+ public ApduList createFromParcel(Parcel in) {
+ return new ApduList(in);
+ }
+
+ @Override
+ public ApduList[] newArray(int size) {
+ return new ApduList[size];
+ }
+ };
+
+ private ApduList(Parcel in) {
+ int count = in.readInt();
+
+ for (int i = 0 ; i < count ; i++) {
+
+ int length = in.readInt();
+ byte[] cmd = new byte[length];
+ in.readByteArray(cmd);
+ commands.add(cmd);
+ }
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeInt(commands.size());
+
+ for (byte[] cmd : commands) {
+ dest.writeInt(cmd.length);
+ dest.writeByteArray(cmd);
+ }
+ }
+}
+
+
diff --git a/core/java/android/nfc/INfcAdapter.aidl b/core/java/android/nfc/INfcAdapter.aidl
index d439a48..870127c 100644
--- a/core/java/android/nfc/INfcAdapter.aidl
+++ b/core/java/android/nfc/INfcAdapter.aidl
@@ -28,7 +28,7 @@ import android.nfc.ILlcpConnectionlessSocket;
import android.nfc.INfcTag;
import android.nfc.IP2pTarget;
import android.nfc.IP2pInitiator;
-import android.nfc.INfcSecureElement;
+import android.nfc.INfcAdapterExtras;
/**
* @hide
@@ -41,13 +41,12 @@ interface INfcAdapter
INfcTag getNfcTagInterface();
IP2pTarget getP2pTargetInterface();
IP2pInitiator getP2pInitiatorInterface();
- INfcSecureElement getNfcSecureElementInterface();
+ INfcAdapterExtras getNfcAdapterExtrasInterface();
// NfcAdapter-class related methods
boolean isEnabled();
NdefMessage localGet();
void localSet(in NdefMessage message);
- void openTagConnection(in Tag tag);
void enableForegroundDispatch(in ComponentName activity, in PendingIntent intent,
in IntentFilter[] filters, in TechListParcel techLists);
void disableForegroundDispatch(in ComponentName activity);
@@ -59,12 +58,8 @@ interface INfcAdapter
int createLlcpConnectionlessSocket(int sap);
int createLlcpServiceSocket(int sap, String sn, int miu, int rw, int linearBufferLength);
int createLlcpSocket(int sap, int miu, int rw, int linearBufferLength);
- int deselectSecureElement();
boolean disable();
boolean enable();
String getProperties(String param);
- int[] getSecureElementList();
- int getSelectedSecureElement();
- int selectSecureElement(int seId);
int setProperties(String param, String value);
-} \ No newline at end of file
+}
diff --git a/core/java/android/nfc/INfcAdapterExtras.aidl b/core/java/android/nfc/INfcAdapterExtras.aidl
new file mode 100755
index 0000000..8677a50
--- /dev/null
+++ b/core/java/android/nfc/INfcAdapterExtras.aidl
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2011 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.nfc;
+
+import android.nfc.ApduList;
+import android.os.Bundle;
+
+
+/**
+ * {@hide}
+ */
+interface INfcAdapterExtras {
+ Bundle open(IBinder b);
+ Bundle close();
+ Bundle transceive(in byte[] data_in);
+ int getCardEmulationRoute();
+ void setCardEmulationRoute(int route);
+ void registerTearDownApdus(String packageName, in ApduList apdu);
+ void unregisterTearDownApdus(String packageName);
+}
diff --git a/core/java/android/nfc/NfcAdapter.java b/core/java/android/nfc/NfcAdapter.java
index 622bcdb..4689804 100644
--- a/core/java/android/nfc/NfcAdapter.java
+++ b/core/java/android/nfc/NfcAdapter.java
@@ -157,31 +157,6 @@ public final class NfcAdapter {
public static final String EXTRA_ID = "android.nfc.extra.ID";
/**
- * Broadcast Action: a transaction with a secure element has been detected.
- * <p>
- * Always contains the extra field
- * {@link android.nfc.NfcAdapter#EXTRA_AID}
- * @hide
- */
- @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
- public static final String ACTION_TRANSACTION_DETECTED =
- "android.nfc.action.TRANSACTION_DETECTED";
-
- /**
- * Broadcast Action: an RF field ON has been detected.
- * @hide
- */
- public static final String ACTION_RF_FIELD_ON_DETECTED =
- "android.nfc.action.RF_FIELD_ON_DETECTED";
-
- /**
- * Broadcast Action: an RF Field OFF has been detected.
- * @hide
- */
- public static final String ACTION_RF_FIELD_OFF_DETECTED =
- "android.nfc.action.RF_FIELD_OFF_DETECTED";
-
- /**
* Broadcast Action: an adapter's state changed between enabled and disabled.
*
* The new value is stored in the extra EXTRA_NEW_BOOLEAN_STATE and just contains
@@ -201,15 +176,6 @@ public final class NfcAdapter {
public static final String EXTRA_NEW_BOOLEAN_STATE = "android.nfc.isEnabled";
/**
- * Mandatory byte array extra field in
- * {@link android.nfc.NfcAdapter#ACTION_TRANSACTION_DETECTED}.
- * <p>
- * Contains the AID of the applet involved in the transaction.
- * @hide
- */
- public static final String EXTRA_AID = "android.nfc.extra.AID";
-
- /**
* LLCP link status: The LLCP link is activated.
* @hide
*/
@@ -691,14 +657,13 @@ public final class NfcAdapter {
}
/**
- * Create an Nfc Secure Element Connection
* @hide
*/
- public NfcSecureElement createNfcSecureElementConnection() {
+ public INfcAdapterExtras getNfcAdapterExtrasInterface() {
try {
- return new NfcSecureElement(sService.getNfcSecureElementInterface());
+ return sService.getNfcAdapterExtrasInterface();
} catch (RemoteException e) {
- Log.e(TAG, "createNfcSecureElementConnection failed", e);
+ attemptDeadServiceRecovery(e);
return null;
}
}
diff --git a/core/java/android/nfc/NfcSecureElement.java b/core/java/android/nfc/NfcSecureElement.java
deleted file mode 100755
index 3b5f39e..0000000
--- a/core/java/android/nfc/NfcSecureElement.java
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * Copyright (C) 2010 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.nfc;
-
-import android.nfc.tech.TagTechnology;
-import android.os.RemoteException;
-import android.util.Log;
-
-import java.io.IOException;
-
-//import android.util.Log;
-
-/**
- * This class provides the primary API for managing all aspects Secure Element.
- * Get an instance of this class by calling
- * Context.getSystemService(Context.NFC_SERVICE).
- * @hide
- */
-public final class NfcSecureElement {
-
- private static final String TAG = "NfcSecureElement";
-
- private INfcSecureElement mService;
-
-
- /**
- * @hide
- */
- public NfcSecureElement(INfcSecureElement mSecureElementService) {
- mService = mSecureElementService;
- }
-
- public int openSecureElementConnection(String seType) throws IOException {
- if (seType.equals("SmartMX")) {
- try {
- int handle = mService.openSecureElementConnection();
- // Handle potential errors
- if (handle != 0) {
- return handle;
- } else {
- throw new IOException("SmartMX connection not allowed");
- }
- } catch (RemoteException e) {
- Log.e(TAG, "RemoteException in openSecureElementConnection(): ", e);
- return 0;
- }
-
- } else if (seType.equals("UICC")) {
- return 0;
- } else {
- throw new IOException("Wrong Secure Element type");
- }
- }
-
-
- public byte [] exchangeAPDU(int handle,byte [] data) throws IOException {
-
-
- // Perform exchange APDU
- try {
- byte[] response = mService.exchangeAPDU(handle, data);
- // Handle potential errors
- if (response == null) {
- throw new IOException("Exchange APDU failed");
- }
- return response;
- } catch (RemoteException e) {
- Log.e(TAG, "RemoteException in exchangeAPDU(): ", e);
- return null;
- }
- }
-
- public void closeSecureElementConnection(int handle) throws IOException {
-
- try {
- int status = mService.closeSecureElementConnection(handle);
- // Handle potential errors
- if (ErrorCodes.isError(status)) {
- throw new IOException("Error during the conection close");
- };
- } catch (RemoteException e) {
- Log.e(TAG, "RemoteException in closeSecureElement(): ", e);
- }
- }
-
-
- /**
- * Returns target type. constants.
- *
- * @return Secure Element technology type. The possible values are defined in
- * {@link TagTechnology}
- *
- */
- public int[] getSecureElementTechList(int handle) throws IOException {
- try {
- return mService.getSecureElementTechList(handle);
- } catch (RemoteException e) {
- Log.e(TAG, "RemoteException in getType(): ", e);
- return null;
- }
- }
-
- /**
- * Returns Secure Element UID.
- *
- * @return Secure Element UID.
- */
- public byte[] getSecureElementUid(int handle) throws IOException {
-
- byte[] uid = null;
- try {
- uid = mService.getSecureElementUid(handle);
- // Handle potential errors
- if (uid == null) {
- throw new IOException("Get Secure Element UID failed");
- }
- return uid;
- } catch (RemoteException e) {
- Log.e(TAG, "RemoteException in getType(): ", e);
- return null;
- }
- }
-
-}
diff --git a/core/java/android/nfc/tech/Ndef.java b/core/java/android/nfc/tech/Ndef.java
index 6727d6a..e4daa57 100644
--- a/core/java/android/nfc/tech/Ndef.java
+++ b/core/java/android/nfc/tech/Ndef.java
@@ -103,6 +103,8 @@ public final class Ndef extends BasicTagTechnology {
public static final int TYPE_4 = 4;
/** @hide */
public static final int TYPE_MIFARE_CLASSIC = 101;
+ /** @hide */
+ public static final int TYPE_ICODE_SLI = 102;
/** @hide */
public static final String UNKNOWN = "android.ndef.unknown";
@@ -117,6 +119,11 @@ public final class Ndef extends BasicTagTechnology {
public static final String NFC_FORUM_TYPE_4 = "org.nfcforum.ndef.type4";
/** NDEF on MIFARE Classic */
public static final String MIFARE_CLASSIC = "com.nxp.ndef.mifareclassic";
+ /**
+ * NDEF on iCODE SLI
+ * @hide
+ */
+ public static final String ICODE_SLI = "com.nxp.ndef.icodesli";
private final int mMaxNdefSize;
private final int mCardState;
@@ -200,6 +207,8 @@ public final class Ndef extends BasicTagTechnology {
return NFC_FORUM_TYPE_4;
case TYPE_MIFARE_CLASSIC:
return MIFARE_CLASSIC;
+ case TYPE_ICODE_SLI:
+ return ICODE_SLI;
default:
return UNKNOWN;
}
diff --git a/core/java/android/nfc/tech/package.html b/core/java/android/nfc/tech/package.html
new file mode 100644
index 0000000..a99828f
--- /dev/null
+++ b/core/java/android/nfc/tech/package.html
@@ -0,0 +1,13 @@
+<HTML>
+<BODY>
+<p>
+These classes provide access to a tag technology's features, which vary by the type
+of tag that is scanned. A scanned tag can support multiple technologies, and you can find
+out what they are by calling {@link android.nfc.Tag#getTechList getTechList()}.</p>
+
+<p>For more information on dealing with tag technologies and handling the ones that you care about, see
+<a href="{@docRoot}guide/topics/nfc/index.html#dispatch">The Tag Dispatch System</a>.
+The {@link android.nfc.tech.TagTechnology} interface provides an overview of the
+supported technologies.</p>
+</BODY>
+</HTML>
diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java
index e4485d1..4ff3572 100644
--- a/core/java/android/os/BatteryStats.java
+++ b/core/java/android/os/BatteryStats.java
@@ -132,6 +132,7 @@ public abstract class BatteryStats implements Parcelable {
private static final String NETWORK_DATA = "nt";
private static final String USER_ACTIVITY_DATA = "ua";
private static final String BATTERY_DATA = "bt";
+ private static final String BATTERY_DISCHARGE_DATA = "dc";
private static final String BATTERY_LEVEL_DATA = "lv";
private static final String WIFI_LOCK_DATA = "wfl";
private static final String MISC_DATA = "m";
@@ -801,6 +802,30 @@ public abstract class BatteryStats implements Parcelable {
public abstract int getHighDischargeAmountSinceCharge();
/**
+ * Get the amount the battery has discharged while the screen was on,
+ * since the last time power was unplugged.
+ */
+ public abstract int getDischargeAmountScreenOn();
+
+ /**
+ * Get the amount the battery has discharged while the screen was on,
+ * since the last time the device was charged.
+ */
+ public abstract int getDischargeAmountScreenOnSinceCharge();
+
+ /**
+ * Get the amount the battery has discharged while the screen was off,
+ * since the last time power was unplugged.
+ */
+ public abstract int getDischargeAmountScreenOff();
+
+ /**
+ * Get the amount the battery has discharged while the screen was off,
+ * since the last time the device was charged.
+ */
+ public abstract int getDischargeAmountScreenOffSinceCharge();
+
+ /**
* Returns the total, last, or current battery uptime in microseconds.
*
* @param curTime the elapsed realtime in microseconds.
@@ -1095,6 +1120,17 @@ public abstract class BatteryStats implements Parcelable {
getDischargeCurrentLevel());
}
+ if (which == STATS_SINCE_UNPLUGGED) {
+ dumpLine(pw, 0 /* uid */, category, BATTERY_DISCHARGE_DATA,
+ getDischargeStartLevel()-getDischargeCurrentLevel(),
+ getDischargeStartLevel()-getDischargeCurrentLevel(),
+ getDischargeAmountScreenOn(), getDischargeAmountScreenOff());
+ } else {
+ dumpLine(pw, 0 /* uid */, category, BATTERY_DISCHARGE_DATA,
+ getLowDischargeAmountSinceCharge(), getHighDischargeAmountSinceCharge(),
+ getDischargeAmountScreenOn(), getDischargeAmountScreenOff());
+ }
+
if (reqUid < 0) {
Map<String, ? extends BatteryStats.Timer> kernelWakelocks = getKernelWakelockStats();
if (kernelWakelocks.size() > 0) {
@@ -1451,6 +1487,10 @@ public abstract class BatteryStats implements Parcelable {
pw.print(prefix); pw.print(" Last discharge cycle end level: ");
pw.println(getDischargeCurrentLevel());
}
+ pw.print(prefix); pw.print(" Amount discharged while screen on: ");
+ pw.println(getDischargeAmountScreenOn());
+ pw.print(prefix); pw.print(" Amount discharged while screen off: ");
+ pw.println(getDischargeAmountScreenOff());
pw.println(" ");
} else {
pw.print(prefix); pw.println(" Device battery use since last full charge");
@@ -1458,6 +1498,10 @@ public abstract class BatteryStats implements Parcelable {
pw.println(getLowDischargeAmountSinceCharge());
pw.print(prefix); pw.print(" Amount discharged (upper bound): ");
pw.println(getHighDischargeAmountSinceCharge());
+ pw.print(prefix); pw.print(" Amount discharged while screen on: ");
+ pw.println(getDischargeAmountScreenOnSinceCharge());
+ pw.print(prefix); pw.print(" Amount discharged while screen off: ");
+ pw.println(getDischargeAmountScreenOffSinceCharge());
pw.println(" ");
}
@@ -1847,7 +1891,6 @@ public abstract class BatteryStats implements Parcelable {
final int NU = uidStats.size();
boolean didPid = false;
long nowRealtime = SystemClock.elapsedRealtime();
- StringBuilder sb = new StringBuilder(64);
for (int i=0; i<NU; i++) {
Uid uid = uidStats.valueAt(i);
SparseArray<? extends Uid.Pid> pids = uid.getPidStats();
diff --git a/core/java/android/os/Looper.java b/core/java/android/os/Looper.java
index d360140..2a66616 100644
--- a/core/java/android/os/Looper.java
+++ b/core/java/android/os/Looper.java
@@ -17,6 +17,7 @@
package android.os;
import android.util.Config;
+import android.util.Log;
import android.util.Printer;
/**
@@ -106,6 +107,12 @@ public class Looper {
public static final void loop() {
Looper me = myLooper();
MessageQueue queue = me.mQueue;
+
+ // Make sure the identity of this thread is that of the local process,
+ // and keep track of what that identity token actually is.
+ Binder.clearCallingIdentity();
+ final long ident = Binder.clearCallingIdentity();
+
while (true) {
Message msg = queue.next(); // might block
//if (!me.mRun) {
@@ -124,6 +131,18 @@ public class Looper {
if (me.mLogging!= null) me.mLogging.println(
"<<<<< Finished to " + msg.target + " "
+ msg.callback);
+
+ // Make sure that during the course of dispatching the
+ // identity of the thread wasn't corrupted.
+ final long newIdent = Binder.clearCallingIdentity();
+ if (ident != newIdent) {
+ Log.wtf("Looper", "Thread identity changed from 0x"
+ + Long.toHexString(ident) + " to 0x"
+ + Long.toHexString(newIdent) + " while dispatching to "
+ + msg.target.getClass().getName() + " "
+ + msg.callback + " what=" + msg.what);
+ }
+
msg.recycle();
}
}
diff --git a/core/java/android/os/Process.java b/core/java/android/os/Process.java
index a718fc6..e1fdfb6 100644
--- a/core/java/android/os/Process.java
+++ b/core/java/android/os/Process.java
@@ -89,7 +89,7 @@ public class Process {
* Defines the UID/GID for the NFC service process.
* @hide
*/
- public static final int NFC_UID = 1022;
+ public static final int NFC_UID = 1025;
/**
* Defines the start of a range of UIDs (and GIDs), going from this
diff --git a/core/java/android/os/RecoverySystem.java b/core/java/android/os/RecoverySystem.java
index 6d19f41..74b4fcb 100644
--- a/core/java/android/os/RecoverySystem.java
+++ b/core/java/android/os/RecoverySystem.java
@@ -16,6 +16,11 @@
package android.os;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.util.Log;
+
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileNotFoundException;
@@ -37,9 +42,6 @@ import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
-import android.content.Context;
-import android.util.Log;
-
import org.apache.harmony.security.asn1.BerInputStream;
import org.apache.harmony.security.pkcs7.ContentInfo;
import org.apache.harmony.security.pkcs7.SignedData;
@@ -336,8 +338,21 @@ public class RecoverySystem {
* @throws IOException if writing the recovery command file
* fails, or if the reboot itself fails.
*/
- public static void rebootWipeUserData(Context context)
- throws IOException {
+ public static void rebootWipeUserData(Context context) throws IOException {
+ final ConditionVariable condition = new ConditionVariable();
+
+ Intent intent = new Intent("android.intent.action.MASTER_CLEAR_NOTIFICATION");
+ context.sendOrderedBroadcast(intent, android.Manifest.permission.MASTER_CLEAR,
+ new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ condition.open();
+ }
+ }, null, 0, null, null);
+
+ // Block until the ordered broadcast has completed.
+ condition.block();
+
bootCommand(context, "--wipe_data");
}
diff --git a/core/java/android/pim/ICalendar.java b/core/java/android/pim/ICalendar.java
index cc0f45e..9c4eaf4 100644
--- a/core/java/android/pim/ICalendar.java
+++ b/core/java/android/pim/ICalendar.java
@@ -578,6 +578,23 @@ public class ICalendar {
+ text);
}
parameter.name = text.substring(startIndex + 1, equalIndex);
+ } else if (c == '"') {
+ if (parameter == null) {
+ throw new FormatException("Expected parameter before '\"' in " + text);
+ }
+ if (equalIndex == -1) {
+ throw new FormatException("Expected '=' within parameter in " + text);
+ }
+ if (state.index > equalIndex + 1) {
+ throw new FormatException("Parameter value cannot contain a '\"' in " + text);
+ }
+ final int endQuote = text.indexOf('"', state.index + 1);
+ if (endQuote < 0) {
+ throw new FormatException("Expected closing '\"' in " + text);
+ }
+ parameter.value = text.substring(state.index + 1, endQuote);
+ state.index = endQuote + 1;
+ return parameter;
}
++state.index;
}
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 2a13d520..38c5dc4 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -1101,6 +1101,12 @@ public final class Settings {
public static final String RADIO_CELL = "cell";
/**
+ * Constant for use in AIRPLANE_MODE_RADIOS to specify WiMAX radio.
+ * @hide
+ */
+ public static final String RADIO_WIMAX = "wimax";
+
+ /**
* A comma separated list of radios that need to be disabled when airplane mode
* is on. This overrides WIFI_ON and BLUETOOTH_ON, if Wi-Fi and bluetooth are
* included in the comma separated list.
@@ -2559,6 +2565,14 @@ public final class Settings {
"wifi_networks_available_repeat_delay";
/**
+ * Whether to nofity the user of WiMAX network.
+ * If WiMAX is connected or disconnected, we will put this notification up.
+ * @hide
+ */
+ public static final String WIMAX_NETWORKS_AVAILABLE_NOTIFICATION_ON =
+ "wimax_networks_available_notification_on";
+
+ /**
* The number of radio channels that are allowed in the local
* 802.11 regulatory domain.
* @hide
@@ -2695,6 +2709,12 @@ public final class Settings {
"wifi_mobile_data_transition_wakelock_timeout_ms";
/**
+ * Whether the Wimax should be on. Only the WiMAX service should touch this.
+ * @hide
+ */
+ public static final String WIMAX_ON = "wimax_on";
+
+ /**
* Whether background data usage is allowed by the user. See
* ConnectivityManager for more info.
*/
diff --git a/core/java/android/provider/Telephony.java b/core/java/android/provider/Telephony.java
index 1a35112..62f66b6 100755
--- a/core/java/android/provider/Telephony.java
+++ b/core/java/android/provider/Telephony.java
@@ -1723,6 +1723,21 @@ public final class Telephony {
public static final String TYPE = "type";
+ /**
+ * The protocol to be used to connect to this APN.
+ *
+ * One of the PDP_type values in TS 27.007 section 10.1.1.
+ * For example, "IP", "IPV6", "IPV4V6", or "PPP".
+ */
+ public static final String PROTOCOL = "protocol";
+
+ /**
+ * The protocol to be used to connect to this APN when roaming.
+ *
+ * The syntax is the same as protocol.
+ */
+ public static final String ROAMING_PROTOCOL = "roaming_protocol";
+
public static final String CURRENT = "current";
}
diff --git a/core/java/android/speech/RecognitionService.java b/core/java/android/speech/RecognitionService.java
index 75a5ed5..32b2d8f 100644
--- a/core/java/android/speech/RecognitionService.java
+++ b/core/java/android/speech/RecognitionService.java
@@ -68,6 +68,8 @@ public abstract class RecognitionService extends Service {
private static final int MSG_CANCEL = 3;
+ private static final int MSG_RESET = 4;
+
private final Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
@@ -81,6 +83,10 @@ public abstract class RecognitionService extends Service {
break;
case MSG_CANCEL:
dispatchCancel((IRecognitionListener) msg.obj);
+ break;
+ case MSG_RESET:
+ dispatchClearCallback();
+ break;
}
}
};
@@ -128,6 +134,10 @@ public abstract class RecognitionService extends Service {
}
}
+ private void dispatchClearCallback() {
+ mCurrentCallback = null;
+ }
+
private class StartListeningArgs {
public final Intent mIntent;
@@ -241,7 +251,7 @@ public abstract class RecognitionService extends Service {
* @param error code is defined in {@link SpeechRecognizer}
*/
public void error(int error) throws RemoteException {
- mCurrentCallback = null;
+ Message.obtain(mHandler, MSG_RESET).sendToTarget();
mListener.onError(error);
}
@@ -278,7 +288,7 @@ public abstract class RecognitionService extends Service {
* {@link SpeechRecognizer#RESULTS_RECOGNITION} as a parameter
*/
public void results(Bundle results) throws RemoteException {
- mCurrentCallback = null;
+ Message.obtain(mHandler, MSG_RESET).sendToTarget();
mListener.onResults(results);
}
diff --git a/core/java/android/text/Layout.java b/core/java/android/text/Layout.java
index 4e197cd..b62aa40 100755
--- a/core/java/android/text/Layout.java
+++ b/core/java/android/text/Layout.java
@@ -1154,7 +1154,7 @@ public abstract class Layout {
if (h2 < 0.5f)
h2 = 0.5f;
- if (h1 == h2) {
+ if (Float.compare(h1, h2) == 0) {
dest.moveTo(h1, top);
dest.lineTo(h1, bottom);
} else {
diff --git a/core/java/android/text/TextUtils.java b/core/java/android/text/TextUtils.java
index 8675d05..0d7aa02 100644
--- a/core/java/android/text/TextUtils.java
+++ b/core/java/android/text/TextUtils.java
@@ -627,10 +627,16 @@ public class TextUtils {
public CharSequence createFromParcel(Parcel p) {
int kind = p.readInt();
- if (kind == 1)
- return p.readString();
+ String string = p.readString();
+ if (string == null) {
+ return null;
+ }
+
+ if (kind == 1) {
+ return string;
+ }
- SpannableString sp = new SpannableString(p.readString());
+ SpannableString sp = new SpannableString(string);
while (true) {
kind = p.readInt();
diff --git a/core/java/android/text/method/MultiTapKeyListener.java b/core/java/android/text/method/MultiTapKeyListener.java
index 6d94788..2a739fa 100644
--- a/core/java/android/text/method/MultiTapKeyListener.java
+++ b/core/java/android/text/method/MultiTapKeyListener.java
@@ -116,7 +116,7 @@ public class MultiTapKeyListener extends BaseKeyListener
content.replace(selStart, selEnd,
String.valueOf(current).toUpperCase());
removeTimeouts(content);
- Timeout t = new Timeout(content);
+ new Timeout(content); // for its side effects
return true;
}
@@ -124,7 +124,7 @@ public class MultiTapKeyListener extends BaseKeyListener
content.replace(selStart, selEnd,
String.valueOf(current).toLowerCase());
removeTimeouts(content);
- Timeout t = new Timeout(content);
+ new Timeout(content); // for its side effects
return true;
}
@@ -140,7 +140,7 @@ public class MultiTapKeyListener extends BaseKeyListener
content.replace(selStart, selEnd, val, ix, ix + 1);
removeTimeouts(content);
- Timeout t = new Timeout(content);
+ new Timeout(content); // for its side effects
return true;
}
@@ -206,7 +206,7 @@ public class MultiTapKeyListener extends BaseKeyListener
}
removeTimeouts(content);
- Timeout t = new Timeout(content);
+ new Timeout(content); // for its side effects
// Set up the callback so we can remove the timeout if the
// cursor moves.
diff --git a/core/java/android/text/style/DrawableMarginSpan.java b/core/java/android/text/style/DrawableMarginSpan.java
index 3c471a5..c2564d5 100644
--- a/core/java/android/text/style/DrawableMarginSpan.java
+++ b/core/java/android/text/style/DrawableMarginSpan.java
@@ -50,9 +50,6 @@ implements LeadingMarginSpan, LineHeightSpan
int dw = mDrawable.getIntrinsicWidth();
int dh = mDrawable.getIntrinsicHeight();
- if (dir < 0)
- x -= dw;
-
// XXX What to do about Paint?
mDrawable.setBounds(ix, itop, ix+dw, itop+dh);
mDrawable.draw(c);
diff --git a/core/java/android/util/SparseArray.java b/core/java/android/util/SparseArray.java
index 1c8b330..4c13460 100644
--- a/core/java/android/util/SparseArray.java
+++ b/core/java/android/util/SparseArray.java
@@ -90,6 +90,17 @@ public class SparseArray<E> {
delete(key);
}
+ /**
+ * Removes the mapping at the specified index.
+ * @hide
+ */
+ public void removeAt(int index) {
+ if (mValues[index] != DELETED) {
+ mValues[index] = DELETED;
+ mGarbage = true;
+ }
+ }
+
private void gc() {
// Log.e("SparseArray", "gc start with " + mSize);
diff --git a/core/java/android/view/GestureDetector.java b/core/java/android/view/GestureDetector.java
index c1e1049..79b3d42 100644..100755
--- a/core/java/android/view/GestureDetector.java
+++ b/core/java/android/view/GestureDetector.java
@@ -193,10 +193,8 @@ public class GestureDetector {
}
}
- // TODO: ViewConfiguration
- private int mBiggerTouchSlopSquare = 20 * 20;
-
private int mTouchSlopSquare;
+ private int mLargeTouchSlopSquare;
private int mDoubleTapSlopSquare;
private int mMinimumFlingVelocity;
private int mMaximumFlingVelocity;
@@ -384,10 +382,11 @@ public class GestureDetector {
mIgnoreMultitouch = ignoreMultitouch;
// Fallback to support pre-donuts releases
- int touchSlop, doubleTapSlop;
+ int touchSlop, largeTouchSlop, doubleTapSlop;
if (context == null) {
//noinspection deprecation
touchSlop = ViewConfiguration.getTouchSlop();
+ largeTouchSlop = touchSlop + 2;
doubleTapSlop = ViewConfiguration.getDoubleTapSlop();
//noinspection deprecation
mMinimumFlingVelocity = ViewConfiguration.getMinimumFlingVelocity();
@@ -395,11 +394,13 @@ public class GestureDetector {
} else {
final ViewConfiguration configuration = ViewConfiguration.get(context);
touchSlop = configuration.getScaledTouchSlop();
+ largeTouchSlop = configuration.getScaledLargeTouchSlop();
doubleTapSlop = configuration.getScaledDoubleTapSlop();
mMinimumFlingVelocity = configuration.getScaledMinimumFlingVelocity();
mMaximumFlingVelocity = configuration.getScaledMaximumFlingVelocity();
}
mTouchSlopSquare = touchSlop * touchSlop;
+ mLargeTouchSlopSquare = largeTouchSlop * largeTouchSlop;
mDoubleTapSlopSquare = doubleTapSlop * doubleTapSlop;
}
@@ -534,7 +535,7 @@ public class GestureDetector {
mHandler.removeMessages(SHOW_PRESS);
mHandler.removeMessages(LONG_PRESS);
}
- if (distance > mBiggerTouchSlopSquare) {
+ if (distance > mLargeTouchSlopSquare) {
mAlwaysInBiggerTapRegion = false;
}
} else if ((Math.abs(scrollX) >= 1) || (Math.abs(scrollY) >= 1)) {
diff --git a/core/java/android/view/ViewConfiguration.java b/core/java/android/view/ViewConfiguration.java
index 924c9d4..5397449 100644..100755
--- a/core/java/android/view/ViewConfiguration.java
+++ b/core/java/android/view/ViewConfiguration.java
@@ -102,6 +102,12 @@ public class ViewConfiguration {
private static final int TOUCH_SLOP = 16;
/**
+ * Distance a touch can wander before we think the user is the first touch
+ * in a sequence of double tap
+ */
+ private static final int LARGE_TOUCH_SLOP = 18;
+
+ /**
* Distance a touch can wander before we think the user is attempting a paged scroll
* (in dips)
*/
@@ -156,6 +162,7 @@ public class ViewConfiguration {
private final int mMaximumFlingVelocity;
private final int mScrollbarSize;
private final int mTouchSlop;
+ private final int mLargeTouchSlop;
private final int mPagingTouchSlop;
private final int mDoubleTapSlop;
private final int mWindowTouchSlop;
@@ -177,6 +184,7 @@ public class ViewConfiguration {
mMaximumFlingVelocity = MAXIMUM_FLING_VELOCITY;
mScrollbarSize = SCROLL_BAR_SIZE;
mTouchSlop = TOUCH_SLOP;
+ mLargeTouchSlop = LARGE_TOUCH_SLOP;
mPagingTouchSlop = PAGING_TOUCH_SLOP;
mDoubleTapSlop = DOUBLE_TAP_SLOP;
mWindowTouchSlop = WINDOW_TOUCH_SLOP;
@@ -206,6 +214,7 @@ public class ViewConfiguration {
mMaximumFlingVelocity = (int) (density * MAXIMUM_FLING_VELOCITY + 0.5f);
mScrollbarSize = (int) (density * SCROLL_BAR_SIZE + 0.5f);
mTouchSlop = (int) (density * TOUCH_SLOP + 0.5f);
+ mLargeTouchSlop = (int) (density * LARGE_TOUCH_SLOP + 0.5f);
mPagingTouchSlop = (int) (density * PAGING_TOUCH_SLOP + 0.5f);
mDoubleTapSlop = (int) (density * DOUBLE_TAP_SLOP + 0.5f);
mWindowTouchSlop = (int) (density * WINDOW_TOUCH_SLOP + 0.5f);
@@ -367,6 +376,14 @@ public class ViewConfiguration {
}
/**
+ * @return Distance a touch can wander before we think the user is the first touch
+ * in a sequence of double tap
+ */
+ public int getScaledLargeTouchSlop() {
+ return mLargeTouchSlop;
+ }
+
+ /**
* @return Distance a touch can wander before we think the user is scrolling a full page
* in dips
*/
diff --git a/core/java/android/view/ViewRoot.java b/core/java/android/view/ViewRoot.java
index ccaef40..afec1c3 100644
--- a/core/java/android/view/ViewRoot.java
+++ b/core/java/android/view/ViewRoot.java
@@ -176,6 +176,7 @@ public final class ViewRoot extends Handler implements ViewParent,
private final Surface mSurface = new Surface();
boolean mAdded;
+ private boolean mAttached;
boolean mAddedTouchMode;
/*package*/ int mAddNesting;
@@ -762,7 +763,10 @@ public final class ViewRoot extends Handler implements ViewParent,
attachInfo.mKeepScreenOn = false;
viewVisibilityChanged = false;
mLastConfiguration.setTo(host.getResources().getConfiguration());
- host.dispatchAttachedToWindow(attachInfo, 0);
+ if (!mAttached) {
+ host.dispatchAttachedToWindow(attachInfo, 0);
+ mAttached = true;
+ }
//Log.i(TAG, "Screen on initialized: " + attachInfo.mKeepScreenOn);
} else {
@@ -1743,8 +1747,9 @@ public final class ViewRoot extends Handler implements ViewParent,
void dispatchDetachedFromWindow() {
if (Config.LOGV) Log.v(TAG, "Detaching in " + this + " of " + mSurface);
- if (mView != null) {
+ if (mView != null && mAttached) {
mView.dispatchDetachedFromWindow();
+ mAttached = false;
}
mView = null;
diff --git a/core/java/android/webkit/FrameLoader.java b/core/java/android/webkit/FrameLoader.java
index 021b53c..4bc12d4 100644
--- a/core/java/android/webkit/FrameLoader.java
+++ b/core/java/android/webkit/FrameLoader.java
@@ -186,7 +186,8 @@ class FrameLoader {
settings.getAllowFileAccess())).sendToTarget();
}
return true;
- } else if (URLUtil.isContentUrl(url)) {
+ } else if (settings.getAllowContentAccess() &&
+ URLUtil.isContentUrl(url)) {
// Send the raw url to the ContentLoader because it will do a
// permission check and the url has to match.
if (loadListener.isSynchronous()) {
diff --git a/core/java/android/webkit/WebSettings.java b/core/java/android/webkit/WebSettings.java
index 4d70e7c..89e25e8 100644
--- a/core/java/android/webkit/WebSettings.java
+++ b/core/java/android/webkit/WebSettings.java
@@ -206,6 +206,7 @@ public class WebSettings {
private boolean mSupportZoom = true;
private boolean mBuiltInZoomControls = false;
private boolean mAllowFileAccess = true;
+ private boolean mAllowContentAccess = true;
private boolean mLoadWithOverviewMode = false;
private boolean mUseWebViewBackgroundOverscrollBackground = true;
@@ -458,7 +459,9 @@ public class WebSettings {
/**
* Enable or disable file access within WebView. File access is enabled by
- * default.
+ * default. Note that this enables or disables file system access only.
+ * Assets and resources are still accessible using file:///android_asset and
+ * file:///android_res.
*/
public void setAllowFileAccess(boolean allow) {
mAllowFileAccess = allow;
@@ -472,6 +475,24 @@ public class WebSettings {
}
/**
+ * Enable or disable content url access within WebView. Content url access
+ * allows WebView to load content from a content provider installed in the
+ * system. The default is enabled.
+ * @hide
+ */
+ public void setAllowContentAccess(boolean allow) {
+ mAllowContentAccess = allow;
+ }
+
+ /**
+ * Returns true if this WebView supports content url access.
+ * @hide
+ */
+ public boolean getAllowContentAccess() {
+ return mAllowContentAccess;
+ }
+
+ /**
* Set whether the WebView loads a page with overview mode.
*/
public void setLoadWithOverviewMode(boolean overview) {
diff --git a/core/java/android/widget/DatePicker.java b/core/java/android/widget/DatePicker.java
index a371290..595b487 100644
--- a/core/java/android/widget/DatePicker.java
+++ b/core/java/android/widget/DatePicker.java
@@ -22,6 +22,7 @@ import android.content.res.TypedArray;
import android.os.Parcel;
import android.os.Parcelable;
import android.text.format.DateFormat;
+import android.text.format.DateUtils;
import android.util.AttributeSet;
import android.util.SparseArray;
import android.view.LayoutInflater;
@@ -33,6 +34,7 @@ import com.android.internal.R;
import java.text.DateFormatSymbols;
import java.text.SimpleDateFormat;
import java.util.Calendar;
+import java.util.Locale;
/**
* A view for selecting a month / year / day based on a calendar like layout.
@@ -47,7 +49,10 @@ public class DatePicker extends FrameLayout {
private static final int DEFAULT_START_YEAR = 1900;
private static final int DEFAULT_END_YEAR = 2100;
-
+
+ // This ignores Undecimber, but we only support real Gregorian calendars.
+ private static final int NUMBER_OF_MONTHS = 12;
+
/* UI Components */
private final NumberPicker mDayPicker;
private final NumberPicker mMonthPicker;
@@ -62,6 +67,10 @@ public class DatePicker extends FrameLayout {
private int mMonth;
private int mYear;
+ private Object mMonthUpdateLock = new Object();
+ private volatile Locale mMonthLocale;
+ private String[] mShortMonths;
+
/**
* The callback used to indicate the user changes the date.
*/
@@ -102,8 +111,7 @@ public class DatePicker extends FrameLayout {
});
mMonthPicker = (NumberPicker) findViewById(R.id.month);
mMonthPicker.setFormatter(NumberPicker.TWO_DIGIT_FORMATTER);
- DateFormatSymbols dfs = new DateFormatSymbols();
- String[] months = dfs.getShortMonths();
+ final String[] months = getShortMonths();
/*
* If the user is in a locale where the month names are numeric,
@@ -114,9 +122,9 @@ public class DatePicker extends FrameLayout {
for (int i = 0; i < months.length; i++) {
months[i] = String.valueOf(i + 1);
}
- mMonthPicker.setRange(1, 12);
+ mMonthPicker.setRange(1, NUMBER_OF_MONTHS);
} else {
- mMonthPicker.setRange(1, 12, months);
+ mMonthPicker.setRange(1, NUMBER_OF_MONTHS, months);
}
mMonthPicker.setSpeed(200);
@@ -246,11 +254,30 @@ public class DatePicker extends FrameLayout {
mMonth = monthOfYear;
mDay = dayOfMonth;
updateSpinners();
- reorderPickers(new DateFormatSymbols().getShortMonths());
+ reorderPickers(getShortMonths());
notifyDateChanged();
}
}
+ private String[] getShortMonths() {
+ final Locale currentLocale = Locale.getDefault();
+ if (currentLocale.equals(mMonthLocale) && mShortMonths != null) {
+ return mShortMonths;
+ } else {
+ synchronized (mMonthUpdateLock) {
+ if (!currentLocale.equals(mMonthLocale)) {
+ mShortMonths = new String[NUMBER_OF_MONTHS];
+ for (int i = 0; i < NUMBER_OF_MONTHS; i++) {
+ mShortMonths[i] = DateUtils.getMonthString(Calendar.JANUARY + i,
+ DateUtils.LENGTH_MEDIUM);
+ }
+ mMonthLocale = currentLocale;
+ }
+ }
+ return mShortMonths;
+ }
+ }
+
private static class SavedState extends BaseSavedState {
private final int mYear;
diff --git a/core/java/android/widget/PopupWindow.java b/core/java/android/widget/PopupWindow.java
index 76755de..66524ab 100644
--- a/core/java/android/widget/PopupWindow.java
+++ b/core/java/android/widget/PopupWindow.java
@@ -1421,6 +1421,10 @@ public class PopupWindow {
@Override
public boolean dispatchKeyEvent(KeyEvent event) {
if (event.getKeyCode() == KeyEvent.KEYCODE_BACK) {
+ if (getKeyDispatcherState() == null) {
+ return super.dispatchKeyEvent(event);
+ }
+
if (event.getAction() == KeyEvent.ACTION_DOWN
&& event.getRepeatCount() == 0) {
getKeyDispatcherState().startTracking(event, this);
diff --git a/core/java/android/widget/ScrollView.java b/core/java/android/widget/ScrollView.java
index de38d05..b1e1fbc 100644
--- a/core/java/android/widget/ScrollView.java
+++ b/core/java/android/widget/ScrollView.java
@@ -832,7 +832,7 @@ public class ScrollView extends FrameLayout {
int count = getChildCount();
if (count > 0) {
View view = getChildAt(count - 1);
- mTempRect.bottom = view.getBottom();
+ mTempRect.bottom = view.getBottom() + mPaddingBottom;
mTempRect.top = mTempRect.bottom - height;
}
}
@@ -912,9 +912,7 @@ public class ScrollView extends FrameLayout {
} else if (direction == View.FOCUS_DOWN) {
if (getChildCount() > 0) {
int daBottom = getChildAt(0).getBottom();
-
- int screenBottom = getScrollY() + getHeight();
-
+ int screenBottom = getScrollY() + getHeight() - mPaddingBottom;
if (daBottom - screenBottom < maxJump) {
scrollDelta = daBottom - screenBottom;
}
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 97b05af..68600cf 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -301,6 +301,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
// Set when this TextView gained focus with some text selected. Will start selection mode.
private boolean mCreatedWithASelection = false;
+ private boolean mNoContextMenuOnUp = false;
+
/*
* Kick-start the font cache for the zygote process (to pay the cost of
* initializing freetype for our default font only once).
@@ -6798,8 +6800,9 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
// Restore previous selection
Selection.setSelection((Spannable)mText, prevStart, prevEnd);
- // Tapping inside the selection displays the cut/copy/paste context menu
- showContextMenu();
+ // Tapping inside the selection displays the cut/copy/paste context menu, unless
+ // this is a double tap that should simply trigger text selection mode.
+ if (!mNoContextMenuOnUp) showContextMenu();
} else {
// Tapping outside stops selection mode, if any
stopTextSelectionMode();
@@ -6857,7 +6860,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
mScrolled = false;
}
- final boolean superResult = super.onTouchEvent(event);
+ boolean result = super.onTouchEvent(event);
/*
* Don't handle the release after a long press, because it will
@@ -6866,11 +6869,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
*/
if (mEatTouchRelease && action == MotionEvent.ACTION_UP) {
mEatTouchRelease = false;
- return superResult;
- }
-
- if ((mMovement != null || onCheckIsTextEditor()) && isEnabled() &&
- mText instanceof Spannable && mLayout != null) {
+ } else if ((mMovement != null || onCheckIsTextEditor()) && mText instanceof Spannable &&
+ mLayout != null) {
boolean handled = false;
// Save previous selection, in case this event is used to show the IME.
@@ -6911,12 +6911,14 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
}
}
- if (handled) {
- return true;
- }
+ if (handled) result = true;
+ }
+
+ if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) {
+ mNoContextMenuOnUp = false;
}
- return superResult;
+ return result;
}
private void prepareCursorControllers() {
@@ -8200,9 +8202,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
final int slopSquared = doubleTapSlop * doubleTapSlop;
if (distanceSquared < slopSquared) {
startTextSelectionMode();
- // Hacky: onTapUpEvent will open a context menu with cut/copy
- // Prevent this by hiding handles which will be revived instead.
- hide();
+ // prevents onTapUpEvent from opening a context menu with cut/copy
+ mNoContextMenuOnUp = true;
}
}
mPreviousTapPositionX = x;