Merge change 21471 into eclair
* changes:
Add Galaxy wallpaper
diff --git a/api/current.xml b/api/current.xml
index d571984..ee8d2eb 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -13463,6 +13463,23 @@
<parameter name="accountType" type="java.lang.String">
</parameter>
</method>
+<method name="getAccountRemovalAllowed"
+ return="android.os.Bundle"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="response" type="android.accounts.AccountAuthenticatorResponse">
+</parameter>
+<parameter name="account" type="android.accounts.Account">
+</parameter>
+<exception name="NetworkErrorException" type="android.accounts.NetworkErrorException">
+</exception>
+</method>
<method name="getAuthToken"
return="android.os.Bundle"
abstract="true"
@@ -13615,7 +13632,7 @@
visibility="public"
>
</field>
-<field name="mName"
+<field name="name"
type="java.lang.String"
transient="false"
volatile="false"
@@ -13625,7 +13642,7 @@
visibility="public"
>
</field>
-<field name="mType"
+<field name="type"
type="java.lang.String"
transient="false"
volatile="false"
@@ -13781,7 +13798,7 @@
visibility="public"
>
<method name="addAccount"
- return="android.accounts.Future2"
+ return="android.accounts.AccountManagerFuture<android.os.Bundle>"
abstract="false"
native="false"
synchronized="false"
@@ -13800,13 +13817,13 @@
</parameter>
<parameter name="activity" type="android.app.Activity">
</parameter>
-<parameter name="callback" type="android.accounts.Future2Callback">
+<parameter name="callback" type="android.accounts.AccountManagerCallback<android.os.Bundle>">
</parameter>
<parameter name="handler" type="android.os.Handler">
</parameter>
</method>
<method name="addAccountExplicitly"
- return="android.accounts.Future1<java.lang.Boolean>"
+ return="boolean"
abstract="false"
native="false"
synchronized="false"
@@ -13815,16 +13832,12 @@
deprecated="not deprecated"
visibility="public"
>
-<parameter name="callback" type="android.accounts.Future1Callback<java.lang.Boolean>">
-</parameter>
<parameter name="account" type="android.accounts.Account">
</parameter>
<parameter name="password" type="java.lang.String">
</parameter>
<parameter name="extras" type="android.os.Bundle">
</parameter>
-<parameter name="handler" type="android.os.Handler">
-</parameter>
</method>
<method name="addOnAccountsUpdatedListener"
return="void"
@@ -13843,81 +13856,6 @@
<parameter name="updateImmediately" type="boolean">
</parameter>
</method>
-<method name="blockingAddAccountExplicitly"
- return="boolean"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="account" type="android.accounts.Account">
-</parameter>
-<parameter name="password" type="java.lang.String">
-</parameter>
-<parameter name="extras" type="android.os.Bundle">
-</parameter>
-</method>
-<method name="blockingClearPassword"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="account" type="android.accounts.Account">
-</parameter>
-</method>
-<method name="blockingGetAccounts"
- return="android.accounts.Account[]"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
-<method name="blockingGetAccountsByType"
- return="android.accounts.Account[]"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="accountType" type="java.lang.String">
-</parameter>
-</method>
-<method name="blockingGetAccountsWithTypeAndFeatures"
- return="android.accounts.Account[]"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="type" type="java.lang.String">
-</parameter>
-<parameter name="features" type="java.lang.String[]">
-</parameter>
-<exception name="AuthenticatorException" type="android.accounts.AuthenticatorException">
-</exception>
-<exception name="IOException" type="java.io.IOException">
-</exception>
-<exception name="OperationCanceledException" type="android.accounts.OperationCanceledException">
-</exception>
-</method>
<method name="blockingGetAuthToken"
return="java.lang.String"
abstract="false"
@@ -13941,139 +13879,8 @@
<exception name="OperationCanceledException" type="android.accounts.OperationCanceledException">
</exception>
</method>
-<method name="blockingGetAuthenticatorTypes"
- return="android.accounts.AuthenticatorDescription[]"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
-<method name="blockingGetPassword"
- return="java.lang.String"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="account" type="android.accounts.Account">
-</parameter>
-</method>
-<method name="blockingGetUserData"
- return="java.lang.String"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="account" type="android.accounts.Account">
-</parameter>
-<parameter name="key" type="java.lang.String">
-</parameter>
-</method>
-<method name="blockingInvalidateAuthToken"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="accountType" type="java.lang.String">
-</parameter>
-<parameter name="authToken" type="java.lang.String">
-</parameter>
-</method>
-<method name="blockingPeekAuthToken"
- return="java.lang.String"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="account" type="android.accounts.Account">
-</parameter>
-<parameter name="authTokenType" type="java.lang.String">
-</parameter>
-</method>
-<method name="blockingRemoveAccount"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="account" type="android.accounts.Account">
-</parameter>
-</method>
-<method name="blockingSetAuthToken"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="account" type="android.accounts.Account">
-</parameter>
-<parameter name="authTokenType" type="java.lang.String">
-</parameter>
-<parameter name="authToken" type="java.lang.String">
-</parameter>
-</method>
-<method name="blockingSetPassword"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="account" type="android.accounts.Account">
-</parameter>
-<parameter name="password" type="java.lang.String">
-</parameter>
-</method>
-<method name="blockingSetUserData"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="account" type="android.accounts.Account">
-</parameter>
-<parameter name="key" type="java.lang.String">
-</parameter>
-<parameter name="value" type="java.lang.String">
-</parameter>
-</method>
<method name="clearPassword"
- return="android.accounts.Future1<java.lang.Void>"
+ return="void"
abstract="false"
native="false"
synchronized="false"
@@ -14082,15 +13889,11 @@
deprecated="not deprecated"
visibility="public"
>
-<parameter name="callback" type="android.accounts.Future1Callback<java.lang.Void>">
-</parameter>
<parameter name="account" type="android.accounts.Account">
</parameter>
-<parameter name="handler" type="android.os.Handler">
-</parameter>
</method>
<method name="confirmCredentials"
- return="android.accounts.Future2"
+ return="android.accounts.AccountManagerFuture<android.os.Bundle>"
abstract="false"
native="false"
synchronized="false"
@@ -14103,13 +13906,13 @@
</parameter>
<parameter name="activity" type="android.app.Activity">
</parameter>
-<parameter name="callback" type="android.accounts.Future2Callback">
+<parameter name="callback" type="android.accounts.AccountManagerCallback<android.os.Bundle>">
</parameter>
<parameter name="handler" type="android.os.Handler">
</parameter>
</method>
<method name="confirmPassword"
- return="android.accounts.Future1<java.lang.Boolean>"
+ return="android.accounts.AccountManagerFuture<java.lang.Boolean>"
abstract="false"
native="false"
synchronized="false"
@@ -14122,13 +13925,13 @@
</parameter>
<parameter name="password" type="java.lang.String">
</parameter>
-<parameter name="callback" type="android.accounts.Future1Callback<java.lang.Boolean>">
+<parameter name="callback" type="android.accounts.AccountManagerCallback<java.lang.Boolean>">
</parameter>
<parameter name="handler" type="android.os.Handler">
</parameter>
</method>
<method name="editProperties"
- return="android.accounts.Future2"
+ return="android.accounts.AccountManagerFuture<android.os.Bundle>"
abstract="false"
native="false"
synchronized="false"
@@ -14141,7 +13944,7 @@
</parameter>
<parameter name="activity" type="android.app.Activity">
</parameter>
-<parameter name="callback" type="android.accounts.Future2Callback">
+<parameter name="callback" type="android.accounts.AccountManagerCallback<android.os.Bundle>">
</parameter>
<parameter name="handler" type="android.os.Handler">
</parameter>
@@ -14160,7 +13963,7 @@
</parameter>
</method>
<method name="getAccounts"
- return="android.accounts.Future1<android.accounts.Account[]>"
+ return="android.accounts.Account[]"
abstract="false"
native="false"
synchronized="false"
@@ -14169,13 +13972,9 @@
deprecated="not deprecated"
visibility="public"
>
-<parameter name="callback" type="android.accounts.Future1Callback<android.accounts.Account[]>">
-</parameter>
-<parameter name="handler" type="android.os.Handler">
-</parameter>
</method>
<method name="getAccountsByType"
- return="android.accounts.Future1<android.accounts.Account[]>"
+ return="android.accounts.Account[]"
abstract="false"
native="false"
synchronized="false"
@@ -14184,15 +13983,11 @@
deprecated="not deprecated"
visibility="public"
>
-<parameter name="callback" type="android.accounts.Future1Callback<android.accounts.Account[]>">
-</parameter>
<parameter name="type" type="java.lang.String">
</parameter>
-<parameter name="handler" type="android.os.Handler">
-</parameter>
</method>
-<method name="getAccountsWithTypeAndFeatures"
- return="android.accounts.Future2"
+<method name="getAccountsByTypeAndFeatures"
+ return="android.accounts.AccountManagerFuture<android.accounts.Account[]>"
abstract="false"
native="false"
synchronized="false"
@@ -14205,13 +14000,13 @@
</parameter>
<parameter name="features" type="java.lang.String[]">
</parameter>
-<parameter name="callback" type="android.accounts.Future2Callback">
+<parameter name="callback" type="android.accounts.AccountManagerCallback<android.accounts.Account[]>">
</parameter>
<parameter name="handler" type="android.os.Handler">
</parameter>
</method>
<method name="getAuthToken"
- return="android.accounts.Future2"
+ return="android.accounts.AccountManagerFuture<android.os.Bundle>"
abstract="false"
native="false"
synchronized="false"
@@ -14228,13 +14023,13 @@
</parameter>
<parameter name="activity" type="android.app.Activity">
</parameter>
-<parameter name="callback" type="android.accounts.Future2Callback">
+<parameter name="callback" type="android.accounts.AccountManagerCallback<android.os.Bundle>">
</parameter>
<parameter name="handler" type="android.os.Handler">
</parameter>
</method>
<method name="getAuthToken"
- return="android.accounts.Future2"
+ return="android.accounts.AccountManagerFuture<android.os.Bundle>"
abstract="false"
native="false"
synchronized="false"
@@ -14249,7 +14044,7 @@
</parameter>
<parameter name="notifyAuthFailure" type="boolean">
</parameter>
-<parameter name="callback" type="android.accounts.Future2Callback">
+<parameter name="callback" type="android.accounts.AccountManagerCallback<android.os.Bundle>">
</parameter>
<parameter name="handler" type="android.os.Handler">
</parameter>
@@ -14276,13 +14071,13 @@
</parameter>
<parameter name="loginOptions" type="android.os.Bundle">
</parameter>
-<parameter name="callback" type="android.accounts.Future2Callback">
+<parameter name="callback" type="android.accounts.AccountManagerCallback<android.os.Bundle>">
</parameter>
<parameter name="handler" type="android.os.Handler">
</parameter>
</method>
<method name="getAuthenticatorTypes"
- return="android.accounts.Future1<android.accounts.AuthenticatorDescription[]>"
+ return="android.accounts.AuthenticatorDescription[]"
abstract="false"
native="false"
synchronized="false"
@@ -14291,13 +14086,9 @@
deprecated="not deprecated"
visibility="public"
>
-<parameter name="callback" type="android.accounts.Future1Callback<android.accounts.AuthenticatorDescription[]>">
-</parameter>
-<parameter name="handler" type="android.os.Handler">
-</parameter>
</method>
<method name="getPassword"
- return="android.accounts.Future1<java.lang.String>"
+ return="java.lang.String"
abstract="false"
native="false"
synchronized="false"
@@ -14306,15 +14097,11 @@
deprecated="not deprecated"
visibility="public"
>
-<parameter name="callback" type="android.accounts.Future1Callback<java.lang.String>">
-</parameter>
<parameter name="account" type="android.accounts.Account">
</parameter>
-<parameter name="handler" type="android.os.Handler">
-</parameter>
</method>
<method name="getUserData"
- return="android.accounts.Future1<java.lang.String>"
+ return="java.lang.String"
abstract="false"
native="false"
synchronized="false"
@@ -14323,17 +14110,13 @@
deprecated="not deprecated"
visibility="public"
>
-<parameter name="callback" type="android.accounts.Future1Callback<java.lang.String>">
-</parameter>
<parameter name="account" type="android.accounts.Account">
</parameter>
<parameter name="key" type="java.lang.String">
</parameter>
-<parameter name="handler" type="android.os.Handler">
-</parameter>
</method>
<method name="invalidateAuthToken"
- return="android.accounts.Future1<java.lang.Void>"
+ return="void"
abstract="false"
native="false"
synchronized="false"
@@ -14342,17 +14125,13 @@
deprecated="not deprecated"
visibility="public"
>
-<parameter name="callback" type="android.accounts.Future1Callback<java.lang.Void>">
-</parameter>
<parameter name="accountType" type="java.lang.String">
</parameter>
<parameter name="authToken" type="java.lang.String">
</parameter>
-<parameter name="handler" type="android.os.Handler">
-</parameter>
</method>
<method name="peekAuthToken"
- return="android.accounts.Future1<java.lang.String>"
+ return="java.lang.String"
abstract="false"
native="false"
synchronized="false"
@@ -14361,17 +14140,13 @@
deprecated="not deprecated"
visibility="public"
>
-<parameter name="callback" type="android.accounts.Future1Callback<java.lang.String>">
-</parameter>
<parameter name="account" type="android.accounts.Account">
</parameter>
<parameter name="authTokenType" type="java.lang.String">
</parameter>
-<parameter name="handler" type="android.os.Handler">
-</parameter>
</method>
<method name="removeAccount"
- return="android.accounts.Future1<java.lang.Void>"
+ return="android.accounts.AccountManagerFuture<java.lang.Boolean>"
abstract="false"
native="false"
synchronized="false"
@@ -14380,10 +14155,10 @@
deprecated="not deprecated"
visibility="public"
>
-<parameter name="callback" type="android.accounts.Future1Callback<java.lang.Void>">
-</parameter>
<parameter name="account" type="android.accounts.Account">
</parameter>
+<parameter name="callback" type="android.accounts.AccountManagerCallback<java.lang.Boolean>">
+</parameter>
<parameter name="handler" type="android.os.Handler">
</parameter>
</method>
@@ -14401,7 +14176,7 @@
</parameter>
</method>
<method name="setAuthToken"
- return="android.accounts.Future1<java.lang.Void>"
+ return="void"
abstract="false"
native="false"
synchronized="false"
@@ -14410,19 +14185,15 @@
deprecated="not deprecated"
visibility="public"
>
-<parameter name="callback" type="android.accounts.Future1Callback<java.lang.Void>">
-</parameter>
<parameter name="account" type="android.accounts.Account">
</parameter>
<parameter name="authTokenType" type="java.lang.String">
</parameter>
<parameter name="authToken" type="java.lang.String">
</parameter>
-<parameter name="handler" type="android.os.Handler">
-</parameter>
</method>
<method name="setPassword"
- return="android.accounts.Future1<java.lang.Void>"
+ return="void"
abstract="false"
native="false"
synchronized="false"
@@ -14431,17 +14202,13 @@
deprecated="not deprecated"
visibility="public"
>
-<parameter name="callback" type="android.accounts.Future1Callback<java.lang.Void>">
-</parameter>
<parameter name="account" type="android.accounts.Account">
</parameter>
<parameter name="password" type="java.lang.String">
</parameter>
-<parameter name="handler" type="android.os.Handler">
-</parameter>
</method>
<method name="setUserData"
- return="android.accounts.Future1<java.lang.Void>"
+ return="void"
abstract="false"
native="false"
synchronized="false"
@@ -14450,19 +14217,15 @@
deprecated="not deprecated"
visibility="public"
>
-<parameter name="callback" type="android.accounts.Future1Callback<java.lang.Void>">
-</parameter>
<parameter name="account" type="android.accounts.Account">
</parameter>
<parameter name="key" type="java.lang.String">
</parameter>
<parameter name="value" type="java.lang.String">
</parameter>
-<parameter name="handler" type="android.os.Handler">
-</parameter>
</method>
<method name="updateCredentials"
- return="android.accounts.Future2"
+ return="android.accounts.AccountManagerFuture<android.os.Bundle>"
abstract="false"
native="false"
synchronized="false"
@@ -14479,12 +14242,117 @@
</parameter>
<parameter name="activity" type="android.app.Activity">
</parameter>
-<parameter name="callback" type="android.accounts.Future2Callback">
+<parameter name="callback" type="android.accounts.AccountManagerCallback<android.os.Bundle>">
</parameter>
<parameter name="handler" type="android.os.Handler">
</parameter>
</method>
</class>
+<interface name="AccountManagerCallback"
+ abstract="true"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<method name="run"
+ return="void"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="future" type="android.accounts.AccountManagerFuture<V>">
+</parameter>
+</method>
+</interface>
+<interface name="AccountManagerFuture"
+ abstract="true"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<implements name="java.util.concurrent.Future">
+</implements>
+<method name="get"
+ return="V"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="deprecated"
+ visibility="public"
+>
+<exception name="ExecutionException" type="java.util.concurrent.ExecutionException">
+</exception>
+<exception name="InterruptedException" type="java.lang.InterruptedException">
+</exception>
+</method>
+<method name="get"
+ return="V"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="deprecated"
+ visibility="public"
+>
+<parameter name="timeout" type="long">
+</parameter>
+<parameter name="unit" type="java.util.concurrent.TimeUnit">
+</parameter>
+<exception name="ExecutionException" type="java.util.concurrent.ExecutionException">
+</exception>
+<exception name="InterruptedException" type="java.lang.InterruptedException">
+</exception>
+<exception name="TimeoutException" type="java.util.concurrent.TimeoutException">
+</exception>
+</method>
+<method name="getResult"
+ return="V"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<exception name="AuthenticatorException" type="android.accounts.AuthenticatorException">
+</exception>
+<exception name="IOException" type="java.io.IOException">
+</exception>
+<exception name="OperationCanceledException" type="android.accounts.OperationCanceledException">
+</exception>
+</method>
+<method name="getResult"
+ return="V"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="timeout" type="long">
+</parameter>
+<parameter name="unit" type="java.util.concurrent.TimeUnit">
+</parameter>
+<exception name="AuthenticatorException" type="android.accounts.AuthenticatorException">
+</exception>
+<exception name="IOException" type="java.io.IOException">
+</exception>
+<exception name="OperationCanceledException" type="android.accounts.OperationCanceledException">
+</exception>
+</method>
+</interface>
<class name="AuthenticatorDescription"
extends="java.lang.Object"
abstract="false"
@@ -14952,6 +14820,17 @@
visibility="public"
>
</field>
+<field name="PASSWORD_KEY"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""password""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="USERDATA_KEY"
type="java.lang.String"
transient="false"
@@ -14964,136 +14843,6 @@
>
</field>
</class>
-<interface name="Future1"
- abstract="true"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<implements name="java.util.concurrent.Future">
-</implements>
-<method name="getResult"
- return="V"
- abstract="true"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<exception name="OperationCanceledException" type="android.accounts.OperationCanceledException">
-</exception>
-</method>
-<method name="getResult"
- return="V"
- abstract="true"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="timeout" type="long">
-</parameter>
-<parameter name="unit" type="java.util.concurrent.TimeUnit">
-</parameter>
-<exception name="OperationCanceledException" type="android.accounts.OperationCanceledException">
-</exception>
-</method>
-</interface>
-<interface name="Future1Callback"
- abstract="true"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<method name="run"
- return="void"
- abstract="true"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="future" type="android.accounts.Future1<V>">
-</parameter>
-</method>
-</interface>
-<interface name="Future2"
- abstract="true"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<implements name="java.util.concurrent.Future">
-</implements>
-<method name="getResult"
- return="android.os.Bundle"
- abstract="true"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<exception name="AuthenticatorException" type="android.accounts.AuthenticatorException">
-</exception>
-<exception name="IOException" type="java.io.IOException">
-</exception>
-<exception name="OperationCanceledException" type="android.accounts.OperationCanceledException">
-</exception>
-</method>
-<method name="getResult"
- return="android.os.Bundle"
- abstract="true"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="timeout" type="long">
-</parameter>
-<parameter name="unit" type="java.util.concurrent.TimeUnit">
-</parameter>
-<exception name="AuthenticatorException" type="android.accounts.AuthenticatorException">
-</exception>
-<exception name="IOException" type="java.io.IOException">
-</exception>
-<exception name="OperationCanceledException" type="android.accounts.OperationCanceledException">
-</exception>
-</method>
-</interface>
-<interface name="Future2Callback"
- abstract="true"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<method name="run"
- return="void"
- abstract="true"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="future" type="android.accounts.Future2">
-</parameter>
-</method>
-</interface>
<interface name="IAccountAuthenticator"
abstract="true"
static="false"
@@ -15179,6 +14928,23 @@
<exception name="RemoteException" type="android.os.RemoteException">
</exception>
</method>
+<method name="getAccountRemovalAllowed"
+ return="void"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="response" type="android.accounts.IAccountAuthenticatorResponse">
+</parameter>
+<parameter name="account" type="android.accounts.Account">
+</parameter>
+<exception name="RemoteException" type="android.os.RemoteException">
+</exception>
+</method>
<method name="getAuthToken"
return="void"
abstract="true"
diff --git a/core/java/android/accounts/AbstractAccountAuthenticator.java b/core/java/android/accounts/AbstractAccountAuthenticator.java
index 3ce3ca3..38ae962 100644
--- a/core/java/android/accounts/AbstractAccountAuthenticator.java
+++ b/core/java/android/accounts/AbstractAccountAuthenticator.java
@@ -188,6 +188,25 @@
response.onResult(result);
}
}
+
+ public void getAccountRemovalAllowed(IAccountAuthenticatorResponse response,
+ Account account) throws RemoteException {
+ checkBinderPermission();
+ try {
+ final Bundle result = AbstractAccountAuthenticator.this.getAccountRemovalAllowed(
+ new AccountAuthenticatorResponse(response), account);
+ if (result != null) {
+ response.onResult(result);
+ }
+ } catch (UnsupportedOperationException e) {
+ response.onError(Constants.ERROR_CODE_UNSUPPORTED_OPERATION,
+ "getAccountRemovalAllowed not supported");
+ return;
+ } catch (NetworkErrorException e) {
+ response.onError(Constants.ERROR_CODE_NETWORK_ERROR, e.getMessage());
+ return;
+ }
+ }
}
private void checkBinderPermission() {
@@ -238,4 +257,10 @@
Account account, String authTokenType, Bundle loginOptions);
public abstract Bundle hasFeatures(AccountAuthenticatorResponse response,
Account account, String[] features) throws NetworkErrorException;
+ public Bundle getAccountRemovalAllowed(AccountAuthenticatorResponse response,
+ Account account) throws NetworkErrorException {
+ final Bundle result = new Bundle();
+ result.putBoolean(Constants.BOOLEAN_RESULT_KEY, true);
+ return result;
+ }
}
diff --git a/core/java/android/accounts/Account.java b/core/java/android/accounts/Account.java
index 30c91b0..7b83a30 100644
--- a/core/java/android/accounts/Account.java
+++ b/core/java/android/accounts/Account.java
@@ -26,20 +26,20 @@
* suitable for use as the key of a {@link java.util.Map}
*/
public class Account implements Parcelable {
- public final String mName;
- public final String mType;
+ public final String name;
+ public final String type;
public boolean equals(Object o) {
if (o == this) return true;
if (!(o instanceof Account)) return false;
final Account other = (Account)o;
- return mName.equals(other.mName) && mType.equals(other.mType);
+ return name.equals(other.name) && type.equals(other.type);
}
public int hashCode() {
int result = 17;
- result = 31 * result + mName.hashCode();
- result = 31 * result + mType.hashCode();
+ result = 31 * result + name.hashCode();
+ result = 31 * result + type.hashCode();
return result;
}
@@ -50,13 +50,13 @@
if (TextUtils.isEmpty(type)) {
throw new IllegalArgumentException("the type must not be empty: " + type);
}
- mName = name;
- mType = type;
+ this.name = name;
+ this.type = type;
}
public Account(Parcel in) {
- mName = in.readString();
- mType = in.readString();
+ this.name = in.readString();
+ this.type = in.readString();
}
public int describeContents() {
@@ -64,8 +64,8 @@
}
public void writeToParcel(Parcel dest, int flags) {
- dest.writeString(mName);
- dest.writeString(mType);
+ dest.writeString(name);
+ dest.writeString(type);
}
public static final Creator<Account> CREATOR = new Creator<Account>() {
@@ -79,6 +79,6 @@
};
public String toString() {
- return "Account {name=" + mName + ", type=" + mType + "}";
+ return "Account {name=" + name + ", type=" + type + "}";
}
}
diff --git a/core/java/android/accounts/AccountManager.java b/core/java/android/accounts/AccountManager.java
index 502abbb..9f70534 100644
--- a/core/java/android/accounts/AccountManager.java
+++ b/core/java/android/accounts/AccountManager.java
@@ -26,8 +26,6 @@
import android.os.Looper;
import android.os.RemoteException;
import android.os.Parcelable;
-import android.util.Config;
-import android.util.Log;
import java.io.IOException;
import java.util.concurrent.Callable;
@@ -80,258 +78,132 @@
return (AccountManager) context.getSystemService(Context.ACCOUNT_SERVICE);
}
- public String blockingGetPassword(Account account) {
- ensureNotOnMainThread();
+ public String getPassword(final Account account) {
try {
return mService.getPassword(account);
} catch (RemoteException e) {
- // if this happens the entire runtime will restart
+ // will never happen
throw new RuntimeException(e);
}
}
- public Future1<String> getPassword(final Future1Callback<String> callback,
- final Account account, final Handler handler) {
- return startAsFuture(callback, handler, new Callable<String>() {
- public String call() throws Exception {
- return blockingGetPassword(account);
- }
- });
- }
-
- public String blockingGetUserData(Account account, String key) {
- ensureNotOnMainThread();
+ public String getUserData(final Account account, final String key) {
try {
return mService.getUserData(account, key);
} catch (RemoteException e) {
- // if this happens the entire runtime will restart
+ // will never happen
throw new RuntimeException(e);
}
}
- public Future1<String> getUserData(Future1Callback<String> callback,
- final Account account, final String key, Handler handler) {
- return startAsFuture(callback, handler, new Callable<String>() {
- public String call() throws Exception {
- return blockingGetUserData(account, key);
- }
- });
- }
-
- public AuthenticatorDescription[] blockingGetAuthenticatorTypes() {
- ensureNotOnMainThread();
+ public AuthenticatorDescription[] getAuthenticatorTypes() {
try {
return mService.getAuthenticatorTypes();
} catch (RemoteException e) {
- // if this happens the entire runtime will restart
+ // will never happen
throw new RuntimeException(e);
}
}
- public Future1<AuthenticatorDescription[]> getAuthenticatorTypes(
- Future1Callback<AuthenticatorDescription[]> callback, Handler handler) {
- return startAsFuture(callback, handler, new Callable<AuthenticatorDescription[]>() {
- public AuthenticatorDescription[] call() throws Exception {
- return blockingGetAuthenticatorTypes();
- }
- });
- }
-
- public Account[] blockingGetAccounts() {
- ensureNotOnMainThread();
+ public Account[] getAccounts() {
try {
- return mService.getAccounts();
+ return mService.getAccounts(null);
} catch (RemoteException e) {
- // if this happens the entire runtime will restart
+ // won't ever happen
throw new RuntimeException(e);
}
}
- public Account[] blockingGetAccountsByType(String accountType) {
- ensureNotOnMainThread();
+ public Account[] getAccountsByType(String type) {
try {
- return mService.getAccountsByType(accountType);
+ return mService.getAccounts(type);
} catch (RemoteException e) {
- // if this happens the entire runtime will restart
+ // won't ever happen
throw new RuntimeException(e);
}
}
- public Future1<Account[]> getAccounts(Future1Callback<Account[]> callback, Handler handler) {
- return startAsFuture(callback, handler, new Callable<Account[]>() {
- public Account[] call() throws Exception {
- return blockingGetAccounts();
- }
- });
- }
-
- public Future1<Account[]> getAccountsByType(Future1Callback<Account[]> callback,
- final String type, Handler handler) {
- return startAsFuture(callback, handler, new Callable<Account[]>() {
- public Account[] call() throws Exception {
- return blockingGetAccountsByType(type);
- }
- });
- }
-
- public boolean blockingAddAccountExplicitly(Account account, String password, Bundle extras) {
- ensureNotOnMainThread();
+ public boolean addAccountExplicitly(Account account, String password, Bundle extras) {
try {
return mService.addAccount(account, password, extras);
} catch (RemoteException e) {
- // if this happens the entire runtime will restart
+ // won't ever happen
throw new RuntimeException(e);
}
}
- public Future1<Boolean> addAccountExplicitly(final Future1Callback<Boolean> callback,
- final Account account, final String password, final Bundle extras,
- final Handler handler) {
- return startAsFuture(callback, handler, new Callable<Boolean>() {
- public Boolean call() throws Exception {
- return blockingAddAccountExplicitly(account, password, extras);
+ public AccountManagerFuture<Boolean> removeAccount(final Account account,
+ AccountManagerCallback<Boolean> callback, Handler handler) {
+ return new Future2Task<Boolean>(handler, callback) {
+ public void doWork() throws RemoteException {
+ mService.removeAccount(mResponse, account);
}
- });
- }
-
- public void blockingRemoveAccount(Account account) {
- ensureNotOnMainThread();
- try {
- mService.removeAccount(account);
- } catch (RemoteException e) {
- // if this happens the entire runtime will restart
- }
- }
-
- public Future1<Void> removeAccount(Future1Callback<Void> callback, final Account account,
- final Handler handler) {
- return startAsFuture(callback, handler, new Callable<Void>() {
- public Void call() throws Exception {
- blockingRemoveAccount(account);
- return null;
+ public Boolean bundleToResult(Bundle bundle) throws AuthenticatorException {
+ if (!bundle.containsKey(Constants.BOOLEAN_RESULT_KEY)) {
+ throw new AuthenticatorException("no result in response");
+ }
+ return bundle.getBoolean(Constants.BOOLEAN_RESULT_KEY);
}
- });
+ }.start();
}
- public void blockingInvalidateAuthToken(String accountType, String authToken) {
- ensureNotOnMainThread();
+ public void invalidateAuthToken(final String accountType, final String authToken) {
try {
mService.invalidateAuthToken(accountType, authToken);
} catch (RemoteException e) {
- // if this happens the entire runtime will restart
- }
- }
-
- public Future1<Void> invalidateAuthToken(Future1Callback<Void> callback,
- final String accountType, final String authToken, final Handler handler) {
- return startAsFuture(callback, handler, new Callable<Void>() {
- public Void call() throws Exception {
- blockingInvalidateAuthToken(accountType, authToken);
- return null;
- }
- });
- }
-
- public String blockingPeekAuthToken(Account account, String authTokenType) {
- ensureNotOnMainThread();
- try {
- return mService.peekAuthToken(account, authTokenType);
- } catch (RemoteException e) {
- // if this happens the entire runtime will restart
+ // won't ever happen
throw new RuntimeException(e);
}
}
- public Future1<String> peekAuthToken(Future1Callback<String> callback,
- final Account account, final String authTokenType, final Handler handler) {
- return startAsFuture(callback, handler, new Callable<String>() {
- public String call() throws Exception {
- return blockingPeekAuthToken(account, authTokenType);
- }
- });
+ public String peekAuthToken(final Account account, final String authTokenType) {
+ try {
+ return mService.peekAuthToken(account, authTokenType);
+ } catch (RemoteException e) {
+ // won't ever happen
+ throw new RuntimeException(e);
+ }
}
- public void blockingSetPassword(Account account, String password) {
- ensureNotOnMainThread();
+ public void setPassword(final Account account, final String password) {
try {
mService.setPassword(account, password);
} catch (RemoteException e) {
- // if this happens the entire runtime will restart
+ // won't ever happen
+ throw new RuntimeException(e);
}
}
- public Future1<Void> setPassword(Future1Callback<Void> callback,
- final Account account, final String password, final Handler handler) {
- return startAsFuture(callback, handler, new Callable<Void>() {
- public Void call() throws Exception {
- blockingSetPassword(account, password);
- return null;
- }
- });
- }
-
- public void blockingClearPassword(Account account) {
- ensureNotOnMainThread();
+ public void clearPassword(final Account account) {
try {
mService.clearPassword(account);
} catch (RemoteException e) {
- // if this happens the entire runtime will restart
+ // won't ever happen
+ throw new RuntimeException(e);
}
}
- public Future1<Void> clearPassword(final Future1Callback<Void> callback, final Account account,
- final Handler handler) {
- return startAsFuture(callback, handler, new Callable<Void>() {
- public Void call() throws Exception {
- blockingClearPassword(account);
- return null;
- }
- });
- }
-
- public void blockingSetUserData(Account account, String key, String value) {
- ensureNotOnMainThread();
+ public void setUserData(final Account account, final String key, final String value) {
try {
mService.setUserData(account, key, value);
} catch (RemoteException e) {
- // if this happens the entire runtime will restart
+ // won't ever happen
+ throw new RuntimeException(e);
}
}
- public Future1<Void> setUserData(Future1Callback<Void> callback,
- final Account account, final String key, final String value, final Handler handler) {
- return startAsFuture(callback, handler, new Callable<Void>() {
- public Void call() throws Exception {
- blockingSetUserData(account, key, value);
- return null;
- }
- });
- }
-
- public void blockingSetAuthToken(Account account, String authTokenType, String authToken) {
- ensureNotOnMainThread();
+ public void setAuthToken(Account account, final String authTokenType, final String authToken) {
try {
mService.setAuthToken(account, authTokenType, authToken);
} catch (RemoteException e) {
- // if this happens the entire runtime will restart
+ // won't ever happen
+ throw new RuntimeException(e);
}
}
- public Future1<Void> setAuthToken(Future1Callback<Void> callback,
- final Account account, final String authTokenType, final String authToken,
- final Handler handler) {
- return startAsFuture(callback, handler, new Callable<Void>() {
- public Void call() throws Exception {
- blockingSetAuthToken(account, authTokenType, authToken);
- return null;
- }
- });
- }
-
public String blockingGetAuthToken(Account account, String authTokenType,
boolean notifyAuthFailure)
throws OperationCanceledException, IOException, AuthenticatorException {
- ensureNotOnMainThread();
Bundle bundle = getAuthToken(account, authTokenType, notifyAuthFailure, null /* callback */,
null /* handler */).getResult();
return bundle.getString(Constants.AUTHTOKEN_KEY);
@@ -349,9 +221,9 @@
* @param loginOptions
* @param activity the activity to launch the login intent, if necessary, and to which
*/
- public Future2 getAuthToken(
+ public AccountManagerFuture<Bundle> getAuthToken(
final Account account, final String authTokenType, final Bundle loginOptions,
- final Activity activity, Future2Callback callback, Handler handler) {
+ final Activity activity, AccountManagerCallback<Bundle> callback, Handler handler) {
if (activity == null) throw new IllegalArgumentException("activity is null");
if (authTokenType == null) throw new IllegalArgumentException("authTokenType is null");
return new AmsTask(activity, handler, callback) {
@@ -363,9 +235,9 @@
}.start();
}
- public Future2 getAuthToken(
+ public AccountManagerFuture<Bundle> getAuthToken(
final Account account, final String authTokenType, final boolean notifyAuthFailure,
- Future2Callback callback, Handler handler) {
+ AccountManagerCallback<Bundle> callback, Handler handler) {
if (account == null) throw new IllegalArgumentException("account is null");
if (authTokenType == null) throw new IllegalArgumentException("authTokenType is null");
return new AmsTask(null, handler, callback) {
@@ -376,10 +248,10 @@
}.start();
}
- public Future2 addAccount(final String accountType,
+ public AccountManagerFuture<Bundle> addAccount(final String accountType,
final String authTokenType, final String[] requiredFeatures,
final Bundle addAccountOptions,
- final Activity activity, Future2Callback callback, Handler handler) {
+ final Activity activity, AccountManagerCallback<Bundle> callback, Handler handler) {
return new AmsTask(activity, handler, callback) {
public void doWork() throws RemoteException {
mService.addAcount(mResponse, accountType, authTokenType,
@@ -389,44 +261,45 @@
}
/** @deprecated use {@link #confirmCredentials} instead */
- public Future1<Boolean> confirmPassword(final Account account, final String password,
- Future1Callback<Boolean> callback, Handler handler) {
- return new AMSTaskBoolean(handler, callback) {
+ public AccountManagerFuture<Boolean> confirmPassword(final Account account, final String password,
+ AccountManagerCallback<Boolean> callback, Handler handler) {
+ return new Future2Task<Boolean>(handler, callback) {
public void doWork() throws RemoteException {
- mService.confirmPassword(response, account, password);
+ mService.confirmPassword(mResponse, account, password);
}
- };
- }
-
- public Account[] blockingGetAccountsWithTypeAndFeatures(String type, String[] features)
- throws AuthenticatorException, IOException, OperationCanceledException {
- Future2 future = getAccountsWithTypeAndFeatures(type, features,
- null /* callback */, null /* handler */);
- Bundle result = future.getResult();
- Parcelable[] accountsTemp = result.getParcelableArray(Constants.ACCOUNTS_KEY);
- if (accountsTemp == null) {
- throw new AuthenticatorException("accounts should not be null");
- }
- Account[] accounts = new Account[accountsTemp.length];
- for (int i = 0; i < accountsTemp.length; i++) {
- accounts[i] = (Account) accountsTemp[i];
- }
- return accounts;
- }
-
- public Future2 getAccountsWithTypeAndFeatures(
- final String type, final String[] features,
- Future2Callback callback, Handler handler) {
- if (type == null) throw new IllegalArgumentException("type is null");
- return new AmsTask(null /* activity */, handler, callback) {
- public void doWork() throws RemoteException {
- mService.getAccountsByTypeAndFeatures(mResponse, type, features);
+ public Boolean bundleToResult(Bundle bundle) throws AuthenticatorException {
+ if (!bundle.containsKey(Constants.BOOLEAN_RESULT_KEY)) {
+ throw new AuthenticatorException("no result in response");
+ }
+ return bundle.getBoolean(Constants.BOOLEAN_RESULT_KEY);
}
}.start();
}
- public Future2 confirmCredentials(final Account account, final Activity activity,
- final Future2Callback callback,
+ 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 {
+ mService.getAccountsByFeatures(mResponse, type, features);
+ }
+ public Account[] bundleToResult(Bundle bundle) throws AuthenticatorException {
+ if (!bundle.containsKey(Constants.ACCOUNTS_KEY)) {
+ throw new AuthenticatorException("no result in response");
+ }
+ final Parcelable[] parcelables = bundle.getParcelableArray(Constants.ACCOUNTS_KEY);
+ Account[] descs = new Account[parcelables.length];
+ for (int i = 0; i < parcelables.length; i++) {
+ descs[i] = (Account) parcelables[i];
+ }
+ return descs;
+ }
+ }.start();
+ }
+
+ public AccountManagerFuture<Bundle> confirmCredentials(final Account account, final Activity activity,
+ final AccountManagerCallback<Bundle> callback,
final Handler handler) {
return new AmsTask(activity, handler, callback) {
public void doWork() throws RemoteException {
@@ -435,9 +308,9 @@
}.start();
}
- public Future2 updateCredentials(final Account account, final String authTokenType,
+ public AccountManagerFuture<Bundle> updateCredentials(final Account account, final String authTokenType,
final Bundle loginOptions, final Activity activity,
- final Future2Callback callback,
+ final AccountManagerCallback<Bundle> callback,
final Handler handler) {
return new AmsTask(activity, handler, callback) {
public void doWork() throws RemoteException {
@@ -447,8 +320,8 @@
}.start();
}
- public Future2 editProperties(final String accountType, final Activity activity,
- final Future2Callback callback,
+ public AccountManagerFuture<Bundle> editProperties(final String accountType, final Activity activity,
+ final AccountManagerCallback<Bundle> callback,
final Handler handler) {
return new AmsTask(activity, handler, callback) {
public void doWork() throws RemoteException {
@@ -471,8 +344,8 @@
}
}
- private void postToHandler(Handler handler, final Future2Callback callback,
- final Future2 future) {
+ private void postToHandler(Handler handler, final AccountManagerCallback<Bundle> callback,
+ final AccountManagerFuture<Bundle> future) {
handler = handler == null ? mMainHandler : handler;
handler.post(new Runnable() {
public void run() {
@@ -483,87 +356,24 @@
private void postToHandler(Handler handler, final OnAccountsUpdatedListener listener,
final Account[] accounts) {
- handler = handler == null ? mMainHandler : handler;
+ final Account[] accountsCopy = new Account[accounts.length];
+ // send a copy to make sure that one doesn't
+ // change what another sees
+ System.arraycopy(accounts, 0, accountsCopy, 0, accountsCopy.length);
+ handler = (handler == null) ? mMainHandler : handler;
handler.post(new Runnable() {
public void run() {
- listener.onAccountsUpdated(accounts);
+ listener.onAccountsUpdated(accountsCopy);
}
});
}
- private <V> void postToHandler(Handler handler, final Future1Callback<V> callback,
- final Future1<V> future) {
- handler = handler == null ? mMainHandler : handler;
- handler.post(new Runnable() {
- public void run() {
- callback.run(future);
- }
- });
- }
-
- private <V> Future1<V> startAsFuture(Future1Callback<V> callback, Handler handler,
- Callable<V> callable) {
- final FutureTaskWithCallback<V> task =
- new FutureTaskWithCallback<V>(callback, callable, handler);
- new Thread(task).start();
- return task;
- }
-
- private class FutureTaskWithCallback<V> extends FutureTask<V> implements Future1<V> {
- final Future1Callback<V> mCallback;
- final Handler mHandler;
-
- public FutureTaskWithCallback(Future1Callback<V> callback, Callable<V> callable,
- Handler handler) {
- super(callable);
- mCallback = callback;
- mHandler = handler;
- }
-
- protected void done() {
- if (mCallback != null) {
- postToHandler(mHandler, mCallback, this);
- }
- }
-
- public V internalGetResult(Long timeout, TimeUnit unit) throws OperationCanceledException {
- try {
- if (timeout == null) {
- return get();
- } else {
- return get(timeout, unit);
- }
- } catch (InterruptedException e) {
- // we will cancel the task below
- } catch (CancellationException e) {
- // we will cancel the task below
- } catch (TimeoutException e) {
- // we will cancel the task below
- } catch (ExecutionException e) {
- // this should never happen
- throw new IllegalStateException(e.getCause());
- } finally {
- cancel(true /* interruptIfRunning */);
- }
- throw new OperationCanceledException();
- }
-
- public V getResult() throws OperationCanceledException {
- return internalGetResult(null, null);
- }
-
- public V getResult(long timeout, TimeUnit unit) throws OperationCanceledException {
- return internalGetResult(null, null);
- }
- }
-
- private abstract class AmsTask extends FutureTask<Bundle> implements Future2 {
+ private abstract class AmsTask extends FutureTask<Bundle> implements AccountManagerFuture<Bundle> {
final IAccountManagerResponse mResponse;
final Handler mHandler;
- final Future2Callback mCallback;
+ final AccountManagerCallback<Bundle> mCallback;
final Activity mActivity;
- final Thread mThread;
- public AmsTask(Activity activity, Handler handler, Future2Callback callback) {
+ public AmsTask(Activity activity, Handler handler, AccountManagerCallback<Bundle> callback) {
super(new Callable<Bundle>() {
public Bundle call() throws Exception {
throw new IllegalStateException("this should never be called");
@@ -574,19 +384,14 @@
mCallback = callback;
mActivity = activity;
mResponse = new Response();
- mThread = new Thread(new Runnable() {
- public void run() {
- try {
- doWork();
- } catch (RemoteException e) {
- // never happens
- }
- }
- }, "AmsTask");
}
- public final Future2 start() {
- mThread.start();
+ public final AccountManagerFuture<Bundle> start() {
+ try {
+ doWork();
+ } catch (RemoteException e) {
+ setException(e);
+ }
return this;
}
@@ -594,6 +399,7 @@
private Bundle internalGetResult(Long timeout, TimeUnit unit)
throws OperationCanceledException, IOException, AuthenticatorException {
+ ensureNotOnMainThread();
try {
if (timeout == null) {
return get();
@@ -676,92 +482,50 @@
}
- private abstract class AMSTaskBoolean extends FutureTask<Boolean> implements Future1<Boolean> {
- final IAccountManagerResponse response;
+ private abstract class BaseFutureTask<T> extends FutureTask<T> {
+ final public IAccountManagerResponse mResponse;
final Handler mHandler;
- final Future1Callback<Boolean> mCallback;
- public AMSTaskBoolean(Handler handler, Future1Callback<Boolean> callback) {
- super(new Callable<Boolean>() {
- public Boolean call() throws Exception {
+
+ public BaseFutureTask(Handler handler) {
+ super(new Callable<T>() {
+ public T call() throws Exception {
throw new IllegalStateException("this should never be called");
}
});
-
mHandler = handler;
- mCallback = callback;
- response = new Response();
-
- new Thread(new Runnable() {
- public void run() {
- try {
- doWork();
- } catch (RemoteException e) {
- // never happens
- }
- }
- }).start();
+ mResponse = new Response();
}
public abstract void doWork() throws RemoteException;
+ public abstract T bundleToResult(Bundle bundle) throws AuthenticatorException;
- protected void done() {
- if (mCallback != null) {
- postToHandler(mHandler, mCallback, this);
- }
+ protected void postRunnableToHandler(Runnable runnable) {
+ Handler handler = (mHandler == null) ? mMainHandler : mHandler;
+ handler.post(runnable);
}
- private Boolean internalGetResult(Long timeout, TimeUnit unit) {
+ protected void startTask() {
try {
- if (timeout == null) {
- return get();
- } else {
- return get(timeout, unit);
- }
- } catch (InterruptedException e) {
- // fall through and cancel
- } catch (TimeoutException e) {
- // fall through and cancel
- } catch (CancellationException e) {
- return false;
- } catch (ExecutionException e) {
- final Throwable cause = e.getCause();
- if (cause instanceof IOException) {
- return false;
- } else if (cause instanceof UnsupportedOperationException) {
- return false;
- } else if (cause instanceof AuthenticatorException) {
- return false;
- } else if (cause instanceof RuntimeException) {
- throw (RuntimeException) cause;
- } else if (cause instanceof Error) {
- throw (Error) cause;
- } else {
- throw new IllegalStateException(cause);
- }
- } finally {
- cancel(true /* interrupt if running */);
+ doWork();
+ } catch (RemoteException e) {
+ setException(e);
}
- return false;
}
- public Boolean getResult() throws OperationCanceledException {
- return internalGetResult(null, null);
- }
-
- public Boolean getResult(long timeout, TimeUnit unit) throws OperationCanceledException {
- return internalGetResult(timeout, unit);
- }
-
- private class Response extends IAccountManagerResponse.Stub {
+ protected class Response extends IAccountManagerResponse.Stub {
public void onResult(Bundle bundle) {
try {
- if (bundle.containsKey(Constants.BOOLEAN_RESULT_KEY)) {
- set(bundle.getBoolean(Constants.BOOLEAN_RESULT_KEY));
+ T result = bundleToResult(bundle);
+ if (result == null) {
return;
}
+ set(result);
+ return;
} catch (ClassCastException e) {
// we will set the exception below
+ } catch (AuthenticatorException e) {
+ // we will set the exception below
}
onError(Constants.ERROR_CODE_INVALID_RESPONSE, "no result in response");
}
@@ -774,6 +538,76 @@
setException(convertErrorToException(code, message));
}
}
+ }
+
+ private abstract class Future2Task<T>
+ extends BaseFutureTask<T> implements AccountManagerFuture<T> {
+ final AccountManagerCallback<T> mCallback;
+ public Future2Task(Handler handler, AccountManagerCallback<T> callback) {
+ super(handler);
+ mCallback = callback;
+ }
+
+ protected void done() {
+ if (mCallback != null) {
+ postRunnableToHandler(new Runnable() {
+ public void run() {
+ mCallback.run(Future2Task.this);
+ }
+ });
+ }
+ }
+
+ public Future2Task<T> start() {
+ startTask();
+ return this;
+ }
+
+ private T internalGetResult(Long timeout, TimeUnit unit)
+ throws OperationCanceledException, IOException, AuthenticatorException {
+ ensureNotOnMainThread();
+ try {
+ if (timeout == null) {
+ return get();
+ } else {
+ return get(timeout, unit);
+ }
+ } catch (InterruptedException e) {
+ // fall through and cancel
+ } catch (TimeoutException e) {
+ // fall through and cancel
+ } catch (CancellationException e) {
+ // fall through and cancel
+ } catch (ExecutionException e) {
+ final Throwable cause = e.getCause();
+ if (cause instanceof IOException) {
+ throw (IOException) cause;
+ } else if (cause instanceof UnsupportedOperationException) {
+ throw new AuthenticatorException(cause);
+ } else if (cause instanceof AuthenticatorException) {
+ throw (AuthenticatorException) cause;
+ } else if (cause instanceof RuntimeException) {
+ throw (RuntimeException) cause;
+ } else if (cause instanceof Error) {
+ throw (Error) cause;
+ } else {
+ throw new IllegalStateException(cause);
+ }
+ } finally {
+ cancel(true /* interrupt if running */);
+ }
+ throw new OperationCanceledException();
+ }
+
+ public T getResult()
+ throws OperationCanceledException, IOException, AuthenticatorException {
+ return internalGetResult(null, null);
+ }
+
+ public T getResult(long timeout, TimeUnit unit)
+ throws OperationCanceledException, IOException, AuthenticatorException {
+ return internalGetResult(timeout, unit);
+ }
}
@@ -797,11 +631,12 @@
return new AuthenticatorException(message);
}
- private class GetAuthTokenByTypeAndFeaturesTask extends AmsTask implements Future2Callback {
+ private class GetAuthTokenByTypeAndFeaturesTask
+ extends AmsTask implements AccountManagerCallback<Bundle> {
GetAuthTokenByTypeAndFeaturesTask(final String accountType, final String authTokenType,
final String[] features, Activity activityForPrompting,
final Bundle addAccountOptions, final Bundle loginOptions,
- Future2Callback callback, Handler handler) {
+ AccountManagerCallback<Bundle> callback, Handler handler) {
super(activityForPrompting, handler, callback);
if (accountType == null) throw new IllegalArgumentException("account type is null");
mAccountType = accountType;
@@ -811,101 +646,100 @@
mLoginOptions = loginOptions;
mMyCallback = this;
}
- volatile Future2 mFuture = null;
+ volatile AccountManagerFuture<Bundle> mFuture = null;
final String mAccountType;
final String mAuthTokenType;
final String[] mFeatures;
final Bundle mAddAccountOptions;
final Bundle mLoginOptions;
- final Future2Callback mMyCallback;
+ final AccountManagerCallback<Bundle> mMyCallback;
public void doWork() throws RemoteException {
- getAccountsWithTypeAndFeatures(mAccountType, mFeatures, new Future2Callback() {
- public void run(Future2 future) {
- Bundle getAccountsResult;
- try {
- getAccountsResult = future.getResult();
- } catch (OperationCanceledException e) {
- setException(e);
- return;
- } catch (IOException e) {
- setException(e);
- return;
- } catch (AuthenticatorException e) {
- setException(e);
- return;
- }
-
- Parcelable[] accounts =
- getAccountsResult.getParcelableArray(Constants.ACCOUNTS_KEY);
- if (accounts.length == 0) {
- if (mActivity != null) {
- // no accounts, add one now. pretend that the user directly
- // made this request
- mFuture = addAccount(mAccountType, mAuthTokenType, mFeatures,
- mAddAccountOptions, mActivity, mMyCallback, mHandler);
- } else {
- // send result since we can't prompt to add an account
- Bundle result = new Bundle();
- result.putString(Constants.ACCOUNT_NAME_KEY, null);
- result.putString(Constants.ACCOUNT_TYPE_KEY, null);
- result.putString(Constants.AUTHTOKEN_KEY, null);
+ getAccountsByTypeAndFeatures(mAccountType, mFeatures,
+ new AccountManagerCallback<Account[]>() {
+ public void run(AccountManagerFuture<Account[]> future) {
+ Account[] accounts;
try {
- mResponse.onResult(result);
- } catch (RemoteException e) {
- // this will never happen
+ accounts = future.getResult();
+ } catch (OperationCanceledException e) {
+ setException(e);
+ return;
+ } catch (IOException e) {
+ setException(e);
+ return;
+ } catch (AuthenticatorException e) {
+ setException(e);
+ return;
}
- // we are done
- }
- } else if (accounts.length == 1) {
- // have a single account, return an authtoken for it
- if (mActivity == null) {
- mFuture = getAuthToken((Account) accounts[0], mAuthTokenType,
- false /* notifyAuthFailure */, mMyCallback, mHandler);
- } else {
- mFuture = getAuthToken((Account) accounts[0],
- mAuthTokenType, mLoginOptions,
- mActivity, mMyCallback, mHandler);
- }
- } else {
- if (mActivity != null) {
- IAccountManagerResponse chooseResponse =
- new IAccountManagerResponse.Stub() {
- public void onResult(Bundle value) throws RemoteException {
- Account account = new Account(
- value.getString(Constants.ACCOUNT_NAME_KEY),
- value.getString(Constants.ACCOUNT_TYPE_KEY));
- mFuture = getAuthToken(account, mAuthTokenType, mLoginOptions,
+
+ if (accounts.length == 0) {
+ if (mActivity != null) {
+ // no accounts, add one now. pretend that the user directly
+ // made this request
+ mFuture = addAccount(mAccountType, mAuthTokenType, mFeatures,
+ mAddAccountOptions, mActivity, mMyCallback, mHandler);
+ } else {
+ // send result since we can't prompt to add an account
+ Bundle result = new Bundle();
+ result.putString(Constants.ACCOUNT_NAME_KEY, null);
+ result.putString(Constants.ACCOUNT_TYPE_KEY, null);
+ result.putString(Constants.AUTHTOKEN_KEY, null);
+ try {
+ mResponse.onResult(result);
+ } catch (RemoteException e) {
+ // this will never happen
+ }
+ // we are done
+ }
+ } else if (accounts.length == 1) {
+ // have a single account, return an authtoken for it
+ if (mActivity == null) {
+ mFuture = getAuthToken(accounts[0], mAuthTokenType,
+ false /* notifyAuthFailure */, mMyCallback, mHandler);
+ } else {
+ mFuture = getAuthToken(accounts[0],
+ mAuthTokenType, mLoginOptions,
mActivity, mMyCallback, mHandler);
}
+ } else {
+ if (mActivity != null) {
+ IAccountManagerResponse chooseResponse =
+ new IAccountManagerResponse.Stub() {
+ public void onResult(Bundle value) throws RemoteException {
+ Account account = new Account(
+ value.getString(Constants.ACCOUNT_NAME_KEY),
+ value.getString(Constants.ACCOUNT_TYPE_KEY));
+ mFuture = getAuthToken(account, mAuthTokenType, mLoginOptions,
+ mActivity, mMyCallback, mHandler);
+ }
- public void onError(int errorCode, String errorMessage)
- throws RemoteException {
- mResponse.onError(errorCode, errorMessage);
+ public void onError(int errorCode, String errorMessage)
+ throws RemoteException {
+ mResponse.onError(errorCode, errorMessage);
+ }
+ };
+ // have many accounts, launch the chooser
+ Intent intent = new Intent();
+ intent.setClassName("android",
+ "android.accounts.ChooseAccountActivity");
+ intent.putExtra(Constants.ACCOUNTS_KEY, accounts);
+ intent.putExtra(Constants.ACCOUNT_MANAGER_RESPONSE_KEY,
+ new AccountManagerResponse(chooseResponse));
+ mActivity.startActivity(intent);
+ // the result will arrive via the IAccountManagerResponse
+ } else {
+ // send result since we can't prompt to select an account
+ Bundle result = new Bundle();
+ result.putString(Constants.ACCOUNTS_KEY, null);
+ try {
+ mResponse.onResult(result);
+ } catch (RemoteException e) {
+ // this will never happen
+ }
+ // we are done
}
- };
- // have many accounts, launch the chooser
- Intent intent = new Intent();
- intent.setClassName("android",
- "android.accounts.ChooseAccountActivity");
- intent.putExtra(Constants.ACCOUNTS_KEY, accounts);
- intent.putExtra(Constants.ACCOUNT_MANAGER_RESPONSE_KEY,
- new AccountManagerResponse(chooseResponse));
- mActivity.startActivity(intent);
- // the result will arrive via the IAccountManagerResponse
- } else {
- // send result since we can't prompt to select an account
- Bundle result = new Bundle();
- result.putString(Constants.ACCOUNTS_KEY, null);
- try {
- mResponse.onResult(result);
- } catch (RemoteException e) {
- // this will never happen
}
- // we are done
- }
- }
- }}, mHandler);
+ }}, mHandler);
}
@@ -915,7 +749,7 @@
// or to cause this to be canceled if mFuture isn't set.
// Once this is done then getAuthTokenByFeatures can be changed to return a Future2.
- public void run(Future2 future) {
+ public void run(AccountManagerFuture<Bundle> future) {
try {
set(future.get());
} catch (InterruptedException e) {
@@ -932,7 +766,7 @@
final String accountType, final String authTokenType, final String[] features,
final Activity activityForPrompting, final Bundle addAccountOptions,
final Bundle loginOptions,
- final Future2Callback callback, final Handler handler) {
+ final AccountManagerCallback<Bundle> callback, final Handler handler) {
if (accountType == null) throw new IllegalArgumentException("account type is null");
if (authTokenType == null) throw new IllegalArgumentException("authTokenType is null");
new GetAuthTokenByTypeAndFeaturesTask(accountType, authTokenType, features,
@@ -942,13 +776,6 @@
private final HashMap<OnAccountsUpdatedListener, Handler> mAccountsUpdatedListeners =
Maps.newHashMap();
- // These variable are only used from the LOGIN_ACCOUNTS_CHANGED_ACTION BroadcastReceiver
- // and its getAccounts() callback which are both invoked only on the main thread. As a
- // result we don't need to protect against concurrent accesses and any changes are guaranteed
- // to be visible when used. Basically, these two variables are thread-confined.
- private Future1<Account[]> mAccountsLookupFuture = null;
- private boolean mAccountLookupPending = false;
-
/**
* BroadcastReceiver that listens for the LOGIN_ACCOUNTS_CHANGED_ACTION intent
* so that it can read the updated list of accounts and send them to the listener
@@ -956,58 +783,14 @@
*/
private final BroadcastReceiver mAccountsChangedBroadcastReceiver = new BroadcastReceiver() {
public void onReceive(final Context context, final Intent intent) {
- if (mAccountsLookupFuture != null) {
- // an accounts lookup is already in progress,
- // don't bother starting another request
- mAccountLookupPending = true;
- return;
- }
- // initiate a read of the accounts
- mAccountsLookupFuture = getAccounts(new Future1Callback<Account[]>() {
- public void run(Future1<Account[]> future) {
- // clear the future so that future receives will try the lookup again
- mAccountsLookupFuture = null;
-
- // get the accounts array
- Account[] accounts;
- try {
- accounts = future.getResult();
- } catch (OperationCanceledException e) {
- // this should never happen, but if it does pretend we got another
- // accounts changed broadcast
- if (Config.LOGD) {
- Log.d(TAG, "the accounts lookup for listener notifications was "
- + "canceled, try again by simulating the receipt of "
- + "a LOGIN_ACCOUNTS_CHANGED_ACTION broadcast");
- }
- onReceive(context, intent);
- return;
- }
-
- // send the result to the listeners
- synchronized (mAccountsUpdatedListeners) {
- for (Map.Entry<OnAccountsUpdatedListener, Handler> entry :
- mAccountsUpdatedListeners.entrySet()) {
- Account[] accountsCopy = new Account[accounts.length];
- // send the listeners a copy to make sure that one doesn't
- // change what another sees
- System.arraycopy(accounts, 0, accountsCopy, 0, accountsCopy.length);
- postToHandler(entry.getValue(), entry.getKey(), accountsCopy);
- }
- }
-
- // If mAccountLookupPending was set when the account lookup finished it
- // means that we had previously ignored a LOGIN_ACCOUNTS_CHANGED_ACTION
- // intent because a lookup was already in progress. Now that we are done
- // with this lookup and notification pretend that another intent
- // was received by calling onReceive() directly.
- if (mAccountLookupPending) {
- mAccountLookupPending = false;
- onReceive(context, intent);
- return;
- }
+ final Account[] accounts = getAccounts();
+ // send the result to the listeners
+ synchronized (mAccountsUpdatedListeners) {
+ for (Map.Entry<OnAccountsUpdatedListener, Handler> entry :
+ mAccountsUpdatedListeners.entrySet()) {
+ postToHandler(entry.getValue(), entry.getKey(), accounts);
}
- }, mMainHandler);
+ }
}
};
@@ -1045,15 +828,7 @@
}
if (updateImmediately) {
- getAccounts(new Future1Callback<Account[]>() {
- public void run(Future1<Account[]> future) {
- try {
- listener.onAccountsUpdated(future.getResult());
- } catch (OperationCanceledException e) {
- // ignore
- }
- }
- }, handler);
+ postToHandler(handler, listener, getAccounts());
}
}
diff --git a/core/java/android/accounts/Future2Callback.java b/core/java/android/accounts/AccountManagerCallback.java
similarity index 87%
rename from core/java/android/accounts/Future2Callback.java
rename to core/java/android/accounts/AccountManagerCallback.java
index 7ef0c94..4aa7169 100644
--- a/core/java/android/accounts/Future2Callback.java
+++ b/core/java/android/accounts/AccountManagerCallback.java
@@ -15,6 +15,6 @@
*/
package android.accounts;
-public interface Future2Callback {
- void run(Future2 future);
+public interface AccountManagerCallback<V> {
+ void run(AccountManagerFuture<V> future);
}
\ No newline at end of file
diff --git a/core/java/android/accounts/AccountManagerFuture.java b/core/java/android/accounts/AccountManagerFuture.java
new file mode 100644
index 0000000..9939398
--- /dev/null
+++ b/core/java/android/accounts/AccountManagerFuture.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2009 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.accounts;
+
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeoutException;
+import java.io.IOException;
+
+/**
+ * An extension of {@link java.util.concurrent.Future} that provides wrappers for {@link #get()}
+ * that handle the various
+ * exceptions that {@link #get()} may return and rethrows them as exceptions specific to
+ * {@link android.accounts.AccountManager}.
+ */
+public interface AccountManagerFuture<V> extends Future<V> {
+ /**
+ * Wrapper for {@link java.util.concurrent.Future#get()}. If the get() throws
+ * {@link InterruptedException} then the
+ * {@link AccountManagerFuture} is canceled and
+ * {@link android.accounts.OperationCanceledException} is thrown.
+ * @return the {@link android.os.Bundle} that is returned by get()
+ * @throws android.accounts.OperationCanceledException if get() throws the unchecked
+ * CancellationException
+ * or if the Future was interrupted.
+ */
+ V getResult() throws OperationCanceledException, IOException, AuthenticatorException;
+
+ /**
+ * Wrapper for {@link java.util.concurrent.Future#get()}. If the get() throws
+ * {@link InterruptedException} then the
+ * {@link AccountManagerFuture} is canceled and
+ * {@link android.accounts.OperationCanceledException} is thrown.
+ * @param timeout the maximum time to wait
+ * @param unit the time unit of the timeout argument
+ * @return the {@link android.os.Bundle} that is returned by
+ * {@link java.util.concurrent.Future#get()}
+ * @throws android.accounts.OperationCanceledException if get() throws the unchecked
+ * {@link java.util.concurrent.CancellationException} or if the {@link AccountManagerFuture}
+ * was interrupted.
+ */
+ V getResult(long timeout, TimeUnit unit)
+ throws OperationCanceledException, IOException, AuthenticatorException;
+
+ @Deprecated
+ V get() throws InterruptedException, ExecutionException;
+
+ @Deprecated
+ V get(long timeout, TimeUnit unit)
+ throws InterruptedException, ExecutionException, TimeoutException;
+}
\ No newline at end of file
diff --git a/core/java/android/accounts/AccountManagerService.java b/core/java/android/accounts/AccountManagerService.java
index 0c941be..140c814 100644
--- a/core/java/android/accounts/AccountManagerService.java
+++ b/core/java/android/accounts/AccountManagerService.java
@@ -214,10 +214,48 @@
long identityToken = clearCallingIdentity();
try {
- SQLiteDatabase db = mOpenHelper.getReadableDatabase();
- Cursor cursor = db.query(TABLE_ACCOUNTS, new String[]{ACCOUNTS_PASSWORD},
- ACCOUNTS_NAME + "=? AND " + ACCOUNTS_TYPE+ "=?",
- new String[]{account.mName, account.mType}, null, null, null);
+ return readPasswordFromDatabase(account);
+ } finally {
+ restoreCallingIdentity(identityToken);
+ }
+ }
+
+ private String readPasswordFromDatabase(Account account) {
+ SQLiteDatabase db = mOpenHelper.getReadableDatabase();
+ Cursor cursor = db.query(TABLE_ACCOUNTS, new String[]{ACCOUNTS_PASSWORD},
+ ACCOUNTS_NAME + "=? AND " + ACCOUNTS_TYPE+ "=?",
+ new String[]{account.name, account.type}, null, null, null);
+ try {
+ if (cursor.moveToNext()) {
+ return cursor.getString(0);
+ }
+ return null;
+ } finally {
+ cursor.close();
+ }
+ }
+
+ public String getUserData(Account account, String key) {
+ checkAuthenticateAccountsPermission(account);
+ long identityToken = clearCallingIdentity();
+ try {
+ return readUserDataFromDatabase(account, key);
+ } finally {
+ restoreCallingIdentity(identityToken);
+ }
+ }
+
+ private String readUserDataFromDatabase(Account account, String key) {
+ SQLiteDatabase db = mOpenHelper.getReadableDatabase();
+ db.beginTransaction();
+ try {
+ long accountId = getAccountId(db, account);
+ if (accountId < 0) {
+ return null;
+ }
+ Cursor cursor = db.query(TABLE_EXTRAS, new String[]{EXTRAS_VALUE},
+ EXTRAS_ACCOUNTS_ID + "=" + accountId + " AND " + EXTRAS_KEY + "=?",
+ new String[]{key}, null, null, null);
try {
if (cursor.moveToNext()) {
return cursor.getString(0);
@@ -227,37 +265,7 @@
cursor.close();
}
} finally {
- restoreCallingIdentity(identityToken);
- }
- }
-
- public String getUserData(Account account, String key) {
- checkAuthenticateAccountsPermission(account);
- long identityToken = clearCallingIdentity();
- try {
- SQLiteDatabase db = mOpenHelper.getReadableDatabase();
- db.beginTransaction();
- try {
- long accountId = getAccountId(db, account);
- if (accountId < 0) {
- return null;
- }
- Cursor cursor = db.query(TABLE_EXTRAS, new String[]{EXTRAS_VALUE},
- EXTRAS_ACCOUNTS_ID + "=" + accountId + " AND " + EXTRAS_KEY + "=?",
- new String[]{key}, null, null, null);
- try {
- if (cursor.moveToNext()) {
- return cursor.getString(0);
- }
- return null;
- } finally {
- cursor.close();
- }
- } finally {
- db.endTransaction();
- }
- } finally {
- restoreCallingIdentity(identityToken);
+ db.endTransaction();
}
}
@@ -280,39 +288,23 @@
}
}
- public Account[] getAccounts() {
- checkReadAccountsPermission();
- long identityToken = clearCallingIdentity();
- try {
- return getAccountsByType(null);
- } finally {
- restoreCallingIdentity(identityToken);
- }
- }
-
public Account[] getAccountsByType(String accountType) {
- checkReadAccountsPermission();
- long identityToken = clearCallingIdentity();
- try {
- SQLiteDatabase db = mOpenHelper.getReadableDatabase();
+ SQLiteDatabase db = mOpenHelper.getReadableDatabase();
- final String selection = accountType == null ? null : (ACCOUNTS_TYPE + "=?");
- final String[] selectionArgs = accountType == null ? null : new String[]{accountType};
- Cursor cursor = db.query(TABLE_ACCOUNTS, ACCOUNT_NAME_TYPE_PROJECTION,
- selection, selectionArgs, null, null, null);
- try {
- int i = 0;
- Account[] accounts = new Account[cursor.getCount()];
- while (cursor.moveToNext()) {
- accounts[i] = new Account(cursor.getString(1), cursor.getString(2));
- i++;
- }
- return accounts;
- } finally {
- cursor.close();
+ final String selection = accountType == null ? null : (ACCOUNTS_TYPE + "=?");
+ final String[] selectionArgs = accountType == null ? null : new String[]{accountType};
+ Cursor cursor = db.query(TABLE_ACCOUNTS, ACCOUNT_NAME_TYPE_PROJECTION,
+ selection, selectionArgs, null, null, null);
+ try {
+ int i = 0;
+ Account[] accounts = new Account[cursor.getCount()];
+ while (cursor.moveToNext()) {
+ accounts[i] = new Account(cursor.getString(1), cursor.getString(2));
+ i++;
}
+ return accounts;
} finally {
- restoreCallingIdentity(identityToken);
+ cursor.close();
}
}
@@ -322,43 +314,47 @@
// fails if the account already exists
long identityToken = clearCallingIdentity();
try {
- SQLiteDatabase db = mOpenHelper.getWritableDatabase();
- db.beginTransaction();
- try {
- long numMatches = DatabaseUtils.longForQuery(db,
- "select count(*) from " + TABLE_ACCOUNTS
- + " WHERE " + ACCOUNTS_NAME + "=? AND " + ACCOUNTS_TYPE+ "=?",
- new String[]{account.mName, account.mType});
- if (numMatches > 0) {
- return false;
- }
- ContentValues values = new ContentValues();
- values.put(ACCOUNTS_NAME, account.mName);
- values.put(ACCOUNTS_TYPE, account.mType);
- values.put(ACCOUNTS_PASSWORD, password);
- long accountId = db.insert(TABLE_ACCOUNTS, ACCOUNTS_NAME, values);
- if (accountId < 0) {
- return false;
- }
- if (extras != null) {
- for (String key : extras.keySet()) {
- final String value = extras.getString(key);
- if (insertExtra(db, accountId, key, value) < 0) {
- return false;
- }
- }
- }
- db.setTransactionSuccessful();
- sendAccountsChangedBroadcast();
- return true;
- } finally {
- db.endTransaction();
- }
+ return insertAccountIntoDatabase(account, password, extras);
} finally {
restoreCallingIdentity(identityToken);
}
}
+ private boolean insertAccountIntoDatabase(Account account, String password, Bundle extras) {
+ SQLiteDatabase db = mOpenHelper.getWritableDatabase();
+ db.beginTransaction();
+ try {
+ long numMatches = DatabaseUtils.longForQuery(db,
+ "select count(*) from " + TABLE_ACCOUNTS
+ + " WHERE " + ACCOUNTS_NAME + "=? AND " + ACCOUNTS_TYPE+ "=?",
+ new String[]{account.name, account.type});
+ if (numMatches > 0) {
+ return false;
+ }
+ ContentValues values = new ContentValues();
+ values.put(ACCOUNTS_NAME, account.name);
+ values.put(ACCOUNTS_TYPE, account.type);
+ values.put(ACCOUNTS_PASSWORD, password);
+ long accountId = db.insert(TABLE_ACCOUNTS, ACCOUNTS_NAME, values);
+ if (accountId < 0) {
+ return false;
+ }
+ if (extras != null) {
+ for (String key : extras.keySet()) {
+ final String value = extras.getString(key);
+ if (insertExtra(db, accountId, key, value) < 0) {
+ return false;
+ }
+ }
+ }
+ db.setTransactionSuccessful();
+ sendAccountsChangedBroadcast();
+ return true;
+ } finally {
+ db.endTransaction();
+ }
+ }
+
private long insertExtra(SQLiteDatabase db, long accountId, String key, String value) {
ContentValues values = new ContentValues();
values.put(EXTRAS_KEY, key);
@@ -367,19 +363,61 @@
return db.insert(TABLE_EXTRAS, EXTRAS_KEY, values);
}
- public void removeAccount(Account account) {
+ public void removeAccount(IAccountManagerResponse response, Account account) {
checkManageAccountsPermission();
long identityToken = clearCallingIdentity();
try {
- final SQLiteDatabase db = mOpenHelper.getWritableDatabase();
- db.delete(TABLE_ACCOUNTS, ACCOUNTS_NAME + "=? AND " + ACCOUNTS_TYPE+ "=?",
- new String[]{account.mName, account.mType});
- sendAccountsChangedBroadcast();
+ new RemoveAccountSession(response, account).bind();
} finally {
restoreCallingIdentity(identityToken);
}
}
+ private class RemoveAccountSession extends Session {
+ final Account mAccount;
+ public RemoveAccountSession(IAccountManagerResponse response, Account account) {
+ super(response, account.type, false /* expectActivityLaunch */);
+ mAccount = account;
+ }
+
+ protected String toDebugString(long now) {
+ return super.toDebugString(now) + ", removeAccount"
+ + ", account " + mAccount;
+ }
+
+ public void run() throws RemoteException {
+ mAuthenticator.getAccountRemovalAllowed(this, mAccount);
+ }
+
+ public void onResult(Bundle result) {
+ if (result != null && result.containsKey(Constants.BOOLEAN_RESULT_KEY)
+ && !result.containsKey(Constants.INTENT_KEY)) {
+ final boolean removalAllowed = result.getBoolean(Constants.BOOLEAN_RESULT_KEY);
+ if (removalAllowed) {
+ removeAccount(mAccount);
+ }
+ IAccountManagerResponse response = getResponseAndClose();
+ if (response != null) {
+ Bundle result2 = new Bundle();
+ result2.putBoolean(Constants.BOOLEAN_RESULT_KEY, removalAllowed);
+ try {
+ response.onResult(result2);
+ } catch (RemoteException e) {
+ // ignore
+ }
+ }
+ }
+ super.onResult(result);
+ }
+ }
+
+ private void removeAccount(Account account) {
+ final SQLiteDatabase db = mOpenHelper.getWritableDatabase();
+ db.delete(TABLE_ACCOUNTS, ACCOUNTS_NAME + "=? AND " + ACCOUNTS_TYPE+ "=?",
+ new String[]{account.name, account.type});
+ sendAccountsChangedBroadcast();
+ }
+
public void invalidateAuthToken(String accountType, String authToken) {
checkManageAccountsPermission();
long identityToken = clearCallingIdentity();
@@ -398,6 +436,9 @@
}
private void invalidateAuthToken(SQLiteDatabase db, String accountType, String authToken) {
+ if (authToken == null || accountType == null) {
+ return;
+ }
Cursor cursor = db.rawQuery(
"SELECT " + TABLE_AUTHTOKENS + "." + AUTHTOKENS_ID
+ ", " + TABLE_ACCOUNTS + "." + ACCOUNTS_NAME
@@ -488,7 +529,7 @@
values.put(ACCOUNTS_PASSWORD, password);
mOpenHelper.getWritableDatabase().update(TABLE_ACCOUNTS, values,
ACCOUNTS_NAME + "=? AND " + ACCOUNTS_TYPE+ "=?",
- new String[]{account.mName, account.mType});
+ new String[]{account.name, account.type});
sendAccountsChangedBroadcast();
} finally {
restoreCallingIdentity(identityToken);
@@ -509,40 +550,58 @@
}
}
+ private void sendResult(IAccountManagerResponse response, Bundle bundle) {
+ if (response != null) {
+ try {
+ response.onResult(bundle);
+ } catch (RemoteException e) {
+ // if the caller is dead then there is no one to care about remote
+ // exceptions
+ if (Log.isLoggable(TAG, Log.VERBOSE)) {
+ Log.v(TAG, "failure while notifying response", e);
+ }
+ }
+ }
+ }
+
public void setUserData(Account account, String key, String value) {
checkAuthenticateAccountsPermission(account);
long identityToken = clearCallingIdentity();
try {
- SQLiteDatabase db = mOpenHelper.getWritableDatabase();
- db.beginTransaction();
- try {
- long accountId = getAccountId(db, account);
- if (accountId < 0) {
- return;
- }
- long extrasId = getExtrasId(db, accountId, key);
- if (extrasId < 0 ) {
- extrasId = insertExtra(db, accountId, key, value);
- if (extrasId < 0) {
- return;
- }
- } else {
- ContentValues values = new ContentValues();
- values.put(EXTRAS_VALUE, value);
- if (1 != db.update(TABLE_EXTRAS, values, EXTRAS_ID + "=" + extrasId, null)) {
- return;
- }
-
- }
- db.setTransactionSuccessful();
- } finally {
- db.endTransaction();
- }
+ writeUserdataIntoDatabase(account, key, value);
} finally {
restoreCallingIdentity(identityToken);
}
}
+ private void writeUserdataIntoDatabase(Account account, String key, String value) {
+ SQLiteDatabase db = mOpenHelper.getWritableDatabase();
+ db.beginTransaction();
+ try {
+ long accountId = getAccountId(db, account);
+ if (accountId < 0) {
+ return;
+ }
+ long extrasId = getExtrasId(db, accountId, key);
+ if (extrasId < 0 ) {
+ extrasId = insertExtra(db, accountId, key, value);
+ if (extrasId < 0) {
+ return;
+ }
+ } else {
+ ContentValues values = new ContentValues();
+ values.put(EXTRAS_VALUE, value);
+ if (1 != db.update(TABLE_EXTRAS, values, EXTRAS_ID + "=" + extrasId, null)) {
+ return;
+ }
+
+ }
+ db.setTransactionSuccessful();
+ } finally {
+ db.endTransaction();
+ }
+ }
+
private void onResult(IAccountManagerResponse response, Bundle result) {
try {
response.onResult(result);
@@ -571,14 +630,14 @@
if (authToken != null) {
Bundle result = new Bundle();
result.putString(Constants.AUTHTOKEN_KEY, authToken);
- result.putString(Constants.ACCOUNT_NAME_KEY, account.mName);
- result.putString(Constants.ACCOUNT_TYPE_KEY, account.mType);
+ result.putString(Constants.ACCOUNT_NAME_KEY, account.name);
+ result.putString(Constants.ACCOUNT_TYPE_KEY, account.type);
onResult(response, result);
return;
}
}
- new Session(response, account.mType, expectActivityLaunch) {
+ new Session(response, account.type, expectActivityLaunch) {
protected String toDebugString(long now) {
if (loginOptions != null) loginOptions.keySet();
return super.toDebugString(now) + ", getAuthToken"
@@ -651,7 +710,7 @@
mContext.getText(R.string.permission_request_notification_subtitle);
n.setLatestEventInfo(mContext,
mContext.getText(R.string.permission_request_notification_title),
- String.format(subtitleFormatString.toString(), account.mName),
+ String.format(subtitleFormatString.toString(), account.name),
PendingIntent.getActivity(mContext, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT));
((NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE))
.notify(getCredentialPermissionNotificationId(account, authTokenType, uid), n);
@@ -661,9 +720,9 @@
AccountAuthenticatorResponse response, String authTokenType, String authTokenLabel) {
RegisteredServicesCache.ServiceInfo<AuthenticatorDescription> serviceInfo =
mAuthenticatorCache.getServiceInfo(
- AuthenticatorDescription.newKey(account.mType));
+ AuthenticatorDescription.newKey(account.type));
if (serviceInfo == null) {
- throw new IllegalArgumentException("unknown account type: " + account.mType);
+ throw new IllegalArgumentException("unknown account type: " + account.type);
}
final Context authContext;
@@ -671,7 +730,7 @@
authContext = mContext.createPackageContext(
serviceInfo.type.packageName, 0);
} catch (PackageManager.NameNotFoundException e) {
- throw new IllegalArgumentException("unknown account type: " + account.mType);
+ throw new IllegalArgumentException("unknown account type: " + account.type);
}
Intent intent = new Intent(mContext, GrantCredentialsPermissionActivity.class);
@@ -750,7 +809,7 @@
checkManageAccountsPermission();
long identityToken = clearCallingIdentity();
try {
- new Session(response, account.mType, expectActivityLaunch) {
+ new Session(response, account.type, expectActivityLaunch) {
public void run() throws RemoteException {
mAuthenticator.confirmCredentials(this, account);
}
@@ -769,7 +828,7 @@
checkManageAccountsPermission();
long identityToken = clearCallingIdentity();
try {
- new Session(response, account.mType, false /* expectActivityLaunch */) {
+ new Session(response, account.type, false /* expectActivityLaunch */) {
public void run() throws RemoteException {
mAuthenticator.confirmPassword(this, account, password);
}
@@ -789,7 +848,7 @@
checkManageAccountsPermission();
long identityToken = clearCallingIdentity();
try {
- new Session(response, account.mType, expectActivityLaunch) {
+ new Session(response, account.type, expectActivityLaunch) {
public void run() throws RemoteException {
mAuthenticator.updateCredentials(this, account, authTokenType, loginOptions);
}
@@ -898,10 +957,21 @@
+ ", " + (mFeatures != null ? TextUtils.join(",", mFeatures) : null);
}
}
- public void getAccountsByTypeAndFeatures(IAccountManagerResponse response,
+
+ public Account[] getAccounts(String type) {
+ checkReadAccountsPermission();
+ long identityToken = clearCallingIdentity();
+ try {
+ return getAccountsByType(type);
+ } finally {
+ restoreCallingIdentity(identityToken);
+ }
+ }
+
+ public void getAccountsByFeatures(IAccountManagerResponse response,
String type, String[] features) {
checkReadAccountsPermission();
- if (type == null) {
+ if (features != null && type == null) {
if (response != null) {
try {
response.onError(Constants.ERROR_CODE_BAD_ARGUMENTS, "type is null");
@@ -913,6 +983,10 @@
}
long identityToken = clearCallingIdentity();
try {
+ if (features == null || features.length == 0) {
+ getAccountsByType(type);
+ return;
+ }
new GetAccountsByTypeAndFeatureSession(response, type, features).bind();
} finally {
restoreCallingIdentity(identityToken);
@@ -925,7 +999,7 @@
private long getAccountId(SQLiteDatabase db, Account account) {
Cursor cursor = db.query(TABLE_ACCOUNTS, new String[]{ACCOUNTS_ID},
- "name=? AND type=?", new String[]{account.mName, account.mType}, null, null, null);
+ "name=? AND type=?", new String[]{account.name, account.type}, null, null, null);
try {
if (cursor.moveToNext()) {
return cursor.getLong(0);
@@ -1401,7 +1475,7 @@
}
private boolean permissionIsGranted(Account account, String authTokenType, int callerUid) {
- final boolean fromAuthenticator = hasAuthenticatorUid(account.mType, callerUid);
+ final boolean fromAuthenticator = hasAuthenticatorUid(account.type, callerUid);
final boolean hasExplicitGrants = hasExplicitlyGrantedPermission(account, authTokenType);
if (Log.isLoggable(TAG, Log.VERBOSE)) {
Log.v(TAG, "checkGrantsOrCallingUidAgainstAuthenticator: caller uid "
@@ -1416,7 +1490,9 @@
for (RegisteredServicesCache.ServiceInfo<AuthenticatorDescription> serviceInfo :
mAuthenticatorCache.getAllServices()) {
if (serviceInfo.type.type.equals(accountType)) {
- return serviceInfo.uid == callingUid;
+ return (serviceInfo.uid == callingUid) ||
+ (mContext.getPackageManager().checkSignatures(serviceInfo.uid, callingUid)
+ == PackageManager.SIGNATURE_MATCH);
}
}
return false;
@@ -1428,7 +1504,7 @@
}
SQLiteDatabase db = mOpenHelper.getReadableDatabase();
String[] args = {String.valueOf(Binder.getCallingUid()), authTokenType,
- account.mName, account.mType};
+ account.name, account.type};
final boolean permissionGranted =
DatabaseUtils.longForQuery(db, COUNT_OF_MATCHING_GRANTS, args) != 0;
if (!permissionGranted && isDebuggableMonkeyBuild) {
@@ -1444,7 +1520,7 @@
private void checkCallingUidAgainstAuthenticator(Account account) {
final int uid = Binder.getCallingUid();
- if (!hasAuthenticatorUid(account.mType, uid)) {
+ if (!hasAuthenticatorUid(account.type, uid)) {
String msg = "caller uid " + uid + " is different than the authenticator's uid";
Log.w(TAG, msg);
throw new SecurityException(msg);
diff --git a/core/java/android/accounts/ChooseAccountActivity.java b/core/java/android/accounts/ChooseAccountActivity.java
index 83377f3..bd6f205 100644
--- a/core/java/android/accounts/ChooseAccountActivity.java
+++ b/core/java/android/accounts/ChooseAccountActivity.java
@@ -45,7 +45,7 @@
String[] mAccountNames = new String[mAccounts.length];
for (int i = 0; i < mAccounts.length; i++) {
- mAccountNames[i] = ((Account) mAccounts[i]).mName;
+ mAccountNames[i] = ((Account) mAccounts[i]).name;
}
// Use an existing ListAdapter that will map an array
@@ -59,8 +59,8 @@
Account account = (Account) mAccounts[position];
Log.d(TAG, "selected account " + account);
Bundle bundle = new Bundle();
- bundle.putString(Constants.ACCOUNT_NAME_KEY, account.mName);
- bundle.putString(Constants.ACCOUNT_TYPE_KEY, account.mType);
+ bundle.putString(Constants.ACCOUNT_NAME_KEY, account.name);
+ bundle.putString(Constants.ACCOUNT_TYPE_KEY, account.type);
mResult = bundle;
finish();
}
diff --git a/core/java/android/accounts/Constants.java b/core/java/android/accounts/Constants.java
index da8173f..8736f41 100644
--- a/core/java/android/accounts/Constants.java
+++ b/core/java/android/accounts/Constants.java
@@ -31,6 +31,7 @@
public static final String AUTHENTICATOR_TYPES_KEY = "authenticator_types";
public static final String USERDATA_KEY = "userdata";
public static final String AUTHTOKEN_KEY = "authtoken";
+ public static final String PASSWORD_KEY = "password";
public static final String ACCOUNT_NAME_KEY = "authAccount";
public static final String ACCOUNT_TYPE_KEY = "accountType";
public static final String ERROR_CODE_KEY = "errorCode";
diff --git a/core/java/android/accounts/Future1.java b/core/java/android/accounts/Future1.java
deleted file mode 100644
index 386cb6e..0000000
--- a/core/java/android/accounts/Future1.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2009 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.accounts;
-
-import java.util.concurrent.Future;
-import java.util.concurrent.TimeUnit;
-
-/**
- * An extension of {@link Future} that provides wrappers for {@link #get()} that handle the various
- * exceptions that {@link #get()} may return and rethrows them as exceptions specific to
- * {@link AccountManager}.
- */
-public interface Future1<V> extends Future<V> {
- /**
- * Wrapper for {@link Future#get()}. If the get() throws {@link InterruptedException} then the
- * {@link Future1} is canceled and {@link OperationCanceledException} is thrown.
- * @return the {@link android.os.Bundle} that is returned by get()
- * @throws OperationCanceledException if get() throws the unchecked CancellationException
- * or if the Future was interrupted.
- */
- V getResult() throws OperationCanceledException;
-
- /**
- * Wrapper for {@link Future#get()}. If the get() throws {@link InterruptedException} then the
- * {@link Future1} is canceled and {@link OperationCanceledException} is thrown.
- * @param timeout the maximum time to wait
- * @param unit the time unit of the timeout argument
- * @return the {@link android.os.Bundle} that is returned by {@link Future#get()}
- * @throws OperationCanceledException if get() throws the unchecked
- * {@link java.util.concurrent.CancellationException} or if the {@link Future1} was interrupted.
- */
- V getResult(long timeout, TimeUnit unit) throws OperationCanceledException;
-}
\ No newline at end of file
diff --git a/core/java/android/accounts/Future1Callback.java b/core/java/android/accounts/Future1Callback.java
deleted file mode 100644
index 886671b..0000000
--- a/core/java/android/accounts/Future1Callback.java
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * Copyright (C) 2009 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.accounts;
-
-public interface Future1Callback<V> {
- void run(Future1<V> future);
-}
diff --git a/core/java/android/accounts/Future2.java b/core/java/android/accounts/Future2.java
deleted file mode 100644
index b2ea84f..0000000
--- a/core/java/android/accounts/Future2.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (C) 2009 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.accounts;
-
-import android.os.Bundle;
-
-import java.io.IOException;
-import java.util.concurrent.Future;
-import java.util.concurrent.TimeUnit;
-
-/**
- * An extension of {@link Future} that provides wrappers for {@link #get()} that handle the various
- * exceptions that {@link #get()} may return and rethrows them as exceptions specific to
- * {@link AccountManager}.
- */
-public interface Future2 extends Future<Bundle> {
- /**
- * Wrapper for {@link Future#get()}. If the get() throws {@link InterruptedException} then the
- * {@link Future2} is canceled and {@link OperationCanceledException} is thrown.
- * @return the {@link android.os.Bundle} that is returned by {@link Future#get()}
- * @throws OperationCanceledException if get() throws the unchecked
- * {@link java.util.concurrent.CancellationException} or if the {@link Future2} was interrupted.
- * @throws IOException if the request was unable to complete due to a network error
- * @throws AuthenticatorException if there was an error communicating with the
- * {@link AbstractAccountAuthenticator}.
- */
- Bundle getResult()
- throws OperationCanceledException, IOException, AuthenticatorException;
-
- /**
- * Wrapper for {@link Future#get()}. If the get() throws {@link InterruptedException} then the
- * {@link Future2} is canceled and {@link OperationCanceledException} is thrown.
- * @param timeout the maximum time to wait
- * @param unit the time unit of the timeout argument
- * @return the {@link android.os.Bundle} that is returned by {@link Future#get()}
- * @throws OperationCanceledException if get() throws the unchecked
- * {@link java.util.concurrent.CancellationException} or if the {@link Future2} was interrupted.
- * @throws IOException if the request was unable to complete due to a network error
- * @throws AuthenticatorException if there was an error communicating with the
- * {@link AbstractAccountAuthenticator}.
- */
- Bundle getResult(long timeout, TimeUnit unit)
- throws OperationCanceledException, IOException, AuthenticatorException;
-}
diff --git a/core/java/android/accounts/GrantCredentialsPermissionActivity.java b/core/java/android/accounts/GrantCredentialsPermissionActivity.java
index f92d43f..e06afb4 100644
--- a/core/java/android/accounts/GrantCredentialsPermissionActivity.java
+++ b/core/java/android/accounts/GrantCredentialsPermissionActivity.java
@@ -63,12 +63,12 @@
CharSequence grantCredentialsPermissionFormat = getResources().getText(
R.string.grant_credentials_permission_message_desc);
messageView.setText(String.format(grantCredentialsPermissionFormat.toString(),
- mAccount.mName, accountTypeLabel));
+ mAccount.name, accountTypeLabel));
} else {
CharSequence grantCredentialsPermissionFormat = getResources().getText(
R.string.grant_credentials_permission_message_with_authtokenlabel_desc);
messageView.setText(String.format(grantCredentialsPermissionFormat.toString(),
- authTokenLabel, mAccount.mName, accountTypeLabel));
+ authTokenLabel, mAccount.name, accountTypeLabel));
}
String[] packageLabels = new String[packages.length];
diff --git a/core/java/android/accounts/IAccountAuthenticator.aidl b/core/java/android/accounts/IAccountAuthenticator.aidl
index 7d4de39..48f053c 100644
--- a/core/java/android/accounts/IAccountAuthenticator.aidl
+++ b/core/java/android/accounts/IAccountAuthenticator.aidl
@@ -70,4 +70,9 @@
*/
void hasFeatures(in IAccountAuthenticatorResponse response, in Account account,
in String[] features);
+
+ /**
+ * Gets whether or not the account is allowed to be removed.
+ */
+ void getAccountRemovalAllowed(in IAccountAuthenticatorResponse response, in Account account);
}
diff --git a/core/java/android/accounts/IAccountManager.aidl b/core/java/android/accounts/IAccountManager.aidl
index 15ab4e8..411952b 100644
--- a/core/java/android/accounts/IAccountManager.aidl
+++ b/core/java/android/accounts/IAccountManager.aidl
@@ -21,6 +21,7 @@
import android.accounts.AuthenticatorDescription;
import android.os.Bundle;
+
/**
* Central application service that provides account management.
* @hide
@@ -29,10 +30,10 @@
String getPassword(in Account account);
String getUserData(in Account account, String key);
AuthenticatorDescription[] getAuthenticatorTypes();
- Account[] getAccounts();
- Account[] getAccountsByType(String accountType);
+ Account[] getAccounts(String accountType);
+ void getAccountsByFeatures(in IAccountManagerResponse response, String accountType, in String[] features);
boolean addAccount(in Account account, String password, in Bundle extras);
- void removeAccount(in Account account);
+ void removeAccount(in IAccountManagerResponse response, in Account account);
void invalidateAuthToken(String accountType, String authToken);
String peekAuthToken(in Account account, String authTokenType);
void setAuthToken(in Account account, String authTokenType, String authToken);
@@ -52,8 +53,6 @@
boolean expectActivityLaunch);
void confirmCredentials(in IAccountManagerResponse response, in Account account,
boolean expectActivityLaunch);
- void getAccountsByTypeAndFeatures(in IAccountManagerResponse response, String accountType,
- in String[] features);
/*
* @deprecated
diff --git a/core/java/android/content/AbstractSyncableContentProvider.java b/core/java/android/content/AbstractSyncableContentProvider.java
index 218f501..808f30c 100644
--- a/core/java/android/content/AbstractSyncableContentProvider.java
+++ b/core/java/android/content/AbstractSyncableContentProvider.java
@@ -170,7 +170,7 @@
// AbstractGDataSyncAdapter, which will put acore into a crash loop
ArrayList<Account> gaiaAccounts = new ArrayList<Account>();
for (Account acct: accounts) {
- if (acct.mType.equals("com.google.GAIA")) {
+ if (acct.type.equals("com.google.GAIA")) {
gaiaAccounts.add(acct);
}
}
@@ -693,7 +693,7 @@
if (!accounts.containsKey(account)) {
int numDeleted;
numDeleted = db.delete(table, "_sync_account=? AND _sync_account_type=?",
- new String[]{account.mName, account.mType});
+ new String[]{account.name, account.type});
if (Config.LOGV) {
Log.v(TAG, "deleted " + numDeleted
+ " records from table " + table
@@ -726,7 +726,7 @@
// remove the data in the synced tables
for (String table : tables) {
db.delete(table, SYNC_ACCOUNT_WHERE_CLAUSE,
- new String[]{account.mName, account.mType});
+ new String[]{account.name, account.type});
}
db.setTransactionSuccessful();
} finally {
diff --git a/core/java/android/content/AbstractTableMerger.java b/core/java/android/content/AbstractTableMerger.java
index a3daa01e..9545fd7f 100644
--- a/core/java/android/content/AbstractTableMerger.java
+++ b/core/java/android/content/AbstractTableMerger.java
@@ -174,7 +174,7 @@
Cursor diffsCursor = null;
try {
// load the local database entries, so we can merge them with the server
- final String[] accountSelectionArgs = new String[]{account.mName, account.mType};
+ final String[] accountSelectionArgs = new String[]{account.name, account.type};
localCursor = mDb.query(mTable, syncDirtyProjection,
SELECT_MARKED, accountSelectionArgs, null, null,
mTable + "." + _SYNC_ID);
@@ -487,7 +487,7 @@
try {
if (deleteBySyncId) {
selectionArgs = new String[]{diffsCursor.getString(serverSyncIdColumn),
- account.mName, account.mType};
+ account.name, account.type};
c = mDb.query(mTable, new String[]{BaseColumns._ID}, SELECT_BY_SYNC_ID_AND_ACCOUNT,
selectionArgs, null, null, null);
} else {
@@ -534,7 +534,7 @@
SyncableContentProvider clientDiffs = mergeResult.tempContentProvider;
if (Log.isLoggable(TAG, Log.VERBOSE)) Log.v(TAG, "generating client updates");
- final String[] accountSelectionArgs = new String[]{account.mName, account.mType};
+ final String[] accountSelectionArgs = new String[]{account.name, account.type};
// Generate the client updates and insertions
// Create a cursor for dirty records
diff --git a/core/java/android/content/SyncManager.java b/core/java/android/content/SyncManager.java
index d54e260..f256394 100644
--- a/core/java/android/content/SyncManager.java
+++ b/core/java/android/content/SyncManager.java
@@ -596,7 +596,7 @@
for (String authority : syncableAuthorities) {
for (Account account : accounts) {
- if (mSyncAdapters.getServiceInfo(new SyncAdapterType(authority, account.mType))
+ if (mSyncAdapters.getServiceInfo(new SyncAdapterType(authority, account.type))
!= null) {
scheduleSyncOperation(
new SyncOperation(account, source, authority, extras, delay));
@@ -1094,8 +1094,8 @@
for (int i=0; i<N; i++) {
SyncStorageEngine.PendingOperation op = ops.get(i);
pw.print(" #"); pw.print(i); pw.print(": account=");
- pw.print(op.account.mName); pw.print(":");
- pw.print(op.account.mType); pw.print(" authority=");
+ pw.print(op.account.name); pw.print(":");
+ pw.print(op.account.type); pw.print(" authority=");
pw.println(op.authority);
if (op.extras != null && op.extras.size() > 0) {
sb.setLength(0);
@@ -1125,8 +1125,8 @@
processedAccounts.add(curAccount);
- pw.print(" Account "); pw.print(authority.account.mName);
- pw.print(" "); pw.print(authority.account.mType);
+ pw.print(" Account "); pw.print(authority.account.name);
+ pw.print(" "); pw.print(authority.account.type);
pw.println(":");
for (int j=i; j<N; j++) {
status = statuses.get(j);
@@ -1248,9 +1248,9 @@
= mSyncStorageEngine.getAuthority(item.authorityId);
pw.print(" #"); pw.print(i+1); pw.print(": ");
if (authority != null) {
- pw.print(authority.account.mName);
+ pw.print(authority.account.name);
pw.print(":");
- pw.print(authority.account.mType);
+ pw.print(authority.account.type);
pw.print(" ");
pw.print(authority.authority);
} else {
@@ -1636,7 +1636,7 @@
// connect to the sync adapter
SyncAdapterType syncAdapterType = new SyncAdapterType(op.authority,
- op.account.mType);
+ op.account.type);
RegisteredServicesCache.ServiceInfo<SyncAdapterType> syncAdapterInfo =
mSyncAdapters.getServiceInfo(syncAdapterType);
if (syncAdapterInfo == null) {
diff --git a/core/java/android/content/SyncStateContentProviderHelper.java b/core/java/android/content/SyncStateContentProviderHelper.java
index dc728ec..64bbe25 100644
--- a/core/java/android/content/SyncStateContentProviderHelper.java
+++ b/core/java/android/content/SyncStateContentProviderHelper.java
@@ -172,7 +172,7 @@
*/
public void copySyncState(SQLiteDatabase dbSrc, SQLiteDatabase dbDest,
Account account) {
- final String[] whereArgs = new String[]{account.mName, account.mType};
+ final String[] whereArgs = new String[]{account.name, account.type};
Cursor c = dbSrc.query(SYNC_STATE_TABLE,
new String[]{"_sync_account", "_sync_account_type", "data"},
ACCOUNT_WHERE, whereArgs, null, null, null);
@@ -209,7 +209,7 @@
public void discardSyncData(SQLiteDatabase db, Account account) {
if (account != null) {
- db.delete(SYNC_STATE_TABLE, ACCOUNT_WHERE, new String[]{account.mName, account.mType});
+ db.delete(SYNC_STATE_TABLE, ACCOUNT_WHERE, new String[]{account.name, account.type});
} else {
db.delete(SYNC_STATE_TABLE, null, null);
}
@@ -220,7 +220,7 @@
*/
public byte[] readSyncDataBytes(SQLiteDatabase db, Account account) {
Cursor c = db.query(SYNC_STATE_TABLE, null, ACCOUNT_WHERE,
- new String[]{account.mName, account.mType}, null, null, null);
+ new String[]{account.name, account.type}, null, null, null);
try {
if (c.moveToFirst()) {
return c.getBlob(c.getColumnIndexOrThrow("data"));
@@ -238,6 +238,6 @@
ContentValues values = new ContentValues();
values.put("data", data);
db.update(SYNC_STATE_TABLE, values, ACCOUNT_WHERE,
- new String[]{account.mName, account.mType});
+ new String[]{account.name, account.type});
}
}
diff --git a/core/java/android/content/SyncStorageEngine.java b/core/java/android/content/SyncStorageEngine.java
index 8cc0642..b3f9bbb 100644
--- a/core/java/android/content/SyncStorageEngine.java
+++ b/core/java/android/content/SyncStorageEngine.java
@@ -1127,8 +1127,8 @@
AuthorityInfo authority = mAuthorities.get(i);
out.startTag(null, "authority");
out.attribute(null, "id", Integer.toString(authority.ident));
- out.attribute(null, "account", authority.account.mName);
- out.attribute(null, "type", authority.account.mType);
+ out.attribute(null, "account", authority.account.name);
+ out.attribute(null, "type", authority.account.type);
out.attribute(null, "authority", authority.authority);
if (!authority.enabled) {
out.attribute(null, "enabled", "false");
diff --git a/core/java/android/provider/Calendar.java b/core/java/android/provider/Calendar.java
index 489d936..fab3f3d 100644
--- a/core/java/android/provider/Calendar.java
+++ b/core/java/android/provider/Calendar.java
@@ -174,7 +174,7 @@
return Calendar.Calendars.delete(cr,
Calendar.Calendars._SYNC_ACCOUNT + "=? AND "
+ Calendar.Calendars._SYNC_ACCOUNT_TYPE + "=?",
- new String[] {account.mName, account.mType});
+ new String[] {account.name, account.type});
}
/**
diff --git a/core/java/android/provider/ContactsContract.java b/core/java/android/provider/ContactsContract.java
index 7a1a9e4..11cb87f 100644
--- a/core/java/android/provider/ContactsContract.java
+++ b/core/java/android/provider/ContactsContract.java
@@ -1360,6 +1360,14 @@
* <P>Type: INTEGER</P>
*/
public static final String DELETED = "deleted";
+
+ /**
+ * Whether this group should be synced if the SYNC_EVERYTHING settings
+ * is false for this group's account.
+ * <p>
+ * Type: INTEGER (boolean)
+ */
+ public static final String SHOULD_SYNC = "should_sync";
}
/**
diff --git a/core/java/android/provider/Im.java b/core/java/android/provider/Im.java
index b11abe8..b1cf648 100644
--- a/core/java/android/provider/Im.java
+++ b/core/java/android/provider/Im.java
@@ -1620,6 +1620,9 @@
/** specifies the last heartbeat interval received from the server */
public static final String SETTING_HEARTBEAT_INTERVAL = "heartbeat_interval";
+ /** specifiy the JID resource used for Google Talk connection */
+ public static final String SETTING_JID_RESOURCE = "jid_resource";
+
/**
* Used for reliable message queue (RMQ). This is for storing the last rmq id received
* from the GTalk server
@@ -1861,6 +1864,14 @@
putLongValue(contentResolver, providerId, SETTING_HEARTBEAT_INTERVAL, interval);
}
+ /**
+ * A convenience method to set the jid resource.
+ */
+ public static void setJidResource(ContentResolver contentResolver,
+ long providerId, String jidResource) {
+ putStringValue(contentResolver, providerId, SETTING_JID_RESOURCE, jidResource);
+ }
+
public static class QueryMap extends ContentQueryMap {
private ContentResolver mContentResolver;
private long mProviderId;
@@ -2047,6 +2058,23 @@
}
/**
+ * Set the JID resource.
+ *
+ * @param jidResource the jid resource to be stored.
+ */
+ public void setJidResource(String jidResource) {
+ ProviderSettings.setJidResource(mContentResolver, mProviderId, jidResource);
+ }
+ /**
+ * Get the JID resource used for the Google Talk connection
+ *
+ * @return the JID resource stored.
+ */
+ public String getJidResource() {
+ return getString(SETTING_JID_RESOURCE, null);
+ }
+
+ /**
* Convenience function for retrieving a single settings value
* as a boolean.
*
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 85a2041..d3e4c4c 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -413,8 +413,6 @@
private static final String TAG = "Settings";
- private static String sJidResource = null;
-
public static class SettingNotFoundException extends AndroidException {
public SettingNotFoundException(String msg) {
super(msg);
@@ -3622,42 +3620,6 @@
}
/**
- * Returns the GTalk JID resource associated with this device.
- *
- * @return String the JID resource of the device. It uses the device IMEI in the computation
- * of the JID resource. If IMEI is not ready (i.e. telephony module not ready), we'll return
- * an empty string.
- * @hide
- */
- // TODO: we shouldn't not have a permenant Jid resource, as that's an easy target for
- // spams. We should change it once a while, like when we resubscribe to the subscription feeds
- // server.
- // (also, should this live in GTalkService?)
- public static synchronized String getJidResource() {
- if (sJidResource != null) {
- return sJidResource;
- }
-
- MessageDigest digest;
- try {
- digest = MessageDigest.getInstance("SHA-1");
- } catch (NoSuchAlgorithmException e) {
- throw new RuntimeException("this should never happen");
- }
-
- String deviceId = TelephonyManager.getDefault().getDeviceId();
- if (TextUtils.isEmpty(deviceId)) {
- return "";
- }
-
- byte[] hashedDeviceId = digest.digest(deviceId.getBytes());
- String id = new String(Base64.encodeBase64(hashedDeviceId), 0, 12);
- id = id.replaceAll("/", "_");
- sJidResource = JID_RESOURCE_PREFIX + id;
- return sJidResource;
- }
-
- /**
* Returns the device ID that we should use when connecting to the mobile gtalk server.
* This is a string like "android-0x1242", where the hex string is the Android ID obtained
* from the GoogleLoginService.
diff --git a/core/java/android/provider/SubscribedFeeds.java b/core/java/android/provider/SubscribedFeeds.java
index f94b442..8e9f402 100644
--- a/core/java/android/provider/SubscribedFeeds.java
+++ b/core/java/android/provider/SubscribedFeeds.java
@@ -119,8 +119,8 @@
String authority, String service) {
ContentValues values = new ContentValues();
values.put(SubscribedFeeds.Feeds.FEED, feed);
- values.put(SubscribedFeeds.Feeds._SYNC_ACCOUNT, account.mName);
- values.put(SubscribedFeeds.Feeds._SYNC_ACCOUNT_TYPE, account.mType);
+ values.put(SubscribedFeeds.Feeds._SYNC_ACCOUNT, account.name);
+ values.put(SubscribedFeeds.Feeds._SYNC_ACCOUNT_TYPE, account.type);
values.put(SubscribedFeeds.Feeds.AUTHORITY, authority);
values.put(SubscribedFeeds.Feeds.SERVICE, service);
return resolver.insert(SubscribedFeeds.Feeds.CONTENT_URI, values);
@@ -134,7 +134,7 @@
where.append(" AND " + SubscribedFeeds.Feeds.FEED + "=?");
where.append(" AND " + SubscribedFeeds.Feeds.AUTHORITY + "=?");
return resolver.delete(SubscribedFeeds.Feeds.CONTENT_URI,
- where.toString(), new String[] {account.mName, account.mType, feed, authority});
+ where.toString(), new String[] {account.name, account.type, feed, authority});
}
public static int deleteFeeds(ContentResolver resolver,
@@ -144,7 +144,7 @@
where.append(" AND " + SubscribedFeeds.Feeds._SYNC_ACCOUNT_TYPE + "=?");
where.append(" AND " + SubscribedFeeds.Feeds.AUTHORITY + "=?");
return resolver.delete(SubscribedFeeds.Feeds.CONTENT_URI,
- where.toString(), new String[] {account.mName, account.mType, authority});
+ where.toString(), new String[] {account.name, account.type, authority});
}
/**
diff --git a/core/java/android/provider/SyncStateContract.java b/core/java/android/provider/SyncStateContract.java
index 7927e28..5c93af0 100644
--- a/core/java/android/provider/SyncStateContract.java
+++ b/core/java/android/provider/SyncStateContract.java
@@ -71,7 +71,7 @@
public static byte[] get(ContentProviderClient provider, Uri uri,
Account account) throws RemoteException {
Cursor c = provider.query(uri, DATA_PROJECTION, SELECT_BY_ACCOUNT,
- new String[]{account.mName, account.mType}, null);
+ new String[]{account.name, account.type}, null);
try {
if (c.moveToNext()) {
return c.getBlob(c.getColumnIndexOrThrow(Columns.DATA));
@@ -96,8 +96,8 @@
Account account, byte[] data) throws RemoteException {
ContentValues values = new ContentValues();
values.put(Columns.DATA, data);
- values.put(Columns.ACCOUNT_NAME, account.mName);
- values.put(Columns.ACCOUNT_TYPE, account.mType);
+ values.put(Columns.ACCOUNT_NAME, account.name);
+ values.put(Columns.ACCOUNT_TYPE, account.type);
provider.insert(uri, values);
}
@@ -116,8 +116,8 @@
values.put(Columns.DATA, data);
return ContentProviderOperation
.newInsert(uri)
- .withValue(Columns.ACCOUNT_NAME, account.mName)
- .withValue(Columns.ACCOUNT_TYPE, account.mType)
+ .withValue(Columns.ACCOUNT_NAME, account.name)
+ .withValue(Columns.ACCOUNT_TYPE, account.type)
.withValues(values)
.build();
}
diff --git a/core/res/res/values-en-rUS/donottranslate-names.xml b/core/res/res/values-en-rUS/donottranslate-names.xml
new file mode 100644
index 0000000..42c8ab4
--- /dev/null
+++ b/core/res/res/values-en-rUS/donottranslate-names.xml
@@ -0,0 +1,155 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+ <!-- various string resources for Contacts -->
+ <string-array name="common_nicknames">
+ <item>Albert, Al, Bert, Bertie</item>
+ <item>Alexander, Al, Alex, Lex, Sasha</item>
+ <item>Alexandra, Al, Alex, Allie, Ally, Lex, Lexie, Sandra, Sandy, Sasha</item>
+ <item>Alice, Allie, Ally</item>
+ <item>Alison, Allie, Ally</item>
+ <item>Allison, Allie, Ally</item>
+ <item>Amanda, Mandi, Mandy</item>
+ <item>Andrea, Andie</item>
+ <item>Andrew, Andy, Drew</item>
+ <item>Anthony, Tony, Toni, Tone</item>
+ <item>Arthur, Art, Arty</item>
+ <item>Barbara, Babs, Barb, Barbie</item>
+ <item>Benjamin, Ben, Benji, Benny</item>
+ <item>Bernard, Bern, Bernie</item>
+ <item>Bertram, Bert, Bertie</item>
+ <item>Bradly, Brad</item>
+ <item>Catherine, Cat, Cate, Cath, Catie, Cathy, Kat, Kate, Katie, Kathy</item>
+ <item>Charles, Chuck, Chaz, Charlie, Buck</item>
+ <item>Christine, Chris, Chrissy, Chrissie</item>
+ <item>Christopher, Chris</item>
+ <item>Cynthia, Cindy, Cynth</item>
+ <item>Daniel, Dan, Danny</item>
+ <item>David, Dave</item>
+ <item>Deborah, Deb, Debbie</item>
+ <item>Dennis, Den, Denny, Dean</item>
+ <item>Dolores, Dolly</item>
+ <item>Donald, Don, Donny</item>
+ <item>Donnatella, Donna</item>
+ <item>Dorothea, Dot, Dotty</item>
+ <item>Dorothy, Dot, Dotty</item>
+ <item>Douglas, Doug</item>
+ <item>Edward, Ed, Eddie, Ned, Neddie, Neddy, Ted, Teddy, Teddie</item>
+ <item>Eleanor, Ella, Ellie, Elle</item>
+ <item>Elisabetta, Betta</item>
+ <item>Elizabeth, Beth, Bess, Bessie, Betsy, Betty, Bette, Eliza, Lisa, Liza, Liz</item>
+ <item>Emily, Em, Ems, Emmy</item>
+ <item>Emma, Em, Ems, Emmy</item>
+ <item>Erica, Rikki, Rikkie, Ricky</item>
+ <item>Eugene, Gene</item>
+ <item>Florence, Flo</item>
+ <item>Frances, Fran, Francie</item>
+ <item>Francis, Fran, Frank</item>
+ <item>Frederick, Fred, Freddy</item>
+ <item>Gabriel, Gabe</item>
+ <item>Geoffrey, Jeff</item>
+ <item>Gerald, Gerry</item>
+ <item>Gerard, Gerry</item>
+ <item>Gregory, Greg</item>
+ <item>Harold, Hal, Hank, Harry</item>
+ <item>Henry, Hal, Hank, Harry</item>
+ <item>Herbert, Bert, Bertie</item>
+ <item>Irving, Irv</item>
+ <item>Isabella, Isa, Izzy</item>
+ <item>Jacob, Jake</item>
+ <item>Jacqueline, Jackie</item>
+ <item>James, Jim, Jimmy, Jamie, Jock</item>
+ <item>Janet, Jan</item>
+ <item>Janice, Jan</item>
+ <item>Jason, Jay</item>
+ <item>Jefferson, Jeff</item>
+ <item>Jeffrey, Jeff</item>
+ <item>Jennifer, Jen, Jenny</item>
+ <item>Jerome, Jerry</item>
+ <item>Jessica, Jessie</item>
+ <item>John, Jack, Jacky, Johnny, Jon</item>
+ <item>Jonathan, Jon, John</item>
+ <item>Joseph, Joe, Joey</item>
+ <item>Joshua, Josh</item>
+ <item>Kaitlyn, Cat, Cate, Catie, Cath, Cathy, Kat, Kate, Katie, Kathy</item>
+ <item>Katherine, Cat, Cate, Catie, Cath, Cathy, Kat, Kate, Katie, Kathy</item>
+ <item>Kathleen, Cat, Cate, Catie, Cath, Cathy, Kat, Kate, Katie, Kathy</item>
+ <item>Katrina, Cat, Cate, Catie, Cath, Cathy, Kat, Kate, Katie, Kathy</item>
+ <item>Kenneth, Ken</item>
+ <item>Kevin, Kev</item>
+ <item>Laura, Lauri, Laurie</item>
+ <item>Lauren, Lauri, Laurie</item>
+ <item>Laurence, Larry, Lauri, Laurie</item>
+ <item>Lawrence, Larry, Lauri, Laurie</item>
+ <item>Leonard, Leo, Len, Lenny</item>
+ <item>Leopold, Leo, Len, Lenny</item>
+ <item>Madeline, Maddie, Maddy</item>
+ <item>Margaret, Marge, Marg, Maggie, Mags, Meg, Peggy</item>
+ <item>Matthew, Matt, Mattie</item>
+ <item>Maureen, Mo</item>
+ <item>Maurice, Mo</item>
+ <item>Megan, Meg</item>
+ <item>Michael, Mickey, Mick, Mike, Mikey</item>
+ <item>Morris, Mo</item>
+ <item>Nancy, Nan</item>
+ <item>Nathan, Nat, Nate</item>
+ <item>Nathaniel, Nat, Nate</item>
+ <item>Nicholas, Nick</item>
+ <item>Pamela, Pam</item>
+ <item>Patricia, Pat, Patsy, Patty, Trish, Tricia</item>
+ <item>Patrick, Paddy, Pat, Patty, Patter, Rick, Ricky</item>
+ <item>Peter, Pete</item>
+ <item>Raymond, Ray</item>
+ <item>Philip, Phil</item>
+ <item>Rebecca, Becca</item>
+ <item>Richard, Rick, Rich, Dick</item>
+ <item>Robert, Bob, Rob, Robbie, Bobby, Rab</item>
+ <item>Roberta, Bobbie</item>
+ <item>Rodney. Rod</item>
+ <item>Ronald, Ron, Ronnie</item>
+ <item>Rosemary, Rosie, Rose</item>
+ <item>Russell, Russ, Rusty</item>
+ <item>Ryan, Ry</item>
+ <item>Samantha, Sam</item>
+ <item>Samuel, Sam, Sammy</item>
+ <item>Sophia, Sophie</item>
+ <item>Stephanie, Steph, Stephie</item>
+ <item>Stephen, Steve</item>
+ <item>Steven, Steve</item>
+ <item>Stuart, Stu</item>
+ <item>Susan, Sue, Susie, Suzie</item>
+ <item>Suzanne, Sue, Susie, Suzie</item>
+ <item>Teresa, Terrie, Terry</item>
+ <item>Theodora, Teddie, Thea, Theo</item>
+ <item>Theodore, Ted, Teddy, Theo</item>
+ <item>Thomas, Tom, Thom, Tommy</item>
+ <item>Timothy, Tim, Timmy</item>
+ <item>Valerie, Val</item>
+ <item>Veronica, Ronnie, Roni, Nica, Nikki, Nikka</item>
+ <item>Victor, Vic</item>
+ <item>Victoria, Vicky, Vicki, Vickie, Tori</item>
+ <item>Vincent, Vince, Vin, Vinnie</item>
+ <item>Vivian, Vivi</item>
+ <item>Walter, Walt, Wally</item>
+ <item>Wendy, Wen, Wendel</item>
+ <item>William, Bill, Billy, Will, Willy, Liam</item>
+ <item>Yvonna, Vonna</item>
+ <item>Zachary, Zach, Zack, Zac</item>
+ </string-array>
+ <string name="common_name_prefixes">
+ 1LT, 1ST, 2LT, 2ND, 3RD, ADMIRAL, CAPT, CAPTAIN, COL, CPT, DR,
+ GEN, GENERAL, LCDR, LT, LTC, LTG, LTJG, MAJ, MAJOR, MG, MR,
+ MRS, MS, PASTOR, PROF, REP, REVEREND, REV, SEN, ST
+ </string>
+ <string name="common_name_suffixes">
+ B.A., BA, D.D.S., DDS, I, II, III, IV, IX, JR, M.A., M.D, MA,
+ MD, MS, PH.D., PHD, SR, V, VI, VII, VIII, X
+ </string>
+ <string name="common_last_name_prefixes">
+ D', DE, DEL, DI, LA, LE, MC, SAN, ST, TER, VAN, VON
+ </string>
+ <string name="common_name_conjunctions">
+ &, AND, OR
+ </string>
+</resources>
diff --git a/core/res/res/values/donottranslate-names.xml b/core/res/res/values/donottranslate-names.xml
new file mode 100644
index 0000000..56ae47a
--- /dev/null
+++ b/core/res/res/values/donottranslate-names.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+ <!-- Various locale-specific string resources for Contacts -->
+ <string-array name="common_nicknames"></string-array>
+ <string name="common_name_prefixes"></string>
+ <string name="common_name_suffixes"></string>
+ <string name="common_last_name_prefixes"></string>
+ <string name="common_name_conjunctions"></string>
+</resources>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 815b767..22f9136 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -1923,157 +1923,6 @@
<!-- This string appears (on two lines) when you type a number into contacts search, to let you create a contact whose phone number is the number you typed. The first line will be in bigger type than the second. -->
<string name="create_contact_using">Create contact\nusing <xliff:g id="number" example="555">%s</xliff:g></string>
- <!-- various string resources for Contacts -->
- <string-array name="common_nicknames">
- <item>Albert, Al, Bert, Bertie</item>
- <item>Alexander, Al, Alex, Lex, Sasha</item>
- <item>Alexandra, Al, Alex, Allie, Ally, Lex, Lexie, Sandra, Sandy, Sasha</item>
- <item>Alice, Allie, Ally</item>
- <item>Alison, Allie, Ally</item>
- <item>Allison, Allie, Ally</item>
- <item>Amanda, Mandi, Mandy</item>
- <item>Andrea, Andie</item>
- <item>Andrew, Andy, Drew</item>
- <item>Anthony, Tony, Toni, Tone</item>
- <item>Arthur, Art, Arty</item>
- <item>Barbara, Babs, Barb, Barbie</item>
- <item>Benjamin, Ben, Benji, Benny</item>
- <item>Bernard, Bern, Bernie</item>
- <item>Bertram, Bert, Bertie</item>
- <item>Bradly, Brad</item>
- <item>Catherine, Cat, Cate, Cath, Catie, Cathy, Kat, Kate, Katie, Kathy</item>
- <item>Charles, Chuck, Chaz, Charlie, Buck</item>
- <item>Christine, Chris, Chrissy, Chrissie</item>
- <item>Christopher, Chris</item>
- <item>Cynthia, Cindy, Cynth</item>
- <item>Daniel, Dan, Danny</item>
- <item>David, Dave</item>
- <item>Deborah, Deb, Debbie</item>
- <item>Dennis, Den, Denny, Dean</item>
- <item>Dolores, Dolly</item>
- <item>Donald, Don, Donny</item>
- <item>Donnatella, Donna</item>
- <item>Dorothea, Dot, Dotty</item>
- <item>Dorothy, Dot, Dotty</item>
- <item>Douglas, Doug</item>
- <item>Edward, Ed, Eddie, Ned, Neddie, Neddy, Ted, Teddy, Teddie</item>
- <item>Eleanor, Ella, Ellie, Elle</item>
- <item>Elisabetta, Betta</item>
- <item>Elizabeth, Beth, Bess, Bessie, Betsy, Betty, Bette, Eliza, Lisa, Liza, Liz</item>
- <item>Emily, Em, Ems, Emmy</item>
- <item>Emma, Em, Ems, Emmy</item>
- <item>Erica, Rikki, Rikkie, Ricky</item>
- <item>Eugene, Gene</item>
- <item>Florence, Flo</item>
- <item>Frances, Fran, Francie</item>
- <item>Francis, Fran, Frank</item>
- <item>Frederick, Fred, Freddy</item>
- <item>Gabriel, Gabe</item>
- <item>Geoffrey, Jeff</item>
- <item>Gerald, Gerry</item>
- <item>Gerard, Gerry</item>
- <item>Gregory, Greg</item>
- <item>Harold, Hal, Hank, Harry</item>
- <item>Henry, Hal, Hank, Harry</item>
- <item>Herbert, Bert, Bertie</item>
- <item>Irving, Irv</item>
- <item>Isabella, Isa, Izzy</item>
- <item>Jacob, Jake</item>
- <item>Jacqueline, Jackie</item>
- <item>James, Jim, Jimmy, Jamie, Jock</item>
- <item>Janet, Jan</item>
- <item>Janice, Jan</item>
- <item>Jason, Jay</item>
- <item>Jefferson, Jeff</item>
- <item>Jeffrey, Jeff</item>
- <item>Jennifer, Jen, Jenny</item>
- <item>Jerome, Jerry</item>
- <item>Jessica, Jessie</item>
- <item>John, Jack, Jacky, Johnny, Jon</item>
- <item>Jonathan, Jon, John</item>
- <item>Joseph, Joe, Joey</item>
- <item>Joshua, Josh</item>
- <item>Kaitlyn, Cat, Cate, Catie, Cath, Cathy, Kat, Kate, Katie, Kathy</item>
- <item>Katherine, Cat, Cate, Catie, Cath, Cathy, Kat, Kate, Katie, Kathy</item>
- <item>Kathleen, Cat, Cate, Catie, Cath, Cathy, Kat, Kate, Katie, Kathy</item>
- <item>Katrina, Cat, Cate, Catie, Cath, Cathy, Kat, Kate, Katie, Kathy</item>
- <item>Kenneth, Ken</item>
- <item>Kevin, Kev</item>
- <item>Laura, Lauri, Laurie</item>
- <item>Lauren, Lauri, Laurie</item>
- <item>Laurence, Larry, Lauri, Laurie</item>
- <item>Lawrence, Larry, Lauri, Laurie</item>
- <item>Leonard, Leo, Len, Lenny</item>
- <item>Leopold, Leo, Len, Lenny</item>
- <item>Madeline, Maddie, Maddy</item>
- <item>Margaret, Marge, Marg, Maggie, Mags, Meg, Peggy</item>
- <item>Matthew, Matt, Mattie</item>
- <item>Maureen, Mo</item>
- <item>Maurice, Mo</item>
- <item>Megan, Meg</item>
- <item>Michael, Mickey, Mick, Mike, Mikey</item>
- <item>Morris, Mo</item>
- <item>Nancy, Nan</item>
- <item>Nathan, Nat, Nate</item>
- <item>Nathaniel, Nat, Nate</item>
- <item>Nicholas, Nick</item>
- <item>Pamela, Pam</item>
- <item>Patricia, Pat, Patsy, Patty, Trish, Tricia</item>
- <item>Patrick, Paddy, Pat, Patty, Patter, Rick, Ricky</item>
- <item>Peter, Pete</item>
- <item>Raymond, Ray</item>
- <item>Philip, Phil</item>
- <item>Rebecca, Becca</item>
- <item>Richard, Rick, Rich, Dick</item>
- <item>Robert, Bob, Rob, Robbie, Bobby, Rab</item>
- <item>Roberta, Bobbie</item>
- <item>Rodney. Rod</item>
- <item>Ronald, Ron, Ronnie</item>
- <item>Rosemary, Rosie, Rose</item>
- <item>Russell, Russ, Rusty</item>
- <item>Ryan, Ry</item>
- <item>Samantha, Sam</item>
- <item>Samuel, Sam, Sammy</item>
- <item>Sophia, Sophie</item>
- <item>Stephanie, Steph, Stephie</item>
- <item>Stephen, Steve</item>
- <item>Steven, Steve</item>
- <item>Stuart, Stu</item>
- <item>Susan, Sue, Susie, Suzie</item>
- <item>Suzanne, Sue, Susie, Suzie</item>
- <item>Teresa, Terrie, Terry</item>
- <item>Theodora, Teddie, Thea, Theo</item>
- <item>Theodore, Ted, Teddy, Theo</item>
- <item>Thomas, Tom, Thom, Tommy</item>
- <item>Timothy, Tim, Timmy</item>
- <item>Valerie, Val</item>
- <item>Veronica, Ronnie, Roni, Nica, Nikki, Nikka</item>
- <item>Victor, Vic</item>
- <item>Victoria, Vicky, Vicki, Vickie, Tori</item>
- <item>Vincent, Vince, Vin, Vinnie</item>
- <item>Vivian, Vivi</item>
- <item>Walter, Walt, Wally</item>
- <item>Wendy, Wen, Wendel</item>
- <item>William, Bill, Billy, Will, Willy, Liam</item>
- <item>Yvonna, Vonna</item>
- <item>Zachary, Zach, Zack, Zac</item>
- </string-array>
- <string name="common_name_prefixes">
- 1LT, 1ST, 2LT, 2ND, 3RD, ADMIRAL, CAPT, CAPTAIN, COL, CPT, DR,
- GEN, GENERAL, LCDR, LT, LTC, LTG, LTJG, MAJ, MAJOR, MG, MR,
- MRS, MS, PASTOR, PROF, REP, REVEREND, REV, SEN, ST
- </string>
- <string name="common_name_suffixes">
- B.A., BA, D.D.S., DDS, I, II, III, IV, IX, JR, M.A., M.D, MA,
- MD, MS, PH.D., PHD, SR, V, VI, VII, VIII, X
- </string>
- <string name="common_last_name_prefixes">
- D', DE, DEL, DI, LA, LE, MC, SAN, ST, TER, VAN, VON
- </string>
- <string name="common_name_conjunctions">
- &, AND, OR
- </string>
-
<!-- This string array should be overridden by the manufacture to present a list of carrier-id,locale,wifi-channel sets. This is used at startup to set system defaults by checking the system property ro.carrier for the carrier-id and searching through this array -->
<!-- An Array of [[Carrier-ID] -->
<!-- [default-locale] -->
diff --git a/include/media/mediametadataretriever.h b/include/media/mediametadataretriever.h
index 3db8a0f..9ea2775 100644
--- a/include/media/mediametadataretriever.h
+++ b/include/media/mediametadataretriever.h
@@ -52,6 +52,7 @@
METADATA_KEY_VIDEO_FORMAT = 18,
METADATA_KEY_VIDEO_HEIGHT = 19,
METADATA_KEY_VIDEO_WIDTH = 20,
+ METADATA_KEY_WRITER = 21,
// Add more here...
};
diff --git a/include/ui/Surface.h b/include/ui/Surface.h
index 4ff0e4a..30ab82f 100644
--- a/include/ui/Surface.h
+++ b/include/ui/Surface.h
@@ -146,16 +146,16 @@
static bool isValid(const sp<Surface>& surface) {
return (surface != 0) && surface->isValid();
}
- bool isValid() {
- return mToken>=0 && mClient!=0;
- }
+
static bool isSameSurface(
const sp<Surface>& lhs, const sp<Surface>& rhs);
- SurfaceID ID() const { return mToken; }
- uint32_t getFlags() const { return mFlags; }
+
+ bool isValid();
+ SurfaceID ID() const { return mToken; }
+ uint32_t getFlags() const { return mFlags; }
uint32_t getIdentity() const { return mIdentity; }
-
+ // the lock/unlock APIs must be used from the same thread
status_t lock(SurfaceInfo* info, bool blocking = true);
status_t lock(SurfaceInfo* info, Region* dirty, bool blocking = true);
status_t unlockAndPost();
@@ -175,14 +175,18 @@
friend class SurfaceComposerClient;
friend class SurfaceControl;
+
// camera and camcorder need access to the ISurface binder interface for preview
friend class Camera;
friend class MediaRecorder;
// mediaplayer needs access to ISurface for display
friend class MediaPlayer;
- friend class Test;
friend class IOMX;
- const sp<ISurface>& getISurface() const { return mSurface; }
+ // this is just to be able to write some unit tests
+ friend class Test;
+
+ sp<SurfaceComposerClient> getClient() const;
+ sp<ISurface> getISurface() const;
status_t getBufferLocked(int index, int usage);
@@ -210,24 +214,38 @@
status_t queueBuffer(const sp<SurfaceBuffer>& buffer);
- alloc_device_t* mAllocDevice;
+ void setUsage(uint32_t reqUsage);
+
+ // constants
sp<SurfaceComposerClient> mClient;
sp<ISurface> mSurface;
- sp<SurfaceBuffer> mBuffers[2];
- sp<SurfaceBuffer> mLockedBuffer;
SurfaceID mToken;
uint32_t mIdentity;
- uint32_t mWidth;
- uint32_t mHeight;
- uint32_t mUsage;
PixelFormat mFormat;
uint32_t mFlags;
- mutable Region mDirtyRegion;
- mutable Region mOldDirtyRegion;
- mutable uint8_t mBackbufferIndex;
- mutable Mutex mSurfaceLock;
- Rect mSwapRectangle;
BufferMapper& mBufferMapper;
+
+ // protected by mSurfaceLock
+ Rect mSwapRectangle;
+ uint32_t mUsage;
+ bool mUsageChanged;
+
+ // protected by mSurfaceLock. These are also used from lock/unlock
+ // but in that case, they must be called form the same thread.
+ sp<SurfaceBuffer> mBuffers[2];
+ mutable Region mDirtyRegion;
+ mutable uint8_t mBackbufferIndex;
+
+ // must be used from the lock/unlock thread
+ sp<SurfaceBuffer> mLockedBuffer;
+ mutable Region mOldDirtyRegion;
+
+ // query() must be called from dequeueBuffer() thread
+ uint32_t mWidth;
+ uint32_t mHeight;
+
+ // Inherently thread-safe
+ mutable Mutex mSurfaceLock;
};
}; // namespace android
diff --git a/libs/ui/Surface.cpp b/libs/ui/Surface.cpp
index 2b6905f..f6792c4 100644
--- a/libs/ui/Surface.cpp
+++ b/libs/ui/Surface.cpp
@@ -382,9 +382,9 @@
Surface::Surface(const sp<SurfaceControl>& surface)
: mClient(surface->mClient), mSurface(surface->mSurface),
mToken(surface->mToken), mIdentity(surface->mIdentity),
- mWidth(surface->mWidth), mHeight(surface->mHeight),
mFormat(surface->mFormat), mFlags(surface->mFlags),
- mBufferMapper(BufferMapper::get())
+ mBufferMapper(BufferMapper::get()),
+ mWidth(surface->mWidth), mHeight(surface->mHeight)
{
init();
}
@@ -426,9 +426,9 @@
const_cast<uint32_t&>(android_native_window_t::flags) = 0;
// be default we request a hardware surface
mUsage = GRALLOC_USAGE_HW_RENDER;
+ mUsageChanged = true;
}
-
Surface::~Surface()
{
// this is a client-side operation, the surface is destroyed, unmap
@@ -446,11 +446,24 @@
IPCThreadState::self()->flushCommands();
}
+sp<SurfaceComposerClient> Surface::getClient() const {
+ return mClient;
+}
+
+sp<ISurface> Surface::getISurface() const {
+ return mSurface;
+}
+
+bool Surface::isValid() {
+ return mToken>=0 && mClient!=0;
+}
+
status_t Surface::validate(per_client_cblk_t const* cblk) const
{
+ sp<SurfaceComposerClient> client(getClient());
if (mToken<0 || mClient==0) {
LOGE("invalid token (%d, identity=%u) or client (%p)",
- mToken, mIdentity, mClient.get());
+ mToken, mIdentity, client.get());
return NO_INIT;
}
if (cblk == 0) {
@@ -477,6 +490,7 @@
{
if (lhs == 0 || rhs == 0)
return false;
+
return lhs->mSurface->asBinder() == rhs->mSurface->asBinder();
}
@@ -532,10 +546,9 @@
{
android_native_buffer_t* out;
status_t err = dequeueBuffer(&out);
- *buffer = SurfaceBuffer::getSelf(out);
- // reset the width/height with the what we get from the buffer
- mWidth = uint32_t(out->width);
- mHeight = uint32_t(out->height);
+ if (err == NO_ERROR) {
+ *buffer = SurfaceBuffer::getSelf(out);
+ }
return err;
}
@@ -557,7 +570,8 @@
Mutex::Autolock _l(mSurfaceLock);
- per_client_cblk_t* const cblk = mClient->mControl;
+ sp<SurfaceComposerClient> client(getClient());
+ per_client_cblk_t* const cblk = client->mControl;
status_t err = validate(cblk);
if (err != NO_ERROR)
return err;
@@ -572,14 +586,17 @@
mBackbufferIndex = backIdx;
layer_cblk_t* const lcblk = &(cblk->layers[index]);
-
volatile const surface_info_t* const back = lcblk->surface + backIdx;
- if (back->flags & surface_info_t::eNeedNewBuffer) {
+ if ((back->flags & surface_info_t::eNeedNewBuffer) || mUsageChanged) {
+ mUsageChanged = false;
err = getBufferLocked(backIdx, mUsage);
}
if (err == NO_ERROR) {
const sp<SurfaceBuffer>& backBuffer(mBuffers[backIdx]);
+ // reset the width/height with the what we get from the buffer
+ mWidth = uint32_t(backBuffer->width);
+ mHeight = uint32_t(backBuffer->height);
mDirtyRegion.set(backBuffer->width, backBuffer->height);
*buffer = backBuffer.get();
}
@@ -591,7 +608,8 @@
{
Mutex::Autolock _l(mSurfaceLock);
- per_client_cblk_t* const cblk = mClient->mControl;
+ sp<SurfaceComposerClient> client(getClient());
+ per_client_cblk_t* const cblk = client->mControl;
status_t err = validate(cblk);
if (err != NO_ERROR)
return err;
@@ -604,7 +622,8 @@
{
Mutex::Autolock _l(mSurfaceLock);
- per_client_cblk_t* const cblk = mClient->mControl;
+ sp<SurfaceComposerClient> client(getClient());
+ per_client_cblk_t* const cblk = client->mControl;
status_t err = validate(cblk);
if (err != NO_ERROR)
return err;
@@ -620,7 +639,7 @@
uint32_t newstate = cblk->unlock_layer_and_post(size_t(index));
if (!(newstate & eNextFlipPending))
- mClient->signalServer();
+ client->signalServer();
return NO_ERROR;
}
@@ -646,7 +665,7 @@
int res = NO_ERROR;
switch (operation) {
case NATIVE_WINDOW_SET_USAGE:
- mUsage = va_arg(args, int);
+ setUsage( va_arg(args, int) );
break;
default:
res = NAME_NOT_FOUND;
@@ -655,6 +674,15 @@
return res;
}
+void Surface::setUsage(uint32_t reqUsage)
+{
+ Mutex::Autolock _l(mSurfaceLock);
+ if (mUsage != reqUsage) {
+ mUsageChanged = true;
+ mUsage = reqUsage;
+ }
+}
+
// ----------------------------------------------------------------------------
status_t Surface::lock(SurfaceInfo* info, bool blocking) {
@@ -663,11 +691,9 @@
status_t Surface::lock(SurfaceInfo* other, Region* dirtyIn, bool blocking)
{
- // FIXME: needs some locking here
-
// we're intending to do software rendering from this point
- mUsage = GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN;
-
+ setUsage(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN);
+
sp<SurfaceBuffer> backBuffer;
status_t err = dequeueBuffer(&backBuffer);
if (err == NO_ERROR) {
@@ -679,7 +705,8 @@
Region scratch(bounds);
Region& newDirtyRegion(dirtyIn ? *dirtyIn : scratch);
- per_client_cblk_t* const cblk = mClient->mControl;
+ sp<SurfaceComposerClient> client(getClient());
+ per_client_cblk_t* const cblk = client->mControl;
layer_cblk_t* const lcblk = &(cblk->layers[SurfaceID(mToken)]);
volatile const surface_info_t* const back = lcblk->surface + mBackbufferIndex;
if (back->flags & surface_info_t::eBufferDirty) {
@@ -725,8 +752,6 @@
status_t Surface::unlockAndPost()
{
- // FIXME: needs some locking here
-
if (mLockedBuffer == 0)
return BAD_VALUE;
@@ -753,13 +778,17 @@
}
void Surface::setSwapRectangle(const Rect& r) {
+ Mutex::Autolock _l(mSurfaceLock);
mSwapRectangle = r;
}
status_t Surface::getBufferLocked(int index, int usage)
{
+ sp<ISurface> s(mSurface);
+ if (s == 0) return NO_INIT;
+
status_t err = NO_MEMORY;
- sp<SurfaceBuffer> buffer = mSurface->getBuffer(usage);
+ sp<SurfaceBuffer> buffer = s->getBuffer(usage);
LOGE_IF(buffer==0, "ISurface::getBuffer() returned NULL");
if (buffer != 0) {
sp<SurfaceBuffer>& currentBuffer(mBuffers[index]);
diff --git a/media/java/android/media/MediaMetadataRetriever.java b/media/java/android/media/MediaMetadataRetriever.java
index c6a9ae8..cecf4f8 100644
--- a/media/java/android/media/MediaMetadataRetriever.java
+++ b/media/java/android/media/MediaMetadataRetriever.java
@@ -254,5 +254,6 @@
public static final int METADATA_KEY_VIDEO_FORMAT = 18;
public static final int METADATA_KEY_VIDEO_HEIGHT = 19;
public static final int METADATA_KEY_VIDEO_WIDTH = 20;
+ public static final int METADATA_KEY_WRITER = 21;
// Add more here...
}
diff --git a/media/java/android/media/MediaScanner.java b/media/java/android/media/MediaScanner.java
index 71af909..376057e 100644
--- a/media/java/android/media/MediaScanner.java
+++ b/media/java/android/media/MediaScanner.java
@@ -396,6 +396,7 @@
private String mPath;
private long mLastModified;
private long mFileSize;
+ private String mWriter;
public FileCacheEntry beginFile(String path, String mimeType, long lastModified, long fileSize) {
@@ -479,6 +480,7 @@
mDuration = 0;
mPath = path;
mLastModified = lastModified;
+ mWriter = null;
return entry;
}
@@ -593,6 +595,8 @@
mTrack = (num * 1000) + (mTrack % 1000);
} else if (name.equalsIgnoreCase("duration")) {
mDuration = parseSubstring(value, 0, 0);
+ } else if (name.equalsIgnoreCase("writer") || name.startsWith("writer;")) {
+ mWriter = value.trim();
}
}
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaNames.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaNames.java
index e76967d..3f2bc39 100755
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaNames.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaNames.java
@@ -372,81 +372,81 @@
public static final String META_DATA_MP3 [][] = {
{"/sdcard/media_api/metaDataTestMedias/MP3/ID3V1_ID3V2.mp3", "1/10", "ID3V2.3 Album", "ID3V2.3 Artist",
"ID3V2.3 Lyricist", "ID3V2.3 Composer", null, "Blues",
- "ID3V2.3 Title", "1234", "295", "1"},
+ "ID3V2.3 Title", "1234", "295", "1", null},
{"/sdcard/media_api/metaDataTestMedias/MP3/ID3V2.mp3", "1/10", "ID3V2.3 Album", "ID3V2.3 Artist",
"ID3V2.3 Lyricist", "ID3V2.3 Composer", null, "Blues",
- "ID3V2.3 Title", "1234", "287", "1"},
+ "ID3V2.3 Title", "1234", "287", "1", null},
{"/sdcard/media_api/metaDataTestMedias/MP3/ID3V1.mp3", "1", "test ID3V1 Album", "test ID3V1 Artist",
- null, null, null, "255", "test ID3V1 Title", "1234", "231332", "1"},
+ null, null, null, "255", "test ID3V1 Title", "1234", "231332", "1", null},
{"/sdcard/media_api/metaDataTestMedias/MP3/Corrupted_ID3V1.mp3" , null, null, null,
- null, null, null, null, null, null, "231330", "1"},
+ null, null, null, null, null, null, "231330", "1", null},
//The corrupted TALB field in id3v2 would not switch to id3v1 tag automatically
{"/sdcard/media_api/metaDataTestMedias/MP3/Corrupted_ID3V2_TALB.mp3", "01", null, "ID3V2.3 Artist",
"ID3V2.3 Lyricist", "ID3V2.3 Composer", null,
- "Blues", "ID3V2.3 Title", "1234", "295", "1"},
+ "Blues", "ID3V2.3 Title", "1234", "295", "1", null},
{"/sdcard/media_api/metaDataTestMedias/MP3/Corrupted_ID3V2_TCOM.mp3", "01", "ID3V2.3 Album",
"ID3V2.3 Artist", "ID3V2.3 Lyricist", null, null,
- "Blues", "ID3V2.3 Title", "1234", "295", "1"},
+ "Blues", "ID3V2.3 Title", "1234", "295", "1", null},
{"/sdcard/media_api/metaDataTestMedias/MP3/Corrupted_ID3V2_TCOM_2.mp3", "01", "ID3V2.3 Album",
- "ID3V2.3 Artist", null, null, null, "Blues", "ID3V2.3 Title", "1234", "295", "1"},
+ "ID3V2.3 Artist", null, null, null, "Blues", "ID3V2.3 Title", "1234", "295", "1", null},
{"/sdcard/media_api/metaDataTestMedias/MP3/Corrupted_ID3V2_TRCK.mp3", "dd", "ID3V2.3 Album",
"ID3V2.3 Artist", "ID3V2.3 Lyricist", "ID3V2.3 Composer", null,
- "Blues", "ID3V2.3 Title", "1234", "295", "1"},
+ "Blues", "ID3V2.3 Title", "1234", "295", "1", null},
{"/sdcard/media_api/metaDataTestMedias/MP3/Corrupted_ID3V2_TRCK_2.mp3", "01", "ID3V2.3 Album",
- "ID3V2.3 Artist", null, null, null, "255", "ID3V2.3 Title", "1234", "295", "1"},
+ "ID3V2.3 Artist", null, null, null, "255", "ID3V2.3 Title", "1234", "295", "1", null},
{"/sdcard/media_api/metaDataTestMedias/MP3/Corrupted_ID3V2_TYER.mp3", "01", "ID3V2.3 Album",
- "ID3V2.3 Artist", null, null, null, null, "ID3V2.3 Title", "9999", "295", "1"},
+ "ID3V2.3 Artist", null, null, null, null, "ID3V2.3 Title", "9999", "295", "1", null},
{"/sdcard/media_api/metaDataTestMedias/MP3/Corrupted_ID3V2_TYER_2.mp3", "01", "ID3V2.3 Album",
"ID3V2.3 Artist", "ID3V2.3 Lyricist", "ID3V2.3 Composer", null,
- "Blues", "ID3V2.3 Title", null, "295", "1"},
+ "Blues", "ID3V2.3 Title", null, "295", "1", null},
{"/sdcard/media_api/metaDataTestMedias/MP3/Corrupted_ID3V2_TIT.mp3", null, null, null,
- null, null, null, null, null, null, "295", "1"}
+ null, null, null, null, null, null, "295", "1", null}
};
public static final String META_DATA_OTHERS [][] = {
{"/sdcard/media_api/metaDataTestMedias/3GP/cat.3gp", null, null, null,
null, null, "20080309T002415.000Z", null,
- null, null, "1404928", "2"},
+ null, null, "1404928", "2", null},
{"/sdcard/media_api/metaDataTestMedias/AMR/AMR_NB.amr", null, null, null,
null, null, null, null,
- null, null, "126540", "1"},
+ null, null, "126540", "1", null},
{"/sdcard/media_api/metaDataTestMedias/AMRWB/AMR_WB.amr", null, null, null,
null, null, null, null,
- null, null, "231180", "1"},
- {"/sdcard/media_api/metaDataTestMedias/M4A/Jaws Of Life_ver1.m4a", null, "Suspended Animation",
+ null, null, "231180", "1", null},
+ {"/sdcard/media_api/metaDataTestMedias/M4A/Jaws Of Life_ver1.m4a", "1/8", "Suspended Animation",
"John Petrucci", null, null, "20070510T125223.000Z",
- null, null, "2005", "231180", "1"},
+ "13", "Jaws Of Life", "2005", "19815424", "1", "m4a composer"},
{"/sdcard/media_api/metaDataTestMedias/M4V/sample_iPod.m4v", null, null,
null, null, null, "20051220T202015.000Z",
- null, null, null, "3771392", "2"},
+ null, null, null, "3771392", "2", null},
{"/sdcard/media_api/metaDataTestMedias/MIDI/MIDI.mid", null, "Suspended Animation",
"John Petrucci", null, null, "20070510T125223.000Z",
- null, null, "2005", "231180", "1"},
- {"/sdcard/media_api/metaDataTestMedias/MP4/kung_fu_panda_h264.mp4", null, "mp4 album Kung Fu Panda",
+ null, null, "2005", "231180", "1", null},
+ {"/sdcard/media_api/metaDataTestMedias/MP4/kung_fu_panda_h264.mp4", "2/0", "mp4 album Kung Fu Panda",
"mp4 artist Kung Fu Panda", null, null, "20080517T091451.000Z",
- "41", "Kung Fu Panda", "2008", "5667840", "2"},
+ "41", "Kung Fu Panda", "2008", "5667840", "2", "mp4 composer"},
{"/sdcard/media_api/metaDataTestMedias/OGG/Ring_Classic_02.ogg", null, "Suspended Animation",
"John Petrucci", null, null, "20070510T125223.000Z",
- null, null, "2005", "231180", "1"},
+ null, null, "2005", "231180", "1", null},
{"/sdcard/media_api/metaDataTestMedias/OGG/When You Say Nothing At All.ogg",
null, "Suspended Animation", "John Petrucci",
- null, null, "20070510T125223.000Z", null, null, "2005", "231180", "1"},
+ null, null, "20070510T125223.000Z", null, null, "2005", "231180", "1", null},
{"/sdcard/media_api/metaDataTestMedias/WAV/Im With You.wav", null, null,
null, null, null, null,
- null, null, null, "224000", "1"},
+ null, null, null, "224000", "1", null},
{"/sdcard/media_api/metaDataTestMedias/WMA/WMA9.wma", "6", "Ten Songs in the Key of Betrayal",
"Alien Crime Syndicate", "Alien Crime Syndicate",
"wma 9 Composer", "20040521T175729.483Z",
- "Rock", "Run for the Money", "2004", "134479", "1"},
+ "Rock", "Run for the Money", "2004", "134479", "1", null},
{"/sdcard/media_api/metaDataTestMedias/WMA/WMA10.wma", "09", "wma 10 Album",
"wma 10 Album Artist", "wma 10 Artist", "wma 10 Composer", "20070705T063625.097Z",
- "Acid Jazz", "wma 10 Title", "2010", "126574", "1"},
+ "Acid Jazz", "wma 10 Title", "2010", "126574", "1", null},
{"/sdcard/media_api/metaDataTestMedias/WMV/bugs.wmv", "8", "wmv 9 Album",
null, "wmv 9 Artist ", null, "20051122T155247.540Z",
- null, "Looney Tunes - Hare-Breadth Hurry", "2005", "193482", "2"},
+ null, "Looney Tunes - Hare-Breadth Hurry", "2005", "193482", "2", null},
{"/sdcard/media_api/metaDataTestMedias/WMV/clips_ver7.wmv", "50", "wmv 7 Album",
null, "Hallau Shoots & Company", null, "20020226T170045.891Z",
- null, "CODEC Shootout", "1986", "43709", "2"}
+ null, "CODEC Shootout", "1986", "43709", "2", null}
};
//output recorded video
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaMetadataTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaMetadataTest.java
index 3715913..1bf4958 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaMetadataTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaMetadataTest.java
@@ -36,7 +36,7 @@
FILE_PATH,CD_TRACK, ALBUM,
ARTIST, AUTHOR, COMPOSER,
DATE, GENRE, TITLE,
- YEAR, DURATION, NUM_TRACKS
+ YEAR, DURATION, NUM_TRACKS, WRITER
}
public static enum MP3_TEST_FILE{
@@ -130,8 +130,6 @@
validateMetatData(non_mp3_test_file.AMRWB.ordinal(), MediaNames.META_DATA_OTHERS);
}
- //Bug# 1440173 - skip this test case now
- @Suppress
@MediumTest
public static void testM4A1_Metadata() throws Exception {
validateMetatData(non_mp3_test_file.M4A1.ordinal(), MediaNames.META_DATA_OTHERS);
@@ -254,6 +252,10 @@
Log.v(TAG, "Track : "+ value);
assertEquals(TAG,meta_data_file[fileIndex][meta.NUM_TRACKS.ordinal()], value);
+ value = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_WRITER);
+ Log.v(TAG, "Writer : "+ value);
+ assertEquals(TAG,meta_data_file[fileIndex][meta.WRITER.ordinal()], value);
+
retriever.release();
}
}
diff --git a/packages/SubscribedFeedsProvider/src/com/android/providers/subscribedfeeds/SubscribedFeedsIntentService.java b/packages/SubscribedFeedsProvider/src/com/android/providers/subscribedfeeds/SubscribedFeedsIntentService.java
index 3cd2cc4..b854f86 100644
--- a/packages/SubscribedFeedsProvider/src/com/android/providers/subscribedfeeds/SubscribedFeedsIntentService.java
+++ b/packages/SubscribedFeedsProvider/src/com/android/providers/subscribedfeeds/SubscribedFeedsIntentService.java
@@ -113,7 +113,7 @@
// TODO(fredq) fix the hardcoded type
final Account account = new Account(accountName, "com.google.GAIA");
c = context.getContentResolver().query(SubscribedFeeds.Feeds.CONTENT_URI,
- null, where, new String[]{account.mName, account.mType, feed}, null);
+ null, where, new String[]{account.name, account.type, feed}, null);
if (c.getCount() == 0) {
Log.w(TAG, "received tickle for non-existent feed: "
+ "account " + accountName + ", feed " + feed);
@@ -171,12 +171,12 @@
try {
ContentValues values = new ContentValues();
for (Account account : accounts) {
- values.put(SyncConstValue._SYNC_ACCOUNT, account.mName);
- values.put(SyncConstValue._SYNC_ACCOUNT_TYPE, account.mType);
+ values.put(SyncConstValue._SYNC_ACCOUNT, account.name);
+ values.put(SyncConstValue._SYNC_ACCOUNT_TYPE, account.type);
contentResolver.update(SubscribedFeeds.Feeds.CONTENT_URI, values,
SubscribedFeeds.Feeds._SYNC_ACCOUNT + "=? AND "
+ SubscribedFeeds.Feeds._SYNC_ACCOUNT_TYPE + "=?",
- new String[] {account.mName, account.mType});
+ new String[] {account.name, account.type});
}
} catch (SQLiteFullException e) {
Log.w(TAG, "disk full while trying to mark the feeds as dirty, skipping");
diff --git a/services/java/com/android/server/ConnectivityService.java b/services/java/com/android/server/ConnectivityService.java
index 1c60058..72a1192 100644
--- a/services/java/com/android/server/ConnectivityService.java
+++ b/services/java/com/android/server/ConnectivityService.java
@@ -100,6 +100,9 @@
// a process dies
private List mFeatureUsers;
+ private boolean mSystemReady;
+ private ArrayList<Intent> mDeferredBroadcasts;
+
private class NetworkAttributes {
/**
* Class for holding settings read from resources.
@@ -820,7 +823,7 @@
(newNet == null || !newNet.isAvailable() ? "" : " other=" +
newNet.getNetworkInfo().getTypeName()));
- mContext.sendStickyBroadcast(intent);
+ sendStickyBroadcast(intent);
/*
* If the failover network is already connected, then immediately send
* out a followup broadcast indicating successful failover
@@ -843,7 +846,7 @@
intent.putExtra(ConnectivityManager.EXTRA_EXTRA_INFO,
info.getExtraInfo());
}
- mContext.sendStickyBroadcast(intent);
+ sendStickyBroadcast(intent);
}
/**
@@ -882,7 +885,33 @@
intent.putExtra(ConnectivityManager.EXTRA_IS_FAILOVER, true);
info.setFailover(false);
}
- mContext.sendStickyBroadcast(intent);
+ sendStickyBroadcast(intent);
+ }
+
+ private void sendStickyBroadcast(Intent intent) {
+ synchronized(this) {
+ if (mSystemReady) {
+ mContext.sendStickyBroadcast(intent);
+ } else {
+ if (mDeferredBroadcasts == null) {
+ mDeferredBroadcasts = new ArrayList<Intent>();
+ }
+ mDeferredBroadcasts.add(intent);
+ }
+ }
+ }
+
+ void systemReady() {
+ synchronized(this) {
+ mSystemReady = true;
+ if (mDeferredBroadcasts != null) {
+ int count = mDeferredBroadcasts.size();
+ for (int i = 0; i < count; i++) {
+ mContext.sendStickyBroadcast(mDeferredBroadcasts.get(i));
+ }
+ mDeferredBroadcasts = null;
+ }
+ }
}
private void handleConnect(NetworkInfo info) {
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index ad8e8921..38bf63a 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -85,6 +85,7 @@
HardwareService hardware = null;
PowerManagerService power = null;
BatteryService battery = null;
+ ConnectivityService connectivity = null;
IPackageManager pm = null;
Context context = null;
WindowManagerService wm = null;
@@ -231,8 +232,8 @@
try {
Log.i(TAG, "Starting Connectivity Service.");
- ServiceManager.addService(Context.CONNECTIVITY_SERVICE,
- ConnectivityService.getInstance(context));
+ connectivity = ConnectivityService.getInstance(context);
+ ServiceManager.addService(Context.CONNECTIVITY_SERVICE, connectivity);
} catch (Throwable e) {
Log.e(TAG, "Failure starting Connectivity Service", e);
}
@@ -384,7 +385,8 @@
}
if (wallpaper != null) wallpaper.systemReady();
- battery.systemReady();
+ if (battery != null) battery.systemReady();
+ if (connectivity != null) connectivity.systemReady();
Watchdog.getInstance().start();
Looper.loop();
diff --git a/telephony/java/com/android/internal/telephony/DataConnectionTracker.java b/telephony/java/com/android/internal/telephony/DataConnectionTracker.java
index a3f1ad8..fa0ffcd 100644
--- a/telephony/java/com/android/internal/telephony/DataConnectionTracker.java
+++ b/telephony/java/com/android/internal/telephony/DataConnectionTracker.java
@@ -94,6 +94,7 @@
protected static final int EVENT_PS_RESTRICT_ENABLED = 32;
protected static final int EVENT_PS_RESTRICT_DISABLED = 33;
public static final int EVENT_CLEAN_UP_CONNECTION = 34;
+ protected static final int EVENT_CDMA_OTA_PROVISION = 35;
//***** Constants
@@ -146,6 +147,9 @@
protected int mNoRecvPollCount = 0;
protected boolean netStatPollEnabled = false;
+ /** Manage the behavior of data retry after failure */
+ protected final RetryManager mRetryMgr = new RetryManager();
+
// wifi connection status will be updated by sticky intent
protected boolean mIsWifiConnected = false;
@@ -202,10 +206,13 @@
if (getDataOnRoamingEnabled() != enabled) {
Settings.Secure.putInt(phone.getContext().getContentResolver(),
Settings.Secure.DATA_ROAMING, enabled ? 1 : 0);
+ if (phone.getServiceState().getRoaming()) {
+ if (enabled) {
+ mRetryMgr.resetRetryCount();
+ }
+ sendMessage(obtainMessage(EVENT_ROAMING_ON));
+ }
}
- Message roamingMsg = phone.getServiceState().getRoaming() ?
- obtainMessage(EVENT_ROAMING_ON) : obtainMessage(EVENT_ROAMING_OFF);
- sendMessage(roamingMsg);
}
//Retrieve the data roaming setting from the shared preferences.
@@ -243,6 +250,9 @@
break;
case EVENT_ROAMING_OFF:
+ if (getDataOnRoamingEnabled() == false) {
+ mRetryMgr.resetRetryCount();
+ }
onRoamingOff();
break;
diff --git a/telephony/java/com/android/internal/telephony/ServiceStateTracker.java b/telephony/java/com/android/internal/telephony/ServiceStateTracker.java
index 46b39a5..39806e9 100644
--- a/telephony/java/com/android/internal/telephony/ServiceStateTracker.java
+++ b/telephony/java/com/android/internal/telephony/ServiceStateTracker.java
@@ -116,6 +116,7 @@
protected static final int EVENT_NV_READY = 35;
protected static final int EVENT_ERI_FILE_LOADED = 36;
protected static final int EVENT_OTA_PROVISION_STATUS_CHANGE = 37;
+ protected static final int EVENT_SET_RADIO_POWER_OFF = 38;
//***** Time Zones
protected static final String TIMEZONE_PROPERTY = "persist.sys.timezone";
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java b/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java
index 38bc24d..8bae483 100644
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java
@@ -48,6 +48,7 @@
import com.android.internal.telephony.DataConnectionTracker;
import com.android.internal.telephony.RetryManager;
import com.android.internal.telephony.Phone;
+import com.android.internal.telephony.ServiceStateTracker;
import com.android.internal.telephony.TelephonyEventLog;
import java.util.ArrayList;
@@ -76,9 +77,6 @@
/** Currently active CdmaDataConnection */
private CdmaDataConnection mActiveDataConnection;
- /** Manage the behavior of data retry after failure */
- private final RetryManager mRetryMgr = new RetryManager();
-
/** Defined cdma connection profiles */
private static final int EXTERNAL_NETWORK_DEFAULT_ID = 0;
private static final int EXTERNAL_NETWORK_NUM_TYPES = 1;
@@ -163,6 +161,7 @@
p.mSST.registerForCdmaDataConnectionDetached(this, EVENT_CDMA_DATA_DETACHED, null);
p.mSST.registerForRoamingOn(this, EVENT_ROAMING_ON, null);
p.mSST.registerForRoamingOff(this, EVENT_ROAMING_OFF, null);
+ p.mCM.registerForCdmaOtaProvision(this, EVENT_CDMA_OTA_PROVISION, null);
this.netstat = INetStatService.Stub.asInterface(ServiceManager.getService("netstat"));
@@ -210,6 +209,7 @@
mCdmaPhone.mSST.unregisterForCdmaDataConnectionDetached(this);
mCdmaPhone.mSST.unregisterForRoamingOn(this);
mCdmaPhone.mSST.unregisterForRoamingOff(this);
+ phone.mCM.unregisterForCdmaOtaProvision(this);
phone.getContext().unregisterReceiver(this.mIntentReceiver);
destroyAllDataConnectionList();
@@ -499,7 +499,7 @@
protected void restartRadio() {
Log.d(LOG_TAG, "************TURN OFF RADIO**************");
- cleanUpConnection(true, Phone.REASON_RADIO_TURNED_OFF);
+ cleanUpConnection(true, Phone.REASON_CDMA_DATA_DETACHED);
phone.mCM.setRadioPower(false, null);
/* Note: no need to call setRadioPower(true). Assuming the desired
* radio power state is still ON (as tracked by ServiceStateTracker),
@@ -771,6 +771,10 @@
reason = (String) ar.userObj;
}
setState(State.IDLE);
+
+ CdmaServiceStateTracker ssTracker = mCdmaPhone.mSST;
+ ssTracker.processPendingRadioPowerOffAfterDataOff();
+
phone.notifyDataConnection(reason);
if (retryAfterDisconnected(reason)) {
trySetupData(reason);
@@ -849,6 +853,22 @@
}
}
+ private void onCdmaOtaProvision(AsyncResult ar) {
+ if (ar.exception != null) {
+ int [] otaPrivision = (int [])ar.result;
+ if ((otaPrivision != null) && (otaPrivision.length > 1)) {
+ switch (otaPrivision[0]) {
+ case Phone.CDMA_OTA_PROVISION_STATUS_COMMITTED:
+ case Phone.CDMA_OTA_PROVISION_STATUS_OTAPA_STOPPED:
+ mRetryMgr.resetRetryCount();
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ }
+
private void writeEventLogCdmaDataDrop() {
CdmaCellLocation loc = (CdmaCellLocation)(phone.getCellLocation());
int bsid = (loc != null) ? loc.getBaseStationId() : -1;
@@ -957,6 +977,10 @@
onDataStateChanged((AsyncResult) msg.obj);
break;
+ case EVENT_CDMA_OTA_PROVISION:
+ onCdmaOtaProvision((AsyncResult) msg.obj);
+ break;
+
default:
// handle the message in the super class DataConnectionTracker
super.handleMessage(msg);
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java b/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java
index b42cffd..b4de09b 100644
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java
@@ -131,6 +131,8 @@
private boolean isEriTextLoaded = false;
private boolean isSubscriptionFromRuim = false;
+ private boolean mPendingRadioPowerOffAfterDataOff = false;
+
// Registration Denied Reason, General/Authentication Failure, used only for debugging purposes
private String mRegistrationDeniedReason;
@@ -520,6 +522,16 @@
}
break;
+ case EVENT_SET_RADIO_POWER_OFF:
+ synchronized(this) {
+ if (mPendingRadioPowerOffAfterDataOff) {
+ if (DBG) log("EVENT_SET_RADIO_OFF, turn radio off now.");
+ cm.setRadioPower(false, null);
+ mPendingRadioPowerOffAfterDataOff = false;
+ }
+ }
+ break;
+
default:
Log.e(LOG_TAG, "Unhandled message with number: " + msg.what);
break;
@@ -548,20 +560,23 @@
msg.obj = CDMAPhone.REASON_RADIO_TURNED_OFF;
dcTracker.sendMessage(msg);
- // Poll data state up to 50 times, with a 100ms delay
- // totaling 5 sec.
- // TODO: change the 5 seconds wait from blocking to non-blocking.
- for (int i = 0; i < 50; i++) {
- DataConnectionTracker.State currentState = dcTracker.getState();
- if (currentState != DataConnectionTracker.State.CONNECTED
- && currentState != DataConnectionTracker.State.DISCONNECTING) {
- if (DBG) log("Data shutdown complete.");
- break;
+ synchronized(this) {
+ if (!mPendingRadioPowerOffAfterDataOff) {
+ DataConnectionTracker.State currentState = dcTracker.getState();
+ if (currentState != DataConnectionTracker.State.CONNECTED
+ && currentState != DataConnectionTracker.State.DISCONNECTING) {
+ if (DBG) log("Data disconnected, turn off radio right away.");
+ cm.setRadioPower(false, null);
+ }
+ else if (sendEmptyMessageDelayed(EVENT_SET_RADIO_POWER_OFF, 5000)) {
+ if (DBG) log("Wait 5 sec for data to be disconnected, then turn off radio.");
+ mPendingRadioPowerOffAfterDataOff = true;
+ } else {
+ Log.w(LOG_TAG, "Cannot send delayed Msg, turn off radio right away.");
+ cm.setRadioPower(false, null);
+ }
}
- SystemClock.sleep(DATA_STATE_POLL_SLEEP_MS);
}
- // If it's on and available and we want it off..
- cm.setRadioPower(false, null);
} // Otherwise, we're in the desired state
}
@@ -1582,4 +1597,22 @@
public boolean isMinInfoReady() {
return mIsMinInfoReady;
}
+
+ /**
+ * process the pending request to turn radio off after data is disconnected
+ *
+ * return true if there is pending request to process; false otherwise.
+ */
+ public boolean processPendingRadioPowerOffAfterDataOff() {
+ synchronized(this) {
+ if (mPendingRadioPowerOffAfterDataOff) {
+ if (DBG) log("Process pending request to turn radio off.");
+ removeMessages(EVENT_SET_RADIO_POWER_OFF);
+ cm.setRadioPower(false, null);
+ mPendingRadioPowerOffAfterDataOff = false;
+ return true;
+ }
+ return false;
+ }
+ }
}
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
index bf60bfe..34d3039 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
@@ -96,8 +96,6 @@
private int mPdpResetCount = 0;
private boolean mIsScreenOn = true;
- private final RetryManager mRetryMgr = new RetryManager();
-
/** Delay between APN attempts */
protected static final int APN_DELAY_MILLIS = 5000;
diff --git a/tests/AndroidTests/src/com/android/unit_tests/accounts/AccountManagerServiceTest.java b/tests/AndroidTests/src/com/android/unit_tests/accounts/AccountManagerServiceTest.java
index 6b8e1f0..1e4f161 100644
--- a/tests/AndroidTests/src/com/android/unit_tests/accounts/AccountManagerServiceTest.java
+++ b/tests/AndroidTests/src/com/android/unit_tests/accounts/AccountManagerServiceTest.java
@@ -28,7 +28,6 @@
import java.util.Arrays;
import java.util.Comparator;
-import java.util.Map;
public class AccountManagerServiceTest extends AndroidTestCase {
@Override
@@ -48,9 +47,9 @@
if (object1 == object2) return 0;
if (object1 == null) return 1;
if (object2 == null) return -1;
- int result = object1.mType.compareTo(object2.mType);
+ int result = object1.type.compareTo(object2.type);
if (result != 0) return result;
- return object1.mName.compareTo(object2.mName);
+ return object1.name.compareTo(object2.name);
}
}
@@ -62,16 +61,14 @@
Account a12 = new Account("account1", "type2");
Account a22 = new Account("account2", "type2");
Account a32 = new Account("account3", "type2");
- assertTrue(ams.addAccount(a11, "p11", null));
- assertTrue(ams.addAccount(a12, "p12", null));
- assertTrue(ams.addAccount(a21, "p21", null));
- assertTrue(ams.addAccount(a22, "p22", null));
- assertTrue(ams.addAccount(a31, "p31", null));
- assertTrue(ams.addAccount(a32, "p32", null));
+ ams.addAccount(a11, "p11", null);
+ ams.addAccount(a12, "p12", null);
+ ams.addAccount(a21, "p21", null);
+ ams.addAccount(a22, "p22", null);
+ ams.addAccount(a31, "p31", null);
+ ams.addAccount(a32, "p32", null);
- assertFalse("duplicate account insertion should fail", ams.addAccount(a32, "p", null));
-
- Account[] accounts = ams.getAccounts();
+ Account[] accounts = ams.getAccounts(null);
Arrays.sort(accounts, new AccountSorter());
assertEquals(6, accounts.length);
assertEquals(a11, accounts[0]);
@@ -88,7 +85,7 @@
assertEquals(a21, accounts[1]);
assertEquals(a31, accounts[2]);
- ams.removeAccount(a21);
+ ams.removeAccount(null, a21);
accounts = ams.getAccountsByType("type1" );
Arrays.sort(accounts, new AccountSorter());
@@ -101,8 +98,8 @@
AccountManagerService ams = new AccountManagerService(getContext());
Account a11 = new Account("account1", "type1");
Account a12 = new Account("account1", "type2");
- assertTrue(ams.addAccount(a11, "p11", null));
- assertTrue(ams.addAccount(a12, "p12", null));
+ ams.addAccount(a11, "p11", null);
+ ams.addAccount(a12, "p12", null);
assertEquals("p11", ams.getPassword(a11));
assertEquals("p12", ams.getPassword(a12));
@@ -125,8 +122,8 @@
u12.putString("a", "a_a12");
u12.putString("b", "b_a12");
u12.putString("c", "c_a12");
- assertTrue(ams.addAccount(a11, "p11", u11));
- assertTrue(ams.addAccount(a12, "p12", u12));
+ ams.addAccount(a11, "p11", u11);
+ ams.addAccount(a12, "p12", u12);
assertEquals("a_a11", ams.getUserData(a11, "a"));
assertEquals("b_a11", ams.getUserData(a11, "b"));
@@ -149,8 +146,8 @@
AccountManagerService ams = new AccountManagerService(getContext());
Account a11 = new Account("account1", "type1");
Account a12 = new Account("account1", "type2");
- assertTrue(ams.addAccount(a11, "p11", null));
- assertTrue(ams.addAccount(a12, "p12", null));
+ ams.addAccount(a11, "p11", null);
+ ams.addAccount(a12, "p12", null);
ams.setAuthToken(a11, "att1", "a11_att1");
ams.setAuthToken(a11, "att2", "a11_att2");
@@ -167,7 +164,7 @@
assertEquals("a12_att3", ams.peekAuthToken(a12, "att3"));
ams.setAuthToken(a11, "att3", "a11_att3b");
- ams.invalidateAuthToken(a12.mType, "a12_att2");
+ ams.invalidateAuthToken(a12.type, "a12_att2");
assertEquals("a11_att1", ams.peekAuthToken(a11, "att1"));
assertEquals("a11_att2", ams.peekAuthToken(a11, "att2"));
diff --git a/tests/FrameworkTest/tests/src/android/content/AbstractTableMergerTest.java b/tests/FrameworkTest/tests/src/android/content/AbstractTableMergerTest.java
index 42c1e78..a8af7f8 100644
--- a/tests/FrameworkTest/tests/src/android/content/AbstractTableMergerTest.java
+++ b/tests/FrameworkTest/tests/src/android/content/AbstractTableMergerTest.java
@@ -74,8 +74,8 @@
if (syncVersion != null) values.put("_sync_version", syncVersion);
if (syncId != null) values.put("_sync_id", syncId);
if (syncAccount != null) {
- values.put("_sync_account", syncAccount.mName);
- values.put("_sync_account_type", syncAccount.mType);
+ values.put("_sync_account", syncAccount.name);
+ values.put("_sync_account_type", syncAccount.type);
}
values.put("_sync_local_id", syncLocalId);
values.put("_sync_dirty", 0);
@@ -88,8 +88,8 @@
if (syncVersion != null) values.put("_sync_version", syncVersion);
if (syncId != null) values.put("_sync_id", syncId);
if (syncAccount != null) {
- values.put("_sync_account", syncAccount.mName);
- values.put("_sync_account_type", syncAccount.mType);
+ values.put("_sync_account", syncAccount.name);
+ values.put("_sync_account_type", syncAccount.type);
}
if (syncLocalId != null) values.put("_sync_local_id", syncLocalId);
return values;
diff --git a/tools/aapt/AaptAssets.h b/tools/aapt/AaptAssets.h
index 5724349..32efa4e 100644
--- a/tools/aapt/AaptAssets.h
+++ b/tools/aapt/AaptAssets.h
@@ -482,6 +482,8 @@
const sp<AaptFile>& file,
const String8& resType);
+ void addGroupEntry(const AaptGroupEntry& entry) { mGroupEntries.add(entry); }
+
ssize_t slurpFromArgs(Bundle* bundle);
virtual ssize_t slurpFullTree(Bundle* bundle,
diff --git a/tools/aapt/Resource.cpp b/tools/aapt/Resource.cpp
index 9d2ed10..1fa7b18 100644
--- a/tools/aapt/Resource.cpp
+++ b/tools/aapt/Resource.cpp
@@ -472,11 +472,22 @@
// didn't find a match fall through and add it..
}
baseGroup->addFile(overlayFiles.valueAt(overlayGroupIndex));
+ assets->addGroupEntry(overlayFiles.keyAt(overlayGroupIndex));
}
} else {
// this group doesn't exist (a file that's only in the overlay)
baseSet->add(overlaySet->keyAt(overlayIndex),
overlaySet->valueAt(overlayIndex));
+ // make sure all flavors are defined in the resources.
+ sp<AaptGroup> overlayGroup = overlaySet->valueAt(overlayIndex);
+ DefaultKeyedVector<AaptGroupEntry, sp<AaptFile> > overlayFiles =
+ overlayGroup->getFiles();
+ size_t overlayGroupSize = overlayFiles.size();
+ for (size_t overlayGroupIndex = 0;
+ overlayGroupIndex<overlayGroupSize;
+ overlayGroupIndex++) {
+ assets->addGroupEntry(overlayFiles.keyAt(overlayGroupIndex));
+ }
}
}
// this overlay didn't have resources for this type