Merge "Clarify some Binder docs regarding things that are thread-local."
diff --git a/api/current.xml b/api/current.xml
index d282e06..03d8a3a 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -205705,6 +205705,331 @@
</parameter>
</method>
</interface>
+<class name="OverScroller"
+ extends="java.lang.Object"
+ abstract="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<constructor name="OverScroller"
+ type="android.widget.OverScroller"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="context" type="android.content.Context">
+</parameter>
+</constructor>
+<constructor name="OverScroller"
+ type="android.widget.OverScroller"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="context" type="android.content.Context">
+</parameter>
+<parameter name="interpolator" type="android.view.animation.Interpolator">
+</parameter>
+</constructor>
+<constructor name="OverScroller"
+ type="android.widget.OverScroller"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="context" type="android.content.Context">
+</parameter>
+<parameter name="interpolator" type="android.view.animation.Interpolator">
+</parameter>
+<parameter name="bounceCoefficientX" type="float">
+</parameter>
+<parameter name="bounceCoefficientY" type="float">
+</parameter>
+</constructor>
+<method name="abortAnimation"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="computeScrollOffset"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="fling"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="startX" type="int">
+</parameter>
+<parameter name="startY" type="int">
+</parameter>
+<parameter name="velocityX" type="int">
+</parameter>
+<parameter name="velocityY" type="int">
+</parameter>
+<parameter name="minX" type="int">
+</parameter>
+<parameter name="maxX" type="int">
+</parameter>
+<parameter name="minY" type="int">
+</parameter>
+<parameter name="maxY" type="int">
+</parameter>
+</method>
+<method name="fling"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="startX" type="int">
+</parameter>
+<parameter name="startY" type="int">
+</parameter>
+<parameter name="velocityX" type="int">
+</parameter>
+<parameter name="velocityY" type="int">
+</parameter>
+<parameter name="minX" type="int">
+</parameter>
+<parameter name="maxX" type="int">
+</parameter>
+<parameter name="minY" type="int">
+</parameter>
+<parameter name="maxY" type="int">
+</parameter>
+<parameter name="overX" type="int">
+</parameter>
+<parameter name="overY" type="int">
+</parameter>
+</method>
+<method name="forceFinished"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="finished" type="boolean">
+</parameter>
+</method>
+<method name="getCurrX"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getCurrY"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getFinalX"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getFinalY"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getStartX"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getStartY"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="isFinished"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="isOverscrolled"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="notifyHorizontalEdgeReached"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="startX" type="int">
+</parameter>
+<parameter name="finalX" type="int">
+</parameter>
+<parameter name="overX" type="int">
+</parameter>
+</method>
+<method name="notifyVerticalEdgeReached"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="startY" type="int">
+</parameter>
+<parameter name="finalY" type="int">
+</parameter>
+<parameter name="overY" type="int">
+</parameter>
+</method>
+<method name="springback"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="startX" type="int">
+</parameter>
+<parameter name="startY" type="int">
+</parameter>
+<parameter name="minX" type="int">
+</parameter>
+<parameter name="maxX" type="int">
+</parameter>
+<parameter name="minY" type="int">
+</parameter>
+<parameter name="maxY" type="int">
+</parameter>
+</method>
+<method name="startScroll"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="startX" type="int">
+</parameter>
+<parameter name="startY" type="int">
+</parameter>
+<parameter name="dx" type="int">
+</parameter>
+<parameter name="dy" type="int">
+</parameter>
+</method>
+<method name="startScroll"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="startX" type="int">
+</parameter>
+<parameter name="startY" type="int">
+</parameter>
+<parameter name="dx" type="int">
+</parameter>
+<parameter name="dy" type="int">
+</parameter>
+<parameter name="duration" type="int">
+</parameter>
+</method>
+</class>
<class name="PopupWindow"
extends="java.lang.Object"
abstract="false"
diff --git a/core/java/android/accounts/AccountManager.java b/core/java/android/accounts/AccountManager.java
index 8356029..15c8856 100644
--- a/core/java/android/accounts/AccountManager.java
+++ b/core/java/android/accounts/AccountManager.java
@@ -227,11 +227,13 @@
* @hide for internal use only
*/
public static Bundle sanitizeResult(Bundle result) {
- if (result.containsKey(KEY_AUTHTOKEN)
- && !TextUtils.isEmpty(result.getString(KEY_AUTHTOKEN))) {
- final Bundle newResult = new Bundle(result);
- newResult.putString(KEY_AUTHTOKEN, "<omitted for logging purposes>");
- return newResult;
+ if (result != null) {
+ if (result.containsKey(KEY_AUTHTOKEN)
+ && !TextUtils.isEmpty(result.getString(KEY_AUTHTOKEN))) {
+ final Bundle newResult = new Bundle(result);
+ newResult.putString(KEY_AUTHTOKEN, "<omitted for logging purposes>");
+ return newResult;
+ }
}
return result;
}
@@ -251,6 +253,7 @@
* @return An {@link AccountManager} instance
*/
public static AccountManager get(Context context) {
+ if (context == null) throw new IllegalArgumentException("context is null");
return (AccountManager) context.getSystemService(Context.ACCOUNT_SERVICE);
}
@@ -269,6 +272,7 @@
* @return The account's password, null if none or if the account doesn't exist
*/
public String getPassword(final Account account) {
+ if (account == null) throw new IllegalArgumentException("account is null");
try {
return mService.getPassword(account);
} catch (RemoteException e) {
@@ -293,6 +297,8 @@
* @return The user data, null if the account or key doesn't exist
*/
public String getUserData(final Account account, final String key) {
+ if (account == null) throw new IllegalArgumentException("account is null");
+ if (key == null) throw new IllegalArgumentException("key is null");
try {
return mService.getUserData(account, key);
} catch (RemoteException e) {
@@ -393,6 +399,8 @@
public AccountManagerFuture<Boolean> hasFeatures(final Account account,
final String[] features,
AccountManagerCallback<Boolean> callback, Handler handler) {
+ if (account == null) throw new IllegalArgumentException("account is null");
+ if (features == null) throw new IllegalArgumentException("features is null");
return new Future2Task<Boolean>(handler, callback) {
public void doWork() throws RemoteException {
mService.hasFeatures(mResponse, account, features);
@@ -436,13 +444,9 @@
public AccountManagerFuture<Account[]> getAccountsByTypeAndFeatures(
final String type, final String[] features,
AccountManagerCallback<Account[]> callback, Handler handler) {
+ if (type == null) throw new IllegalArgumentException("type is null");
return new Future2Task<Account[]>(handler, callback) {
public void doWork() throws RemoteException {
- if (type == null) {
- Log.e(TAG, "Type is null");
- set(new Account[0]);
- return;
- }
mService.getAccountsByFeatures(mResponse, type, features);
}
public Account[] bundleToResult(Bundle bundle) throws AuthenticatorException {
@@ -476,6 +480,7 @@
* already exists, the account is null, or another error occurs.
*/
public boolean addAccountExplicitly(Account account, String password, Bundle userdata) {
+ if (account == null) throw new IllegalArgumentException("account is null");
try {
return mService.addAccount(account, password, userdata);
} catch (RemoteException e) {
@@ -507,6 +512,7 @@
*/
public AccountManagerFuture<Boolean> removeAccount(final Account account,
AccountManagerCallback<Boolean> callback, Handler handler) {
+ if (account == null) throw new IllegalArgumentException("account is null");
return new Future2Task<Boolean>(handler, callback) {
public void doWork() throws RemoteException {
mService.removeAccount(mResponse, account);
@@ -537,6 +543,8 @@
* @param authToken The auth token to invalidate
*/
public void invalidateAuthToken(final String accountType, final String authToken) {
+ if (accountType == null) throw new IllegalArgumentException("accountType is null");
+ if (authToken == null) throw new IllegalArgumentException("authToken is null");
try {
mService.invalidateAuthToken(accountType, authToken);
} catch (RemoteException e) {
@@ -563,13 +571,8 @@
* no auth token is cached or the account does not exist.
*/
public String peekAuthToken(final Account account, final String authTokenType) {
- if (account == null) {
- Log.e(TAG, "peekAuthToken: the account must not be null");
- return null;
- }
- if (authTokenType == null) {
- return null;
- }
+ if (account == null) throw new IllegalArgumentException("account is null");
+ if (authTokenType == null) throw new IllegalArgumentException("authTokenType is null");
try {
return mService.peekAuthToken(account, authTokenType);
} catch (RemoteException e) {
@@ -594,10 +597,7 @@
* @param password The password to set, null to clear the password
*/
public void setPassword(final Account account, final String password) {
- if (account == null) {
- Log.e(TAG, "the account must not be null");
- return;
- }
+ if (account == null) throw new IllegalArgumentException("account is null");
try {
mService.setPassword(account, password);
} catch (RemoteException e) {
@@ -621,10 +621,7 @@
* @param account The account whose password to clear
*/
public void clearPassword(final Account account) {
- if (account == null) {
- Log.e(TAG, "the account must not be null");
- return;
- }
+ if (account == null) throw new IllegalArgumentException("account is null");
try {
mService.clearPassword(account);
} catch (RemoteException e) {
@@ -649,14 +646,8 @@
* @param value The value to set, null to clear this userdata key
*/
public void setUserData(final Account account, final String key, final String value) {
- if (account == null) {
- Log.e(TAG, "the account must not be null");
- return;
- }
- if (key == null) {
- Log.e(TAG, "the key must not be null");
- return;
- }
+ if (account == null) throw new IllegalArgumentException("account is null");
+ if (key == null) throw new IllegalArgumentException("key is null");
try {
mService.setUserData(account, key, value);
} catch (RemoteException e) {
@@ -682,6 +673,8 @@
* @param authToken The auth token to add to the cache
*/
public void setAuthToken(Account account, final String authTokenType, final String authToken) {
+ if (account == null) throw new IllegalArgumentException("account is null");
+ if (authTokenType == null) throw new IllegalArgumentException("authTokenType is null");
try {
mService.setAuthToken(account, authTokenType, authToken);
} catch (RemoteException e) {
@@ -716,6 +709,8 @@
public String blockingGetAuthToken(Account account, String authTokenType,
boolean notifyAuthFailure)
throws OperationCanceledException, IOException, AuthenticatorException {
+ if (account == null) throw new IllegalArgumentException("account is null");
+ if (authTokenType == null) throw new IllegalArgumentException("authTokenType is null");
Bundle bundle = getAuthToken(account, authTokenType, notifyAuthFailure, null /* callback */,
null /* handler */).getResult();
if (bundle == null) {
@@ -786,7 +781,7 @@
public AccountManagerFuture<Bundle> getAuthToken(
final Account account, final String authTokenType, final Bundle options,
final Activity activity, AccountManagerCallback<Bundle> callback, Handler handler) {
- if (activity == null) throw new IllegalArgumentException("activity is null");
+ if (account == null) throw new IllegalArgumentException("account is null");
if (authTokenType == null) throw new IllegalArgumentException("authTokenType is null");
return new AmsTask(activity, handler, callback) {
public void doWork() throws RemoteException {
@@ -930,14 +925,9 @@
final String authTokenType, final String[] requiredFeatures,
final Bundle addAccountOptions,
final Activity activity, AccountManagerCallback<Bundle> callback, Handler handler) {
+ if (accountType == null) throw new IllegalArgumentException("accountType is null");
return new AmsTask(activity, handler, callback) {
public void doWork() throws RemoteException {
- if (accountType == null) {
- Log.e(TAG, "the account must not be null");
- // to unblock caller waiting on Future.get()
- set(new Bundle());
- return;
- }
mService.addAcount(mResponse, accountType, authTokenType,
requiredFeatures, activity != null, addAccountOptions);
}
@@ -1004,6 +994,7 @@
final Activity activity,
final AccountManagerCallback<Bundle> callback,
final Handler handler) {
+ if (account == null) throw new IllegalArgumentException("account is null");
return new AmsTask(activity, handler, callback) {
public void doWork() throws RemoteException {
mService.confirmCredentials(mResponse, account, options, activity != null);
@@ -1064,6 +1055,7 @@
final Bundle options, final Activity activity,
final AccountManagerCallback<Bundle> callback,
final Handler handler) {
+ if (account == null) throw new IllegalArgumentException("account is null");
return new AmsTask(activity, handler, callback) {
public void doWork() throws RemoteException {
mService.updateCredentials(mResponse, account, authTokenType, activity != null,
@@ -1112,6 +1104,7 @@
public AccountManagerFuture<Bundle> editProperties(final String accountType,
final Activity activity, final AccountManagerCallback<Bundle> callback,
final Handler handler) {
+ if (accountType == null) throw new IllegalArgumentException("accountType is null");
return new AmsTask(activity, handler, callback) {
public void doWork() throws RemoteException {
mService.editProperties(mResponse, accountType, activity != null);
@@ -1734,10 +1727,7 @@
* @throws IllegalStateException if listener was not already added
*/
public void removeOnAccountsUpdatedListener(OnAccountsUpdateListener listener) {
- if (listener == null) {
- Log.e(TAG, "Missing listener");
- return;
- }
+ if (listener == null) throw new IllegalArgumentException("listener is null");
synchronized (mAccountsUpdatedListeners) {
if (!mAccountsUpdatedListeners.containsKey(listener)) {
Log.e(TAG, "Listener was not previously added");
diff --git a/core/java/android/accounts/AccountManagerService.java b/core/java/android/accounts/AccountManagerService.java
index 16b603c..1d9e0f1 100644
--- a/core/java/android/accounts/AccountManagerService.java
+++ b/core/java/android/accounts/AccountManagerService.java
@@ -282,6 +282,7 @@
}
public String getPassword(Account account) {
+ if (account == null) throw new IllegalArgumentException("account is null");
checkAuthenticateAccountsPermission(account);
long identityToken = clearCallingIdentity();
@@ -312,6 +313,8 @@
}
public String getUserData(Account account, String key) {
+ if (account == null) throw new IllegalArgumentException("account is null");
+ if (key == null) throw new IllegalArgumentException("key is null");
checkAuthenticateAccountsPermission(account);
long identityToken = clearCallingIdentity();
try {
@@ -382,6 +385,7 @@
}
public boolean addAccount(Account account, String password, Bundle extras) {
+ if (account == null) throw new IllegalArgumentException("account is null");
checkAuthenticateAccountsPermission(account);
// fails if the account already exists
@@ -451,6 +455,9 @@
public void hasFeatures(IAccountManagerResponse response,
Account account, String[] features) {
+ if (response == null) throw new IllegalArgumentException("response is null");
+ if (account == null) throw new IllegalArgumentException("account is null");
+ if (features == null) throw new IllegalArgumentException("features is null");
checkReadAccountsPermission();
long identityToken = clearCallingIdentity();
try {
@@ -509,6 +516,8 @@
}
public void removeAccount(IAccountManagerResponse response, Account account) {
+ if (response == null) throw new IllegalArgumentException("response is null");
+ if (account == null) throw new IllegalArgumentException("account is null");
checkManageAccountsPermission();
long identityToken = clearCallingIdentity();
try {
@@ -565,6 +574,8 @@
}
public void invalidateAuthToken(String accountType, String authToken) {
+ if (accountType == null) throw new IllegalArgumentException("accountType is null");
+ if (authToken == null) throw new IllegalArgumentException("authToken is null");
checkManageAccountsOrUseCredentialsPermissions();
long identityToken = clearCallingIdentity();
try {
@@ -658,6 +669,8 @@
}
public String peekAuthToken(Account account, String authTokenType) {
+ if (account == null) throw new IllegalArgumentException("account is null");
+ if (authTokenType == null) throw new IllegalArgumentException("authTokenType is null");
checkAuthenticateAccountsPermission(account);
long identityToken = clearCallingIdentity();
try {
@@ -668,6 +681,8 @@
}
public void setAuthToken(Account account, String authTokenType, String authToken) {
+ if (account == null) throw new IllegalArgumentException("account is null");
+ if (authTokenType == null) throw new IllegalArgumentException("authTokenType is null");
checkAuthenticateAccountsPermission(account);
long identityToken = clearCallingIdentity();
try {
@@ -678,6 +693,7 @@
}
public void setPassword(Account account, String password) {
+ if (account == null) throw new IllegalArgumentException("account is null");
checkAuthenticateAccountsPermission(account);
long identityToken = clearCallingIdentity();
try {
@@ -714,6 +730,7 @@
}
public void clearPassword(Account account) {
+ if (account == null) throw new IllegalArgumentException("account is null");
checkManageAccountsPermission();
long identityToken = clearCallingIdentity();
try {
@@ -724,6 +741,8 @@
}
public void setUserData(Account account, String key, String value) {
+ if (key == null) throw new IllegalArgumentException("key is null");
+ if (account == null) throw new IllegalArgumentException("account is null");
checkAuthenticateAccountsPermission(account);
long identityToken = clearCallingIdentity();
if (account == null) {
@@ -786,6 +805,9 @@
public void getAuthToken(IAccountManagerResponse response, final Account account,
final String authTokenType, final boolean notifyOnAuthFailure,
final boolean expectActivityLaunch, final Bundle loginOptions) {
+ 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);
@@ -955,6 +977,8 @@
public void addAcount(final IAccountManagerResponse response, final String accountType,
final String authTokenType, final String[] requiredFeatures,
final boolean expectActivityLaunch, final Bundle options) {
+ if (response == null) throw new IllegalArgumentException("response is null");
+ if (accountType == null) throw new IllegalArgumentException("accountType is null");
checkManageAccountsPermission();
long identityToken = clearCallingIdentity();
try {
@@ -981,6 +1005,8 @@
public void confirmCredentials(IAccountManagerResponse response,
final Account account, final Bundle options, final boolean expectActivityLaunch) {
+ if (response == null) throw new IllegalArgumentException("response is null");
+ if (account == null) throw new IllegalArgumentException("account is null");
checkManageAccountsPermission();
long identityToken = clearCallingIdentity();
try {
@@ -1002,6 +1028,9 @@
public void updateCredentials(IAccountManagerResponse response, final Account account,
final String authTokenType, final boolean expectActivityLaunch,
final Bundle loginOptions) {
+ 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");
checkManageAccountsPermission();
long identityToken = clearCallingIdentity();
try {
@@ -1025,6 +1054,8 @@
public void editProperties(IAccountManagerResponse response, final String accountType,
final boolean expectActivityLaunch) {
+ if (response == null) throw new IllegalArgumentException("response is null");
+ if (accountType == null) throw new IllegalArgumentException("accountType is null");
checkManageAccountsPermission();
long identityToken = clearCallingIdentity();
try {
@@ -1142,6 +1173,8 @@
public void getAccountsByFeatures(IAccountManagerResponse response,
String type, String[] features) {
+ if (response == null) throw new IllegalArgumentException("response is null");
+ if (type == null) throw new IllegalArgumentException("accountType is null");
checkReadAccountsPermission();
if (features != null && type == null) {
if (response != null) {
@@ -1878,7 +1911,8 @@
* @hide
*/
public void grantAppPermission(Account account, String authTokenType, int uid) {
- if (account == null || authTokenType == null) {
+ if (account == null || authTokenType == null) {
+ Log.e(TAG, "grantAppPermission: called with invalid arguments", new Exception());
return;
}
SQLiteDatabase db = mOpenHelper.getWritableDatabase();
@@ -1908,7 +1942,8 @@
* @hide
*/
public void revokeAppPermission(Account account, String authTokenType, int uid) {
- if (account == null || authTokenType == null) {
+ if (account == null || authTokenType == null) {
+ Log.e(TAG, "revokeAppPermission: called with invalid arguments", new Exception());
return;
}
SQLiteDatabase db = mOpenHelper.getWritableDatabase();
diff --git a/core/java/android/accounts/GrantCredentialsPermissionActivity.java b/core/java/android/accounts/GrantCredentialsPermissionActivity.java
index f4b7258..fd340cbe 100644
--- a/core/java/android/accounts/GrantCredentialsPermissionActivity.java
+++ b/core/java/android/accounts/GrantCredentialsPermissionActivity.java
@@ -57,6 +57,14 @@
final Bundle extras = getIntent().getExtras();
mAccount = extras.getParcelable(EXTRAS_ACCOUNT);
mAuthTokenType = extras.getString(EXTRAS_AUTH_TOKEN_TYPE);
+
+ if (mAccount == null || mAuthTokenType == null) {
+ // we were somehow started with bad parameters. abort the activity.
+ setResult(Activity.RESULT_CANCELED);
+ finish();
+ return;
+ }
+
mUid = extras.getInt(EXTRAS_REQUESTING_UID);
final String accountTypeLabel = extras.getString(EXTRAS_ACCOUNT_TYPE_LABEL);
final String[] packages = extras.getStringArray(EXTRAS_PACKAGES);
diff --git a/core/java/android/os/INetworkManagementService.aidl b/core/java/android/os/INetworkManagementService.aidl
index 1254782..e970e7e 100644
--- a/core/java/android/os/INetworkManagementService.aidl
+++ b/core/java/android/os/INetworkManagementService.aidl
@@ -78,8 +78,9 @@
/**
* Start tethering services with the specified dhcp server range
+ * arg is a set of start end pairs defining the ranges.
*/
- void startTethering(String dhcpRangeStart, String dhcpRangeEnd);
+ void startTethering(in String[] dhcpRanges);
/**
* Stop currently running tethering services
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 6e37f69..b8e5747 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -2508,11 +2508,13 @@
public static final String WIFI_ON = "wifi_on";
/**
- * Whether the Wi-Fi AP should be on.
+ * Used to save the Wifi_ON state prior to tethering.
+ * This state will be checked to restore Wifi after
+ * the user turns off tethering.
*
* @hide
*/
- public static final String WIFI_AP_ON = "wifi_ap_on";
+ public static final String WIFI_SAVED_STATE = "wifi_saved_state";
/**
* AP SSID
diff --git a/core/java/android/webkit/MimeTypeMap.java b/core/java/android/webkit/MimeTypeMap.java
index 3ed9851..034c88a 100644
--- a/core/java/android/webkit/MimeTypeMap.java
+++ b/core/java/android/webkit/MimeTypeMap.java
@@ -484,6 +484,7 @@
sMimeTypeMap.loadEntry("text/x-tex", "cls");
sMimeTypeMap.loadEntry("text/x-vcalendar", "vcs");
sMimeTypeMap.loadEntry("text/x-vcard", "vcf");
+ sMimeTypeMap.loadEntry("video/3gpp", "3gpp");
sMimeTypeMap.loadEntry("video/3gpp", "3gp");
sMimeTypeMap.loadEntry("video/3gpp", "3g2");
sMimeTypeMap.loadEntry("video/dl", "dl");
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index 9150b5e..bd6105f 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -2597,6 +2597,8 @@
mTouchMode = TOUCH_MODE_OVERFLING;
invalidate();
post(this);
+ } else {
+ mTouchMode = TOUCH_MODE_REST;
}
}
@@ -2610,14 +2612,7 @@
}
void edgeReached() {
- mScroller.notifyVerticalEdgeReached(mScrollY, 0, Integer.MAX_VALUE);
- mTouchMode = TOUCH_MODE_OVERFLING;
- invalidate();
- post(this);
- }
-
- void marginReached() {
- mScroller.notifyVerticalBoundaryReached(mScrollY, 0);
+ mScroller.notifyVerticalEdgeReached(mScrollY, 0, getOverscrollMax());
mTouchMode = TOUCH_MODE_OVERFLING;
invalidate();
post(this);
diff --git a/core/java/android/widget/HorizontalScrollView.java b/core/java/android/widget/HorizontalScrollView.java
index 06da5fa..3bd4767 100644
--- a/core/java/android/widget/HorizontalScrollView.java
+++ b/core/java/android/widget/HorizontalScrollView.java
@@ -599,6 +599,7 @@
} else {
super.scrollTo(scrollX, scrollY);
}
+ awakenScrollBars();
}
private int getOverscrollMax() {
@@ -961,7 +962,6 @@
dx = Math.max(0, Math.min(scrollX + dx, maxX)) - scrollX;
mScroller.startScroll(scrollX, mScrollY, dx, 0);
- awakenScrollBars(mScroller.getDuration());
invalidate();
} else {
if (!mScroller.isFinished()) {
@@ -1319,7 +1319,6 @@
mScrollViewMovedFocus = false;
}
- awakenScrollBars(mScroller.getDuration());
invalidate();
}
}
diff --git a/core/java/android/widget/OverScroller.java b/core/java/android/widget/OverScroller.java
index 48e7493..e8d92de 100644
--- a/core/java/android/widget/OverScroller.java
+++ b/core/java/android/widget/OverScroller.java
@@ -17,21 +17,27 @@
package android.widget;
import android.content.Context;
+import android.util.FloatMath;
import android.view.animation.AnimationUtils;
import android.view.animation.Interpolator;
+import android.widget.Scroller.MagneticScroller;
/**
* This class encapsulates scrolling with the ability to overshoot the bounds
- * of a scrolling operation. This class attempts to be a drop-in replacement
- * for {@link android.widget.Scroller} in most cases.
- *
- * @hide Pending API approval
+ * of a scrolling operation. This class is a drop-in replacement for
+ * {@link android.widget.Scroller} in most cases.
*/
-public class OverScroller extends Scroller {
+public class OverScroller {
+ private int mMode;
- // Identical to mScrollers, but casted to MagneticOverScroller.
- private MagneticOverScroller mOverScrollerX;
- private MagneticOverScroller mOverScrollerY;
+ private MagneticOverScroller mScrollerX;
+ private MagneticOverScroller mScrollerY;
+
+ private final Interpolator mInterpolator;
+
+ private static final int DEFAULT_DURATION = 250;
+ private static final int SCROLL_MODE = 0;
+ private static final int FLING_MODE = 1;
/**
* Creates an OverScroller with a viscous fluid scroll interpolator.
@@ -64,15 +70,259 @@
*/
public OverScroller(Context context, Interpolator interpolator,
float bounceCoefficientX, float bounceCoefficientY) {
- super(context, interpolator);
- mOverScrollerX.setBounceCoefficient(bounceCoefficientX);
- mOverScrollerY.setBounceCoefficient(bounceCoefficientY);
+ mInterpolator = interpolator;
+ mScrollerX = new MagneticOverScroller();
+ mScrollerY = new MagneticOverScroller();
+ MagneticScroller.initializeFromContext(context);
+
+ mScrollerX.setBounceCoefficient(bounceCoefficientX);
+ mScrollerY.setBounceCoefficient(bounceCoefficientY);
}
- @Override
- void instantiateScrollers() {
- mScrollerX = mOverScrollerX = new MagneticOverScroller();
- mScrollerY = mOverScrollerY = new MagneticOverScroller();
+ /**
+ *
+ * Returns whether the scroller has finished scrolling.
+ *
+ * @return True if the scroller has finished scrolling, false otherwise.
+ */
+ public final boolean isFinished() {
+ return mScrollerX.mFinished && mScrollerY.mFinished;
+ }
+
+ /**
+ * Force the finished field to a particular value. Contrary to
+ * {@link #abortAnimation()}, forcing the animation to finished
+ * does NOT cause the scroller to move to the final x and y
+ * position.
+ *
+ * @param finished The new finished value.
+ */
+ public final void forceFinished(boolean finished) {
+ mScrollerX.mFinished = mScrollerY.mFinished = finished;
+ }
+
+ /**
+ * Returns the current X offset in the scroll.
+ *
+ * @return The new X offset as an absolute distance from the origin.
+ */
+ public final int getCurrX() {
+ return mScrollerX.mCurrentPosition;
+ }
+
+ /**
+ * Returns the current Y offset in the scroll.
+ *
+ * @return The new Y offset as an absolute distance from the origin.
+ */
+ public final int getCurrY() {
+ return mScrollerY.mCurrentPosition;
+ }
+
+ /**
+ * @hide
+ * Returns the current velocity.
+ *
+ * @return The original velocity less the deceleration, norm of the X and Y velocity vector.
+ */
+ public float getCurrVelocity() {
+ float squaredNorm = mScrollerX.mCurrVelocity * mScrollerX.mCurrVelocity;
+ squaredNorm += mScrollerY.mCurrVelocity * mScrollerY.mCurrVelocity;
+ return FloatMath.sqrt(squaredNorm);
+ }
+
+ /**
+ * Returns the start X offset in the scroll.
+ *
+ * @return The start X offset as an absolute distance from the origin.
+ */
+ public final int getStartX() {
+ return mScrollerX.mStart;
+ }
+
+ /**
+ * Returns the start Y offset in the scroll.
+ *
+ * @return The start Y offset as an absolute distance from the origin.
+ */
+ public final int getStartY() {
+ return mScrollerY.mStart;
+ }
+
+ /**
+ * Returns where the scroll will end. Valid only for "fling" scrolls.
+ *
+ * @return The final X offset as an absolute distance from the origin.
+ */
+ public final int getFinalX() {
+ return mScrollerX.mFinal;
+ }
+
+ /**
+ * Returns where the scroll will end. Valid only for "fling" scrolls.
+ *
+ * @return The final Y offset as an absolute distance from the origin.
+ */
+ public final int getFinalY() {
+ return mScrollerY.mFinal;
+ }
+
+ /**
+ * Returns how long the scroll event will take, in milliseconds.
+ *
+ * @return The duration of the scroll in milliseconds.
+ *
+ * @hide Pending removal once nothing depends on it
+ * @deprecated OverScrollers don't necessarily have a fixed duration.
+ * This function will lie to the best of its ability.
+ */
+ public final int getDuration() {
+ return Math.max(mScrollerX.mDuration, mScrollerY.mDuration);
+ }
+
+ /**
+ * Extend the scroll animation. This allows a running animation to scroll
+ * further and longer, when used with {@link #setFinalX(int)} or {@link #setFinalY(int)}.
+ *
+ * @param extend Additional time to scroll in milliseconds.
+ * @see #setFinalX(int)
+ * @see #setFinalY(int)
+ *
+ * @hide Pending removal once nothing depends on it
+ * @deprecated OverScrollers don't necessarily have a fixed duration.
+ * Instead of setting a new final position and extending
+ * the duration of an existing scroll, use startScroll
+ * to begin a new animation.
+ */
+ public void extendDuration(int extend) {
+ mScrollerX.extendDuration(extend);
+ mScrollerY.extendDuration(extend);
+ }
+
+ /**
+ * Sets the final position (X) for this scroller.
+ *
+ * @param newX The new X offset as an absolute distance from the origin.
+ * @see #extendDuration(int)
+ * @see #setFinalY(int)
+ *
+ * @hide Pending removal once nothing depends on it
+ * @deprecated OverScroller's final position may change during an animation.
+ * Instead of setting a new final position and extending
+ * the duration of an existing scroll, use startScroll
+ * to begin a new animation.
+ */
+ public void setFinalX(int newX) {
+ mScrollerX.setFinalPosition(newX);
+ }
+
+ /**
+ * Sets the final position (Y) for this scroller.
+ *
+ * @param newY The new Y offset as an absolute distance from the origin.
+ * @see #extendDuration(int)
+ * @see #setFinalX(int)
+ *
+ * @hide Pending removal once nothing depends on it
+ * @deprecated OverScroller's final position may change during an animation.
+ * Instead of setting a new final position and extending
+ * the duration of an existing scroll, use startScroll
+ * to begin a new animation.
+ */
+ public void setFinalY(int newY) {
+ mScrollerY.setFinalPosition(newY);
+ }
+
+ /**
+ * Call this when you want to know the new location. If it returns true, the
+ * animation is not yet finished.
+ */
+ public boolean computeScrollOffset() {
+ if (isFinished()) {
+ return false;
+ }
+
+ switch (mMode) {
+ case SCROLL_MODE:
+ long time = AnimationUtils.currentAnimationTimeMillis();
+ // Any scroller can be used for time, since they were started
+ // together in scroll mode. We use X here.
+ final long elapsedTime = time - mScrollerX.mStartTime;
+
+ final int duration = mScrollerX.mDuration;
+ if (elapsedTime < duration) {
+ float q = (float) (elapsedTime) / duration;
+
+ if (mInterpolator == null)
+ q = Scroller.viscousFluid(q);
+ else
+ q = mInterpolator.getInterpolation(q);
+
+ mScrollerX.updateScroll(q);
+ mScrollerY.updateScroll(q);
+ } else {
+ abortAnimation();
+ }
+ break;
+
+ case FLING_MODE:
+ if (!mScrollerX.mFinished) {
+ if (!mScrollerX.update()) {
+ if (!mScrollerX.continueWhenFinished()) {
+ mScrollerX.finish();
+ }
+ }
+ }
+
+ if (!mScrollerY.mFinished) {
+ if (!mScrollerY.update()) {
+ if (!mScrollerY.continueWhenFinished()) {
+ mScrollerY.finish();
+ }
+ }
+ }
+
+ break;
+ }
+
+ return true;
+ }
+
+ /**
+ * Start scrolling by providing a starting point and the distance to travel.
+ * The scroll will use the default value of 250 milliseconds for the
+ * duration.
+ *
+ * @param startX Starting horizontal scroll offset in pixels. Positive
+ * numbers will scroll the content to the left.
+ * @param startY Starting vertical scroll offset in pixels. Positive numbers
+ * will scroll the content up.
+ * @param dx Horizontal distance to travel. Positive numbers will scroll the
+ * content to the left.
+ * @param dy Vertical distance to travel. Positive numbers will scroll the
+ * content up.
+ */
+ public void startScroll(int startX, int startY, int dx, int dy) {
+ startScroll(startX, startY, dx, dy, DEFAULT_DURATION);
+ }
+
+ /**
+ * Start scrolling by providing a starting point and the distance to travel.
+ *
+ * @param startX Starting horizontal scroll offset in pixels. Positive
+ * numbers will scroll the content to the left.
+ * @param startY Starting vertical scroll offset in pixels. Positive numbers
+ * will scroll the content up.
+ * @param dx Horizontal distance to travel. Positive numbers will scroll the
+ * content to the left.
+ * @param dy Vertical distance to travel. Positive numbers will scroll the
+ * content up.
+ * @param duration Duration of the scroll in milliseconds.
+ */
+ public void startScroll(int startX, int startY, int dx, int dy, int duration) {
+ mMode = SCROLL_MODE;
+ mScrollerX.startScroll(startX, dx, duration);
+ mScrollerY.startScroll(startY, dy, duration);
}
/**
@@ -91,12 +341,11 @@
mMode = FLING_MODE;
// Make sure both methods are called.
- final boolean spingbackX = mOverScrollerX.springback(startX, minX, maxX);
- final boolean spingbackY = mOverScrollerY.springback(startY, minY, maxY);
+ final boolean spingbackX = mScrollerX.springback(startX, minX, maxX);
+ final boolean spingbackY = mScrollerY.springback(startY, minY, maxY);
return spingbackX || spingbackY;
}
- @Override
public void fling(int startX, int startY, int velocityX, int velocityY,
int minX, int maxX, int minY, int maxY) {
fling(startX, startY, velocityX, velocityY, minX, maxX, minY, maxY, 0, 0);
@@ -105,7 +354,7 @@
/**
* Start scrolling based on a fling gesture. The distance traveled will
* depend on the initial velocity of the fling.
- *
+ *
* @param startX Starting point of the scroll (X)
* @param startY Starting point of the scroll (Y)
* @param velocityX Initial velocity of the fling (X) measured in pixels per
@@ -132,43 +381,87 @@
public void fling(int startX, int startY, int velocityX, int velocityY,
int minX, int maxX, int minY, int maxY, int overX, int overY) {
mMode = FLING_MODE;
- mOverScrollerX.fling(startX, velocityX, minX, maxX, overX);
- mOverScrollerY.fling(startY, velocityY, minY, maxY, overY);
+ mScrollerX.fling(startX, velocityX, minX, maxX, overX);
+ mScrollerY.fling(startY, velocityY, minY, maxY, overY);
}
- void notifyHorizontalBoundaryReached(int startX, int finalX) {
- mOverScrollerX.springback(startX, finalX, finalX);
+ /**
+ * Notify the scroller that we've reached a horizontal boundary.
+ * Normally the information to handle this will already be known
+ * when the animation is started, such as in a call to one of the
+ * fling functions. However there are cases where this cannot be known
+ * in advance. This function will transition the current motion and
+ * animate from startX to finalX as appropriate.
+ *
+ * @param startX Starting/current X position
+ * @param finalX Desired final X position
+ * @param overX Magnitude of overscroll allowed. This should be the maximum
+ * desired distance from finalX. Absolute value - must be positive.
+ */
+ public void notifyHorizontalEdgeReached(int startX, int finalX, int overX) {
+ mScrollerX.notifyEdgeReached(startX, finalX, overX);
}
- void notifyVerticalBoundaryReached(int startY, int finalY) {
- mOverScrollerY.springback(startY, finalY, finalY);
- }
-
- void notifyHorizontalEdgeReached(int startX, int finalX, int overX) {
- mOverScrollerX.notifyEdgeReached(startX, finalX, overX);
- }
-
- void notifyVerticalEdgeReached(int startY, int finalY, int overY) {
- mOverScrollerY.notifyEdgeReached(startY, finalY, overY);
+ /**
+ * Notify the scroller that we've reached a vertical boundary.
+ * Normally the information to handle this will already be known
+ * when the animation is started, such as in a call to one of the
+ * fling functions. However there are cases where this cannot be known
+ * in advance. This function will animate a parabolic motion from
+ * startY to finalY.
+ *
+ * @param startY Starting/current Y position
+ * @param finalY Desired final Y position
+ * @param overY Magnitude of overscroll allowed. This should be the maximum
+ * desired distance from finalY.
+ */
+ public void notifyVerticalEdgeReached(int startY, int finalY, int overY) {
+ mScrollerY.notifyEdgeReached(startY, finalY, overY);
}
/**
* Returns whether the current Scroller is currently returning to a valid position.
* Valid bounds were provided by the
* {@link #fling(int, int, int, int, int, int, int, int, int, int)} method.
- *
+ *
* One should check this value before calling
- * {@link startScroll(int, int, int, int)} as the interpolation currently in progress to restore
- * a valid position will then be stopped. The caller has to take into account the fact that the
- * started scroll will start from an overscrolled position.
+ * {@link #startScroll(int, int, int, int)} as the interpolation currently in progress
+ * to restore a valid position will then be stopped. The caller has to take into account
+ * the fact that the started scroll will start from an overscrolled position.
*
- * @return true when the current position is overscrolled and interpolated back to a valid value.
+ * @return true when the current position is overscrolled and in the process of
+ * interpolating back to a valid value.
*/
public boolean isOverscrolled() {
- return ((!mOverScrollerX.mFinished &&
- mOverScrollerX.mState != MagneticOverScroller.TO_EDGE) ||
- (!mOverScrollerY.mFinished &&
- mOverScrollerY.mState != MagneticOverScroller.TO_EDGE));
+ return ((!mScrollerX.mFinished &&
+ mScrollerX.mState != MagneticOverScroller.TO_EDGE) ||
+ (!mScrollerY.mFinished &&
+ mScrollerY.mState != MagneticOverScroller.TO_EDGE));
+ }
+
+ /**
+ * Stops the animation. Contrary to {@link #forceFinished(boolean)},
+ * aborting the animating causes the scroller to move to the final x and y
+ * positions.
+ *
+ * @see #forceFinished(boolean)
+ */
+ public void abortAnimation() {
+ mScrollerX.finish();
+ mScrollerY.finish();
+ }
+
+ /**
+ * Returns the time elapsed since the beginning of the scrolling.
+ *
+ * @return The elapsed time in milliseconds.
+ *
+ * @hide
+ */
+ public int timePassed() {
+ final long time = AnimationUtils.currentAnimationTimeMillis();
+ final long startTime = Math.min(mScrollerX.mStartTime, mScrollerY.mStartTime);
+ return (int) (time - startTime);
}
static class MagneticOverScroller extends Scroller.MagneticScroller {
diff --git a/core/java/android/widget/ScrollView.java b/core/java/android/widget/ScrollView.java
index 36d244f..23e1234 100644
--- a/core/java/android/widget/ScrollView.java
+++ b/core/java/android/widget/ScrollView.java
@@ -963,7 +963,6 @@
dy = Math.max(0, Math.min(scrollY + dy, maxY)) - scrollY;
mScroller.startScroll(mScrollX, scrollY, 0, dy);
- awakenScrollBars(mScroller.getDuration());
invalidate();
} else {
if (!mScroller.isFinished()) {
diff --git a/core/java/android/widget/Scroller.java b/core/java/android/widget/Scroller.java
index 6a2f000..abb3e32 100644
--- a/core/java/android/widget/Scroller.java
+++ b/core/java/android/widget/Scroller.java
@@ -32,16 +32,16 @@
* computeScrollOffset() will always return false to indicate that scrolling is over.
*/
public class Scroller {
- int mMode;
+ private int mMode;
- MagneticScroller mScrollerX;
- MagneticScroller mScrollerY;
+ private MagneticScroller mScrollerX;
+ private MagneticScroller mScrollerY;
private final Interpolator mInterpolator;
- static final int DEFAULT_DURATION = 250;
- static final int SCROLL_MODE = 0;
- static final int FLING_MODE = 1;
+ private static final int DEFAULT_DURATION = 250;
+ private static final int SCROLL_MODE = 0;
+ private static final int FLING_MODE = 1;
// This controls the viscous fluid effect (how much of it)
private final static float VISCOUS_FLUID_SCALE = 8.0f;
@@ -65,16 +65,12 @@
* null, the default (viscous) interpolator will be used.
*/
public Scroller(Context context, Interpolator interpolator) {
- instantiateScrollers();
+ mScrollerX = new MagneticScroller();
+ mScrollerY = new MagneticScroller();
MagneticScroller.initializeFromContext(context);
mInterpolator = interpolator;
}
-
- void instantiateScrollers() {
- mScrollerX = new MagneticScroller();
- mScrollerY = new MagneticScroller();
- }
/**
*
@@ -289,7 +285,7 @@
mScrollerY.fling(startY, velocityY, minY, maxY);
}
- private static float viscousFluid(float x) {
+ static float viscousFluid(float x) {
x *= VISCOUS_FLUID_SCALE;
if (x < 1.0f) {
x -= (1.0f - (float)Math.exp(-x));
diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java
index 37cd412..dbbd286 100644
--- a/core/java/com/android/internal/widget/LockPatternUtils.java
+++ b/core/java/com/android/internal/widget/LockPatternUtils.java
@@ -47,7 +47,6 @@
public class LockPatternUtils {
private static final String TAG = "LockPatternUtils";
- private static final boolean LDEBUG = false;
private static final String LOCK_PATTERN_FILE = "/system/gesture.key";
private static final String LOCK_PASSWORD_FILE = "/system/password.key";
@@ -81,17 +80,6 @@
public static final int MIN_LOCK_PATTERN_SIZE = 4;
/**
- * Type of password being stored.
- * pattern = pattern screen
- * pin = digit-only password
- * password = alphanumeric password
- */
- public static final int MODE_UNSPECIFIED = DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
- public static final int MODE_PATTERN = DevicePolicyManager.PASSWORD_QUALITY_SOMETHING;
- public static final int MODE_PIN = DevicePolicyManager.PASSWORD_QUALITY_NUMERIC;
- public static final int MODE_PASSWORD = DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC;
-
- /**
* The minimum number of dots the user must include in a wrong pattern
* attempt for it to be counted against the counts that affect
* {@link #FAILED_ATTEMPTS_BEFORE_TIMEOUT} and {@link #FAILED_ATTEMPTS_BEFORE_RESET}
@@ -110,7 +98,7 @@
private static String sLockPatternFilename;
private static String sLockPasswordFilename;
- DevicePolicyManager getDevicePolicyManager() {
+ public DevicePolicyManager getDevicePolicyManager() {
if (mDevicePolicyManager == null) {
mDevicePolicyManager =
(DevicePolicyManager)mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
@@ -141,22 +129,13 @@
return getDevicePolicyManager().getPasswordMinimumLength(null);
}
+
/**
* Gets the device policy password mode. If the mode is non-specific, returns
* MODE_PATTERN which allows the user to choose anything.
*/
- public int getRequestedPasswordMode() {
- int policyMode = getDevicePolicyManager().getPasswordQuality(null);
- switch (policyMode) {
- case DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC:
- case DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC:
- return MODE_PASSWORD;
- case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC:
- return MODE_PIN;
- case DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED:
- return MODE_PATTERN;
- }
- return MODE_PATTERN;
+ public int getRequestedPasswordQuality() {
+ return getDevicePolicyManager().getPasswordQuality(null);
}
/**
@@ -232,7 +211,7 @@
try {
// Check if we can read a byte from the file
RandomAccessFile raf = new RandomAccessFile(filename, "r");
- byte first = raf.readByte();
+ raf.readByte();
raf.close();
return true;
} catch (FileNotFoundException fnfe) {
@@ -273,41 +252,42 @@
* information it has.
*/
public int getActivePasswordQuality() {
- switch (getPasswordMode()) {
- case MODE_UNSPECIFIED:
- return DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
- case MODE_PATTERN:
+ int activePasswordQuality = DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
+ switch (getKeyguardStoredPasswordQuality()) {
+ case DevicePolicyManager.PASSWORD_QUALITY_SOMETHING:
if (isLockPatternEnabled()) {
- return DevicePolicyManager.PASSWORD_QUALITY_SOMETHING;
- } else {
- return DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
+ activePasswordQuality = DevicePolicyManager.PASSWORD_QUALITY_SOMETHING;
}
- case MODE_PIN:
+ break;
+ case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC:
if (isLockPasswordEnabled()) {
- return DevicePolicyManager.PASSWORD_QUALITY_NUMERIC;
- } else {
- return DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
+ activePasswordQuality = DevicePolicyManager.PASSWORD_QUALITY_NUMERIC;
}
- case MODE_PASSWORD:
+ break;
+ case DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC:
if (isLockPasswordEnabled()) {
- return DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC;
- } else {
- return DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
+ activePasswordQuality = DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC;
}
+ break;
+ case DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC:
+ if (isLockPasswordEnabled()) {
+ activePasswordQuality = DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC;
+ }
+ break;
}
- return DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
+ return activePasswordQuality;
}
-
+
/**
* Clear any lock pattern or password.
*/
public void clearLock() {
getDevicePolicyManager().setActivePasswordState(
DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED, 0);
- saveLockPassword(null, LockPatternUtils.MODE_PATTERN);
+ saveLockPassword(null, DevicePolicyManager.PASSWORD_QUALITY_SOMETHING);
setLockPatternEnabled(false);
saveLockPattern(null);
- setLong(PASSWORD_TYPE_KEY, MODE_PATTERN);
+ setLong(PASSWORD_TYPE_KEY, DevicePolicyManager.PASSWORD_QUALITY_SOMETHING);
}
/**
@@ -330,7 +310,7 @@
DevicePolicyManager dpm = getDevicePolicyManager();
if (pattern != null) {
setBoolean(PATTERN_EVER_CHOSEN_KEY, true);
- setLong(PASSWORD_TYPE_KEY, MODE_PATTERN);
+ setLong(PASSWORD_TYPE_KEY, DevicePolicyManager.PASSWORD_QUALITY_SOMETHING);
dpm.setActivePasswordState(
DevicePolicyManager.PASSWORD_QUALITY_SOMETHING, pattern.size());
} else {
@@ -374,12 +354,13 @@
}
/**
- * Save a lock password. Does not ensure that the pattern is as good
+ * Save a lock password. Does not ensure that the password is as good
* as the requested mode, but will adjust the mode to be as good as the
* pattern.
* @param password The password to save
+ * @param quality {@see DevicePolicyManager#getPasswordQuality(android.content.ComponentName)}
*/
- public void saveLockPassword(String password, int mode) {
+ public void saveLockPassword(String password, int quality) {
// Compute the hash
final byte[] hash = passwordToHash(password);
try {
@@ -394,10 +375,10 @@
raf.close();
DevicePolicyManager dpm = getDevicePolicyManager();
if (password != null) {
- setLong(PASSWORD_TYPE_KEY, mode);
- int quality = computePasswordQuality(password);
- if (quality != DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED) {
- dpm.setActivePasswordState(quality, password.length());
+ int computedQuality = computePasswordQuality(password);
+ setLong(PASSWORD_TYPE_KEY, computedQuality);
+ if (computedQuality != DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED) {
+ dpm.setActivePasswordState(computedQuality, password.length());
} else {
// The password is not anything.
dpm.setActivePasswordState(
@@ -416,8 +397,14 @@
}
}
- public int getPasswordMode() {
- return (int) getLong(PASSWORD_TYPE_KEY, MODE_PATTERN);
+ /**
+ * Retrieves the quality mode we're in.
+ * {@see DevicePolicyManager#getPasswordQuality(android.content.ComponentName)}
+ *
+ * @return stored password quality
+ */
+ public int getKeyguardStoredPasswordQuality() {
+ return (int) getLong(PASSWORD_TYPE_KEY, DevicePolicyManager.PASSWORD_QUALITY_SOMETHING);
}
/**
@@ -536,7 +523,10 @@
*/
public boolean isLockPasswordEnabled() {
long mode = getLong(PASSWORD_TYPE_KEY, 0);
- return savedPasswordExists() && (mode == MODE_PASSWORD || mode == MODE_PIN);
+ return savedPasswordExists() &&
+ (mode == DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC
+ || mode == DevicePolicyManager.PASSWORD_QUALITY_NUMERIC
+ || mode == DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC);
}
/**
@@ -544,7 +534,8 @@
*/
public boolean isLockPatternEnabled() {
return getBoolean(Settings.Secure.LOCK_PATTERN_ENABLED)
- && getLong(PASSWORD_TYPE_KEY, MODE_PATTERN) == MODE_PATTERN;
+ && getLong(PASSWORD_TYPE_KEY, DevicePolicyManager.PASSWORD_QUALITY_SOMETHING)
+ == DevicePolicyManager.PASSWORD_QUALITY_SOMETHING;
}
/**
@@ -660,9 +651,13 @@
}
public boolean isSecure() {
- long mode = getPasswordMode();
- boolean secure = mode == MODE_PATTERN && isLockPatternEnabled() && savedPatternExists()
- || (mode == MODE_PIN || mode == MODE_PASSWORD) && savedPasswordExists();
+ long mode = getKeyguardStoredPasswordQuality();
+ final boolean isPattern = mode == DevicePolicyManager.PASSWORD_QUALITY_SOMETHING;
+ final boolean isPassword = mode == DevicePolicyManager.PASSWORD_QUALITY_NUMERIC
+ || mode == DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC
+ || mode == DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC;
+ final boolean secure = isPattern && isLockPatternEnabled() && savedPatternExists()
+ || isPassword && savedPasswordExists();
return secure;
}
diff --git a/core/jni/android_util_Binder.cpp b/core/jni/android_util_Binder.cpp
index 901be58..d26cd28 100644
--- a/core/jni/android_util_Binder.cpp
+++ b/core/jni/android_util_Binder.cpp
@@ -23,7 +23,6 @@
#include <fcntl.h>
#include <stdio.h>
#include <sys/stat.h>
-#include <sys/syscall.h>
#include <sys/types.h>
#include <unistd.h>
@@ -36,6 +35,7 @@
#include <binder/Parcel.h>
#include <binder/ProcessState.h>
#include <binder/IServiceManager.h>
+#include <utils/threads.h>
#include <android_runtime/AndroidRuntime.h>
@@ -850,8 +850,8 @@
// have gettid, so we just ignore this and don't log if we can't
// get the thread id.
static bool should_time_binder_calls() {
-#ifdef __NR_gettid
- return (getpid() == syscall(__NR_gettid));
+#ifdef HAVE_GETTID
+ return (getpid() == androidGetTid());
#else
#warning no gettid(), so not logging Binder calls...
return false;
diff --git a/core/res/res/color/primary_text_dark.xml b/core/res/res/color/primary_text_dark.xml
index 2ec46b9..39c9e22 100644
--- a/core/res/res/color/primary_text_dark.xml
+++ b/core/res/res/color/primary_text_dark.xml
@@ -16,7 +16,7 @@
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_enabled="false" android:color="@android:color/bright_foreground_dark_disabled"/>
- <item android:state_window_focused="false" android:color="@android:color/bright_foreground_dark"/>
+ <item android:state_window_focused="false" android:color="@android:color/bright_foreground_dark"/>
<item android:state_pressed="true" android:color="@android:color/bright_foreground_dark_inverse"/>
<item android:state_selected="true" android:color="@android:color/bright_foreground_dark_inverse"/>
<item android:color="@android:color/bright_foreground_dark"/> <!-- not selected -->
diff --git a/core/res/res/color/primary_text_light.xml b/core/res/res/color/primary_text_light.xml
index bd9ac8b..e112034 100644
--- a/core/res/res/color/primary_text_light.xml
+++ b/core/res/res/color/primary_text_light.xml
@@ -16,7 +16,7 @@
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_enabled="false" android:color="@android:color/bright_foreground_light_disabled"/>
- <item android:state_window_focused="false" android:color="@android:color/bright_foreground_light"/>
+ <item android:state_window_focused="false" android:color="@android:color/bright_foreground_light"/>
<item android:state_pressed="true" android:color="@android:color/bright_foreground_light"/>
<item android:state_selected="true" android:color="@android:color/bright_foreground_light"/>
<item android:color="@android:color/bright_foreground_light"/> <!-- not selected -->
diff --git a/core/res/res/color/secondary_text_dark.xml b/core/res/res/color/secondary_text_dark.xml
index 0d96221..c195ef0 100644
--- a/core/res/res/color/secondary_text_dark.xml
+++ b/core/res/res/color/secondary_text_dark.xml
@@ -15,7 +15,7 @@
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:state_window_focused="false" android:state_enabled="false" android:color="@android:color/dim_foreground_dark_disabled"/>
+ <item android:state_window_focused="false" android:state_enabled="false" android:color="@android:color/dim_foreground_dark_disabled"/>
<item android:state_window_focused="false" android:color="@android:color/dim_foreground_dark"/>
<item android:state_selected="true" android:state_enabled="false" android:color="@android:color/dim_foreground_dark_inverse_disabled"/>
<item android:state_pressed="true" android:state_enabled="false" android:color="@android:color/dim_foreground_dark_inverse_disabled"/>
diff --git a/core/res/res/color/secondary_text_light.xml b/core/res/res/color/secondary_text_light.xml
index 0846b5e..99249a5 100644
--- a/core/res/res/color/secondary_text_light.xml
+++ b/core/res/res/color/secondary_text_light.xml
@@ -15,7 +15,7 @@
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:state_window_focused="false" android:state_enabled="false" android:color="@android:color/dim_foreground_light_disabled"/>
+ <item android:state_window_focused="false" android:state_enabled="false" android:color="@android:color/dim_foreground_light_disabled"/>
<item android:state_window_focused="false" android:color="@android:color/dim_foreground_light"/>
<!-- Since there is only one selector (for both light and dark), the light's selected state shouldn't be inversed like the dark's. -->
<item android:state_pressed="true" android:state_enabled="false" android:color="@android:color/dim_foreground_light_disabled"/>
diff --git a/core/res/res/color/tertiary_text_dark.xml b/core/res/res/color/tertiary_text_dark.xml
index 7ce3580..66227bc 100644
--- a/core/res/res/color/tertiary_text_dark.xml
+++ b/core/res/res/color/tertiary_text_dark.xml
@@ -16,7 +16,7 @@
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_enabled="false" android:color="#808080"/>
- <item android:state_window_focused="false" android:color="#808080"/>
+ <item android:state_window_focused="false" android:color="#808080"/>
<item android:state_pressed="true" android:color="#808080"/>
<item android:state_selected="true" android:color="@android:color/dim_foreground_light"/>
<item android:color="#808080"/> <!-- not selected -->
diff --git a/core/res/res/color/tertiary_text_light.xml b/core/res/res/color/tertiary_text_light.xml
index 7e61fc89..ea65756 100644
--- a/core/res/res/color/tertiary_text_light.xml
+++ b/core/res/res/color/tertiary_text_light.xml
@@ -16,7 +16,7 @@
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_enabled="false" android:color="#808080"/>
- <item android:state_window_focused="false" android:color="#808080"/>
+ <item android:state_window_focused="false" android:color="#808080"/>
<item android:state_pressed="true" android:color="#808080"/>
<item android:state_selected="true" android:color="#808080"/>
<item android:color="#808080"/> <!-- not selected -->
diff --git a/core/res/res/drawable-hdpi/stat_sys_adb.png b/core/res/res/drawable-hdpi/stat_sys_adb.png
new file mode 100644
index 0000000..aef8650
--- /dev/null
+++ b/core/res/res/drawable-hdpi/stat_sys_adb.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_adb.png b/core/res/res/drawable-mdpi/stat_sys_adb.png
new file mode 100644
index 0000000..12abeda
--- /dev/null
+++ b/core/res/res/drawable-mdpi/stat_sys_adb.png
Binary files differ
diff --git a/core/res/res/drawable/btn_default.xml b/core/res/res/drawable/btn_default.xml
index b8ce2bf..4765084 100644
--- a/core/res/res/drawable/btn_default.xml
+++ b/core/res/res/drawable/btn_default.xml
@@ -15,9 +15,9 @@
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:state_window_focused="false" android:state_enabled="true"
+ <item android:state_window_focused="false" android:state_enabled="true"
android:drawable="@drawable/btn_default_normal" />
- <item android:state_window_focused="false" android:state_enabled="false"
+ <item android:state_window_focused="false" android:state_enabled="false"
android:drawable="@drawable/btn_default_normal_disable" />
<item android:state_pressed="true"
android:drawable="@drawable/btn_default_pressed" />
diff --git a/core/res/res/drawable/btn_default_small.xml b/core/res/res/drawable/btn_default_small.xml
index 247e9e2..5485ea0 100644
--- a/core/res/res/drawable/btn_default_small.xml
+++ b/core/res/res/drawable/btn_default_small.xml
@@ -15,9 +15,9 @@
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:state_window_focused="false" android:state_enabled="true"
+ <item android:state_window_focused="false" android:state_enabled="true"
android:drawable="@drawable/btn_default_small_normal" />
- <item android:state_window_focused="false" android:state_enabled="false"
+ <item android:state_window_focused="false" android:state_enabled="false"
android:drawable="@drawable/btn_default_small_normal_disable" />
<item android:state_pressed="true"
android:drawable="@drawable/btn_default_small_pressed" />
diff --git a/core/res/res/drawable/btn_dialog.xml b/core/res/res/drawable/btn_dialog.xml
index ed4c28a..d1d7e29 100644
--- a/core/res/res/drawable/btn_dialog.xml
+++ b/core/res/res/drawable/btn_dialog.xml
@@ -15,9 +15,9 @@
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:state_window_focused="false" android:state_enabled="true"
+ <item android:state_window_focused="false" android:state_enabled="true"
android:drawable="@drawable/btn_dialog_normal" />
- <item android:state_window_focused="false" android:state_enabled="false"
+ <item android:state_window_focused="false" android:state_enabled="false"
android:drawable="@drawable/btn_dialog_disable" />
<item android:state_pressed="true"
android:drawable="@drawable/btn_dialog_pressed" />
diff --git a/core/res/res/drawable/btn_dropdown.xml b/core/res/res/drawable/btn_dropdown.xml
index 34a0504..d9905c6 100644
--- a/core/res/res/drawable/btn_dropdown.xml
+++ b/core/res/res/drawable/btn_dropdown.xml
@@ -18,7 +18,7 @@
<item
android:state_window_focused="false" android:state_enabled="true"
android:drawable="@drawable/btn_dropdown_normal" />
- <item
+ <item
android:state_window_focused="false" android:state_enabled="false"
android:drawable="@drawable/btn_dropdown_disabled" />
<item
diff --git a/core/res/res/drawable/btn_global_search.xml b/core/res/res/drawable/btn_global_search.xml
index 531f07e..2807a01 100644
--- a/core/res/res/drawable/btn_global_search.xml
+++ b/core/res/res/drawable/btn_global_search.xml
@@ -16,9 +16,9 @@
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<!-- TODO Need different assets for some of these button states. -->
- <item android:state_window_focused="false" android:state_enabled="true"
+ <item android:state_window_focused="false" android:state_enabled="true"
android:drawable="@drawable/btn_global_search_normal" />
- <item android:state_window_focused="false" android:state_enabled="false"
+ <item android:state_window_focused="false" android:state_enabled="false"
android:drawable="@drawable/btn_global_search_normal" />
<item android:state_pressed="true"
android:drawable="@drawable/btn_default_pressed" />
diff --git a/core/res/res/drawable/btn_search_dialog.xml b/core/res/res/drawable/btn_search_dialog.xml
index b7f5187..082633e 100644
--- a/core/res/res/drawable/btn_search_dialog.xml
+++ b/core/res/res/drawable/btn_search_dialog.xml
@@ -16,7 +16,7 @@
<selector xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:state_window_focused="false" android:state_enabled="true"
+ <item android:state_window_focused="false" android:state_enabled="true"
android:drawable="@drawable/btn_search_dialog_default" />
<item android:state_pressed="true"
diff --git a/core/res/res/drawable/btn_search_dialog_voice.xml b/core/res/res/drawable/btn_search_dialog_voice.xml
index 748aaf5..1a76efa 100644
--- a/core/res/res/drawable/btn_search_dialog_voice.xml
+++ b/core/res/res/drawable/btn_search_dialog_voice.xml
@@ -16,7 +16,7 @@
<selector xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:state_window_focused="false" android:state_enabled="true"
+ <item android:state_window_focused="false" android:state_enabled="true"
android:drawable="@drawable/btn_search_dialog_voice_default" />
<item android:state_pressed="true"
diff --git a/core/res/res/drawable/edit_text.xml b/core/res/res/drawable/edit_text.xml
index 23a97e9..315278d 100644
--- a/core/res/res/drawable/edit_text.xml
+++ b/core/res/res/drawable/edit_text.xml
@@ -15,9 +15,9 @@
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:state_window_focused="false" android:state_enabled="true"
+ <item android:state_window_focused="false" android:state_enabled="true"
android:drawable="@drawable/textfield_default" />
- <item android:state_window_focused="false" android:state_enabled="false"
+ <item android:state_window_focused="false" android:state_enabled="false"
android:drawable="@drawable/textfield_disabled" />
<item android:state_pressed="true" android:drawable="@drawable/textfield_pressed" />
<item android:state_enabled="true" android:state_focused="true" android:drawable="@drawable/textfield_selected" />
diff --git a/core/res/res/drawable/textfield_search.xml b/core/res/res/drawable/textfield_search.xml
index 2923368..78c9486 100644
--- a/core/res/res/drawable/textfield_search.xml
+++ b/core/res/res/drawable/textfield_search.xml
@@ -16,7 +16,7 @@
<selector xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:state_window_focused="false" android:state_enabled="true"
+ <item android:state_window_focused="false" android:state_enabled="true"
android:drawable="@drawable/textfield_search_default" />
<item android:state_pressed="true"
diff --git a/graphics/java/android/graphics/drawable/GradientDrawable.java b/graphics/java/android/graphics/drawable/GradientDrawable.java
index 91a2bc1..63d1446 100644
--- a/graphics/java/android/graphics/drawable/GradientDrawable.java
+++ b/graphics/java/android/graphics/drawable/GradientDrawable.java
@@ -778,8 +778,8 @@
com.android.internal.R.styleable.DrawableCorners_bottomLeftRadius, radius);
int bottomRightRadius = a.getDimensionPixelSize(
com.android.internal.R.styleable.DrawableCorners_bottomRightRadius, radius);
- if (topLeftRadius != radius && topRightRadius != radius &&
- bottomLeftRadius != radius && bottomRightRadius != radius) {
+ if (topLeftRadius != radius || topRightRadius != radius ||
+ bottomLeftRadius != radius || bottomRightRadius != radius) {
setCornerRadii(new float[] {
topLeftRadius, topLeftRadius,
topRightRadius, topRightRadius,
diff --git a/include/ui/GraphicBufferAllocator.h b/include/ui/GraphicBufferAllocator.h
index be9c79b..741d763 100644
--- a/include/ui/GraphicBufferAllocator.h
+++ b/include/ui/GraphicBufferAllocator.h
@@ -86,7 +86,6 @@
GraphicBufferAllocator();
~GraphicBufferAllocator();
- mutable Mutex mLock;
alloc_device_t *mAllocDev;
};
diff --git a/libs/ui/GraphicBufferAllocator.cpp b/libs/ui/GraphicBufferAllocator.cpp
index 57d5fc3..6ae7e74 100644
--- a/libs/ui/GraphicBufferAllocator.cpp
+++ b/libs/ui/GraphicBufferAllocator.cpp
@@ -78,8 +78,6 @@
status_t GraphicBufferAllocator::alloc(uint32_t w, uint32_t h, PixelFormat format,
int usage, buffer_handle_t* handle, int32_t* stride)
{
- Mutex::Autolock _l(mLock);
-
// make sure to not allocate a 0 x 0 buffer
w = clamp(w);
h = clamp(h);
@@ -118,8 +116,6 @@
status_t GraphicBufferAllocator::free(buffer_handle_t handle)
{
- Mutex::Autolock _l(mLock);
-
status_t err;
if (sw_gralloc_handle_t::validate(handle) < 0) {
err = mAllocDev->free(mAllocDev, handle);
diff --git a/opengl/java/android/opengl/GLSurfaceView.java b/opengl/java/android/opengl/GLSurfaceView.java
index 1b99e78..0f79b15 100644
--- a/opengl/java/android/opengl/GLSurfaceView.java
+++ b/opengl/java/android/opengl/GLSurfaceView.java
@@ -158,7 +158,7 @@
private final static boolean LOG_THREADS = false;
private final static boolean LOG_PAUSE_RESUME = true;
private final static boolean LOG_SURFACE = true;
- private final static boolean LOG_RENDERER = false;
+ private final static boolean LOG_RENDERER = true;
private final static boolean LOG_RENDERER_DRAW_FRAME = false;
private final static boolean LOG_EGL = true;
// Work-around for bug 2263168
@@ -1161,6 +1161,15 @@
break;
}
+ // Update the pause state.
+ if (mPaused != mRequestPaused) {
+ mPaused = mRequestPaused;
+ sGLThreadManager.notifyAll();
+ if (LOG_PAUSE_RESUME) {
+ Log.i("GLThread", "mPaused is now " + mPaused + " tid=" + getId());
+ }
+ }
+
// Have we lost the EGL context?
if (lostEglContext) {
stopEglSurfaceLocked();
@@ -1360,6 +1369,13 @@
}
mHasSurface = true;
sGLThreadManager.notifyAll();
+ while((mWaitingForSurface) && (!mExited)) {
+ try {
+ sGLThreadManager.wait();
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ }
+ }
}
}
@@ -1385,8 +1401,18 @@
if (LOG_PAUSE_RESUME) {
Log.i("GLThread", "onPause tid=" + getId());
}
- mPaused = true;
+ mRequestPaused = true;
sGLThreadManager.notifyAll();
+ while ((! mExited) && (! mPaused)) {
+ if (LOG_PAUSE_RESUME) {
+ Log.i("Main thread", "onPause waiting for mPaused.");
+ }
+ try {
+ sGLThreadManager.wait();
+ } catch (InterruptedException ex) {
+ Thread.currentThread().interrupt();
+ }
+ }
}
}
@@ -1395,9 +1421,20 @@
if (LOG_PAUSE_RESUME) {
Log.i("GLThread", "onResume tid=" + getId());
}
- mPaused = false;
+ mRequestPaused = false;
mRequestRender = true;
+ mRenderComplete = false;
sGLThreadManager.notifyAll();
+ while ((! mExited) && mPaused && (!mRenderComplete)) {
+ if (LOG_PAUSE_RESUME) {
+ Log.i("Main thread", "onResume waiting for !mPaused.");
+ }
+ try {
+ sGLThreadManager.wait();
+ } catch (InterruptedException ex) {
+ Thread.currentThread().interrupt();
+ }
+ }
}
}
@@ -1458,6 +1495,7 @@
// variables are protected by the sGLThreadManager monitor
private boolean mShouldExit;
private boolean mExited;
+ private boolean mRequestPaused;
private boolean mPaused;
private boolean mHasSurface;
private boolean mWaitingForSurface;
diff --git a/opengl/libagl/state.cpp b/opengl/libagl/state.cpp
index 1224a96..27bb545 100644
--- a/opengl/libagl/state.cpp
+++ b/opengl/libagl/state.cpp
@@ -37,7 +37,7 @@
// ----------------------------------------------------------------------------
static char const * const gVendorString = "Android";
-static char const * const gRendererString = "Android PixelFlinger 1.2";
+static char const * const gRendererString = "Android PixelFlinger 1.3";
static char const * const gVersionString = "OpenGL ES-CM 1.0";
static char const * const gExtensionsString =
"GL_OES_byte_coordinates " // OK
diff --git a/services/java/com/android/server/DiskStatsService.java b/services/java/com/android/server/DiskStatsService.java
new file mode 100644
index 0000000..8ef974a
--- /dev/null
+++ b/services/java/com/android/server/DiskStatsService.java
@@ -0,0 +1,111 @@
+/*
+ * 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 com.android.server;
+
+import android.content.Context;
+import android.os.Binder;
+import android.os.Environment;
+import android.os.FileUtils;
+import android.os.StatFs;
+import android.os.SystemClock;
+
+import java.io.File;
+import java.io.FileDescriptor;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.PrintWriter;
+
+/**
+ * This service exists only as a "dumpsys" target which reports
+ * statistics about the status of the disk.
+ */
+public class DiskStatsService extends Binder {
+ private final Context mContext;
+
+ public DiskStatsService(Context context) {
+ mContext = context;
+ }
+
+ @Override
+ protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+ // This data is accessible to any app -- no permission check needed.
+
+ // Run a quick-and-dirty performance test: write 512 bytes
+ byte[] junk = new byte[512];
+ for (int i = 0; i < junk.length; i++) junk[i] = (byte) i; // Write nonzero bytes
+
+ File tmp = new File(Environment.getDataDirectory(), "system/perftest.tmp");
+ FileOutputStream fos = null;
+ IOException error = null;
+
+ long before = SystemClock.uptimeMillis();
+ try {
+ fos = new FileOutputStream(tmp);
+ fos.write(junk);
+ } catch (IOException e) {
+ error = e;
+ } finally {
+ try { if (fos != null) fos.close(); } catch (IOException e) {}
+ }
+
+ long after = SystemClock.uptimeMillis();
+ if (tmp.exists()) tmp.delete();
+
+ if (error != null) {
+ pw.print("Test-Error: ");
+ pw.println(error.toString());
+ } else {
+ pw.print("Latency: ");
+ pw.print(after - before);
+ pw.println("ms [512B Data Write]");
+ }
+
+ reportFreeSpace(Environment.getDataDirectory(), "Data", pw);
+ reportFreeSpace(Environment.getDownloadCacheDirectory(), "Cache", pw);
+ reportFreeSpace(new File("/system"), "System", pw);
+
+ // TODO: Read /proc/yaffs and report interesting values;
+ // add configurable (through args) performance test parameters.
+ }
+
+ private void reportFreeSpace(File path, String name, PrintWriter pw) {
+ try {
+ StatFs statfs = new StatFs(path.getPath());
+ long bsize = statfs.getBlockSize();
+ long avail = statfs.getAvailableBlocks();
+ long total = statfs.getBlockCount();
+ if (bsize <= 0 || total <= 0) {
+ throw new IllegalArgumentException(
+ "Invalid stat: bsize=" + bsize + " avail=" + avail + " total=" + total);
+ }
+
+ pw.print(name);
+ pw.print("-Free: ");
+ pw.print(avail * bsize / 1024);
+ pw.print("K / ");
+ pw.print(total * bsize / 1024);
+ pw.print("K total = ");
+ pw.print(avail * 100 / total);
+ pw.println("% free");
+ } catch (IllegalArgumentException e) {
+ pw.print(name);
+ pw.print("-Error: ");
+ pw.println(e.toString());
+ return;
+ }
+ }
+}
diff --git a/services/java/com/android/server/NetStatService.java b/services/java/com/android/server/NetStatService.java
index ac3445e..7fe6743 100644
--- a/services/java/com/android/server/NetStatService.java
+++ b/services/java/com/android/server/NetStatService.java
@@ -19,11 +19,16 @@
import android.content.Context;
import android.net.TrafficStats;
import android.os.INetStatService;
+import android.os.SystemClock;
+
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
public class NetStatService extends INetStatService.Stub {
+ private final Context mContext;
public NetStatService(Context context) {
-
+ mContext = context;
}
public long getMobileTxPackets() {
@@ -57,4 +62,35 @@
public long getTotalRxBytes() {
return TrafficStats.getTotalRxBytes();
}
+
+ @Override
+ protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+ // This data is accessible to any app -- no permission check needed.
+
+ pw.print("Elapsed: total=");
+ pw.print(SystemClock.elapsedRealtime());
+ pw.print("ms awake=");
+ pw.print(SystemClock.uptimeMillis());
+ pw.println("ms");
+
+ pw.print("Mobile: Tx=");
+ pw.print(getMobileTxBytes());
+ pw.print("B/");
+ pw.print(getMobileTxPackets());
+ pw.print("Pkts Rx=");
+ pw.print(getMobileRxBytes());
+ pw.print("B/");
+ pw.print(getMobileRxPackets());
+ pw.println("Pkts");
+
+ pw.print("Total: Tx=");
+ pw.print(getTotalTxBytes());
+ pw.print("B/");
+ pw.print(getTotalTxPackets());
+ pw.print("Pkts Rx=");
+ pw.print(getTotalRxBytes());
+ pw.print("B/");
+ pw.print(getTotalRxPackets());
+ pw.println("Pkts");
+ }
}
diff --git a/services/java/com/android/server/NetworkManagementService.java b/services/java/com/android/server/NetworkManagementService.java
index a3f2e09..072fc1b 100644
--- a/services/java/com/android/server/NetworkManagementService.java
+++ b/services/java/com/android/server/NetworkManagementService.java
@@ -312,11 +312,17 @@
mConnector.doCommand(String.format("ipfwd %sable", (enable ? "en" : "dis")));
}
- public void startTethering(String dhcpRangeStart, String dhcpRangeEnd)
+ public void startTethering(String[] dhcpRange)
throws IllegalStateException {
mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.CHANGE_NETWORK_STATE, "NetworkManagementService");
- mConnector.doCommand(String.format("tether start %s %s", dhcpRangeStart, dhcpRangeEnd));
+ // cmd is "tether start first_start first_stop second_start second_stop ..."
+ // an odd number of addrs will fail
+ String cmd = "tether start";
+ for (String d : dhcpRange) {
+ cmd += " " + d;
+ }
+ mConnector.doCommand(cmd);
}
public void stopTethering() throws IllegalStateException {
diff --git a/services/java/com/android/server/NotificationManagerService.java b/services/java/com/android/server/NotificationManagerService.java
index da9232b..3e1adf1 100755
--- a/services/java/com/android/server/NotificationManagerService.java
+++ b/services/java/com/android/server/NotificationManagerService.java
@@ -1136,11 +1136,13 @@
if (mAdbNotification == null) {
mAdbNotification = new Notification();
- mAdbNotification.icon = com.android.internal.R.drawable.stat_sys_warning;
+ mAdbNotification.icon = com.android.internal.R.drawable.stat_sys_adb;
mAdbNotification.when = 0;
mAdbNotification.flags = Notification.FLAG_ONGOING_EVENT;
mAdbNotification.tickerText = title;
- mAdbNotification.defaults |= Notification.DEFAULT_SOUND;
+ mAdbNotification.defaults = 0; // please be quiet
+ mAdbNotification.sound = null;
+ mAdbNotification.vibrate = null;
}
Intent intent = new Intent(
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index b023958..25a60a6 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -399,6 +399,13 @@
} catch (Throwable e) {
Slog.e(TAG, "Failure installing status bar icons", e);
}
+
+ try {
+ Slog.i(TAG, "DiskStats Service");
+ ServiceManager.addService("diskstats", new DiskStatsService(context));
+ } catch (Throwable e) {
+ Slog.e(TAG, "Failure starting DiskStats Service", e);
+ }
}
// make sure the ADB_ENABLED setting value matches the secure property value
diff --git a/services/java/com/android/server/WifiService.java b/services/java/com/android/server/WifiService.java
index b41443e..e4d7623 100644
--- a/services/java/com/android/server/WifiService.java
+++ b/services/java/com/android/server/WifiService.java
@@ -264,10 +264,11 @@
* if needed
*/
public void startWifi() {
- boolean wifiEnabled = getPersistedWifiEnabled();
+ /* Start if Wi-Fi is enabled or the saved state indicates Wi-Fi was on */
+ boolean wifiEnabled = getPersistedWifiEnabled() || testAndClearWifiSavedState();
Slog.i(TAG, "WifiService starting up with Wi-Fi " +
(wifiEnabled ? "enabled" : "disabled"));
- setWifiEnabledBlocking(wifiEnabled, false, Process.myUid());
+ setWifiEnabledBlocking(wifiEnabled, true, Process.myUid());
}
private void updateTetherState(ArrayList<String> available, ArrayList<String> tethered) {
@@ -289,8 +290,8 @@
try {
ifcg = service.getInterfaceConfig(intf);
if (ifcg != null) {
- /* IP/netmask: 169.254.2.2/255.255.255.0 */
- ifcg.ipAddr = (169 << 24) + (254 << 16) + (2 << 8) + 2;
+ /* IP/netmask: 192.168.43.1/255.255.255.0 */
+ ifcg.ipAddr = (192 << 24) + (168 << 16) + (43 << 8) + 1;
ifcg.netmask = (255 << 24) + (255 << 16) + (255 << 8) + 0;
ifcg.interfaceFlags = "up";
@@ -316,6 +317,19 @@
}
}
+ private boolean testAndClearWifiSavedState() {
+ final ContentResolver cr = mContext.getContentResolver();
+ int wifiSavedState = 0;
+ try {
+ wifiSavedState = Settings.Secure.getInt(cr, Settings.Secure.WIFI_SAVED_STATE);
+ if(wifiSavedState == 1)
+ Settings.Secure.putInt(cr, Settings.Secure.WIFI_SAVED_STATE, 0);
+ } catch (Settings.SettingNotFoundException e) {
+ ;
+ }
+ return (wifiSavedState == 1);
+ }
+
private boolean getPersistedWifiEnabled() {
final ContentResolver cr = mContext.getContentResolver();
try {
diff --git a/services/java/com/android/server/WindowManagerService.java b/services/java/com/android/server/WindowManagerService.java
index a1cf868..0e4b38d 100644
--- a/services/java/com/android/server/WindowManagerService.java
+++ b/services/java/com/android/server/WindowManagerService.java
@@ -7401,7 +7401,7 @@
try {
try {
mSurfaceX = mFrame.left + mXOffset;
- mSurfaceY = mFrame.top = mYOffset;
+ mSurfaceY = mFrame.top + mYOffset;
mSurface.setPosition(mSurfaceX, mSurfaceY);
mSurfaceLayer = mAnimLayer;
mSurface.setLayer(mAnimLayer);
diff --git a/services/java/com/android/server/connectivity/Tethering.java b/services/java/com/android/server/connectivity/Tethering.java
index 5e1b82f..f335287 100644
--- a/services/java/com/android/server/connectivity/Tethering.java
+++ b/services/java/com/android/server/connectivity/Tethering.java
@@ -31,6 +31,7 @@
import android.net.IConnectivityManager;
import android.net.INetworkManagementEventObserver;
import android.net.NetworkInfo;
+import android.net.NetworkUtils;
import android.os.BatteryManager;
import android.os.Binder;
import android.os.Environment;
@@ -80,11 +81,16 @@
private BroadcastReceiver mStateReceiver;
- private static final String USB_NEAR_IFACE_ADDR = "169.254.2.1";
+ private static final String USB_NEAR_IFACE_ADDR = "192.168.42.129";
+ private static final String USB_NETMASK = "255.255.255.0";
+
+ // FYI - the default wifi is 192.168.43.1 and 255.255.255.0
private String[] mDhcpRange;
- private static final String DHCP_DEFAULT_RANGE_START = "169.254.2.10";
- private static final String DHCP_DEFAULT_RANGE_STOP = "169.254.2.64";
+ private static final String DHCP_DEFAULT_RANGE1_START = "192.168.42.2";
+ private static final String DHCP_DEFAULT_RANGE1_STOP = "192.168.42.254";
+ private static final String DHCP_DEFAULT_RANGE2_START = "192.168.43.2";
+ private static final String DHCP_DEFAULT_RANGE2_STOP = "192.168.43.254";
private String[] mDnsServers;
private static final String DNS_DEFAULT_SERVER1 = "8.8.8.8";
@@ -138,15 +144,12 @@
mDhcpRange = context.getResources().getStringArray(
com.android.internal.R.array.config_tether_dhcp_range);
- if (mDhcpRange.length == 0) {
- mDhcpRange = new String[2];
- mDhcpRange[0] = DHCP_DEFAULT_RANGE_START;
- mDhcpRange[1] = DHCP_DEFAULT_RANGE_STOP;
- } else if(mDhcpRange.length == 1) {
- String[] tmp = new String[2];
- tmp[0] = mDhcpRange[0];
- tmp[1] = new String("");
- mDhcpRange = tmp;
+ if ((mDhcpRange.length == 0) || (mDhcpRange.length % 2 ==1)) {
+ mDhcpRange = new String[4];
+ mDhcpRange[0] = DHCP_DEFAULT_RANGE1_START;
+ mDhcpRange[1] = DHCP_DEFAULT_RANGE1_STOP;
+ mDhcpRange[2] = DHCP_DEFAULT_RANGE2_START;
+ mDhcpRange[3] = DHCP_DEFAULT_RANGE2_STOP;
}
mDunRequired = context.getResources().getBoolean(
com.android.internal.R.bool.config_tether_dun_required);
@@ -504,8 +507,16 @@
try {
ifcg = service.getInterfaceConfig(iface);
if (ifcg != null) {
- ifcg.ipAddr = (169 << 24) + (254 << 16) + (2 << 8) + 1;
- ifcg.netmask = (255 << 24) + (255 << 16) + (255 << 8) + 0;
+ String[] addr = USB_NEAR_IFACE_ADDR.split("\\.");
+ ifcg.ipAddr = (Integer.parseInt(addr[0]) << 24) +
+ (Integer.parseInt(addr[1]) << 16) +
+ (Integer.parseInt(addr[2]) << 8) +
+ (Integer.parseInt(addr[3]));
+ addr = USB_NETMASK.split("\\.");
+ ifcg.netmask = (Integer.parseInt(addr[0]) << 24) +
+ (Integer.parseInt(addr[1]) << 16) +
+ (Integer.parseInt(addr[2]) << 8) +
+ (Integer.parseInt(addr[3]));
if (enabled) {
ifcg.interfaceFlags = ifcg.interfaceFlags.replace("down", "up");
} else {
@@ -836,6 +847,7 @@
if (mMyUpstreamIfaceName != null) {
try {
service.disableNat(mIfaceName, mMyUpstreamIfaceName);
+ mMyUpstreamIfaceName = null;
} catch (Exception e) {
try {
service.untetherInterface(mIfaceName);
@@ -876,6 +888,7 @@
if (mMyUpstreamIfaceName != null) {
try {
service.disableNat(mIfaceName, mMyUpstreamIfaceName);
+ mMyUpstreamIfaceName = null;
} catch (Exception e) {
try {
service.untetherInterface(mIfaceName);
@@ -915,6 +928,7 @@
if (mMyUpstreamIfaceName != null) {
try {
service.disableNat(mIfaceName, mMyUpstreamIfaceName);
+ mMyUpstreamIfaceName = null;
} catch (Exception e) {
try {
service.untetherInterface(mIfaceName);
@@ -1015,6 +1029,8 @@
private boolean mConnectionRequested = false;
+ private String mUpstreamIfaceName = null;
+
private static final int UPSTREAM_SETTLE_TIME_MS = 10000;
private static final int CELL_CONNECTION_RENEW_MS = 40000;
@@ -1101,7 +1117,7 @@
return false;
}
try {
- service.startTethering(mDhcpRange[0], mDhcpRange[1]);
+ service.startTethering(mDhcpRange);
} catch (Exception e) {
transitionTo(mStartTetheringErrorState);
return false;
@@ -1217,10 +1233,11 @@
// wait for things to settle and retry
sendMessageDelayed(CMD_RETRY_UPSTREAM, UPSTREAM_SETTLE_TIME_MS);
}
- notifyTetheredOfNewIface(iface);
+ notifyTetheredOfNewUpstreamIface(iface);
}
- protected void notifyTetheredOfNewIface(String ifaceName) {
+ protected void notifyTetheredOfNewUpstreamIface(String ifaceName) {
Log.d(TAG, "notifying tethered with iface =" + ifaceName);
+ mUpstreamIfaceName = ifaceName;
for (Object o : mNotifyList) {
TetherInterfaceSM sm = (TetherInterfaceSM)o;
sm.sendMessage(TetherInterfaceSM.CMD_TETHER_CONNECTION_CHANGED,
@@ -1273,7 +1290,7 @@
@Override
public void exit() {
turnOffMobileConnection();
- notifyTetheredOfNewIface(null);
+ notifyTetheredOfNewUpstreamIface(null);
}
@Override
public boolean processMessage(Message message) {
@@ -1283,7 +1300,8 @@
case CMD_TETHER_MODE_REQUESTED:
TetherInterfaceSM who = (TetherInterfaceSM)message.obj;
mNotifyList.add(who);
- who.sendMessage(TetherInterfaceSM.CMD_TETHER_CONNECTION_CHANGED);
+ who.sendMessage(TetherInterfaceSM.CMD_TETHER_CONNECTION_CHANGED,
+ mUpstreamIfaceName);
break;
case CMD_TETHER_MODE_UNREQUESTED:
who = (TetherInterfaceSM)message.obj;
diff --git a/services/java/com/android/server/status/NotificationViewList.java b/services/java/com/android/server/status/NotificationViewList.java
index 1598b68..1bb56a7 100644
--- a/services/java/com/android/server/status/NotificationViewList.java
+++ b/services/java/com/android/server/status/NotificationViewList.java
@@ -173,6 +173,12 @@
}
void add(StatusBarNotification notification) {
+ if (StatusBarService.SPEW) {
+ Slog.d(StatusBarService.TAG, "before add NotificationViewList"
+ + " notification.data.ongoingEvent=" + notification.data.ongoingEvent);
+ dump(notification);
+ }
+
ArrayList<StatusBarNotification> list = notification.data.ongoingEvent ? mOngoing : mLatest;
long when = notification.data.when;
final int N = list.size();
@@ -187,20 +193,25 @@
list.add(index, notification);
if (StatusBarService.SPEW) {
- Slog.d(StatusBarService.TAG, "NotificationViewList index=" + index);
+ Slog.d(StatusBarService.TAG, "after add NotificationViewList index=" + index);
dump(notification);
}
}
void dump(StatusBarNotification notification) {
if (StatusBarService.SPEW) {
+ boolean showTime = false;
String s = "";
for (int i=0; i<mOngoing.size(); i++) {
StatusBarNotification that = mOngoing.get(i);
if (that.key == notification.key) {
s += "[";
}
- s += that.data.when;
+ if (showTime) {
+ s += that.data.when;
+ } else {
+ s += that.data.pkg + "/" + that.data.id + "/" + that.view;
+ }
if (that.key == notification.key) {
s += "]";
}
@@ -214,7 +225,11 @@
if (that.key == notification.key) {
s += "[";
}
- s += that.data.when;
+ if (showTime) {
+ s += that.data.when;
+ } else {
+ s += that.data.pkg + "/" + that.data.id + "/" + that.view;
+ }
if (that.key == notification.key) {
s += "]";
}
diff --git a/services/java/com/android/server/status/StatusBarService.java b/services/java/com/android/server/status/StatusBarService.java
index 27b7b504..bcaf0a4 100644
--- a/services/java/com/android/server/status/StatusBarService.java
+++ b/services/java/com/android/server/status/StatusBarService.java
@@ -893,6 +893,8 @@
void updateNotificationView(StatusBarNotification notification, NotificationData oldData) {
NotificationData n = notification.data;
if (oldData != null && n != null
+ && n.when == oldData.when
+ && n.ongoingEvent == oldData.ongoingEvent
&& n.contentView != null && oldData.contentView != null
&& n.contentView.getPackage() != null
&& oldData.contentView.getPackage() != null