Merge "Fix for issue 3495914: (In Java) Video clip switches between start and end"
diff --git a/Android.mk b/Android.mk
index 52ebd6f..a28bde2 100644
--- a/Android.mk
+++ b/Android.mk
@@ -115,7 +115,7 @@
core/java/android/content/pm/IPackageMoveObserver.aidl \
core/java/android/content/pm/IPackageStatsObserver.aidl \
core/java/android/database/IContentObserver.aidl \
- core/java/android/hardware/IUsbManager.aidl \
+ core/java/android/hardware/usb/IUsbManager.aidl \
core/java/android/net/IConnectivityManager.aidl \
core/java/android/net/INetworkManagementEventObserver.aidl \
core/java/android/net/IThrottleManager.aidl \
diff --git a/CleanSpec.mk b/CleanSpec.mk
index 6f9a1e1..2eee813 100644
--- a/CleanSpec.mk
+++ b/CleanSpec.mk
@@ -94,6 +94,8 @@
$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/APPS/ModelViewer_intermediates/)
$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/APPS/PerfTest_intermediates/)
$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/APPS/RSTest_intermediates/)
+$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/core/java/android/hardware/IUsbManager.java)
+
# ************************************************
# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
diff --git a/api/current.xml b/api/current.xml
index 2663c53..f98edab 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -94374,11 +94374,14 @@
>
</field>
</class>
+</package>
+<package name="android.hardware.usb"
+>
<class name="UsbAccessory"
extends="java.lang.Object"
abstract="false"
static="false"
- final="true"
+ final="false"
deprecated="not deprecated"
visibility="public"
>
@@ -94474,7 +94477,7 @@
visibility="public"
>
<constructor name="UsbConstants"
- type="android.hardware.UsbConstants"
+ type="android.hardware.usb.UsbConstants"
static="false"
final="false"
deprecated="not deprecated"
@@ -94865,7 +94868,7 @@
deprecated="not deprecated"
visibility="public"
>
-<parameter name="endpoint" type="android.hardware.UsbEndpoint">
+<parameter name="endpoint" type="android.hardware.usb.UsbEndpoint">
</parameter>
<parameter name="buffer" type="byte[]">
</parameter>
@@ -94884,7 +94887,7 @@
deprecated="not deprecated"
visibility="public"
>
-<parameter name="intf" type="android.hardware.UsbInterface">
+<parameter name="intf" type="android.hardware.usb.UsbInterface">
</parameter>
<parameter name="force" type="boolean">
</parameter>
@@ -95029,7 +95032,7 @@
>
</method>
<method name="getInterface"
- return="android.hardware.UsbInterface"
+ return="android.hardware.usb.UsbInterface"
abstract="false"
native="false"
synchronized="false"
@@ -95095,11 +95098,11 @@
deprecated="not deprecated"
visibility="public"
>
-<parameter name="intf" type="android.hardware.UsbInterface">
+<parameter name="intf" type="android.hardware.usb.UsbInterface">
</parameter>
</method>
<method name="requestWait"
- return="android.hardware.UsbRequest"
+ return="android.hardware.usb.UsbRequest"
abstract="false"
native="false"
synchronized="false"
@@ -95179,7 +95182,7 @@
>
</method>
<method name="getDevice"
- return="android.hardware.UsbDevice"
+ return="android.hardware.usb.UsbDevice"
abstract="false"
native="false"
synchronized="false"
@@ -95212,7 +95215,7 @@
>
</method>
<method name="getInterface"
- return="android.hardware.UsbInterface"
+ return="android.hardware.usb.UsbInterface"
abstract="false"
native="false"
synchronized="false"
@@ -95285,7 +95288,7 @@
extends="java.lang.Object"
abstract="false"
static="false"
- final="true"
+ final="false"
deprecated="not deprecated"
visibility="public"
>
@@ -95303,7 +95306,7 @@
>
</method>
<method name="getDevice"
- return="android.hardware.UsbDevice"
+ return="android.hardware.usb.UsbDevice"
abstract="false"
native="false"
synchronized="false"
@@ -95314,7 +95317,7 @@
>
</method>
<method name="getEndpoint"
- return="android.hardware.UsbEndpoint"
+ return="android.hardware.usb.UsbEndpoint"
abstract="false"
native="false"
synchronized="false"
@@ -95416,7 +95419,7 @@
visibility="public"
>
<method name="getAccessoryList"
- return="android.hardware.UsbAccessory[]"
+ return="android.hardware.usb.UsbAccessory[]"
abstract="false"
native="false"
synchronized="false"
@@ -95427,7 +95430,7 @@
>
</method>
<method name="getDeviceList"
- return="java.util.HashMap<java.lang.String, android.hardware.UsbDevice>"
+ return="java.util.HashMap<java.lang.String, android.hardware.usb.UsbDevice>"
abstract="false"
native="false"
synchronized="false"
@@ -95473,7 +95476,7 @@
deprecated="not deprecated"
visibility="public"
>
-<parameter name="accessory" type="android.hardware.UsbAccessory">
+<parameter name="accessory" type="android.hardware.usb.UsbAccessory">
</parameter>
</method>
<method name="openDevice"
@@ -95486,14 +95489,14 @@
deprecated="not deprecated"
visibility="public"
>
-<parameter name="device" type="android.hardware.UsbDevice">
+<parameter name="device" type="android.hardware.usb.UsbDevice">
</parameter>
</method>
<field name="ACTION_USB_ACCESSORY_ATTACHED"
type="java.lang.String"
transient="false"
volatile="false"
- value=""android.hardware.action.USB_ACCESSORY_ATTACHED""
+ value=""android.hardware.usb.action.USB_ACCESSORY_ATTACHED""
static="true"
final="true"
deprecated="not deprecated"
@@ -95504,7 +95507,7 @@
type="java.lang.String"
transient="false"
volatile="false"
- value=""android.hardware.action.USB_ACCESSORY_DETACHED""
+ value=""android.hardware.usb.action.USB_ACCESSORY_DETACHED""
static="true"
final="true"
deprecated="not deprecated"
@@ -95515,7 +95518,7 @@
type="java.lang.String"
transient="false"
volatile="false"
- value=""android.hardware.action.USB_DEVICE_ATTACHED""
+ value=""android.hardware.usb.action.USB_DEVICE_ATTACHED""
static="true"
final="true"
deprecated="not deprecated"
@@ -95526,7 +95529,7 @@
type="java.lang.String"
transient="false"
volatile="false"
- value=""android.hardware.action.USB_DEVICE_DETACHED""
+ value=""android.hardware.usb.action.USB_DEVICE_DETACHED""
static="true"
final="true"
deprecated="not deprecated"
@@ -95537,7 +95540,7 @@
type="java.lang.String"
transient="false"
volatile="false"
- value=""android.hardware.action.USB_STATE""
+ value=""android.hardware.usb.action.USB_STATE""
static="true"
final="true"
deprecated="not deprecated"
@@ -95675,7 +95678,7 @@
visibility="public"
>
<constructor name="UsbRequest"
- type="android.hardware.UsbRequest"
+ type="android.hardware.usb.UsbRequest"
static="false"
final="false"
deprecated="not deprecated"
@@ -95716,7 +95719,7 @@
>
</method>
<method name="getEndpoint"
- return="android.hardware.UsbEndpoint"
+ return="android.hardware.usb.UsbEndpoint"
abstract="false"
native="false"
synchronized="false"
@@ -95736,7 +95739,7 @@
deprecated="not deprecated"
visibility="public"
>
-<parameter name="endpoint" type="android.hardware.UsbEndpoint">
+<parameter name="endpoint" type="android.hardware.usb.UsbEndpoint">
</parameter>
</method>
<method name="queue"
@@ -112707,7 +112710,7 @@
deprecated="not deprecated"
visibility="public"
>
-<parameter name="device" type="android.hardware.UsbDevice">
+<parameter name="device" type="android.hardware.usb.UsbDevice">
</parameter>
</method>
<method name="removeListener"
@@ -113474,7 +113477,7 @@
deprecated="not deprecated"
visibility="public"
>
-<parameter name="device" type="android.hardware.UsbDevice">
+<parameter name="device" type="android.hardware.usb.UsbDevice">
</parameter>
</constructor>
<method name="close"
@@ -113667,7 +113670,7 @@
deprecated="not deprecated"
visibility="public"
>
-<parameter name="manager" type="android.hardware.UsbManager">
+<parameter name="manager" type="android.hardware.usb.UsbManager">
</parameter>
</method>
</class>
@@ -266666,7 +266669,7 @@
deprecated="not deprecated"
visibility="public"
>
-<parameter name="arg0" type="T">
+<parameter name="t" type="T">
</parameter>
</method>
</interface>
diff --git a/cmds/pm/src/com/android/commands/pm/Pm.java b/cmds/pm/src/com/android/commands/pm/Pm.java
index cc6e739..d058e38 100644
--- a/cmds/pm/src/com/android/commands/pm/Pm.java
+++ b/cmds/pm/src/com/android/commands/pm/Pm.java
@@ -767,10 +767,10 @@
boolean finished;
boolean result;
- public void packageDeleted(boolean succeeded) {
+ public void packageDeleted(String packageName, int returnCode) {
synchronized (this) {
finished = true;
- result = succeeded;
+ result = returnCode == PackageManager.DELETE_SUCCEEDED;
notifyAll();
}
}
diff --git a/core/java/android/accounts/AccountManagerService.java b/core/java/android/accounts/AccountManagerService.java
index a1c2867..894e196 100644
--- a/core/java/android/accounts/AccountManagerService.java
+++ b/core/java/android/accounts/AccountManagerService.java
@@ -52,7 +52,6 @@
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.SystemClock;
-import android.os.SystemProperties;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.Log;
@@ -81,8 +80,6 @@
public class AccountManagerService
extends IAccountManager.Stub
implements RegisteredServicesCacheListener<AuthenticatorDescription> {
- private static final String GOOGLE_ACCOUNT_TYPE = "com.google";
-
private static final String TAG = "AccountManagerService";
private static final int TIMEOUT_DELAY_MS = 1000 * 60;
@@ -198,7 +195,9 @@
mContext = context;
mPackageManager = packageManager;
- mOpenHelper = new DatabaseHelper(mContext);
+ synchronized (mCacheLock) {
+ mOpenHelper = new DatabaseHelper(mContext);
+ }
mMessageThread = new HandlerThread("AccountManagerService");
mMessageThread.start();
@@ -248,13 +247,13 @@
}
private void validateAccountsAndPopulateCache() {
- boolean accountDeleted = false;
- SQLiteDatabase db = mOpenHelper.getWritableDatabase();
- Cursor cursor = db.query(TABLE_ACCOUNTS,
- new String[]{ACCOUNTS_ID, ACCOUNTS_TYPE, ACCOUNTS_NAME},
- null, null, null, null, null);
- try {
- synchronized (mCacheLock) {
+ synchronized (mCacheLock) {
+ final SQLiteDatabase db = mOpenHelper.getWritableDatabase();
+ boolean accountDeleted = false;
+ Cursor cursor = db.query(TABLE_ACCOUNTS,
+ new String[]{ACCOUNTS_ID, ACCOUNTS_TYPE, ACCOUNTS_NAME},
+ null, null, null, null, null);
+ try {
mAccountCache.clear();
final HashMap<String, ArrayList<String>> accountNamesByType =
new HashMap<String, ArrayList<String>>();
@@ -280,7 +279,8 @@
accountNames.add(accountName);
}
}
- for (HashMap.Entry<String, ArrayList<String>> cur : accountNamesByType.entrySet()) {
+ for (HashMap.Entry<String, ArrayList<String>> cur
+ : accountNamesByType.entrySet()) {
final String accountType = cur.getKey();
final ArrayList<String> accountNames = cur.getValue();
final Account[] accountsForType = new Account[accountNames.size()];
@@ -291,11 +291,11 @@
}
mAccountCache.put(accountType, accountsForType);
}
- }
- } finally {
- cursor.close();
- if (accountDeleted) {
- sendAccountsChangedBroadcast();
+ } finally {
+ cursor.close();
+ if (accountDeleted) {
+ sendAccountsChangedBroadcast();
+ }
}
}
}
@@ -315,28 +315,30 @@
long identityToken = clearCallingIdentity();
try {
- return readPasswordFromDatabase(account);
+ return readPasswordInternal(account);
} finally {
restoreCallingIdentity(identityToken);
}
}
- private String readPasswordFromDatabase(Account account) {
+ private String readPasswordInternal(Account account) {
if (account == null) {
return null;
}
- 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);
+ synchronized (mCacheLock) {
+ final 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();
}
- return null;
- } finally {
- cursor.close();
}
}
@@ -352,7 +354,7 @@
checkAuthenticateAccountsPermission(account);
long identityToken = clearCallingIdentity();
try {
- return readUserDataFromCache(account, key);
+ return readUserDataInternal(account, key);
} finally {
restoreCallingIdentity(identityToken);
}
@@ -394,58 +396,60 @@
// fails if the account already exists
long identityToken = clearCallingIdentity();
try {
- return insertAccountIntoDatabase(account, password, extras);
+ return addAccountInternal(account, password, extras);
} finally {
restoreCallingIdentity(identityToken);
}
}
- private boolean insertAccountIntoDatabase(Account account, String password, Bundle extras) {
- SQLiteDatabase db = mOpenHelper.getWritableDatabase();
+ private boolean addAccountInternal(Account account, String password, Bundle extras) {
if (account == null) {
return false;
}
- 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) {
- Log.w(TAG, "insertAccountIntoDatabase: " + account
- + ", skipping since the account already exists");
- 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) {
- Log.w(TAG, "insertAccountIntoDatabase: " + account
- + ", skipping the DB insert failed");
- return false;
- }
- if (extras != null) {
- for (String key : extras.keySet()) {
- final String value = extras.getString(key);
- if (insertExtra(db, accountId, key, value) < 0) {
- Log.w(TAG, "insertAccountIntoDatabase: " + account
- + ", skipping since insertExtra failed for key " + key);
- return false;
+ synchronized (mCacheLock) {
+ final 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) {
+ Log.w(TAG, "insertAccountIntoDatabase: " + account
+ + ", skipping since the account already exists");
+ 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) {
+ Log.w(TAG, "insertAccountIntoDatabase: " + account
+ + ", skipping the DB insert failed");
+ return false;
+ }
+ if (extras != null) {
+ for (String key : extras.keySet()) {
+ final String value = extras.getString(key);
+ if (insertExtraLocked(db, accountId, key, value) < 0) {
+ Log.w(TAG, "insertAccountIntoDatabase: " + account
+ + ", skipping since insertExtra failed for key " + key);
+ return false;
+ }
}
}
+ db.setTransactionSuccessful();
+ insertAccountIntoCacheLocked(account);
+ } finally {
+ db.endTransaction();
}
- db.setTransactionSuccessful();
- insertAccountIntoCache(account);
- } finally {
- db.endTransaction();
+ sendAccountsChangedBroadcast();
+ return true;
}
- sendAccountsChangedBroadcast();
- return true;
}
- private long insertExtra(SQLiteDatabase db, long accountId, String key, String value) {
+ private long insertExtraLocked(SQLiteDatabase db, long accountId, String key, String value) {
ContentValues values = new ContentValues();
values.put(EXTRAS_KEY, key);
values.put(EXTRAS_ACCOUNTS_ID, accountId);
@@ -578,7 +582,7 @@
&& !result.containsKey(AccountManager.KEY_INTENT)) {
final boolean removalAllowed = result.getBoolean(AccountManager.KEY_BOOLEAN_RESULT);
if (removalAllowed) {
- removeAccount(mAccount);
+ removeAccountInternal(mAccount);
}
IAccountManagerResponse response = getResponseAndClose();
if (response != null) {
@@ -599,12 +603,14 @@
}
}
- protected void removeAccount(Account account) {
- final SQLiteDatabase db = mOpenHelper.getWritableDatabase();
- db.delete(TABLE_ACCOUNTS, ACCOUNTS_NAME + "=? AND " + ACCOUNTS_TYPE+ "=?",
- new String[]{account.name, account.type});
- removeAccountFromCache(account);
- sendAccountsChangedBroadcast();
+ protected void removeAccountInternal(Account account) {
+ synchronized (mCacheLock) {
+ final SQLiteDatabase db = mOpenHelper.getWritableDatabase();
+ db.delete(TABLE_ACCOUNTS, ACCOUNTS_NAME + "=? AND " + ACCOUNTS_TYPE+ "=?",
+ new String[]{account.name, account.type});
+ removeAccountFromCacheLocked(account);
+ sendAccountsChangedBroadcast();
+ }
}
public void invalidateAuthToken(String accountType, String authToken) {
@@ -618,20 +624,22 @@
checkManageAccountsOrUseCredentialsPermissions();
long identityToken = clearCallingIdentity();
try {
- SQLiteDatabase db = mOpenHelper.getWritableDatabase();
- db.beginTransaction();
- try {
- invalidateAuthToken(db, accountType, authToken);
- db.setTransactionSuccessful();
- } finally {
- db.endTransaction();
+ synchronized (mCacheLock) {
+ final SQLiteDatabase db = mOpenHelper.getWritableDatabase();
+ db.beginTransaction();
+ try {
+ invalidateAuthTokenLocked(db, accountType, authToken);
+ db.setTransactionSuccessful();
+ } finally {
+ db.endTransaction();
+ }
}
} finally {
restoreCallingIdentity(identityToken);
}
}
- private void invalidateAuthToken(SQLiteDatabase db, String accountType, String authToken) {
+ private void invalidateAuthTokenLocked(SQLiteDatabase db, String accountType, String authToken) {
if (authToken == null || accountType == null) {
return;
}
@@ -652,7 +660,8 @@
String accountName = cursor.getString(1);
String authTokenType = cursor.getString(2);
db.delete(TABLE_AUTHTOKENS, AUTHTOKENS_ID + "=" + authTokenId, null);
- writeAuthTokenIntoCache(new Account(accountName, accountType), authTokenType, null);
+ writeAuthTokenIntoCacheLocked(db, new Account(accountName, accountType),
+ authTokenType, null);
}
} finally {
cursor.close();
@@ -664,28 +673,30 @@
return false;
}
cancelNotification(getSigninRequiredNotificationId(account));
- SQLiteDatabase db = mOpenHelper.getWritableDatabase();
- db.beginTransaction();
- try {
- long accountId = getAccountId(db, account);
- if (accountId < 0) {
+ synchronized (mCacheLock) {
+ final SQLiteDatabase db = mOpenHelper.getWritableDatabase();
+ db.beginTransaction();
+ try {
+ long accountId = getAccountIdLocked(db, account);
+ if (accountId < 0) {
+ return false;
+ }
+ db.delete(TABLE_AUTHTOKENS,
+ AUTHTOKENS_ACCOUNTS_ID + "=" + accountId + " AND " + AUTHTOKENS_TYPE + "=?",
+ new String[]{type});
+ ContentValues values = new ContentValues();
+ values.put(AUTHTOKENS_ACCOUNTS_ID, accountId);
+ values.put(AUTHTOKENS_TYPE, type);
+ values.put(AUTHTOKENS_AUTHTOKEN, authToken);
+ if (db.insert(TABLE_AUTHTOKENS, AUTHTOKENS_AUTHTOKEN, values) >= 0) {
+ db.setTransactionSuccessful();
+ writeAuthTokenIntoCacheLocked(db, account, type, authToken);
+ return true;
+ }
return false;
+ } finally {
+ db.endTransaction();
}
- db.delete(TABLE_AUTHTOKENS,
- AUTHTOKENS_ACCOUNTS_ID + "=" + accountId + " AND " + AUTHTOKENS_TYPE + "=?",
- new String[]{type});
- ContentValues values = new ContentValues();
- values.put(AUTHTOKENS_ACCOUNTS_ID, accountId);
- values.put(AUTHTOKENS_TYPE, type);
- values.put(AUTHTOKENS_AUTHTOKEN, authToken);
- if (db.insert(TABLE_AUTHTOKENS, AUTHTOKENS_AUTHTOKEN, values) >= 0) {
- db.setTransactionSuccessful();
- writeAuthTokenIntoCache(account, type, authToken);
- return true;
- }
- return false;
- } finally {
- db.endTransaction();
}
}
@@ -701,7 +712,7 @@
checkAuthenticateAccountsPermission(account);
long identityToken = clearCallingIdentity();
try {
- return readAuthTokenFromCache(account, authTokenType);
+ return readAuthTokenInternal(account, authTokenType);
} finally {
restoreCallingIdentity(identityToken);
}
@@ -735,35 +746,35 @@
checkAuthenticateAccountsPermission(account);
long identityToken = clearCallingIdentity();
try {
- setPasswordInDB(account, password);
+ setPasswordInternal(account, password);
} finally {
restoreCallingIdentity(identityToken);
}
}
- private void setPasswordInDB(Account account, String password) {
+ private void setPasswordInternal(Account account, String password) {
if (account == null) {
return;
}
- SQLiteDatabase db = mOpenHelper.getWritableDatabase();
- db.beginTransaction();
- try {
- final ContentValues values = new ContentValues();
- values.put(ACCOUNTS_PASSWORD, password);
- final long accountId = getAccountId(db, account);
- if (accountId >= 0) {
- final String[] argsAccountId = {String.valueOf(accountId)};
- db.update(TABLE_ACCOUNTS, values, ACCOUNTS_ID + "=?", argsAccountId);
- db.delete(TABLE_AUTHTOKENS, AUTHTOKENS_ACCOUNTS_ID + "=?", argsAccountId);
- synchronized (mCacheLock) {
+ synchronized (mCacheLock) {
+ final SQLiteDatabase db = mOpenHelper.getWritableDatabase();
+ db.beginTransaction();
+ try {
+ final ContentValues values = new ContentValues();
+ values.put(ACCOUNTS_PASSWORD, password);
+ final long accountId = getAccountIdLocked(db, account);
+ if (accountId >= 0) {
+ final String[] argsAccountId = {String.valueOf(accountId)};
+ db.update(TABLE_ACCOUNTS, values, ACCOUNTS_ID + "=?", argsAccountId);
+ db.delete(TABLE_AUTHTOKENS, AUTHTOKENS_ACCOUNTS_ID + "=?", argsAccountId);
mAuthTokenCache.remove(account);
+ db.setTransactionSuccessful();
}
- db.setTransactionSuccessful();
+ } finally {
+ db.endTransaction();
}
- } finally {
- db.endTransaction();
+ sendAccountsChangedBroadcast();
}
- sendAccountsChangedBroadcast();
}
private void sendAccountsChangedBroadcast() {
@@ -782,7 +793,7 @@
checkManageAccountsPermission();
long identityToken = clearCallingIdentity();
try {
- setPasswordInDB(account, null);
+ setPasswordInternal(account, null);
} finally {
restoreCallingIdentity(identityToken);
}
@@ -800,41 +811,43 @@
checkAuthenticateAccountsPermission(account);
long identityToken = clearCallingIdentity();
try {
- writeUserdataIntoDatabase(account, key, value);
+ setUserdataInternal(account, key, value);
} finally {
restoreCallingIdentity(identityToken);
}
}
- private void writeUserdataIntoDatabase(Account account, String key, String value) {
+ private void setUserdataInternal(Account account, String key, String value) {
if (account == null || key == null) {
return;
}
- 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) {
+ synchronized (mCacheLock) {
+ final SQLiteDatabase db = mOpenHelper.getWritableDatabase();
+ db.beginTransaction();
+ try {
+ long accountId = getAccountIdLocked(db, account);
+ if (accountId < 0) {
return;
}
- } else {
- ContentValues values = new ContentValues();
- values.put(EXTRAS_VALUE, value);
- if (1 != db.update(TABLE_EXTRAS, values, EXTRAS_ID + "=" + extrasId, null)) {
- return;
- }
+ long extrasId = getExtrasIdLocked(db, accountId, key);
+ if (extrasId < 0 ) {
+ extrasId = insertExtraLocked(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;
+ }
+ }
+ writeUserDataIntoCacheLocked(db, account, key, value);
+ db.setTransactionSuccessful();
+ } finally {
+ db.endTransaction();
}
- db.setTransactionSuccessful();
- writeUserDataIntoCache(account, key, value);
- } finally {
- db.endTransaction();
}
}
@@ -940,7 +953,7 @@
// if the caller has permission, do the peek. otherwise go the more expensive
// route of starting a Session
if (!customTokens && permissionGranted) {
- String authToken = readAuthTokenFromCache(account, authTokenType);
+ String authToken = readAuthTokenInternal(account, authTokenType);
if (authToken != null) {
Bundle result = new Bundle();
result.putString(AccountManager.KEY_AUTHTOKEN, authToken);
@@ -1246,7 +1259,9 @@
}
public void run() throws RemoteException {
- mAccountsOfType = getAccountsByTypeFromCache(mAccountType);
+ synchronized (mCacheLock) {
+ mAccountsOfType = getAccountsFromCacheLocked(mAccountType);
+ }
// check whether each account matches the requested features
mAccountsWithFeatures = new ArrayList<Account>(mAccountsOfType.length);
mCurrentAccount = 0;
@@ -1332,7 +1347,9 @@
checkReadAccountsPermission();
long identityToken = clearCallingIdentity();
try {
- return getAccountsByTypeFromCache(type);
+ synchronized (mCacheLock) {
+ return getAccountsFromCacheLocked(type);
+ }
} finally {
restoreCallingIdentity(identityToken);
}
@@ -1353,7 +1370,10 @@
long identityToken = clearCallingIdentity();
try {
if (features == null || features.length == 0) {
- Account[] accounts = getAccountsByTypeFromCache(type);
+ Account[] accounts;
+ synchronized (mCacheLock) {
+ accounts = getAccountsFromCacheLocked(type);
+ }
Bundle result = new Bundle();
result.putParcelableArray(AccountManager.KEY_ACCOUNTS, accounts);
onResult(response, result);
@@ -1365,7 +1385,7 @@
}
}
- private long getAccountId(SQLiteDatabase db, Account account) {
+ private long getAccountIdLocked(SQLiteDatabase db, Account account) {
Cursor cursor = db.query(TABLE_ACCOUNTS, new String[]{ACCOUNTS_ID},
"name=? AND type=?", new String[]{account.name, account.type}, null, null, null);
try {
@@ -1378,7 +1398,7 @@
}
}
- private long getExtrasId(SQLiteDatabase db, long accountId, String key) {
+ private long getExtrasIdLocked(SQLiteDatabase db, long accountId, String key) {
Cursor cursor = db.query(TABLE_EXTRAS, new String[]{EXTRAS_ID},
EXTRAS_ACCOUNTS_ID + "=" + accountId + " AND " + EXTRAS_KEY + "=?",
new String[]{key}, null, null, null);
@@ -1668,6 +1688,11 @@
super(context, AccountManagerService.getDatabaseName(), null, DATABASE_VERSION);
}
+ /**
+ * This call needs to be made while the mCacheLock is held. The way to
+ * ensure this is to get the lock any time a method is called ont the DatabaseHelper
+ * @param db The database.
+ */
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE " + TABLE_ACCOUNTS + " ( "
@@ -1756,19 +1781,24 @@
ContentValues values = new ContentValues();
values.put(META_KEY, key);
values.put(META_VALUE, value);
- mOpenHelper.getWritableDatabase().replace(TABLE_META, META_KEY, values);
+ synchronized (mCacheLock) {
+ mOpenHelper.getWritableDatabase().replace(TABLE_META, META_KEY, values);
+ }
}
private String getMetaValue(String key) {
- Cursor c = mOpenHelper.getReadableDatabase().query(TABLE_META,
- new String[]{META_VALUE}, META_KEY + "=?", new String[]{key}, null, null, null);
- try {
- if (c.moveToNext()) {
- return c.getString(0);
+ synchronized (mCacheLock) {
+ final SQLiteDatabase db = mOpenHelper.getReadableDatabase();
+ Cursor c = db.query(TABLE_META,
+ new String[]{META_VALUE}, META_KEY + "=?", new String[]{key}, null, null, null);
+ try {
+ if (c.moveToNext()) {
+ return c.getString(0);
+ }
+ return null;
+ } finally {
+ c.close();
}
- return null;
- } finally {
- c.close();
}
}
@@ -1794,42 +1824,44 @@
}
protected void dump(FileDescriptor fd, PrintWriter fout, String[] args) {
- final boolean isCheckinRequest = scanArgs(args, "--checkin") || scanArgs(args, "-c");
+ synchronized (mCacheLock) {
+ final SQLiteDatabase db = mOpenHelper.getReadableDatabase();
- if (isCheckinRequest) {
- // This is a checkin request. *Only* upload the account types and the count of each.
- SQLiteDatabase db = mOpenHelper.getReadableDatabase();
+ final boolean isCheckinRequest = scanArgs(args, "--checkin") || scanArgs(args, "-c");
- Cursor cursor = db.query(TABLE_ACCOUNTS, ACCOUNT_TYPE_COUNT_PROJECTION,
- null, null, ACCOUNTS_TYPE, null, null);
- try {
- while (cursor.moveToNext()) {
- // print type,count
- fout.println(cursor.getString(0) + "," + cursor.getString(1));
+ if (isCheckinRequest) {
+ // This is a checkin request. *Only* upload the account types and the count of each.
+ Cursor cursor = db.query(TABLE_ACCOUNTS, ACCOUNT_TYPE_COUNT_PROJECTION,
+ null, null, ACCOUNTS_TYPE, null, null);
+ try {
+ while (cursor.moveToNext()) {
+ // print type,count
+ fout.println(cursor.getString(0) + "," + cursor.getString(1));
+ }
+ } finally {
+ if (cursor != null) {
+ cursor.close();
+ }
}
- } finally {
- if (cursor != null) {
- cursor.close();
+ } else {
+ Account[] accounts = getAccountsFromCacheLocked(null /* type */);
+ fout.println("Accounts: " + accounts.length);
+ for (Account account : accounts) {
+ fout.println(" " + account);
}
- }
- } else {
- Account[] accounts = getAccountsByTypeFromCache(null /* type */);
- fout.println("Accounts: " + accounts.length);
- for (Account account : accounts) {
- fout.println(" " + account);
- }
- fout.println();
- synchronized (mSessions) {
- final long now = SystemClock.elapsedRealtime();
- fout.println("Active Sessions: " + mSessions.size());
- for (Session session : mSessions.values()) {
- fout.println(" " + session.toDebugString(now));
+ fout.println();
+ synchronized (mSessions) {
+ final long now = SystemClock.elapsedRealtime();
+ fout.println("Active Sessions: " + mSessions.size());
+ for (Session session : mSessions.values()) {
+ fout.println(" " + session.toDebugString(now));
+ }
}
- }
- fout.println();
- mAuthenticatorCache.dump(fd, fout, args);
+ fout.println();
+ mAuthenticatorCache.dump(fd, fout, args);
+ }
}
}
@@ -1942,20 +1974,22 @@
if (Binder.getCallingUid() == android.os.Process.SYSTEM_UID) {
return true;
}
- SQLiteDatabase db = mOpenHelper.getReadableDatabase();
- String[] args = {String.valueOf(Binder.getCallingUid()), authTokenType,
- account.name, account.type};
- final boolean permissionGranted =
- DatabaseUtils.longForQuery(db, COUNT_OF_MATCHING_GRANTS, args) != 0;
- if (!permissionGranted && ActivityManager.isRunningInTestHarness()) {
- // TODO: Skip this check when running automated tests. Replace this
- // with a more general solution.
- Log.d(TAG, "no credentials permission for usage of " + account + ", "
- + authTokenType + " by uid " + Binder.getCallingUid()
- + " but ignoring since device is in test harness.");
- return true;
+ synchronized (mCacheLock) {
+ final SQLiteDatabase db = mOpenHelper.getReadableDatabase();
+ String[] args = {String.valueOf(Binder.getCallingUid()), authTokenType,
+ account.name, account.type};
+ final boolean permissionGranted =
+ DatabaseUtils.longForQuery(db, COUNT_OF_MATCHING_GRANTS, args) != 0;
+ if (!permissionGranted && ActivityManager.isRunningInTestHarness()) {
+ // TODO: Skip this check when running automated tests. Replace this
+ // with a more general solution.
+ Log.d(TAG, "no credentials permission for usage of " + account + ", "
+ + authTokenType + " by uid " + Binder.getCallingUid()
+ + " but ignoring since device is in test harness.");
+ return true;
+ }
+ return permissionGranted;
}
- return permissionGranted;
}
private void checkCallingUidAgainstAuthenticator(Account account) {
@@ -2000,22 +2034,24 @@
Log.e(TAG, "grantAppPermission: called with invalid arguments", new Exception());
return;
}
- SQLiteDatabase db = mOpenHelper.getWritableDatabase();
- db.beginTransaction();
- try {
- long accountId = getAccountId(db, account);
- if (accountId >= 0) {
- ContentValues values = new ContentValues();
- values.put(GRANTS_ACCOUNTS_ID, accountId);
- values.put(GRANTS_AUTH_TOKEN_TYPE, authTokenType);
- values.put(GRANTS_GRANTEE_UID, uid);
- db.insert(TABLE_GRANTS, GRANTS_ACCOUNTS_ID, values);
- db.setTransactionSuccessful();
+ synchronized (mCacheLock) {
+ final SQLiteDatabase db = mOpenHelper.getWritableDatabase();
+ db.beginTransaction();
+ try {
+ long accountId = getAccountIdLocked(db, account);
+ if (accountId >= 0) {
+ ContentValues values = new ContentValues();
+ values.put(GRANTS_ACCOUNTS_ID, accountId);
+ values.put(GRANTS_AUTH_TOKEN_TYPE, authTokenType);
+ values.put(GRANTS_GRANTEE_UID, uid);
+ db.insert(TABLE_GRANTS, GRANTS_ACCOUNTS_ID, values);
+ db.setTransactionSuccessful();
+ }
+ } finally {
+ db.endTransaction();
}
- } finally {
- db.endTransaction();
+ cancelNotification(getCredentialPermissionNotificationId(account, authTokenType, uid));
}
- cancelNotification(getCredentialPermissionNotificationId(account, authTokenType, uid));
}
/**
@@ -2031,153 +2067,149 @@
Log.e(TAG, "revokeAppPermission: called with invalid arguments", new Exception());
return;
}
- SQLiteDatabase db = mOpenHelper.getWritableDatabase();
- db.beginTransaction();
- try {
- long accountId = getAccountId(db, account);
- if (accountId >= 0) {
- db.delete(TABLE_GRANTS,
- GRANTS_ACCOUNTS_ID + "=? AND " + GRANTS_AUTH_TOKEN_TYPE + "=? AND "
- + GRANTS_GRANTEE_UID + "=?",
- new String[]{String.valueOf(accountId), authTokenType,
- String.valueOf(uid)});
- db.setTransactionSuccessful();
+ synchronized (mCacheLock) {
+ final SQLiteDatabase db = mOpenHelper.getWritableDatabase();
+ db.beginTransaction();
+ try {
+ long accountId = getAccountIdLocked(db, account);
+ if (accountId >= 0) {
+ db.delete(TABLE_GRANTS,
+ GRANTS_ACCOUNTS_ID + "=? AND " + GRANTS_AUTH_TOKEN_TYPE + "=? AND "
+ + GRANTS_GRANTEE_UID + "=?",
+ new String[]{String.valueOf(accountId), authTokenType,
+ String.valueOf(uid)});
+ db.setTransactionSuccessful();
+ }
+ } finally {
+ db.endTransaction();
}
- } finally {
- db.endTransaction();
+ cancelNotification(getCredentialPermissionNotificationId(account, authTokenType, uid));
}
- cancelNotification(getCredentialPermissionNotificationId(account, authTokenType, uid));
}
static final private String stringArrayToString(String[] value) {
return value != null ? ("[" + TextUtils.join(",", value) + "]") : null;
}
- private void removeAccountFromCache(Account account) {
- synchronized (mCacheLock) {
- final Account[] oldAccountsForType = mAccountCache.get(account.type);
- if (oldAccountsForType != null) {
- ArrayList<Account> newAccountsList = new ArrayList<Account>();
- for (Account curAccount : oldAccountsForType) {
- if (!curAccount.equals(account)) {
- newAccountsList.add(curAccount);
- }
- }
- if (newAccountsList.isEmpty()) {
- mAccountCache.remove(account.type);
- } else {
- Account[] newAccountsForType = new Account[newAccountsList.size()];
- newAccountsForType = newAccountsList.toArray(newAccountsForType);
- mAccountCache.put(account.type, newAccountsForType);
+ private void removeAccountFromCacheLocked(Account account) {
+ final Account[] oldAccountsForType = mAccountCache.get(account.type);
+ if (oldAccountsForType != null) {
+ ArrayList<Account> newAccountsList = new ArrayList<Account>();
+ for (Account curAccount : oldAccountsForType) {
+ if (!curAccount.equals(account)) {
+ newAccountsList.add(curAccount);
}
}
- mUserDataCache.remove(account);
- mAuthTokenCache.remove(account);
+ if (newAccountsList.isEmpty()) {
+ mAccountCache.remove(account.type);
+ } else {
+ Account[] newAccountsForType = new Account[newAccountsList.size()];
+ newAccountsForType = newAccountsList.toArray(newAccountsForType);
+ mAccountCache.put(account.type, newAccountsForType);
+ }
}
+ mUserDataCache.remove(account);
+ mAuthTokenCache.remove(account);
}
/**
* This assumes that the caller has already checked that the account is not already present.
*/
- private void insertAccountIntoCache(Account account) {
- synchronized (mCacheLock) {
- Account[] accountsForType = mAccountCache.get(account.type);
- int oldLength = (accountsForType != null) ? accountsForType.length : 0;
- Account[] newAccountsForType = new Account[oldLength + 1];
- if (accountsForType != null) {
- System.arraycopy(accountsForType, 0, newAccountsForType, 0, oldLength);
- }
- newAccountsForType[oldLength] = account;
- mAccountCache.put(account.type, newAccountsForType);
+ private void insertAccountIntoCacheLocked(Account account) {
+ Account[] accountsForType = mAccountCache.get(account.type);
+ int oldLength = (accountsForType != null) ? accountsForType.length : 0;
+ Account[] newAccountsForType = new Account[oldLength + 1];
+ if (accountsForType != null) {
+ System.arraycopy(accountsForType, 0, newAccountsForType, 0, oldLength);
}
+ newAccountsForType[oldLength] = account;
+ mAccountCache.put(account.type, newAccountsForType);
}
- protected Account[] getAccountsByTypeFromCache(String accountType) {
- synchronized (mCacheLock) {
- if (accountType != null) {
- final Account[] accounts = mAccountCache.get(accountType);
- if (accounts == null) {
- return EMPTY_ACCOUNT_ARRAY;
- } else {
- return Arrays.copyOf(accounts, accounts.length);
- }
+ protected Account[] getAccountsFromCacheLocked(String accountType) {
+ if (accountType != null) {
+ final Account[] accounts = mAccountCache.get(accountType);
+ if (accounts == null) {
+ return EMPTY_ACCOUNT_ARRAY;
} else {
- int totalLength = 0;
- for (Account[] accounts : mAccountCache.values()) {
- totalLength += accounts.length;
- }
- if (totalLength == 0) {
- return EMPTY_ACCOUNT_ARRAY;
- }
- Account[] accounts = new Account[totalLength];
- totalLength = 0;
- for (Account[] accountsOfType : mAccountCache.values()) {
- System.arraycopy(accountsOfType, 0, accounts, totalLength,
- accountsOfType.length);
- totalLength += accountsOfType.length;
- }
- return accounts;
+ return Arrays.copyOf(accounts, accounts.length);
}
+ } else {
+ int totalLength = 0;
+ for (Account[] accounts : mAccountCache.values()) {
+ totalLength += accounts.length;
+ }
+ if (totalLength == 0) {
+ return EMPTY_ACCOUNT_ARRAY;
+ }
+ Account[] accounts = new Account[totalLength];
+ totalLength = 0;
+ for (Account[] accountsOfType : mAccountCache.values()) {
+ System.arraycopy(accountsOfType, 0, accounts, totalLength,
+ accountsOfType.length);
+ totalLength += accountsOfType.length;
+ }
+ return accounts;
}
}
- protected void writeUserDataIntoCache(Account account, String key, String value) {
- synchronized (mCacheLock) {
- HashMap<String, String> userDataForAccount = mUserDataCache.get(account);
- if (userDataForAccount == null) {
- userDataForAccount = readUserDataForAccountFromDatabase(account);
- mUserDataCache.put(account, userDataForAccount);
- }
- if (value == null) {
- userDataForAccount.remove(key);
- } else {
- userDataForAccount.put(key, value);
- }
+ protected void writeUserDataIntoCacheLocked(final SQLiteDatabase db, Account account,
+ String key, String value) {
+ HashMap<String, String> userDataForAccount = mUserDataCache.get(account);
+ if (userDataForAccount == null) {
+ userDataForAccount = readUserDataForAccountFromDatabaseLocked(db, account);
+ mUserDataCache.put(account, userDataForAccount);
+ }
+ if (value == null) {
+ userDataForAccount.remove(key);
+ } else {
+ userDataForAccount.put(key, value);
}
}
- protected void writeAuthTokenIntoCache(Account account, String key, String value) {
- synchronized (mCacheLock) {
- HashMap<String, String> authTokensForAccount = mAuthTokenCache.get(account);
- if (authTokensForAccount == null) {
- authTokensForAccount = readAuthTokensForAccountFromDatabase(account);
- mAuthTokenCache.put(account, authTokensForAccount);
- }
- if (value == null) {
- authTokensForAccount.remove(key);
- } else {
- authTokensForAccount.put(key, value);
- }
+ protected void writeAuthTokenIntoCacheLocked(final SQLiteDatabase db, Account account,
+ String key, String value) {
+ HashMap<String, String> authTokensForAccount = mAuthTokenCache.get(account);
+ if (authTokensForAccount == null) {
+ authTokensForAccount = readAuthTokensForAccountFromDatabaseLocked(db, account);
+ mAuthTokenCache.put(account, authTokensForAccount);
+ }
+ if (value == null) {
+ authTokensForAccount.remove(key);
+ } else {
+ authTokensForAccount.put(key, value);
}
}
- protected String readAuthTokenFromCache(Account account, String authTokenType) {
+ protected String readAuthTokenInternal(Account account, String authTokenType) {
synchronized (mCacheLock) {
HashMap<String, String> authTokensForAccount = mAuthTokenCache.get(account);
if (authTokensForAccount == null) {
// need to populate the cache for this account
- authTokensForAccount = readAuthTokensForAccountFromDatabase(account);
+ final SQLiteDatabase db = mOpenHelper.getReadableDatabase();
+ authTokensForAccount = readAuthTokensForAccountFromDatabaseLocked(db, account);
mAuthTokenCache.put(account, authTokensForAccount);
}
return authTokensForAccount.get(authTokenType);
}
}
- protected String readUserDataFromCache(Account account, String key) {
+ protected String readUserDataInternal(Account account, String key) {
synchronized (mCacheLock) {
HashMap<String, String> userDataForAccount = mUserDataCache.get(account);
if (userDataForAccount == null) {
// need to populate the cache for this account
- userDataForAccount = readUserDataForAccountFromDatabase(account);
+ final SQLiteDatabase db = mOpenHelper.getReadableDatabase();
+ userDataForAccount = readUserDataForAccountFromDatabaseLocked(db, account);
mUserDataCache.put(account, userDataForAccount);
}
return userDataForAccount.get(key);
}
}
- protected HashMap<String, String> readUserDataForAccountFromDatabase(Account account) {
+ protected HashMap<String, String> readUserDataForAccountFromDatabaseLocked(
+ final SQLiteDatabase db, Account account) {
HashMap<String, String> userDataForAccount = new HashMap<String, String>();
- SQLiteDatabase db = mOpenHelper.getReadableDatabase();
Cursor cursor = db.query(TABLE_EXTRAS,
COLUMNS_EXTRAS_KEY_AND_VALUE,
SELECTION_USERDATA_BY_ACCOUNT,
@@ -2195,9 +2227,9 @@
return userDataForAccount;
}
- protected HashMap<String, String> readAuthTokensForAccountFromDatabase(Account account) {
+ protected HashMap<String, String> readAuthTokensForAccountFromDatabaseLocked(
+ final SQLiteDatabase db, Account account) {
HashMap<String, String> authTokensForAccount = new HashMap<String, String>();
- SQLiteDatabase db = mOpenHelper.getReadableDatabase();
Cursor cursor = db.query(TABLE_AUTHTOKENS,
COLUMNS_AUTHTOKENS_TYPE_AND_AUTHTOKEN,
SELECTION_AUTHTOKENS_BY_ACCOUNT,
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 9e72c1b..3a82c78 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -66,6 +66,7 @@
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
+import android.view.WindowManagerImpl;
import android.view.View.OnCreateContextMenuListener;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
@@ -2417,6 +2418,7 @@
*/
public boolean onMenuOpened(int featureId, Menu menu) {
if (featureId == Window.FEATURE_ACTION_BAR) {
+ initActionBar();
if (mActionBar != null) {
mActionBar.dispatchMenuVisibilityChanged(true);
} else {
@@ -4401,6 +4403,9 @@
if (mStopped) {
mStopped = false;
mCalled = false;
+ if (mToken != null && mParent == null) {
+ WindowManagerImpl.getDefault().setStoppedState(mToken, false);
+ }
mInstrumentation.callActivityOnRestart(this);
if (!mCalled) {
throw new SuperNotCalledException(
@@ -4477,6 +4482,10 @@
mWindow.closeAllPanels();
}
+ if (mToken != null && mParent == null) {
+ WindowManagerImpl.getDefault().setStoppedState(mToken, true);
+ }
+
mFragments.dispatchStop();
mCalled = false;
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index 8737e93..539e946 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -41,9 +41,9 @@
import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.graphics.Bitmap;
import android.graphics.drawable.Drawable;
-import android.hardware.IUsbManager;
import android.hardware.SensorManager;
-import android.hardware.UsbManager;
+import android.hardware.usb.IUsbManager;
+import android.hardware.usb.UsbManager;
import android.location.CountryDetector;
import android.location.ICountryDetector;
import android.location.ILocationManager;
diff --git a/core/java/android/app/DialogFragment.java b/core/java/android/app/DialogFragment.java
index 50953d7..dee1ef3 100644
--- a/core/java/android/app/DialogFragment.java
+++ b/core/java/android/app/DialogFragment.java
@@ -25,6 +25,9 @@
import android.view.Window;
import android.view.WindowManager;
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+
/**
* A fragment that displays a dialog window, floating on top of its
* activity's window. This fragment contains a Dialog object, which it
@@ -177,8 +180,9 @@
int mBackStackId = -1;
Dialog mDialog;
- boolean mDestroyed;
- boolean mRemoved;
+ boolean mViewDestroyed;
+ boolean mDismissed;
+ boolean mShownByMe;
public DialogFragment() {
}
@@ -219,6 +223,8 @@
* {@link FragmentTransaction#add(Fragment, String) FragmentTransaction.add}.
*/
public void show(FragmentManager manager, String tag) {
+ mDismissed = false;
+ mShownByMe = true;
FragmentTransaction ft = manager.beginTransaction();
ft.add(this, tag);
ft.commit();
@@ -234,8 +240,10 @@
* {@link FragmentTransaction#commit() FragmentTransaction.commit()}.
*/
public int show(FragmentTransaction transaction, String tag) {
+ mDismissed = false;
+ mShownByMe = true;
transaction.add(this, tag);
- mRemoved = false;
+ mViewDestroyed = false;
mBackStackId = transaction.commit();
return mBackStackId;
}
@@ -251,11 +259,16 @@
}
void dismissInternal(boolean allowStateLoss) {
+ if (mDismissed) {
+ return;
+ }
+ mDismissed = true;
+ mShownByMe = false;
if (mDialog != null) {
mDialog.dismiss();
mDialog = null;
}
- mRemoved = true;
+ mViewDestroyed = true;
if (mBackStackId >= 0) {
getFragmentManager().popBackStack(mBackStackId,
FragmentManager.POP_BACK_STACK_INCLUSIVE);
@@ -329,6 +342,27 @@
}
@Override
+ public void onAttach(Activity activity) {
+ super.onAttach(activity);
+ if (!mShownByMe) {
+ // If not explicitly shown through our API, take this as an
+ // indication that the dialog is no longer dismissed.
+ mDismissed = false;
+ }
+ }
+
+ @Override
+ public void onDetach() {
+ super.onDetach();
+ if (!mShownByMe && !mDismissed) {
+ // The fragment was not shown by a direct call here, it is not
+ // dismissed, and now it is being detached... well, okay, thou
+ // art now dismissed. Have fun.
+ mDismissed = true;
+ }
+ }
+
+ @Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@@ -352,7 +386,6 @@
}
mDialog = onCreateDialog(savedInstanceState);
- mDestroyed = false;
switch (mStyle) {
case STYLE_NO_INPUT:
mDialog.getWindow().addFlags(
@@ -363,7 +396,11 @@
case STYLE_NO_TITLE:
mDialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
}
- return (LayoutInflater)mDialog.getContext().getSystemService(
+ if (mDialog != null) {
+ return (LayoutInflater)mDialog.getContext().getSystemService(
+ Context.LAYOUT_INFLATER_SERVICE);
+ }
+ return (LayoutInflater)mActivity.getSystemService(
Context.LAYOUT_INFLATER_SERVICE);
}
@@ -397,7 +434,7 @@
}
public void onDismiss(DialogInterface dialog) {
- if (!mRemoved) {
+ if (!mViewDestroyed) {
// Note: we need to use allowStateLoss, because the dialog
// dispatches this asynchronously so we can receive the call
// after the activity is paused. Worst case, when the user comes
@@ -439,7 +476,7 @@
public void onStart() {
super.onStart();
if (mDialog != null) {
- mRemoved = false;
+ mViewDestroyed = false;
mDialog.show();
}
}
@@ -484,14 +521,28 @@
@Override
public void onDestroyView() {
super.onDestroyView();
- mDestroyed = true;
if (mDialog != null) {
// Set removed here because this dismissal is just to hide
// the dialog -- we don't want this to cause the fragment to
// actually be removed.
- mRemoved = true;
+ mViewDestroyed = true;
mDialog.dismiss();
mDialog = null;
}
}
+
+ @Override
+ public void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) {
+ super.dump(prefix, fd, writer, args);
+ writer.print(prefix); writer.println("DialogFragment:");
+ writer.print(prefix); writer.print(" mStyle="); writer.print(mStyle);
+ writer.print(" mTheme=0x"); writer.println(Integer.toHexString(mTheme));
+ writer.print(prefix); writer.print(" mCancelable="); writer.print(mCancelable);
+ writer.print(" mShowsDialog="); writer.print(mShowsDialog);
+ writer.print(" mBackStackId="); writer.println(mBackStackId);
+ writer.print(prefix); writer.print(" mDialog="); writer.println(mDialog);
+ writer.print(prefix); writer.print(" mViewDestroyed="); writer.print(mViewDestroyed);
+ writer.print(" mDismissed="); writer.print(mDismissed);
+ writer.print(" mShownByMe="); writer.println(mShownByMe);
+ }
}
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 051ae9e..4c7d87f 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -1664,11 +1664,11 @@
/**
* Use with {@link #getSystemService} to retrieve a {@link
- * android.hardware.UsbManager} for access to USB devices (as a USB host)
+ * android.hardware.usb.UsbManager} for access to USB devices (as a USB host)
* and for controlling this device's behavior as a USB device.
*
* @see #getSystemService
- * @see android.harware.UsbManager
+ * @see android.harware.usb.UsbManager
*/
public static final String USB_SERVICE = "usb";
diff --git a/core/java/android/content/pm/IPackageDeleteObserver.aidl b/core/java/android/content/pm/IPackageDeleteObserver.aidl
index bc16b3e..2e2d16e 100644
--- a/core/java/android/content/pm/IPackageDeleteObserver.aidl
+++ b/core/java/android/content/pm/IPackageDeleteObserver.aidl
@@ -23,6 +23,6 @@
* {@hide}
*/
oneway interface IPackageDeleteObserver {
- void packageDeleted(in boolean succeeded);
+ void packageDeleted(in String packageName, in int returnCode);
}
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 7525749..fc07478 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -552,9 +552,38 @@
public static final int DONT_DELETE_DATA = 0x00000001;
/**
+ * Return code for when package deletion succeeds. This is passed to the
+ * {@link IPackageDeleteObserver} by {@link #deletePackage()} if the system
+ * succeeded in deleting the package.
+ *
+ * @hide
+ */
+ public static final int DELETE_SUCCEEDED = 1;
+
+ /**
+ * Deletion failed return code: this is passed to the
+ * {@link IPackageDeleteObserver} by {@link #deletePackage()} if the system
+ * failed to delete the package for an unspecified reason.
+ *
+ * @hide
+ */
+ public static final int DELETE_FAILED_INTERNAL_ERROR = -1;
+
+ /**
+ * Deletion failed return code: this is passed to the
+ * {@link IPackageDeleteObserver} by {@link #deletePackage()} if the system
+ * failed to delete the package because it is the active DevicePolicy
+ * manager.
+ *
+ * @hide
+ */
+ public static final int DELETE_FAILED_DEVICE_POLICY_MANAGER = -2;
+
+ /**
* Return code that is passed to the {@link IPackageMoveObserver} by
- * {@link #movePackage(android.net.Uri, IPackageMoveObserver)}
- * when the package has been successfully moved by the system.
+ * {@link #movePackage(android.net.Uri, IPackageMoveObserver)} when the
+ * package has been successfully moved by the system.
+ *
* @hide
*/
public static final int MOVE_SUCCEEDED = 1;
diff --git a/core/java/android/database/AbstractWindowedCursor.java b/core/java/android/database/AbstractWindowedCursor.java
index 8addaa8..3d95769 100644
--- a/core/java/android/database/AbstractWindowedCursor.java
+++ b/core/java/android/database/AbstractWindowedCursor.java
@@ -117,7 +117,8 @@
super.checkPosition();
if (mWindow == null) {
- throw new StaleDataException("Attempting to access a closed cursor");
+ throw new StaleDataException("Attempting to access a closed CursorWindow." +
+ "Most probable cause: cursor is deactivated prior to calling this method.");
}
}
diff --git a/core/java/android/database/CursorWindow.java b/core/java/android/database/CursorWindow.java
index bd78063..f7cbf7a 100644
--- a/core/java/android/database/CursorWindow.java
+++ b/core/java/android/database/CursorWindow.java
@@ -17,14 +17,12 @@
package android.database;
import android.content.res.Resources;
-import android.database.sqlite.DatabaseObjectNotClosedException;
import android.database.sqlite.SQLiteClosable;
import android.os.Binder;
import android.os.IBinder;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.Process;
-import android.os.StrictMode;
import android.util.Log;
import android.util.SparseIntArray;
@@ -47,7 +45,6 @@
private int nWindow;
private int mStartPos;
- private final Throwable mStackTrace;
/**
* Creates a new empty window.
@@ -59,7 +56,6 @@
int rslt = native_init(sCursorWindowSize, localWindow);
printDebugMsgIfError(rslt);
recordNewWindow(Binder.getCallingPid(), nWindow);
- mStackTrace = new DatabaseObjectNotClosedException().fillInStackTrace();
}
private void printDebugMsgIfError(int rslt) {
@@ -568,12 +564,9 @@
if (nWindow == 0) {
return;
}
- if (StrictMode.vmSqliteObjectLeaksEnabled()) {
- StrictMode.onSqliteObjectLeaked(
- "Releasing cursor in a finalizer. Please ensure " +
- "that you explicitly call close() on your cursor: ",
- mStackTrace);
- }
+ // due to bugs 3329504, 3502276, cursorwindow sometimes is closed in fialize()
+ // don't print any warning saying "don't release cursor in finzlize"
+ // because it is a bug in framework code - NOT an app bug.
recordClosingOfWindow(nWindow);
close_native();
}
@@ -606,7 +599,6 @@
IBinder nativeBinder = source.readStrongBinder();
mStartPos = source.readInt();
int rslt = native_init(nativeBinder);
- mStackTrace = new DatabaseObjectNotClosedException().fillInStackTrace();
printDebugMsgIfError(rslt);
}
diff --git a/core/java/android/hardware/IUsbManager.aidl b/core/java/android/hardware/usb/IUsbManager.aidl
similarity index 95%
rename from core/java/android/hardware/IUsbManager.aidl
rename to core/java/android/hardware/usb/IUsbManager.aidl
index 8086f37..be65bdb 100644
--- a/core/java/android/hardware/IUsbManager.aidl
+++ b/core/java/android/hardware/usb/IUsbManager.aidl
@@ -14,10 +14,10 @@
* limitations under the License.
*/
-package android.hardware;
+package android.hardware.usb;
-import android.hardware.UsbAccessory;
-import android.hardware.UsbDevice;
+import android.hardware.usb.UsbAccessory;
+import android.hardware.usb.UsbDevice;
import android.os.Bundle;
import android.os.ParcelFileDescriptor;
diff --git a/core/java/android/hardware/UsbAccessory.aidl b/core/java/android/hardware/usb/UsbAccessory.aidl
similarity index 95%
rename from core/java/android/hardware/UsbAccessory.aidl
rename to core/java/android/hardware/usb/UsbAccessory.aidl
index 97a777b..1c15f1c 100644
--- a/core/java/android/hardware/UsbAccessory.aidl
+++ b/core/java/android/hardware/usb/UsbAccessory.aidl
@@ -14,6 +14,6 @@
* limitations under the License.
*/
-package android.hardware;
+package android.hardware.usb;
parcelable UsbAccessory;
diff --git a/core/java/android/hardware/UsbAccessory.java b/core/java/android/hardware/usb/UsbAccessory.java
similarity index 93%
rename from core/java/android/hardware/UsbAccessory.java
rename to core/java/android/hardware/usb/UsbAccessory.java
index 15dff3e..6cd9178 100644
--- a/core/java/android/hardware/UsbAccessory.java
+++ b/core/java/android/hardware/usb/UsbAccessory.java
@@ -14,28 +14,24 @@
* limitations under the License.
*/
-package android.hardware;
+package android.hardware.usb;
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
-import android.os.ParcelFileDescriptor;
import android.util.Log;
/**
* A class representing a USB accessory.
*/
-public final class UsbAccessory implements Parcelable {
+public class UsbAccessory implements Parcelable {
private static final String TAG = "UsbAccessory";
- private String mManufacturer;
- private String mModel;
- private String mType;
- private String mVersion;
-
- private UsbAccessory() {
- }
+ private final String mManufacturer;
+ private final String mModel;
+ private final String mType;
+ private final String mVersion;
/**
* UsbAccessory should only be instantiated by UsbService implementation
diff --git a/core/java/android/hardware/UsbConstants.java b/core/java/android/hardware/usb/UsbConstants.java
similarity index 98%
rename from core/java/android/hardware/UsbConstants.java
rename to core/java/android/hardware/usb/UsbConstants.java
index 4c8c4d4..6626c9f 100644
--- a/core/java/android/hardware/UsbConstants.java
+++ b/core/java/android/hardware/usb/UsbConstants.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package android.hardware;
+package android.hardware.usb;
/**
* Contains constants for the USB protocol.
diff --git a/core/java/android/hardware/UsbDevice.aidl b/core/java/android/hardware/usb/UsbDevice.aidl
similarity index 95%
rename from core/java/android/hardware/UsbDevice.aidl
rename to core/java/android/hardware/usb/UsbDevice.aidl
index 6dfd43f..6030ad1 100644
--- a/core/java/android/hardware/UsbDevice.aidl
+++ b/core/java/android/hardware/usb/UsbDevice.aidl
@@ -14,6 +14,6 @@
* limitations under the License.
*/
-package android.hardware;
+package android.hardware.usb;
parcelable UsbDevice;
diff --git a/core/java/android/hardware/UsbDevice.java b/core/java/android/hardware/usb/UsbDevice.java
similarity index 91%
rename from core/java/android/hardware/UsbDevice.java
rename to core/java/android/hardware/usb/UsbDevice.java
index ca7dae3..37bd82b 100644
--- a/core/java/android/hardware/UsbDevice.java
+++ b/core/java/android/hardware/usb/UsbDevice.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package android.hardware;
+package android.hardware.usb;
import android.os.Bundle;
import android.os.Parcel;
@@ -106,7 +106,7 @@
/**
* Returns the devices's class field.
* Some useful constants for USB device classes can be found in
- * {@link android.hardware.UsbConstants}
+ * {@link android.hardware.usb.UsbConstants}
*
* @return the devices's class
*/
@@ -133,7 +133,7 @@
}
/**
- * Returns the number of {@link android.hardware.UsbInterface}s this device contains.
+ * Returns the number of {@link android.hardware.usb.UsbInterface}s this device contains.
*
* @return the number of interfaces
*/
@@ -142,7 +142,7 @@
}
/**
- * Returns the {@link android.hardware.UsbInterface} at the given index.
+ * Returns the {@link android.hardware.usb.UsbInterface} at the given index.
*
* @return the interface
*/
@@ -171,9 +171,9 @@
}
/**
- * Claims exclusive access to a {@link android.hardware.UsbInterface}.
+ * Claims exclusive access to a {@link android.hardware.usb.UsbInterface}.
* This must be done before sending or receiving data on any
- * {@link android.hardware.UsbEndpoint}s belonging to the interface
+ * {@link android.hardware.usb.UsbEndpoint}s belonging to the interface
* @param intf the interface to claim
* @param force true to disconnect kernel driver if necessary
* @return true if the interface was successfully claimed
@@ -183,7 +183,7 @@
}
/**
- * Releases exclusive access to a {@link android.hardware.UsbInterface}.
+ * Releases exclusive access to a {@link android.hardware.usb.UsbInterface}.
*
* @return true if the interface was successfully released
*/
@@ -231,11 +231,12 @@
}
/**
- * Waits for the result of a {@link android.hardware.UsbRequest#queue} operation
- * Note that this may return requests queued on multiple {@link android.hardware.UsbEndpoint}s.
- * When multiple endpoints are in use, {@link android.hardware.UsbRequest#getEndpoint} and
- * {@link android.hardware.UsbRequest#getClientData} can be useful in determining how to process
- * the result of this function.
+ * Waits for the result of a {@link android.hardware.usb.UsbRequest#queue} operation
+ * Note that this may return requests queued on multiple
+ * {@link android.hardware.usb.UsbEndpoint}s.
+ * When multiple endpoints are in use, {@link android.hardware.usb.UsbRequest#getEndpoint} and
+ * {@link android.hardware.usb.UsbRequest#getClientData} can be useful in determining
+ * how to process the result of this function.
*
* @return a completed USB request, or null if an error occurred
*/
diff --git a/core/java/android/hardware/UsbEndpoint.aidl b/core/java/android/hardware/usb/UsbEndpoint.aidl
similarity index 95%
rename from core/java/android/hardware/UsbEndpoint.aidl
rename to core/java/android/hardware/usb/UsbEndpoint.aidl
index 51fc67b..a75cd7e 100644
--- a/core/java/android/hardware/UsbEndpoint.aidl
+++ b/core/java/android/hardware/usb/UsbEndpoint.aidl
@@ -14,6 +14,6 @@
* limitations under the License.
*/
-package android.hardware;
+package android.hardware.usb;
parcelable UsbEndpoint;
diff --git a/core/java/android/hardware/UsbEndpoint.java b/core/java/android/hardware/usb/UsbEndpoint.java
similarity index 85%
rename from core/java/android/hardware/UsbEndpoint.java
rename to core/java/android/hardware/usb/UsbEndpoint.java
index 8d4099d..a48d88f 100644
--- a/core/java/android/hardware/UsbEndpoint.java
+++ b/core/java/android/hardware/usb/UsbEndpoint.java
@@ -14,14 +14,14 @@
* limitations under the License.
*/
-package android.hardware;
+package android.hardware.usb;
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
/**
- * A class representing an endpoint on a {@link android.hardware.UsbInterface}.
+ * A class representing an endpoint on a {@link android.hardware.usb.UsbInterface}.
*/
public final class UsbEndpoint implements Parcelable {
@@ -65,9 +65,9 @@
/**
* Returns the endpoint's direction.
- * Returns {@link android.hardware.UsbConstants#USB_DIR_OUT}
+ * Returns {@link android.hardware.usb.UsbConstants#USB_DIR_OUT}
* if the direction is host to device, and
- * {@link android.hardware.UsbConstants#USB_DIR_IN} if the
+ * {@link android.hardware.usb.UsbConstants#USB_DIR_IN} if the
* direction is device to host.
*
* @return the endpoint's direction
@@ -89,10 +89,10 @@
* Returns the endpoint's type.
* Possible results are:
* <ul>
- * <li>{@link android.hardware.UsbConstants#USB_ENDPOINT_XFER_CONTROL} (endpoint zero)
- * <li>{@link android.hardware.UsbConstants#USB_ENDPOINT_XFER_ISOC} (isochronous endpoint)
- * <li>{@link android.hardware.UsbConstants#USB_ENDPOINT_XFER_BULK} (bulk endpoint)
- * <li>{@link android.hardware.UsbConstants#USB_ENDPOINT_XFER_INT} (interrupt endpoint)
+ * <li>{@link android.hardware.usb.UsbConstants#USB_ENDPOINT_XFER_CONTROL} (endpoint zero)
+ * <li>{@link android.hardware.usb.UsbConstants#USB_ENDPOINT_XFER_ISOC} (isochronous endpoint)
+ * <li>{@link android.hardware.usb.UsbConstants#USB_ENDPOINT_XFER_BULK} (bulk endpoint)
+ * <li>{@link android.hardware.usb.UsbConstants#USB_ENDPOINT_XFER_INT} (interrupt endpoint)
* </ul>
*
* @return the endpoint's type
@@ -120,7 +120,7 @@
}
/**
- * Returns the {@link android.hardware.UsbInterface} this endpoint belongs to.
+ * Returns the {@link android.hardware.usb.UsbInterface} this endpoint belongs to.
*
* @return the endpoint's interface
*/
@@ -129,7 +129,7 @@
}
/**
- * Returns the {@link android.hardware.UsbDevice} this endpoint belongs to.
+ * Returns the {@link android.hardware.usb.UsbDevice} this endpoint belongs to.
*
* @return the endpoint's device
*/
diff --git a/core/java/android/hardware/UsbInterface.aidl b/core/java/android/hardware/usb/UsbInterface.aidl
similarity index 95%
rename from core/java/android/hardware/UsbInterface.aidl
rename to core/java/android/hardware/usb/UsbInterface.aidl
index a715ccd..32b8c64 100644
--- a/core/java/android/hardware/UsbInterface.aidl
+++ b/core/java/android/hardware/usb/UsbInterface.aidl
@@ -14,6 +14,6 @@
* limitations under the License.
*/
-package android.hardware;
+package android.hardware.usb;
parcelable UsbInterface;
diff --git a/core/java/android/hardware/UsbInterface.java b/core/java/android/hardware/usb/UsbInterface.java
similarity index 90%
rename from core/java/android/hardware/UsbInterface.java
rename to core/java/android/hardware/usb/UsbInterface.java
index deef81f..b3b0e81 100644
--- a/core/java/android/hardware/UsbInterface.java
+++ b/core/java/android/hardware/usb/UsbInterface.java
@@ -14,16 +14,16 @@
* limitations under the License.
*/
-package android.hardware;
+package android.hardware.usb;
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
/**
- * A class representing an interface on a {@link android.hardware.UsbDevice}.
+ * A class representing an interface on a {@link android.hardware.usb.UsbDevice}.
*/
-public final class UsbInterface implements Parcelable {
+public class UsbInterface implements Parcelable {
private int mId;
private int mClass;
@@ -60,7 +60,7 @@
/**
* Returns the interface's class field.
* Some useful constants for USB classes can be found in
- * {@link android.hardware.UsbConstants}
+ * {@link android.hardware.usb.UsbConstants}
*
* @return the interface's class
*/
@@ -87,7 +87,7 @@
}
/**
- * Returns the number of {@link android.hardware.UsbEndpoint}s this interface contains.
+ * Returns the number of {@link android.hardware.usb.UsbEndpoint}s this interface contains.
*
* @return the number of endpoints
*/
@@ -96,7 +96,7 @@
}
/**
- * Returns the {@link android.hardware.UsbEndpoint} at the given index.
+ * Returns the {@link android.hardware.usb.UsbEndpoint} at the given index.
*
* @return the endpoint
*/
@@ -105,7 +105,7 @@
}
/**
- * Returns the {@link android.hardware.UsbDevice} this interface belongs to.
+ * Returns the {@link android.hardware.usb.UsbDevice} this interface belongs to.
*
* @return the interface's device
*/
diff --git a/core/java/android/hardware/UsbManager.java b/core/java/android/hardware/usb/UsbManager.java
similarity index 95%
rename from core/java/android/hardware/UsbManager.java
rename to core/java/android/hardware/usb/UsbManager.java
index e9a34ea..6683179 100644
--- a/core/java/android/hardware/UsbManager.java
+++ b/core/java/android/hardware/usb/UsbManager.java
@@ -15,7 +15,7 @@
*/
-package android.hardware;
+package android.hardware.usb;
import android.os.Bundle;
import android.os.ParcelFileDescriptor;
@@ -55,55 +55,55 @@
* </ul>
*/
public static final String ACTION_USB_STATE =
- "android.hardware.action.USB_STATE";
+ "android.hardware.usb.action.USB_STATE";
/**
* Broadcast Action: A broadcast for USB device attached event.
*
* This intent is sent when a USB device is attached to the USB bus when in host mode.
* <ul>
- * <li> {@link #EXTRA_DEVICE} containing the {@link android.hardware.UsbDevice}
+ * <li> {@link #EXTRA_DEVICE} containing the {@link android.hardware.usb.UsbDevice}
* for the attached device
* </ul>
*/
public static final String ACTION_USB_DEVICE_ATTACHED =
- "android.hardware.action.USB_DEVICE_ATTACHED";
+ "android.hardware.usb.action.USB_DEVICE_ATTACHED";
/**
* Broadcast Action: A broadcast for USB device detached event.
*
* This intent is sent when a USB device is detached from the USB bus when in host mode.
* <ul>
- * <li> {@link #EXTRA_DEVICE} containing the {@link android.hardware.UsbDevice}
+ * <li> {@link #EXTRA_DEVICE} containing the {@link android.hardware.usb.UsbDevice}
* for the detached device
* </ul>
*/
public static final String ACTION_USB_DEVICE_DETACHED =
- "android.hardware.action.USB_DEVICE_DETACHED";
+ "android.hardware.usb.action.USB_DEVICE_DETACHED";
/**
* Broadcast Action: A broadcast for USB accessory attached event.
*
* This intent is sent when a USB accessory is attached.
* <ul>
- * <li> {@link #EXTRA_ACCESSORY} containing the {@link android.hardware.UsbAccessory}
+ * <li> {@link #EXTRA_ACCESSORY} containing the {@link android.hardware.usb.UsbAccessory}
* for the attached accessory
* </ul>
*/
public static final String ACTION_USB_ACCESSORY_ATTACHED =
- "android.hardware.action.USB_ACCESSORY_ATTACHED";
+ "android.hardware.usb.action.USB_ACCESSORY_ATTACHED";
/**
* Broadcast Action: A broadcast for USB accessory detached event.
*
* This intent is sent when a USB accessory is detached.
* <ul>
- * <li> {@link #EXTRA_ACCESSORY} containing the {@link android.hardware.UsbAccessory}
+ * <li> {@link #EXTRA_ACCESSORY} containing the {@link android.hardware.usb.UsbAccessory}
* for the attached accessory that was detached
* </ul>
*/
public static final String ACTION_USB_ACCESSORY_DETACHED =
- "android.hardware.action.USB_ACCESSORY_DETACHED";
+ "android.hardware.usb.action.USB_ACCESSORY_DETACHED";
/**
* Boolean extra indicating whether USB is connected or disconnected.
@@ -210,7 +210,7 @@
/**
* Opens the device so it can be used to send and receive
- * data using {@link android.hardware.UsbRequest}.
+ * data using {@link android.hardware.usb.UsbRequest}.
*
* @param device the device to open
* @return true if we successfully opened the device
diff --git a/core/java/android/hardware/UsbRequest.java b/core/java/android/hardware/usb/UsbRequest.java
similarity index 94%
rename from core/java/android/hardware/UsbRequest.java
rename to core/java/android/hardware/usb/UsbRequest.java
index ae3a289..80085c1 100644
--- a/core/java/android/hardware/UsbRequest.java
+++ b/core/java/android/hardware/usb/UsbRequest.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package android.hardware;
+package android.hardware.usb;
import android.util.Log;
@@ -23,9 +23,9 @@
/**
* A class representing USB request packet.
* This can be used for both reading and writing data to or from a
- * {@link android.hardware.UsbDevice}.
+ * {@link android.hardware.usb.UsbDevice}.
* UsbRequests are sent asynchronously via {@link #queue} and the results
- * are read by {@link android.hardware.UsbDevice#requestWait}.
+ * are read by {@link android.hardware.usb.UsbDevice#requestWait}.
*/
public class UsbRequest {
@@ -94,7 +94,7 @@
* This can be used in conjunction with {@link #setClientData}
* to associate another object with this request, which can be useful for
* maintaining state between calls to {@link #queue} and
- * {@link android.hardware.UsbDevice#requestWait}
+ * {@link android.hardware.usb.UsbDevice#requestWait}
*
* @return the client data for the request
*/
@@ -107,7 +107,7 @@
* This can be used in conjunction with {@link #getClientData}
* to associate another object with this request, which can be useful for
* maintaining state between calls to {@link #queue} and
- * {@link android.hardware.UsbDevice#requestWait}
+ * {@link android.hardware.usb.UsbDevice#requestWait}
*
* @param data the client data for the request
*/
@@ -121,7 +121,7 @@
* For IN endpoints, the endpoint will attempt to read the given number of bytes
* into the specified buffer.
* If the queueing operation is successful, we return true and the result will be
- * returned via {@link android.hardware.UsbDevice#requestWait}
+ * returned via {@link android.hardware.usb.UsbDevice#requestWait}
*
* @param buffer the buffer containing the bytes to write, or location to store
* the results of a read
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index 5c06151..af4c221 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -2447,21 +2447,26 @@
}
cache = child.getDrawingCache(true);
} else {
- if (layerType == LAYER_TYPE_SOFTWARE) {
- child.buildDrawingCache(true);
- cache = child.getDrawingCache(true);
- } else if (layerType == LAYER_TYPE_NONE) {
- // Delay getting the display list until animation-driven alpha values are
- // set up and possibly passed on to the view
- hasDisplayList = child.canHaveDisplayList();
+ switch (layerType) {
+ case LAYER_TYPE_SOFTWARE:
+ child.buildDrawingCache(true);
+ cache = child.getDrawingCache(true);
+ break;
+ case LAYER_TYPE_NONE:
+ // Delay getting the display list until animation-driven alpha values are
+ // set up and possibly passed on to the view
+ hasDisplayList = child.canHaveDisplayList();
+ break;
}
}
}
final boolean hasNoCache = cache == null || hasDisplayList;
+ final boolean offsetForScroll = cache == null && !hasDisplayList &&
+ layerType != LAYER_TYPE_HARDWARE;
final int restoreTo = canvas.save();
- if (cache == null && !hasDisplayList) {
+ if (offsetForScroll) {
canvas.translate(cl - sx, ct - sy);
} else {
canvas.translate(cl, ct);
@@ -2477,7 +2482,7 @@
int transX = 0;
int transY = 0;
- if (cache == null && !hasDisplayList) {
+ if (offsetForScroll) {
transX = -sx;
transY = -sy;
}
@@ -2517,8 +2522,10 @@
layerFlags |= Canvas.CLIP_TO_LAYER_SAVE_FLAG;
}
if (layerType == LAYER_TYPE_NONE) {
- canvas.saveLayerAlpha(sx, sy, sx + cr - cl, sy + cb - ct,
- multipliedAlpha, layerFlags);
+ final int scrollX = hasDisplayList ? 0 : sx;
+ final int scrollY = hasDisplayList ? 0 : sy;
+ canvas.saveLayerAlpha(scrollX, scrollY, scrollX + cr - cl,
+ scrollY + cb - ct, multipliedAlpha, layerFlags);
}
} else {
// Alpha is handled by the child directly, clobber the layer's alpha
@@ -2532,7 +2539,7 @@
}
if ((flags & FLAG_CLIP_CHILDREN) == FLAG_CLIP_CHILDREN) {
- if (cache == null && !hasDisplayList) {
+ if (offsetForScroll) {
canvas.clipRect(sx, sy, sx + (cr - cl), sy + (cb - ct));
} else {
if (!scalingRequired || cache == null) {
@@ -2556,7 +2563,10 @@
((HardwareCanvas) canvas).drawHardwareLayer(layer, 0, 0, child.mLayerPaint);
layerRendered = true;
} else {
- canvas.saveLayer(sx, sy, sx + cr - cl, sy + cb - ct, child.mLayerPaint,
+ final int scrollX = hasDisplayList ? 0 : sx;
+ final int scrollY = hasDisplayList ? 0 : sy;
+ canvas.saveLayer(scrollX, scrollY,
+ scrollX + cr - cl, scrollY + cb - ct, child.mLayerPaint,
Canvas.HAS_ALPHA_LAYER_SAVE_FLAG | Canvas.CLIP_TO_LAYER_SAVE_FLAG);
}
}
diff --git a/core/java/android/view/ViewRoot.java b/core/java/android/view/ViewRoot.java
index c7b1955..965c959 100644
--- a/core/java/android/view/ViewRoot.java
+++ b/core/java/android/view/ViewRoot.java
@@ -155,6 +155,10 @@
int mViewVisibility;
boolean mAppVisible = true;
+ // Set to true if the owner of this window is in the stopped state,
+ // so the window should no longer be active.
+ boolean mStopped = false;
+
SurfaceHolder.Callback2 mSurfaceHolderCallback;
BaseSurfaceHolder mSurfaceHolder;
boolean mIsCreating;
@@ -618,6 +622,15 @@
scheduleTraversals();
}
+ void setStopped(boolean stopped) {
+ if (mStopped != stopped) {
+ mStopped = stopped;
+ if (!stopped) {
+ scheduleTraversals();
+ }
+ }
+ }
+
public ViewParent getParent() {
return null;
}
@@ -760,7 +773,7 @@
boolean insetsChanged = false;
- if (mLayoutRequested) {
+ if (mLayoutRequested && !mStopped) {
// Execute enqueued actions on every layout in case a view that was detached
// enqueued an action after being detached
getRunQueue().executeActions(attachInfo.mHandler);
@@ -1143,54 +1156,56 @@
mAttachInfo.mHardwareRenderer.setup(mWidth, mHeight);
}
- boolean focusChangedDueToTouchMode = ensureTouchModeLocally(
- (relayoutResult&WindowManagerImpl.RELAYOUT_IN_TOUCH_MODE) != 0);
- if (focusChangedDueToTouchMode || mWidth != host.getMeasuredWidth()
- || mHeight != host.getMeasuredHeight() || contentInsetsChanged) {
- childWidthMeasureSpec = getRootMeasureSpec(mWidth, lp.width);
- childHeightMeasureSpec = getRootMeasureSpec(mHeight, lp.height);
-
- if (DEBUG_LAYOUT) Log.v(TAG, "Ooops, something changed! mWidth="
- + mWidth + " measuredWidth=" + host.getMeasuredWidth()
- + " mHeight=" + mHeight
- + " measuredHeight=" + host.getMeasuredHeight()
- + " coveredInsetsChanged=" + contentInsetsChanged);
-
- // Ask host how big it wants to be
- host.measure(childWidthMeasureSpec, childHeightMeasureSpec);
-
- // Implementation of weights from WindowManager.LayoutParams
- // We just grow the dimensions as needed and re-measure if
- // needs be
- int width = host.getMeasuredWidth();
- int height = host.getMeasuredHeight();
- boolean measureAgain = false;
-
- if (lp.horizontalWeight > 0.0f) {
- width += (int) ((mWidth - width) * lp.horizontalWeight);
- childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(width,
- MeasureSpec.EXACTLY);
- measureAgain = true;
- }
- if (lp.verticalWeight > 0.0f) {
- height += (int) ((mHeight - height) * lp.verticalWeight);
- childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(height,
- MeasureSpec.EXACTLY);
- measureAgain = true;
- }
-
- if (measureAgain) {
- if (DEBUG_LAYOUT) Log.v(TAG,
- "And hey let's measure once more: width=" + width
- + " height=" + height);
+ if (!mStopped) {
+ boolean focusChangedDueToTouchMode = ensureTouchModeLocally(
+ (relayoutResult&WindowManagerImpl.RELAYOUT_IN_TOUCH_MODE) != 0);
+ if (focusChangedDueToTouchMode || mWidth != host.getMeasuredWidth()
+ || mHeight != host.getMeasuredHeight() || contentInsetsChanged) {
+ childWidthMeasureSpec = getRootMeasureSpec(mWidth, lp.width);
+ childHeightMeasureSpec = getRootMeasureSpec(mHeight, lp.height);
+
+ if (DEBUG_LAYOUT) Log.v(TAG, "Ooops, something changed! mWidth="
+ + mWidth + " measuredWidth=" + host.getMeasuredWidth()
+ + " mHeight=" + mHeight
+ + " measuredHeight=" + host.getMeasuredHeight()
+ + " coveredInsetsChanged=" + contentInsetsChanged);
+
+ // Ask host how big it wants to be
host.measure(childWidthMeasureSpec, childHeightMeasureSpec);
+
+ // Implementation of weights from WindowManager.LayoutParams
+ // We just grow the dimensions as needed and re-measure if
+ // needs be
+ int width = host.getMeasuredWidth();
+ int height = host.getMeasuredHeight();
+ boolean measureAgain = false;
+
+ if (lp.horizontalWeight > 0.0f) {
+ width += (int) ((mWidth - width) * lp.horizontalWeight);
+ childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(width,
+ MeasureSpec.EXACTLY);
+ measureAgain = true;
+ }
+ if (lp.verticalWeight > 0.0f) {
+ height += (int) ((mHeight - height) * lp.verticalWeight);
+ childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(height,
+ MeasureSpec.EXACTLY);
+ measureAgain = true;
+ }
+
+ if (measureAgain) {
+ if (DEBUG_LAYOUT) Log.v(TAG,
+ "And hey let's measure once more: width=" + width
+ + " height=" + height);
+ host.measure(childWidthMeasureSpec, childHeightMeasureSpec);
+ }
+
+ mLayoutRequested = true;
}
-
- mLayoutRequested = true;
}
}
- final boolean didLayout = mLayoutRequested;
+ final boolean didLayout = mLayoutRequested && !mStopped;
boolean triggerGlobalLayoutListener = didLayout
|| attachInfo.mRecomputeGlobalAttributes;
if (didLayout) {
diff --git a/core/java/android/view/WindowManagerImpl.java b/core/java/android/view/WindowManagerImpl.java
index 07953d6..a4c4544 100644
--- a/core/java/android/view/WindowManagerImpl.java
+++ b/core/java/android/view/WindowManagerImpl.java
@@ -302,6 +302,20 @@
}
}
+ public void setStoppedState(IBinder token, boolean stopped) {
+ synchronized (this) {
+ if (mViews == null)
+ return;
+ int count = mViews.length;
+ for (int i=0; i<count; i++) {
+ if (token == null || mParams[i].token == token) {
+ ViewRoot root = mRoots[i];
+ root.setStopped(stopped);
+ }
+ }
+ }
+ }
+
public WindowManager.LayoutParams getRootViewLayoutParameter(View view) {
ViewParent vp = view.getParent();
while (vp != null && !(vp instanceof ViewRoot)) {
diff --git a/core/java/android/webkit/CookieManager.java b/core/java/android/webkit/CookieManager.java
index 40877e7..d6e36bb 100644
--- a/core/java/android/webkit/CookieManager.java
+++ b/core/java/android/webkit/CookieManager.java
@@ -293,6 +293,11 @@
* @param value The value for set-cookie: in http response header
*/
public void setCookie(String url, String value) {
+ if (JniUtil.useChromiumHttpStack()) {
+ setCookie(url, value, false);
+ return;
+ }
+
WebAddress uri;
try {
uri = new WebAddress(url);
@@ -301,11 +306,33 @@
return;
}
- if (JniUtil.useChromiumHttpStack()) {
- nativeSetCookie(uri.toString(), value);
- } else {
- setCookie(uri, value);
+ setCookie(uri, value);
+ }
+
+ /**
+ * Set cookie for a given url. The old cookie with same host/path/name will
+ * be removed. The new cookie will be added if it is not expired or it does
+ * not have expiration which implies it is session cookie.
+ * @param url The url which cookie is set for
+ * @param value The value for set-cookie: in http response header
+ * @param privateBrowsing cookie jar to use
+ * @hide hiding private browsing
+ */
+ public void setCookie(String url, String value, boolean privateBrowsing) {
+ if (!JniUtil.useChromiumHttpStack()) {
+ setCookie(url, value);
+ return;
}
+
+ WebAddress uri;
+ try {
+ uri = new WebAddress(url);
+ } catch (ParseException ex) {
+ Log.e(LOGTAG, "Bad address: " + url);
+ return;
+ }
+
+ nativeSetCookie(uri.toString(), value, privateBrowsing);
}
/**
@@ -424,6 +451,10 @@
* @return The cookies in the format of NAME=VALUE [; NAME=VALUE]
*/
public String getCookie(String url) {
+ if (JniUtil.useChromiumHttpStack()) {
+ return getCookie(url, false);
+ }
+
WebAddress uri;
try {
uri = new WebAddress(url);
@@ -432,11 +463,32 @@
return null;
}
- if (JniUtil.useChromiumHttpStack()) {
- return nativeGetCookie(uri.toString());
- } else {
- return getCookie(uri);
+ return getCookie(uri);
+ }
+
+ /**
+ * Get cookie(s) for a given url so that it can be set to "cookie:" in http
+ * request header.
+ * @param url The url needs cookie
+ * @param privateBrowsing cookie jar to use
+ * @return The cookies in the format of NAME=VALUE [; NAME=VALUE]
+ * @hide Private mode is not very well exposed for now
+ */
+ public String getCookie(String url, boolean privateBrowsing) {
+ if (!JniUtil.useChromiumHttpStack()) {
+ // Just redirect to regular get cookie for android stack
+ return getCookie(url);
}
+
+ WebAddress uri;
+ try {
+ uri = new WebAddress(url);
+ } catch (ParseException ex) {
+ Log.e(LOGTAG, "Bad address: " + url);
+ return null;
+ }
+
+ return nativeGetCookie(uri.toString(), privateBrowsing);
}
/**
@@ -605,13 +657,26 @@
*/
public synchronized boolean hasCookies() {
if (JniUtil.useChromiumHttpStack()) {
- return nativeHasCookies();
+ return hasCookies(false);
}
return CookieSyncManager.getInstance().hasCookies();
}
/**
+ * Return true if there are stored cookies.
+ * @param privateBrowsing cookie jar to use
+ * @hide Hiding private mode
+ */
+ public synchronized boolean hasCookies(boolean privateBrowsing) {
+ if (!JniUtil.useChromiumHttpStack()) {
+ return hasCookies();
+ }
+
+ return nativeHasCookies(privateBrowsing);
+ }
+
+ /**
* Remove all expired cookies
*/
public void removeExpiredCookie() {
@@ -1132,13 +1197,13 @@
// Native functions
private static native boolean nativeAcceptCookie();
- private static native String nativeGetCookie(String url);
- private static native boolean nativeHasCookies();
+ private static native String nativeGetCookie(String url, boolean privateBrowsing);
+ private static native boolean nativeHasCookies(boolean privateBrowsing);
private static native void nativeRemoveAllCookie();
private static native void nativeRemoveExpiredCookie();
private static native void nativeRemoveSessionCookie();
private static native void nativeSetAcceptCookie(boolean accept);
- private static native void nativeSetCookie(String url, String value);
+ private static native void nativeSetCookie(String url, String value, boolean privateBrowsing);
private static native void nativeFlushCookieStore();
private static native boolean nativeAcceptFileSchemeCookies();
private static native void nativeSetAcceptFileSchemeCookies(boolean accept);
diff --git a/core/java/android/webkit/HTML5VideoViewProxy.java b/core/java/android/webkit/HTML5VideoViewProxy.java
index 2cc3881..85763da 100644
--- a/core/java/android/webkit/HTML5VideoViewProxy.java
+++ b/core/java/android/webkit/HTML5VideoViewProxy.java
@@ -184,12 +184,13 @@
mVideoView.setWillNotDraw(false);
mVideoView.setMediaController(new MediaController(proxy.getContext()));
- String cookieValue = CookieManager.getInstance().getCookie(url);
+ boolean isPrivate = mCurrentProxy.getWebView().isPrivateBrowsingEnabled();
+ String cookieValue = CookieManager.getInstance().getCookie(url, isPrivate);
Map<String, String> headers = new HashMap<String, String>();
if (cookieValue != null) {
headers.put(COOKIE, cookieValue);
}
- if (mCurrentProxy.getWebView().isPrivateBrowsingEnabled()) {
+ if (isPrivate) {
headers.put(HIDE_URL_LOGS, "true");
}
diff --git a/core/java/android/webkit/WebTextView.java b/core/java/android/webkit/WebTextView.java
index 492cb80..47c69be 100644
--- a/core/java/android/webkit/WebTextView.java
+++ b/core/java/android/webkit/WebTextView.java
@@ -947,6 +947,8 @@
@Override
public void setBounds(int left, int top, int right, int bottom) {
super.setBounds(left, top, right, bottom);
+ bottom--;
+ right -= 2;
// Top line
mLines[0] = left;
mLines[1] = top + 1;
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index f877fc8..43f8790 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -5043,15 +5043,13 @@
super.onAttachedToWindow();
if (hasWindowFocus()) setActive(true);
final ViewTreeObserver treeObserver = getViewTreeObserver();
- if (treeObserver != null) {
- if (mGlobalLayoutListener == null) {
- mGlobalLayoutListener = new InnerGlobalLayoutListener();
- treeObserver.addOnGlobalLayoutListener(mGlobalLayoutListener);
- }
- if (mScrollChangedListener == null) {
- mScrollChangedListener = new InnerScrollChangedListener();
- treeObserver.addOnScrollChangedListener(mScrollChangedListener);
- }
+ if (mGlobalLayoutListener == null) {
+ mGlobalLayoutListener = new InnerGlobalLayoutListener();
+ treeObserver.addOnGlobalLayoutListener(mGlobalLayoutListener);
+ }
+ if (mScrollChangedListener == null) {
+ mScrollChangedListener = new InnerScrollChangedListener();
+ treeObserver.addOnScrollChangedListener(mScrollChangedListener);
}
addAccessibilityApisToJavaScript();
@@ -5064,15 +5062,13 @@
if (hasWindowFocus()) setActive(false);
final ViewTreeObserver treeObserver = getViewTreeObserver();
- if (treeObserver != null) {
- if (mGlobalLayoutListener != null) {
- treeObserver.removeGlobalOnLayoutListener(mGlobalLayoutListener);
- mGlobalLayoutListener = null;
- }
- if (mScrollChangedListener != null) {
- treeObserver.removeOnScrollChangedListener(mScrollChangedListener);
- mScrollChangedListener = null;
- }
+ if (mGlobalLayoutListener != null) {
+ treeObserver.removeGlobalOnLayoutListener(mGlobalLayoutListener);
+ mGlobalLayoutListener = null;
+ }
+ if (mScrollChangedListener != null) {
+ treeObserver.removeOnScrollChangedListener(mScrollChangedListener);
+ mScrollChangedListener = null;
}
removeAccessibilityApisFromJavaScript();
@@ -5106,8 +5102,7 @@
/**
* @deprecated WebView should not have implemented
- * ViewTreeObserver.OnGlobalFocusChangeListener. This method
- * does nothing now.
+ * ViewTreeObserver.OnGlobalFocusChangeListener. This method does nothing now.
*/
@Deprecated
public void onGlobalFocusChanged(View oldFocus, View newFocus) {
@@ -7758,6 +7753,7 @@
int mEnabled;
int mId;
+ @Override
public String toString() {
return mString;
}
@@ -8222,6 +8218,7 @@
* zero to make the view transparent.
* @param color the ARGB color described by Color.java
*/
+ @Override
public void setBackgroundColor(int color) {
mBackgroundColor = color;
mWebViewCore.sendMessage(EventHub.SET_BACKGROUND_COLOR, color);
diff --git a/core/java/android/webkit/ZoomManager.java b/core/java/android/webkit/ZoomManager.java
index 6303850..ee0d122 100644
--- a/core/java/android/webkit/ZoomManager.java
+++ b/core/java/android/webkit/ZoomManager.java
@@ -704,9 +704,10 @@
* false otherwise.
*/
public boolean isPreventingWebkitUpdates() {
- // currently only animating a multi-touch zoom prevents updates, but
- // others can add their own conditions to this method if necessary.
- return mPinchToZoomAnimating;
+ // currently only animating a multi-touch zoom and fixed length
+ // animations prevent updates, but others can add their own conditions
+ // to this method if necessary.
+ return isZoomAnimating();
}
public ScaleGestureDetector getMultiTouchGestureDetector() {
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index 47bf57f..2925632 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -1251,6 +1251,7 @@
if (mOnScrollListener != null) {
mOnScrollListener.onScroll(this, mFirstPosition, getChildCount(), mItemCount);
}
+ onScrollChanged(0, 0, 0, 0); // dummy values, View's implementation does not use these.
}
/**
@@ -2268,11 +2269,9 @@
super.onAttachedToWindow();
final ViewTreeObserver treeObserver = getViewTreeObserver();
- if (treeObserver != null) {
- treeObserver.addOnTouchModeChangeListener(this);
- if (mTextFilterEnabled && mPopup != null && !mGlobalLayoutListenerAddedFilter) {
- treeObserver.addOnGlobalLayoutListener(this);
- }
+ treeObserver.addOnTouchModeChangeListener(this);
+ if (mTextFilterEnabled && mPopup != null && !mGlobalLayoutListenerAddedFilter) {
+ treeObserver.addOnGlobalLayoutListener(this);
}
if (mAdapter != null && mDataSetObserver == null) {
@@ -2297,12 +2296,10 @@
mRecycler.clear();
final ViewTreeObserver treeObserver = getViewTreeObserver();
- if (treeObserver != null) {
- treeObserver.removeOnTouchModeChangeListener(this);
- if (mTextFilterEnabled && mPopup != null) {
- treeObserver.removeGlobalOnLayoutListener(this);
- mGlobalLayoutListenerAddedFilter = false;
- }
+ treeObserver.removeOnTouchModeChangeListener(this);
+ if (mTextFilterEnabled && mPopup != null) {
+ treeObserver.removeGlobalOnLayoutListener(this);
+ mGlobalLayoutListenerAddedFilter = false;
}
if (mAdapter != null) {
@@ -2793,8 +2790,9 @@
if (!mDataChanged) {
if ((mTouchMode != TOUCH_MODE_FLING) && (motionPosition >= 0)
&& (getAdapter().isEnabled(motionPosition))) {
- // User clicked on an actual view (and was not stopping a fling). It might be a
- // click or a scroll. Assume it is a click until proven otherwise
+ // User clicked on an actual view (and was not stopping a fling).
+ // It might be a click or a scroll. Assume it is a click until
+ // proven otherwise
mTouchMode = TOUCH_MODE_DOWN;
// FIXME Debounce
if (mPendingCheckForTap == null) {
@@ -2803,9 +2801,10 @@
postDelayed(mPendingCheckForTap, ViewConfiguration.getTapTimeout());
} else {
if (ev.getEdgeFlags() != 0 && motionPosition < 0) {
- // If we couldn't find a view to click on, but the down event was touching
- // the edge, we will bail out and try again. This allows the edge correcting
- // code in ViewRoot to try to find a nearby view to select
+ // If we couldn't find a view to click on, but the down event
+ // was touching the edge, we will bail out and try again.
+ // This allows the edge correcting code in ViewRoot to try to
+ // find a nearby view to select
return false;
}
@@ -3019,7 +3018,11 @@
case TOUCH_MODE_DONE_WAITING:
final int motionPosition = mMotionPosition;
final View child = getChildAt(motionPosition - mFirstPosition);
- if (child != null && !child.hasFocusable()) {
+
+ final float x = ev.getX();
+ final boolean inList = x > mListPadding.left && x < getWidth() - mListPadding.right;
+
+ if (child != null && !child.hasFocusable() && inList) {
if (mTouchMode != TOUCH_MODE_DOWN) {
child.setPressed(false);
}
@@ -3268,18 +3271,20 @@
}
@Override
- protected void onOverScrolled(int scrollX, int scrollY,
- boolean clampedX, boolean clampedY) {
- mScrollY = scrollY;
- invalidateParentIfNeeded();
+ protected void onOverScrolled(int scrollX, int scrollY, boolean clampedX, boolean clampedY) {
+ if (mScrollY != scrollY) {
+ onScrollChanged(mScrollX, scrollY, mScrollX, mScrollY);
+ mScrollY = scrollY;
+ invalidateParentIfNeeded();
- if (clampedY) {
- // Velocity is broken by hitting the limit; don't start a fling off of this.
- if (mVelocityTracker != null) {
- mVelocityTracker.clear();
+ if (clampedY) {
+ // Velocity is broken by hitting the limit; don't start a fling off of this.
+ if (mVelocityTracker != null) {
+ mVelocityTracker.clear();
+ }
}
+ awakenScrollBars();
}
- awakenScrollBars();
}
@Override
@@ -4297,17 +4302,12 @@
mLastPositionDistanceGuess += incrementalDeltaY;
}
- if (firstPosition == 0 && firstTop >= listPadding.top && incrementalDeltaY >= 0) {
- // Don't need to move views down if the top of the first position
- // is already visible
- return incrementalDeltaY != 0;
- }
+ final boolean cannotScrollDown = (firstPosition == 0 &&
+ firstTop >= listPadding.top && incrementalDeltaY >= 0);
+ final boolean cannotScrollUp = (firstPosition + childCount == mItemCount &&
+ lastBottom <= getHeight() - listPadding.bottom && incrementalDeltaY <= 0);
- if (firstPosition + childCount == mItemCount &&
- lastBottom <= getHeight() - listPadding.bottom &&
- incrementalDeltaY <= 0) {
- // Don't need to move views up if the bottom of the last position
- // is already visible
+ if (cannotScrollDown || cannotScrollUp) {
return incrementalDeltaY != 0;
}
diff --git a/core/java/android/widget/StackView.java b/core/java/android/widget/StackView.java
index e6cf31e..bab469b 100644
--- a/core/java/android/widget/StackView.java
+++ b/core/java/android/widget/StackView.java
@@ -33,6 +33,7 @@
import android.graphics.TableMaskFilter;
import android.util.AttributeSet;
import android.util.Log;
+import android.view.InputDevice;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.View;
@@ -114,6 +115,8 @@
private static final int MIN_TIME_BETWEEN_INTERACTION_AND_AUTOADVANCE = 5000;
+ private static long MIN_TIME_BETWEEN_SCROLLS = 100;
+
/**
* These variables are all related to the current state of touch interaction
* with the stack
@@ -137,6 +140,7 @@
private StackSlider mStackSlider;
private boolean mFirstLayoutHappened = false;
private long mLastInteractionTime = 0;
+ private long mLastScrollTime;
private int mStackMode;
private int mFramePadding;
private final Rect stackInvalidateRect = new Rect();
@@ -565,6 +569,38 @@
}
}
+ @Override
+ public boolean onGenericMotionEvent(MotionEvent event) {
+ if ((event.getSource() & InputDevice.SOURCE_CLASS_POINTER) != 0) {
+ switch (event.getAction()) {
+ case MotionEvent.ACTION_SCROLL: {
+ final float vscroll = event.getAxisValue(MotionEvent.AXIS_VSCROLL);
+ if (vscroll < 0) {
+ pacedScroll(false);
+ return true;
+ } else if (vscroll > 0) {
+ pacedScroll(true);
+ return true;
+ }
+ }
+ }
+ }
+ return super.onGenericMotionEvent(event);
+ }
+
+ // This ensures that the frequency of stack flips caused by scrolls is capped
+ private void pacedScroll(boolean up) {
+ long timeSinceLastScroll = System.currentTimeMillis() - mLastScrollTime;
+ if (timeSinceLastScroll > MIN_TIME_BETWEEN_SCROLLS) {
+ if (up) {
+ showPrevious();
+ } else {
+ showNext();
+ }
+ mLastScrollTime = System.currentTimeMillis();
+ }
+ }
+
/**
* {@inheritDoc}
*/
diff --git a/core/java/android/widget/TabHost.java b/core/java/android/widget/TabHost.java
index 03eea66..57a8531 100644
--- a/core/java/android/widget/TabHost.java
+++ b/core/java/android/widget/TabHost.java
@@ -183,18 +183,14 @@
protected void onAttachedToWindow() {
super.onAttachedToWindow();
final ViewTreeObserver treeObserver = getViewTreeObserver();
- if (treeObserver != null) {
- treeObserver.addOnTouchModeChangeListener(this);
- }
+ treeObserver.addOnTouchModeChangeListener(this);
}
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
final ViewTreeObserver treeObserver = getViewTreeObserver();
- if (treeObserver != null) {
- treeObserver.removeOnTouchModeChangeListener(this);
- }
+ treeObserver.removeOnTouchModeChangeListener(this);
}
/**
diff --git a/core/java/android/widget/TabWidget.java b/core/java/android/widget/TabWidget.java
index d74ef24..6f76dd0 100644
--- a/core/java/android/widget/TabWidget.java
+++ b/core/java/android/widget/TabWidget.java
@@ -172,6 +172,11 @@
@Override
void measureHorizontal(int widthMeasureSpec, int heightMeasureSpec) {
+ if (MeasureSpec.getMode(widthMeasureSpec) == MeasureSpec.UNSPECIFIED) {
+ super.measureHorizontal(widthMeasureSpec, heightMeasureSpec);
+ return;
+ }
+
// First, measure with no constraint
final int unspecifiedWidth = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
mImposedTabsHeight = -1;
@@ -208,9 +213,7 @@
}
// Measure again, this time with imposed tab widths and respecting initial spec request
- if (mImposedTabsHeight >= 0 || unspecifiedWidth != widthMeasureSpec) {
- super.measureHorizontal(widthMeasureSpec, heightMeasureSpec);
- }
+ super.measureHorizontal(widthMeasureSpec, heightMeasureSpec);
}
/**
diff --git a/core/jni/android_hardware_UsbDevice.cpp b/core/jni/android_hardware_UsbDevice.cpp
index 9014450..b01820c 100644
--- a/core/jni/android_hardware_UsbDevice.cpp
+++ b/core/jni/android_hardware_UsbDevice.cpp
@@ -237,7 +237,7 @@
(void *)android_hardware_UsbDevice_control_request},
{"native_bulk_request", "(I[BII)I",
(void *)android_hardware_UsbDevice_bulk_request},
- {"native_request_wait", "()Landroid/hardware/UsbRequest;",
+ {"native_request_wait", "()Landroid/hardware/usb/UsbRequest;",
(void *)android_hardware_UsbDevice_request_wait},
{ "native_get_serial", "()Ljava/lang/String;",
(void*)android_hardware_UsbDevice_get_serial },
@@ -251,9 +251,9 @@
int register_android_hardware_UsbDevice(JNIEnv *env)
{
- jclass clazz = env->FindClass("android/hardware/UsbDevice");
+ jclass clazz = env->FindClass("android/hardware/usb/UsbDevice");
if (clazz == NULL) {
- LOGE("Can't find android/hardware/UsbDevice");
+ LOGE("Can't find android/hardware/usb/UsbDevice");
return -1;
}
field_context = env->GetFieldID(clazz, "mNativeContext", "I");
@@ -262,7 +262,7 @@
return -1;
}
- return AndroidRuntime::registerNativeMethods(env, "android/hardware/UsbDevice",
+ return AndroidRuntime::registerNativeMethods(env, "android/hardware/usb/UsbDevice",
method_table, NELEM(method_table));
}
diff --git a/core/jni/android_hardware_UsbEndpoint.cpp b/core/jni/android_hardware_UsbEndpoint.cpp
deleted file mode 100644
index 00c8235..0000000
--- a/core/jni/android_hardware_UsbEndpoint.cpp
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "UsbEndpoint"
-
-#include "utils/Log.h"
-
-#include "jni.h"
-#include "JNIHelp.h"
-#include "android_runtime/AndroidRuntime.h"
-
-#include <usbhost/usbhost.h>
-
-#include <stdio.h>
-
-using namespace android;
-
-static jfieldID field_context;
-static jfieldID field_address;
-static jfieldID field_attributes;
-static jfieldID field_max_packet_size;
-static jfieldID field_interval;
-
-struct usb_endpoint* get_endpoint_from_object(JNIEnv* env, jobject javaEndpoint)
-{
- return (struct usb_endpoint*)env->GetIntField(javaEndpoint, field_context);
-}
-
-// in android_hardware_UsbDevice.cpp
-extern struct usb_device* get_device_from_object(JNIEnv* env, jobject javaDevice);
-
-static jboolean
-android_hardware_UsbEndpoint_init(JNIEnv *env, jobject thiz, jobject javaDevice)
-{
- LOGD("open\n");
-
- struct usb_device* device = get_device_from_object(env, javaDevice);
- if (!device) {
- LOGE("device null in native_init");
- return false;
- }
-
- // construct an endpoint descriptor from the Java object fields
- struct usb_endpoint_descriptor desc;
- desc.bLength = USB_DT_ENDPOINT_SIZE;
- desc.bDescriptorType = USB_DT_ENDPOINT;
- desc.bEndpointAddress = env->GetIntField(thiz, field_address);
- desc.bmAttributes = env->GetIntField(thiz, field_attributes);
- desc.wMaxPacketSize = env->GetIntField(thiz, field_max_packet_size);
- desc.bInterval = env->GetIntField(thiz, field_interval);
-
- struct usb_endpoint* endpoint = usb_endpoint_init(device, &desc);
- if (endpoint)
- env->SetIntField(thiz, field_context, (int)device);
- return (endpoint != NULL);
-}
-
-static void
-android_hardware_UsbEndpoint_close(JNIEnv *env, jobject thiz)
-{
- LOGD("close\n");
- struct usb_endpoint* endpoint = get_endpoint_from_object(env, thiz);
- if (endpoint) {
- usb_endpoint_close(endpoint);
- env->SetIntField(thiz, field_context, 0);
- }
-}
-
-static JNINativeMethod method_table[] = {
- {"native_init", "(Landroid/hardware/UsbDevice;)Z",
- (void *)android_hardware_UsbEndpoint_init},
- {"native_close", "()V", (void *)android_hardware_UsbEndpoint_close},
-};
-
-int register_android_hardware_UsbEndpoint(JNIEnv *env)
-{
- jclass clazz = env->FindClass("android/hardware/UsbEndpoint");
- if (clazz == NULL) {
- LOGE("Can't find android/hardware/UsbEndpoint");
- return -1;
- }
- field_context = env->GetFieldID(clazz, "mNativeContext", "I");
- if (field_context == NULL) {
- LOGE("Can't find UsbEndpoint.mNativeContext");
- return -1;
- }
- field_address = env->GetFieldID(clazz, "mAddress", "I");
- if (field_address == NULL) {
- LOGE("Can't find UsbEndpoint.mAddress");
- return -1;
- }
- field_attributes = env->GetFieldID(clazz, "mAttributes", "I");
- if (field_attributes == NULL) {
- LOGE("Can't find UsbEndpoint.mAttributes");
- return -1;
- }
- field_max_packet_size = env->GetFieldID(clazz, "mMaxPacketSize", "I");
- if (field_max_packet_size == NULL) {
- LOGE("Can't find UsbEndpoint.mMaxPacketSize");
- return -1;
- }
- field_interval = env->GetFieldID(clazz, "mInterval", "I");
- if (field_interval == NULL) {
- LOGE("Can't find UsbEndpoint.mInterval");
- return -1;
- }
-
- return AndroidRuntime::registerNativeMethods(env, "android/hardware/UsbEndpoint",
- method_table, NELEM(method_table));
-}
-
diff --git a/core/jni/android_hardware_UsbRequest.cpp b/core/jni/android_hardware_UsbRequest.cpp
index 710afae..b497adb 100644
--- a/core/jni/android_hardware_UsbRequest.cpp
+++ b/core/jni/android_hardware_UsbRequest.cpp
@@ -187,7 +187,7 @@
}
static JNINativeMethod method_table[] = {
- {"native_init", "(Landroid/hardware/UsbDevice;IIII)Z",
+ {"native_init", "(Landroid/hardware/usb/UsbDevice;IIII)Z",
(void *)android_hardware_UsbRequest_init},
{"native_close", "()V", (void *)android_hardware_UsbRequest_close},
{"native_queue_array", "([BIZ)Z", (void *)android_hardware_UsbRequest_queue_array},
@@ -200,9 +200,9 @@
int register_android_hardware_UsbRequest(JNIEnv *env)
{
- jclass clazz = env->FindClass("android/hardware/UsbRequest");
+ jclass clazz = env->FindClass("android/hardware/usb/UsbRequest");
if (clazz == NULL) {
- LOGE("Can't find android/hardware/UsbRequest");
+ LOGE("Can't find android/hardware/usb/UsbRequest");
return -1;
}
field_context = env->GetFieldID(clazz, "mNativeContext", "I");
@@ -211,7 +211,7 @@
return -1;
}
- return AndroidRuntime::registerNativeMethods(env, "android/hardware/UsbRequest",
+ return AndroidRuntime::registerNativeMethods(env, "android/hardware/usb/UsbRequest",
method_table, NELEM(method_table));
}
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 50d3fb8..0ad174f 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -84,11 +84,11 @@
<protected-broadcast android:name="android.bluetooth.device.action.PAIRING_REQUEST" />
<protected-broadcast android:name="android.bluetooth.device.action.PAIRING_CANCEL" />
- <protected-broadcast android:name="android.hardware.action.USB_STATE" />
- <protected-broadcast android:name="android.hardware.action.USB_ACCESSORY_ATTACHED" />
- <protected-broadcast android:name="android.hardware.action.USB_ACCESSORY_ATTACHED" />
- <protected-broadcast android:name="android.hardware.action.USB_DEVICE_ATTACHED" />
- <protected-broadcast android:name="android.hardware.action.USB_DEVICE_DETACHED" />
+ <protected-broadcast android:name="android.hardware.usb.action.USB_STATE" />
+ <protected-broadcast android:name="android.hardware.usb.action.USB_ACCESSORY_ATTACHED" />
+ <protected-broadcast android:name="android.hardware.usb.action.USB_ACCESSORY_ATTACHED" />
+ <protected-broadcast android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" />
+ <protected-broadcast android:name="android.hardware.usb.action.USB_DEVICE_DETACHED" />
<protected-broadcast android:name="android.nfc.action.LLCP_LINK_STATE_CHANGED" />
<protected-broadcast android:name="android.nfc.action.TRANSACTION_DETECTED" />
diff --git a/core/res/res/drawable-hdpi/btn_check_off_holo.png b/core/res/res/drawable-hdpi/btn_check_off_holo.png
new file mode 100644
index 0000000..4021a3b
--- /dev/null
+++ b/core/res/res/drawable-hdpi/btn_check_off_holo.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_check_on_holo.png b/core/res/res/drawable-hdpi/btn_check_on_holo.png
new file mode 100644
index 0000000..4c1bfbc
--- /dev/null
+++ b/core/res/res/drawable-hdpi/btn_check_on_holo.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_radio_off_holo.png b/core/res/res/drawable-hdpi/btn_radio_off_holo.png
new file mode 100644
index 0000000..f159c62
--- /dev/null
+++ b/core/res/res/drawable-hdpi/btn_radio_off_holo.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_radio_on_holo.png b/core/res/res/drawable-hdpi/btn_radio_on_holo.png
new file mode 100644
index 0000000..0fcfbe1
--- /dev/null
+++ b/core/res/res/drawable-hdpi/btn_radio_on_holo.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_check_off_holo.png b/core/res/res/drawable-mdpi/btn_check_off_holo.png
new file mode 100644
index 0000000..67d70b4
--- /dev/null
+++ b/core/res/res/drawable-mdpi/btn_check_off_holo.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_check_on_holo.png b/core/res/res/drawable-mdpi/btn_check_on_holo.png
new file mode 100644
index 0000000..38ab51a
--- /dev/null
+++ b/core/res/res/drawable-mdpi/btn_check_on_holo.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_radio_off_holo.png b/core/res/res/drawable-mdpi/btn_radio_off_holo.png
new file mode 100644
index 0000000..ba90d96
--- /dev/null
+++ b/core/res/res/drawable-mdpi/btn_radio_off_holo.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_radio_on_holo.png b/core/res/res/drawable-mdpi/btn_radio_on_holo.png
new file mode 100644
index 0000000..41b603c
--- /dev/null
+++ b/core/res/res/drawable-mdpi/btn_radio_on_holo.png
Binary files differ
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index 4f74846..41fa758 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -125,10 +125,10 @@
<string name="contentServiceSync" msgid="8353523060269335667">"Sincronización"</string>
<string name="contentServiceSyncNotificationTitle" msgid="397743349191901458">"Sincronización"</string>
<string name="contentServiceTooManyDeletesNotificationDesc" msgid="8100981435080696431">"Demasiadas eliminaciones de <xliff:g id="CONTENT_TYPE">%s</xliff:g>"</string>
- <string name="low_memory" product="tablet" msgid="2292820184396262278">"Se ha agotado el espacio de almacenamiento de la tableta. Elimina algunos archivos para liberar espacio."</string>
+ <string name="low_memory" product="tablet" msgid="2292820184396262278">"Se ha agotado el espacio de almacenamiento del tablet. Elimina algunos archivos para liberar espacio."</string>
<string name="low_memory" product="default" msgid="6632412458436461203">"Se ha agotado el espacio de almacenamiento del teléfono. Elimina algunos archivos para liberar espacio."</string>
<string name="me" msgid="6545696007631404292">"Yo"</string>
- <string name="power_dialog" product="tablet" msgid="8545351420865202853">"Opciones de tableta"</string>
+ <string name="power_dialog" product="tablet" msgid="8545351420865202853">"Opciones del tablet"</string>
<string name="power_dialog" product="default" msgid="1319919075463988638">"Opciones del teléfono"</string>
<string name="silent_mode" msgid="7167703389802618663">"Modo silencio"</string>
<string name="turn_on_radio" msgid="3912793092339962371">"Activar conexión inalámbrica"</string>
@@ -136,12 +136,12 @@
<string name="screen_lock" msgid="799094655496098153">"Bloqueo de pantalla"</string>
<string name="power_off" msgid="4266614107412865048">"Apagar"</string>
<string name="shutdown_progress" msgid="2281079257329981203">"Apagando..."</string>
- <string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"La tableta se apagará."</string>
+ <string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"El tablet se apagará."</string>
<string name="shutdown_confirm" product="default" msgid="649792175242821353">"El teléfono se apagará."</string>
<string name="shutdown_confirm_question" msgid="6656441286856415014">"¿Quieres apagar el teléfono?"</string>
<string name="recent_tasks_title" msgid="3691764623638127888">"Reciente"</string>
<string name="no_recent_tasks" msgid="279702952298056674">"No hay aplicaciones recientes"</string>
- <string name="global_actions" product="tablet" msgid="408477140088053665">"Opciones de tableta"</string>
+ <string name="global_actions" product="tablet" msgid="408477140088053665">"Opciones del tablet"</string>
<string name="global_actions" product="default" msgid="2406416831541615258">"Opciones del teléfono"</string>
<string name="global_action_lock" msgid="2844945191792119712">"Bloqueo de pantalla"</string>
<string name="global_action_power_off" msgid="4471879440839879722">"Apagar"</string>
@@ -159,7 +159,7 @@
<string name="permgrouplab_messages" msgid="7521249148445456662">"Tus mensajes"</string>
<string name="permgroupdesc_messages" msgid="7045736972019211994">"Leer y escribir SMS, mensajes de correo electrónico y otros mensajes"</string>
<string name="permgrouplab_personalInfo" msgid="3519163141070533474">"Tu información personal"</string>
- <string name="permgroupdesc_personalInfo" product="tablet" msgid="6975389054186265786">"Accede directamente al calendario y a los contactos almacenados en la tableta."</string>
+ <string name="permgroupdesc_personalInfo" product="tablet" msgid="6975389054186265786">"Accede directamente al calendario y a los contactos almacenados en el tablet."</string>
<string name="permgroupdesc_personalInfo" product="default" msgid="5488050357388806068">"Acceso directo al calendario y a los contactos almacenados en el teléfono"</string>
<string name="permgrouplab_location" msgid="635149742436692049">"Tu ubicación"</string>
<string name="permgroupdesc_location" msgid="2430258821648348660">"Controlar su ubicación física"</string>
@@ -193,10 +193,10 @@
<string name="permlab_sendSms" msgid="5600830612147671529">"enviar mensajes SMS"</string>
<string name="permdesc_sendSms" msgid="1946540351763502120">"Permite que la aplicación envíe mensajes SMS. Es posible que tengas que pagar si las aplicaciones malintencionadas envían mensajes sin tu confirmación."</string>
<string name="permlab_readSms" msgid="4085333708122372256">"leer SMS o MMS"</string>
- <string name="permdesc_readSms" product="tablet" msgid="5836710350295631545">"Permite que la aplicación lea mensajes SMS almacenados en la tableta o en la tarjeta SIM. Las aplicaciones malintencionadas pueden leer los mensajes confidenciales."</string>
+ <string name="permdesc_readSms" product="tablet" msgid="5836710350295631545">"Permite que la aplicación lea mensajes SMS almacenados en el tablet o en la tarjeta SIM. Las aplicaciones malintencionadas pueden leer los mensajes confidenciales."</string>
<string name="permdesc_readSms" product="default" msgid="3002170087197294591">"Permite que la aplicación lea mensajes SMS almacenados en el teléfono o en la tarjeta SIM. Las aplicaciones malintencionadas pueden leer los mensajes confidenciales."</string>
<string name="permlab_writeSms" msgid="6881122575154940744">"editar SMS o MMS"</string>
- <string name="permdesc_writeSms" product="tablet" msgid="5332124772918835437">"Permite que la aplicación escriba en mensajes SMS almacenados en la tableta o en la tarjeta SIM. Las aplicaciones malintencionadas pueden borrar los mensajes."</string>
+ <string name="permdesc_writeSms" product="tablet" msgid="5332124772918835437">"Permite que la aplicación escriba en mensajes SMS almacenados en el tablet o en la tarjeta SIM. Las aplicaciones malintencionadas pueden borrar los mensajes."</string>
<string name="permdesc_writeSms" product="default" msgid="6299398896177548095">"Permite que la aplicación escriba en mensajes SMS almacenados en el teléfono o en la tarjeta SIM. Las aplicaciones malintencionadas pueden borrar los mensajes."</string>
<string name="permlab_receiveWapPush" msgid="8258226427716551388">"recibir WAP"</string>
<string name="permdesc_receiveWapPush" msgid="5979623826128082171">"Permite que la aplicación reciba y procese mensajes WAP. Las aplicaciones malintencionadas pueden controlar los mensajes o eliminarlos sin mostrarlos al usuario."</string>
@@ -247,7 +247,7 @@
<string name="permlab_manageAppTokens" msgid="17124341698093865">"administrar tokens de aplicación"</string>
<string name="permdesc_manageAppTokens" msgid="977127907524195988">"Permite que las aplicaciones creen y administren sus propios tokens, ignorando su orden z normal. Nunca debería ser necesario para las aplicaciones normales."</string>
<string name="permlab_injectEvents" msgid="1378746584023586600">"pulsar teclas y botones de control"</string>
- <string name="permdesc_injectEvents" product="tablet" msgid="7200014808195664505">"Permite que la aplicación proporcione sus propios eventos de entrada (pulsación de teclas, etc.) a otras aplicaciones. Las aplicaciones malintencionadas pueden utilizar este permiso para controlar la tableta."</string>
+ <string name="permdesc_injectEvents" product="tablet" msgid="7200014808195664505">"Permite que la aplicación proporcione sus propios eventos de entrada (pulsación de teclas, etc.) a otras aplicaciones. Las aplicaciones malintencionadas pueden utilizar este permiso para controlar el tablet."</string>
<string name="permdesc_injectEvents" product="default" msgid="3946098050410874715">"Permite que la aplicación proporcione sus propios eventos de entrada (pulsación de teclas, etc.) a otras aplicaciones. Las aplicaciones malintencionadas pueden utilizar este permiso para controlar el teléfono."</string>
<string name="permlab_readInputState" msgid="469428900041249234">"registrar lo que se escribe y las acciones que se realizan"</string>
<string name="permdesc_readInputState" msgid="5132879321450325445">"Permite que las aplicaciones observen las teclas que pulsas incluso cuando interactúas con otra aplicación (como, por ejemplo, al introducir una contraseña). No debería ser necesario nunca para las aplicaciones normales."</string>
@@ -276,17 +276,17 @@
<string name="permlab_installPackages" msgid="335800214119051089">"instalar aplicaciones directamente"</string>
<string name="permdesc_installPackages" msgid="526669220850066132">"Permite que una aplicación instale paquetes Android nuevos o actualizados. Las aplicaciones malintencionadas pueden utilizar este permiso para añadir aplicaciones nuevas con permisos arbitrariamente potentes."</string>
<string name="permlab_clearAppCache" msgid="4747698311163766540">"eliminar todos los datos de caché de la aplicación"</string>
- <string name="permdesc_clearAppCache" product="tablet" msgid="3097119797652477973">"Permite que una aplicación libere espacio de almacenamiento en la tableta mediante la eliminación de archivos del directorio de caché de la aplicación. El acceso está muy restringido (limitado normalmente al proceso del sistema)."</string>
+ <string name="permdesc_clearAppCache" product="tablet" msgid="3097119797652477973">"Permite que una aplicación libere espacio de almacenamiento en el tablet mediante la eliminación de archivos del directorio de caché de la aplicación. El acceso está muy restringido (limitado normalmente al proceso del sistema)."</string>
<string name="permdesc_clearAppCache" product="default" msgid="7740465694193671402">"Permite que una aplicación libere espacio de almacenamiento en el teléfono mediante la eliminación de archivos en el directorio de caché de la aplicación. El acceso al proceso del sistema suele estar muy restringido."</string>
<string name="permlab_movePackage" msgid="728454979946503926">"Mover recursos de aplicaciones"</string>
<string name="permdesc_movePackage" msgid="6323049291923925277">"Permite que una aplicación mueva los recursos de aplicaciones de un medio interno a otro externo y viceversa."</string>
<string name="permlab_readLogs" msgid="6615778543198967614">"leer datos de registro personales"</string>
- <string name="permdesc_readLogs" product="tablet" msgid="4077356893924755294">"Permite que una aplicación lea diversos archivos de registro del sistema. Con este permiso, la aplicación puede ver información general sobre las acciones que se realizan con la tableta (que puede incluir datos personales o privados)."</string>
+ <string name="permdesc_readLogs" product="tablet" msgid="4077356893924755294">"Permite que una aplicación lea diversos archivos de registro del sistema. Con este permiso, la aplicación puede ver información general sobre las acciones que se realizan con el tablet (que puede incluir datos personales o privados)."</string>
<string name="permdesc_readLogs" product="default" msgid="8896449437464867766">"Permite que una aplicación lea distintos archivos de registro del sistema. Con este permiso, la aplicación puede ver información general sobre las acciones que realizas con el teléfono, que puede incluir datos personales o privados."</string>
<string name="permlab_diagnostic" msgid="8076743953908000342">"leer/escribir en los recursos propiedad del grupo de diagnóstico"</string>
<string name="permdesc_diagnostic" msgid="3121238373951637049">"Permite que una aplicación lea y escriba en cualquier recurso propiedad del grupo de diagnóstico como, por ejemplo, archivos in/dev. Este permiso podría afectar a la seguridad y estabilidad del sistema. SÓLO se debe utilizar para diagnósticos específicos de hardware realizados por el fabricante o el operador."</string>
<string name="permlab_changeComponentState" msgid="79425198834329406">"habilitar o inhabilitar componentes de la aplicación"</string>
- <string name="permdesc_changeComponentState" product="tablet" msgid="4647419365510068321">"Permite que una aplicación cambie si un componente de otra aplicación está habilitado o inhabilitado. Las aplicaciones malintencionadas pueden utilizar este permiso para inhabilitar funciones importantes de la tableta. Este permiso se debe utilizar con precaución, ya que es posible que los componentes se vuelvan inservibles, inconsistentes o inestables."</string>
+ <string name="permdesc_changeComponentState" product="tablet" msgid="4647419365510068321">"Permite que una aplicación cambie si un componente de otra aplicación está habilitado o inhabilitado. Las aplicaciones malintencionadas pueden utilizar este permiso para inhabilitar funciones importantes del tablet. Este permiso se debe utilizar con precaución, ya que es posible que los componentes se vuelvan inservibles, inconsistentes o inestables."</string>
<string name="permdesc_changeComponentState" product="default" msgid="3443473726140080761">"Permite que una aplicación cambie si un componente de otra aplicación está habilitado o inhabilitado. Las aplicaciones malintencionadas pueden utilizar este permiso para inhabilitar funciones importantes del teléfono. Este permiso se debe utilizar con precaución, ya que es posible que los componentes se vuelvan inservibles, inconsistentes o inestables."</string>
<string name="permlab_setPreferredApplications" msgid="3393305202145172005">"establecer aplicaciones preferidas"</string>
<string name="permdesc_setPreferredApplications" msgid="760008293501937546">"Permite que una aplicación modifique las aplicaciones preferidas del usuario. De esta forma, las aplicaciones malintencionadas pueden cambiar de forma silenciosa las aplicaciones que se están ejecutando, falsificando las aplicaciones existentes para recopilar datos privados del usuario."</string>
@@ -297,19 +297,19 @@
<string name="permlab_writeGservices" msgid="2149426664226152185">"modificar la asignación de servicios de Google"</string>
<string name="permdesc_writeGservices" msgid="6602362746516676175">"Permite que una aplicación modifique la asignación de servicios de Google. No está destinado al uso por parte de aplicaciones normales."</string>
<string name="permlab_receiveBootCompleted" msgid="7776779842866993377">"ejecutar automáticamente al iniciar"</string>
- <string name="permdesc_receiveBootCompleted" product="tablet" msgid="7530977064379338199">"Permite que una aplicación se ejecute automáticamente en cuanto se haya terminado de iniciar el sistema. Esto puede hacer que la tableta tarde más en iniciarse y permite que la aplicación ralentice el funcionamiento global de la tableta al ejecutarse continuamente."</string>
+ <string name="permdesc_receiveBootCompleted" product="tablet" msgid="7530977064379338199">"Permite que una aplicación se ejecute automáticamente en cuanto se haya terminado de iniciar el sistema. Esto puede hacer que el tablet tarde más en iniciarse y permite que la aplicación ralentice el funcionamiento global del tablet al ejecutarse continuamente."</string>
<string name="permdesc_receiveBootCompleted" product="default" msgid="698336728415008796">"Permite que una aplicación se ejecute automáticamente en cuanto se haya terminado de iniciar el sistema. Esto puede provocar que el teléfono tarde más en iniciarse y permite que la aplicación ralentice el funcionamiento global del teléfono al ejecutarse continuamente."</string>
<string name="permlab_broadcastSticky" msgid="7919126372606881614">"enviar emisión persistente"</string>
- <string name="permdesc_broadcastSticky" product="tablet" msgid="6322249605930062595">"Permite que una aplicación envíe emisiones persistentes que permanecen en el teléfono una vez que la emisión finaliza. Las aplicaciones malintencionadas pueden ralentizar la tableta o volverla inestable al hacer que emplee demasiada memoria."</string>
+ <string name="permdesc_broadcastSticky" product="tablet" msgid="6322249605930062595">"Permite que una aplicación envíe emisiones persistentes que permanecen en el tablet una vez que la emisión finaliza. Las aplicaciones malintencionadas pueden ralentizar el tablet o volverlo inestable al hacer que emplee demasiada memoria."</string>
<string name="permdesc_broadcastSticky" product="default" msgid="1920045289234052219">"Permite que una aplicación envíe emisiones persistentes, que permanecen en el teléfono una vez que la emisión finaliza. Las aplicaciones malintencionadas pueden ralentizar el teléfono o volverlo inestable al hacer que emplee demasiada memoria."</string>
<string name="permlab_readContacts" msgid="6219652189510218240">"leer los datos de contacto"</string>
- <string name="permdesc_readContacts" product="tablet" msgid="7596158687301157686">"Permite que una aplicación lea todos los datos de contacto (direcciones) almacenados en la tableta. Las aplicaciones malintencionadas pueden utilizar este permiso para enviar tus datos a otras personas."</string>
+ <string name="permdesc_readContacts" product="tablet" msgid="7596158687301157686">"Permite que una aplicación lea todos los datos de contacto (direcciones) almacenados en el tablet. Las aplicaciones malintencionadas pueden utilizar este permiso para enviar tus datos a otras personas."</string>
<string name="permdesc_readContacts" product="default" msgid="3371591512896545975">"Permite que una aplicación lea todos los datos de contacto (direcciones) almacenados en el teléfono. Las aplicaciones malintencionadas pueden utilizar este permiso para enviar tus datos a otras personas."</string>
<string name="permlab_writeContacts" msgid="644616215860933284">"escribir datos de contacto"</string>
- <string name="permdesc_writeContacts" product="tablet" msgid="7782689510038568495">"Permite que una aplicación modifique los datos de contacto (direcciones) almacenados en la tableta. Las aplicaciones malintencionadas pueden utilizar este permiso para borrar o modificar los datos de contacto."</string>
+ <string name="permdesc_writeContacts" product="tablet" msgid="7782689510038568495">"Permite que una aplicación modifique los datos de contacto (direcciones) almacenados en el tablet. Las aplicaciones malintencionadas pueden utilizar este permiso para borrar o modificar los datos de contacto."</string>
<string name="permdesc_writeContacts" product="default" msgid="3924383579108183601">"Permite que una aplicación modifique los datos de contacto (direcciones) almacenados en el teléfono. Las aplicaciones malintencionadas pueden utilizar este permiso para borrar o modificar tus datos de contacto."</string>
<string name="permlab_readCalendar" msgid="6898987798303840534">"leer eventos de calendario"</string>
- <string name="permdesc_readCalendar" product="tablet" msgid="5905870265734599678">"Permite que una aplicación lea todos los eventos de calendario almacenados en la tableta. Las aplicaciones malintencionadas pueden utilizar este permiso para enviar tus eventos de calendario a otras personas."</string>
+ <string name="permdesc_readCalendar" product="tablet" msgid="5905870265734599678">"Permite que una aplicación lea todos los eventos de calendario almacenados en el tablet. Las aplicaciones malintencionadas pueden utilizar este permiso para enviar tus eventos de calendario a otras personas."</string>
<string name="permdesc_readCalendar" product="default" msgid="5533029139652095734">"Permite que una aplicación lea todos los eventos de calendario almacenados en el teléfono. Las aplicaciones malintencionadas pueden utilizar este permiso para enviar tus eventos de calendario a otras personas."</string>
<string name="permlab_writeCalendar" msgid="3894879352594904361">"añadir o modificar eventos de calendario y enviar mensajes de correo electrónico a los invitados"</string>
<string name="permdesc_writeCalendar" msgid="2988871373544154221">"Permite que una aplicación añada o modifique los eventos de tu calendario, que puede enviar mensajes de correo electrónico a los invitados. Las aplicaciones malintencionadas pueden utilizar este permiso para borrar o modificar tus eventos de calendario o para enviar mensajes a los invitados."</string>
@@ -320,10 +320,10 @@
<string name="permlab_installLocationProvider" msgid="6578101199825193873">"permiso para instalar un proveedor de ubicación"</string>
<string name="permdesc_installLocationProvider" msgid="5449175116732002106">"Crear fuentes de origen simuladas para realizar pruebas. Las aplicaciones malintencionadas pueden utilizar este permiso para sobrescribir la ubicación o el estado devueltos por orígenes de ubicación reales, tales como los proveedores de red o GPS, o para controlar y notificar tu ubicación a una fuente externa."</string>
<string name="permlab_accessFineLocation" msgid="8116127007541369477">"precisar la ubicación (GPS)"</string>
- <string name="permdesc_accessFineLocation" product="tablet" msgid="243973693233359681">"Permite acceder a fuentes de ubicación precisas como, por ejemplo, el sistema de posicionamiento global, en la tableta, si hay alguna disponible. Las aplicaciones malintencionadas pueden utilizar este permiso para determinar la ubicación del usuario y pueden consumir batería adicional."</string>
+ <string name="permdesc_accessFineLocation" product="tablet" msgid="243973693233359681">"Permite acceder a fuentes de ubicación precisas como, por ejemplo, el sistema de posicionamiento global, en el tablet, si hay alguna disponible. Las aplicaciones malintencionadas pueden utilizar este permiso para determinar la ubicación del usuario y pueden consumir batería adicional."</string>
<string name="permdesc_accessFineLocation" product="default" msgid="7411213317434337331">"Permite precisar las fuentes de ubicación como, por ejemplo, el sistema de posicionamiento global, en el teléfono, en los casos en que estén disponibles. Las aplicaciones malintencionadas pueden utilizar este permiso para determinar dónde se encuentra el usuario y pueden consumir batería adicional."</string>
<string name="permlab_accessCoarseLocation" msgid="4642255009181975828">"ubicación común (basada en red)"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="3704633168985466045">"Permite acceder a fuentes de ubicación comunes como, por ejemplo, la base de datos de la red de telefonía móvil, para determinar la ubicación aproximada de una tableta, si hay alguna disponible. Las aplicaciones malintencionadas pueden utilizar este permiso para determinar tu ubicación aproximada."</string>
+ <string name="permdesc_accessCoarseLocation" product="tablet" msgid="3704633168985466045">"Permite acceder a fuentes de ubicación comunes como, por ejemplo, la base de datos de la red de telefonía móvil, para determinar la ubicación aproximada de un tablet, si hay alguna disponible. Las aplicaciones malintencionadas pueden utilizar este permiso para determinar tu ubicación aproximada."</string>
<string name="permdesc_accessCoarseLocation" product="default" msgid="8235655958070862293">"Acceder a fuentes de ubicación comunes como, por ejemplo, la base de datos de red de un teléfono móvil, para determinar una ubicación telefónica aproximada, en los casos en que esté disponible. Las aplicaciones malintencionadas pueden utilizar este permiso para determinar dónde te encuentras aproximadamente."</string>
<string name="permlab_accessSurfaceFlinger" msgid="2363969641792388947">"acceder a SurfaceFlinger"</string>
<string name="permdesc_accessSurfaceFlinger" msgid="6805241830020733025">"Permite que la aplicación utilice funciones de SurfaceFlinger de nivel inferior."</string>
@@ -335,13 +335,13 @@
<string name="permdesc_recordAudio" msgid="6493228261176552356">"Permite que la aplicación acceda a la ruta de grabación de audio."</string>
<string name="permlab_camera" msgid="3616391919559751192">"realizar fotografías y vídeos"</string>
<string name="permdesc_camera" msgid="6004878235852154239">"Permite que la aplicación realice fotografías y vídeos con la cámara. De este modo, puede recopilar en cualquier momento las imágenes que ve la cámara."</string>
- <string name="permlab_brick" product="tablet" msgid="2961292205764488304">"inhabilitar tableta de forma permanente"</string>
+ <string name="permlab_brick" product="tablet" msgid="2961292205764488304">"inhabilitar tablet de forma permanente"</string>
<string name="permlab_brick" product="default" msgid="8337817093326370537">"inhabilitar el teléfono de forma permanente"</string>
- <string name="permdesc_brick" product="tablet" msgid="7379164636920817963">"Permite que la aplicación inhabilite todas las funciones de la tableta de forma permanente. Este permiso es muy peligroso."</string>
+ <string name="permdesc_brick" product="tablet" msgid="7379164636920817963">"Permite que la aplicación inhabilite todas las funciones del tablet de forma permanente. Este permiso es muy peligroso."</string>
<string name="permdesc_brick" product="default" msgid="5569526552607599221">"Permite que la aplicación inhabilite todas las funciones del teléfono de forma permanente. Este permiso es muy peligroso."</string>
- <string name="permlab_reboot" product="tablet" msgid="3436634972561795002">"forzar reinicio de la tableta"</string>
+ <string name="permlab_reboot" product="tablet" msgid="3436634972561795002">"forzar reinicio del tablet"</string>
<string name="permlab_reboot" product="default" msgid="2898560872462638242">"forzar reinicio del teléfono"</string>
- <string name="permdesc_reboot" product="tablet" msgid="4555793623560701557">"Permite que la aplicación fuerce a la tableta a reiniciarse."</string>
+ <string name="permdesc_reboot" product="tablet" msgid="4555793623560701557">"Permite que la aplicación fuerce al tablet a reiniciarse."</string>
<string name="permdesc_reboot" product="default" msgid="7914933292815491782">"Permite que la aplicación fuerce al teléfono a reiniciarse."</string>
<string name="permlab_mount_unmount_filesystems" msgid="1761023272170956541">"activar y desactivar sistemas de archivos"</string>
<string name="permdesc_mount_unmount_filesystems" msgid="6253263792535859767">"Permite que las aplicaciones activen y desactiven sistemas de archivos para un almacenamiento extraíble."</string>
@@ -371,7 +371,7 @@
<string name="permdesc_callPhone" msgid="3369867353692722456">"Permite que la aplicación llame a números de teléfono sin la intervención del usuario. Las aplicaciones malintencionadas pueden originar llamadas inesperadas en la factura telefónica. Ten en cuenta que con este permiso la aplicación no puede realizar llamadas a números de emergencia."</string>
<string name="permlab_callPrivileged" msgid="4198349211108497879">"llamar directamente a cualquier número de teléfono"</string>
<string name="permdesc_callPrivileged" msgid="244405067160028452">"Permite que la aplicación llame a cualquier número de teléfono, incluidos los números de emergencia, sin que el usuario intervenga. Las aplicaciones malintencionadas pueden realizar llamadas innecesarias e ilícitas a los servicios de emergencias."</string>
- <string name="permlab_performCdmaProvisioning" product="tablet" msgid="4842576994144604821">"iniciar directamente el método de acceso CDMA de la tableta"</string>
+ <string name="permlab_performCdmaProvisioning" product="tablet" msgid="4842576994144604821">"iniciar directamente el método de acceso CDMA del tablet"</string>
<string name="permlab_performCdmaProvisioning" product="default" msgid="5604848095315421425">"iniciar directamente el método de acceso CDMA del teléfono"</string>
<string name="permdesc_performCdmaProvisioning" msgid="6457447676108355905">"Permite que la aplicación inicie el método de acceso CDMA. Las aplicaciones malintencionadas pueden iniciar el método CDMA de forma innecesaria."</string>
<string name="permlab_locationUpdates" msgid="7785408253364335740">"controlar las notificaciones de actualización de la ubicación"</string>
@@ -384,16 +384,16 @@
<string name="permdesc_modifyPhoneState" msgid="3302284561346956587">"Permite que la aplicación controle las funciones de teléfono del dispositivo. Una aplicación con este permiso puede cambiar redes, activar y desactivar la señal móvil, etc., sin necesidad de notificar al usuario."</string>
<string name="permlab_readPhoneState" msgid="2326172951448691631">"leer la identidad y el estado del teléfono"</string>
<string name="permdesc_readPhoneState" msgid="188877305147626781">"Permite que la aplicación acceda a las funciones de teléfono del dispositivo. Una aplicación con este permiso puede determinar el número de teléfono y el número de serie de este teléfono, si una llamada está activa, el número al que está vinculada esa llamada, etc."</string>
- <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"impedir que la tableta entre en modo de suspensión"</string>
+ <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"impedir que el tablet entre en modo de suspensión"</string>
<string name="permlab_wakeLock" product="default" msgid="573480187941496130">"impedir que el teléfono entre en modo de suspensión"</string>
- <string name="permdesc_wakeLock" product="tablet" msgid="4032181488045338551">"Permite que una aplicación impida que la tableta entre en modo de suspensión."</string>
+ <string name="permdesc_wakeLock" product="tablet" msgid="4032181488045338551">"Permite que una aplicación impida que el tablet entre en modo de suspensión."</string>
<string name="permdesc_wakeLock" product="default" msgid="7584036471227467099">"Permite que una aplicación impida que el teléfono entre en modo de suspensión."</string>
- <string name="permlab_devicePower" product="tablet" msgid="2787034722616350417">"encender o apagar la tableta"</string>
+ <string name="permlab_devicePower" product="tablet" msgid="2787034722616350417">"encender o apagar el tablet"</string>
<string name="permlab_devicePower" product="default" msgid="4928622470980943206">"encender o apagar el teléfono"</string>
- <string name="permdesc_devicePower" product="tablet" msgid="3853773100100451905">"Permite que la aplicación active o desactive la tableta."</string>
+ <string name="permdesc_devicePower" product="tablet" msgid="3853773100100451905">"Permite que la aplicación active o desactive el tablet."</string>
<string name="permdesc_devicePower" product="default" msgid="4577331933252444818">"Permite que la aplicación active o desactive el teléfono."</string>
<string name="permlab_factoryTest" msgid="3715225492696416187">"ejecutar en modo de prueba de fábrica"</string>
- <string name="permdesc_factoryTest" product="tablet" msgid="3952059318359653091">"Permite la ejecución como prueba de fabricante de nivel inferior, lo que posibilita un acceso completo al hardware de la tableta. Sólo está disponible cuando una tableta se está ejecutando en modo de prueba."</string>
+ <string name="permdesc_factoryTest" product="tablet" msgid="3952059318359653091">"Permite la ejecución como prueba de fabricante de nivel inferior, lo que posibilita un acceso completo al hardware del tablet. Solo está disponible cuando un tablet se está ejecutando en modo de prueba."</string>
<string name="permdesc_factoryTest" product="default" msgid="8136644990319244802">"Ejecutar como prueba de fabricante de nivel inferior, permitiendo un acceso íntegro al hardware del teléfono. Sólo está disponible cuando un teléfono se está ejecutando en modo de prueba."</string>
<string name="permlab_setWallpaper" msgid="6627192333373465143">"establecer fondo de pantalla"</string>
<string name="permdesc_setWallpaper" msgid="6417041752170585837">"Permite que la aplicación establezca el fondo de pantalla del sistema."</string>
@@ -402,15 +402,15 @@
<string name="permlab_masterClear" msgid="2315750423139697397">"restablecer el sistema a los valores predeterminados de fábrica"</string>
<string name="permdesc_masterClear" msgid="5033465107545174514">"Permite que una aplicación restablezca por completo el sistema a su configuración de fábrica, borrando todos los datos, la configuración y las aplicaciones instaladas."</string>
<string name="permlab_setTime" msgid="2021614829591775646">"establecer hora"</string>
- <string name="permdesc_setTime" product="tablet" msgid="209693136361006073">"Permite que una aplicación cambie la hora del reloj de la tableta."</string>
+ <string name="permdesc_setTime" product="tablet" msgid="209693136361006073">"Permite que una aplicación cambie la hora del reloj del tablet."</string>
<string name="permdesc_setTime" product="default" msgid="667294309287080045">"Permite que una aplicación cambie la hora del reloj del teléfono."</string>
<string name="permlab_setTimeZone" msgid="2945079801013077340">"establecer zona horaria"</string>
- <string name="permdesc_setTimeZone" product="tablet" msgid="2522877107613885139">"Permite que una aplicación cambie la zona horaria de la tableta."</string>
+ <string name="permdesc_setTimeZone" product="tablet" msgid="2522877107613885139">"Permite que una aplicación cambie la zona horaria del tablet."</string>
<string name="permdesc_setTimeZone" product="default" msgid="1902540227418179364">"Permite que una aplicación cambie la zona horaria del teléfono."</string>
<string name="permlab_accountManagerService" msgid="4829262349691386986">"actuar como servicio de administrador de cuentas"</string>
<string name="permdesc_accountManagerService" msgid="6056903274106394752">"Permite que una aplicación realice llamadas a los autenticadores de cuentas."</string>
<string name="permlab_getAccounts" msgid="4549918644233460103">"ver cuentas reconocidas"</string>
- <string name="permdesc_getAccounts" product="tablet" msgid="857622793935544694">"Permite que una aplicación obtenga una lista de cuentas reconocidas por la tableta."</string>
+ <string name="permdesc_getAccounts" product="tablet" msgid="857622793935544694">"Permite que una aplicación obtenga una lista de cuentas reconocidas por el tablet."</string>
<string name="permdesc_getAccounts" product="default" msgid="6839262446413155394">"Permite que una aplicación obtenga una lista de cuentas reconocidas por el teléfono."</string>
<string name="permlab_authenticateAccounts" msgid="3940505577982882450">"actuar como autenticador de cuentas"</string>
<string name="permdesc_authenticateAccounts" msgid="4006839406474208874">"Permite que una aplicación utilice las funciones de autenticador de cuentas del administrador de cuentas, incluida la creación de cuentas y la obtención y el establecimiento de sus contraseñas."</string>
@@ -437,10 +437,10 @@
<string name="permlab_changeWifiMulticastState" msgid="1368253871483254784">"permitir recepción multidifusión Wi-Fi"</string>
<string name="permdesc_changeWifiMulticastState" msgid="8199464507656067553">"Permite que una aplicación reciba paquetes no dirigidos directamente a tu dispositivo. Esta función puede resultar útil para descubrir servicios cercanos. Utiliza más energía que el modo de no multidifusión."</string>
<string name="permlab_bluetoothAdmin" msgid="1092209628459341292">"administración de Bluetooth"</string>
- <string name="permdesc_bluetoothAdmin" product="tablet" msgid="3511795757324345837">"Permite que una aplicación configure la tableta Bluetooth local, vea dispositivos remotos y sincronice el teléfono con ellos."</string>
+ <string name="permdesc_bluetoothAdmin" product="tablet" msgid="3511795757324345837">"Permite que una aplicación configure el tablet Bluetooth local, vea dispositivos remotos y sincronice el tablet con ellos."</string>
<string name="permdesc_bluetoothAdmin" product="default" msgid="7256289774667054555">"Permite que una aplicación configure el teléfono Bluetooth local, y vea dispositivos remotos y sincronice el teléfono con ellos."</string>
<string name="permlab_bluetooth" msgid="8361038707857018732">"crear conexiones de Bluetooth"</string>
- <string name="permdesc_bluetooth" product="tablet" msgid="4191941825910543803">"Permite que una aplicación vea la configuración de la tableta Bluetooth local, y cree y acepte conexiones con los dispositivos sincronizados."</string>
+ <string name="permdesc_bluetooth" product="tablet" msgid="4191941825910543803">"Permite que una aplicación vea la configuración del tablet Bluetooth local, y cree y acepte conexiones con los dispositivos sincronizados."</string>
<string name="permdesc_bluetooth" product="default" msgid="762515380679392945">"Permite que una aplicación vea la configuración del teléfono Bluetooth local, y cree y acepte conexiones con los dispositivos sincronizados."</string>
<string name="permlab_nfc" msgid="4423351274757876953">"controlar Comunicación de campo cercano (NFC)"</string>
<string name="permdesc_nfc" msgid="9171401851954407226">"Permite que la aplicación se comunique con lectores, tarjetas y etiquetas de Comunicación de campo cercano (NFC)."</string>
@@ -473,14 +473,14 @@
<string name="policylab_limitPassword" msgid="4497420728857585791">"Establecimiento de reglas de contraseña"</string>
<string name="policydesc_limitPassword" msgid="9083400080861728056">"Control de la longitud y de los caracteres permitidos en las contraseñas de bloqueo de pantalla"</string>
<string name="policylab_watchLogin" msgid="914130646942199503">"Control de intentos de bloqueo de pantalla"</string>
- <string name="policydesc_watchLogin" product="tablet" msgid="933601759466308092">"Controla el número de contraseñas incorrectas introducidas al desbloquear la pantalla, bloquea la tableta o borra todos los datos de la tableta si se introducen demasiadas contraseñas incorrectas."</string>
+ <string name="policydesc_watchLogin" product="tablet" msgid="933601759466308092">"Controla el número de contraseñas incorrectas introducidas al desbloquear la pantalla, bloquea el tablet o borra todos los datos del tablet si se introducen demasiadas contraseñas incorrectas."</string>
<string name="policydesc_watchLogin" product="default" msgid="7227578260165172673">"Control del número de contraseñas incorrectas introducidas al desbloquear la pantalla, así como bloqueo del teléfono o borrado de todos los datos si se introducen demasiadas contraseñas incorrectas"</string>
<string name="policylab_resetPassword" msgid="2620077191242688955">"Modificación de contraseña de bloqueo de pantalla"</string>
<string name="policydesc_resetPassword" msgid="5391240616981297361">"Modificación de contraseña de bloqueo de pantalla"</string>
<string name="policylab_forceLock" msgid="2274085384704248431">"Bloqueo de pantalla"</string>
<string name="policydesc_forceLock" msgid="5696964126226028442">"Control de la forma en que se bloquea la pantalla y del momento en que se bloquea"</string>
<string name="policylab_wipeData" msgid="3910545446758639713">"Borrar todos los datos"</string>
- <string name="policydesc_wipeData" product="tablet" msgid="314455232799486222">"Borrado de los datos de la tableta sin avisar restableciendo datos de fábrica"</string>
+ <string name="policydesc_wipeData" product="tablet" msgid="314455232799486222">"Borrado de los datos del tablet sin avisar restableciendo datos de fábrica"</string>
<string name="policydesc_wipeData" product="default" msgid="7669895333814222586">"Borrado de los datos del teléfono sin avisar restableciendo datos de fábrica"</string>
<string name="policylab_setGlobalProxy" msgid="2784828293747791446">"Definir el servidor proxy global"</string>
<string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Define el servidor proxy global que se debe utilizar mientras la política esté habilitada. Solo el primer administrador de dispositivos define el servidor proxy global efectivo."</string>
@@ -623,7 +623,7 @@
<string name="lockscreen_battery_short" msgid="3617549178603354656">"<xliff:g id="NUMBER">%d</xliff:g> <xliff:g id="PERCENT">%%</xliff:g>"</string>
<string name="lockscreen_low_battery" msgid="1482873981919249740">"Conecta el cargador"</string>
<string name="lockscreen_missing_sim_message_short" msgid="7381499217732227295">"Falta la tarjeta SIM"</string>
- <string name="lockscreen_missing_sim_message" product="tablet" msgid="151659196095791474">"No se ha insertado ninguna tarjeta SIM en la tableta."</string>
+ <string name="lockscreen_missing_sim_message" product="tablet" msgid="151659196095791474">"No se ha insertado ninguna tarjeta SIM en el tablet."</string>
<string name="lockscreen_missing_sim_message" product="default" msgid="2186920585695169078">"No se ha insertado ninguna tarjeta SIM en el teléfono."</string>
<string name="lockscreen_missing_sim_instructions" msgid="8874620818937719067">"Inserta una tarjeta SIM"</string>
<string name="emergency_calls_only" msgid="6733978304386365407">"Solo llamadas de emergencia"</string>
@@ -635,7 +635,7 @@
<string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="3514742106066877476">"Has realizado <xliff:g id="NUMBER_0">%d</xliff:g> intentos fallidos de creación de un patrón de desbloqueo. "\n\n"Inténtalo de nuevo dentro de <xliff:g id="NUMBER_1">%d</xliff:g> segundos."</string>
<string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="4906034376425175381">"Has introducido una contraseña incorrecta <xliff:g id="NUMBER_0">%d</xliff:g> veces. "\n\n"Inténtalo de nuevo dentro de <xliff:g id="NUMBER_1">%d</xliff:g> segundos."</string>
<string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6827749231465145590">"Has introducido un PIN incorrecto <xliff:g id="NUMBER_0">%d</xliff:g> veces. "\n\n"Inténtalo de nuevo dentro de <xliff:g id="NUMBER_1">%d</xliff:g> segundos."</string>
- <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="8687762517114904651">"Has realizado <xliff:g id="NUMBER_0">%d</xliff:g> intentos fallidos de creación del patrón de desbloqueo. Si realizas <xliff:g id="NUMBER_1">%d</xliff:g> intentos fallidos más, se te pedirá que desbloquees la tableta con tus credenciales de acceso de Google."\n\n" Espera <xliff:g id="NUMBER_2">%d</xliff:g> segundos e inténtalo de nuevo."</string>
+ <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="8687762517114904651">"Has realizado <xliff:g id="NUMBER_0">%d</xliff:g> intentos fallidos de creación del patrón de desbloqueo. Si realizas <xliff:g id="NUMBER_1">%d</xliff:g> intentos fallidos más, se te pedirá que desbloquees el tablet con tus credenciales de acceso de Google."\n\n" Espera <xliff:g id="NUMBER_2">%d</xliff:g> segundos e inténtalo de nuevo."</string>
<string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="3351013842320127827">"Has realizado <xliff:g id="NUMBER_0">%d</xliff:g> intentos fallidos de creación del patrón de desbloqueo. Si realizas <xliff:g id="NUMBER_1">%d</xliff:g> intentos fallidos más, se te pedirá que desbloquees el teléfono con tus credenciales de acceso de Google."\n\n" Espera <xliff:g id="NUMBER_2">%d</xliff:g> segundos e inténtalo de nuevo."</string>
<string name="lockscreen_too_many_failed_attempts_countdown" msgid="6251480343394389665">"Espera <xliff:g id="NUMBER">%d</xliff:g> segundos y vuelve a intentarlo."</string>
<string name="lockscreen_forgot_pattern_button_text" msgid="2626999449610695930">"¿Has olvidado el patrón?"</string>
@@ -674,7 +674,7 @@
<string name="permlab_readHistoryBookmarks" msgid="1284843728203412135">"leer información de marcadores y del historial del navegador"</string>
<string name="permdesc_readHistoryBookmarks" msgid="4981489815467617191">"Permite que la aplicación lea todas las URL que ha visitado el navegador y todos sus marcadores."</string>
<string name="permlab_writeHistoryBookmarks" msgid="9009434109836280374">"escribir en marcadores y en el historial del navegador"</string>
- <string name="permdesc_writeHistoryBookmarks" product="tablet" msgid="7193514090469945307">"Permite que una aplicación modifique la información de los marcadores o del historial del navegador almacenada en la tableta. Las aplicaciones malintencionadas pueden utilizar este permiso para borrar o modificar los datos del navegador."</string>
+ <string name="permdesc_writeHistoryBookmarks" product="tablet" msgid="7193514090469945307">"Permite que una aplicación modifique la información de los marcadores o del historial del navegador almacenada en el tablet. Las aplicaciones malintencionadas pueden utilizar este permiso para borrar o modificar los datos del navegador."</string>
<string name="permdesc_writeHistoryBookmarks" product="default" msgid="945571990357114950">"Permite que una aplicación modifique la información de los marcadores o del historial del navegador almacenada en el teléfono. Las aplicaciones malintencionadas pueden utilizar este permiso para borrar o modificar los datos del navegador."</string>
<string name="permlab_setAlarm" msgid="5924401328803615165">"establecer alarma en un reloj"</string>
<string name="permdesc_setAlarm" msgid="5966966598149875082">"Permite a la aplicación establecer una alarma en una aplicación de reloj instalada. Es posible que algunas aplicaciones de reloj no incluyan esta función."</string>
@@ -800,7 +800,7 @@
<string name="inputMethod" msgid="1653630062304567879">"Método de introducción de texto"</string>
<string name="editTextMenuTitle" msgid="4909135564941815494">"Acciones de texto"</string>
<string name="low_internal_storage_view_title" msgid="1399732408701697546">"Poco espacio"</string>
- <string name="low_internal_storage_view_text" product="tablet" msgid="4231085657068852042">"Se está agotando el espacio de almacenamiento de la tableta."</string>
+ <string name="low_internal_storage_view_text" product="tablet" msgid="4231085657068852042">"Se está agotando el espacio de almacenamiento del tablet."</string>
<string name="low_internal_storage_view_text" product="default" msgid="635106544616378836">"Se está agotando el espacio de almacenamiento del teléfono."</string>
<string name="ok" msgid="5970060430562524910">"Aceptar"</string>
<string name="cancel" msgid="6442560571259935130">"Cancelar"</string>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index 5d897e3..eb14169 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -130,7 +130,7 @@
<string name="me" msgid="6545696007631404292">"Saya"</string>
<string name="power_dialog" product="tablet" msgid="8545351420865202853">"Opsi tablet"</string>
<string name="power_dialog" product="default" msgid="1319919075463988638">"Opsi telepon"</string>
- <string name="silent_mode" msgid="7167703389802618663">"Mode senyap"</string>
+ <string name="silent_mode" msgid="7167703389802618663">"Modus senyap"</string>
<string name="turn_on_radio" msgid="3912793092339962371">"Hidupkan nirkabel"</string>
<string name="turn_off_radio" msgid="8198784949987062346">"Matikan nirkabel"</string>
<string name="screen_lock" msgid="799094655496098153">"Kunci layar"</string>
@@ -683,7 +683,7 @@
<string name="save_password_message" msgid="767344687139195790">"Apakah Anda ingin peramban menyimpan sandi ini?"</string>
<string name="save_password_notnow" msgid="6389675316706699758">"Tidak sekarang"</string>
<string name="save_password_remember" msgid="6491879678996749466">"Ingat"</string>
- <string name="save_password_never" msgid="8274330296785855105">"Tidak pernah"</string>
+ <string name="save_password_never" msgid="8274330296785855105">"Jangan"</string>
<string name="open_permission_deny" msgid="5661861460947222274">"Anda tidak memiliki izin untuk membuka laman ini."</string>
<string name="text_copied" msgid="4985729524670131385">"Teks disalin ke clipboard."</string>
<string name="more_item_label" msgid="4650918923083320495">"Lainnya"</string>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index e9acf14..7aa7b30 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -489,7 +489,7 @@
<string name="policylab_encryptedStorage" msgid="8901326199909132915">"הגדר הצפנת אחסון"</string>
<string name="policydesc_encryptedStorage" msgid="2504984732631479399">"דורש שנתוני היישום המאוחסנים יהיו מוצפנים"</string>
<string-array name="phoneTypes">
- <item msgid="8901098336658710359">"דף הבית"</item>
+ <item msgid="8901098336658710359">"בית"</item>
<item msgid="869923650527136615">"נייד"</item>
<item msgid="7897544654242874543">"עבודה"</item>
<item msgid="1103601433382158155">"פקס בעבודה"</item>
@@ -499,19 +499,19 @@
<item msgid="9192514806975898961">"מותאם אישית"</item>
</string-array>
<string-array name="emailAddressTypes">
- <item msgid="8073994352956129127">"דף הבית"</item>
+ <item msgid="8073994352956129127">"בית"</item>
<item msgid="7084237356602625604">"עבודה"</item>
<item msgid="1112044410659011023">"אחר"</item>
<item msgid="2374913952870110618">"מותאם אישית"</item>
</string-array>
<string-array name="postalAddressTypes">
- <item msgid="6880257626740047286">"דף הבית"</item>
+ <item msgid="6880257626740047286">"בית"</item>
<item msgid="5629153956045109251">"עבודה"</item>
<item msgid="4966604264500343469">"אחר"</item>
<item msgid="4932682847595299369">"מותאם אישית"</item>
</string-array>
<string-array name="imAddressTypes">
- <item msgid="1738585194601476694">"דף הבית"</item>
+ <item msgid="1738585194601476694">"בית"</item>
<item msgid="1359644565647383708">"עבודה"</item>
<item msgid="7868549401053615677">"אחר"</item>
<item msgid="3145118944639869809">"מותאם אישית"</item>
@@ -532,7 +532,7 @@
<item msgid="1648797903785279353">"Jabber"</item>
</string-array>
<string name="phoneTypeCustom" msgid="1644738059053355820">"מותאם אישית"</string>
- <string name="phoneTypeHome" msgid="2570923463033985887">"דף הבית"</string>
+ <string name="phoneTypeHome" msgid="2570923463033985887">"בית"</string>
<string name="phoneTypeMobile" msgid="6501463557754751037">"נייד"</string>
<string name="phoneTypeWork" msgid="8863939667059911633">"עבודה"</string>
<string name="phoneTypeFaxWork" msgid="3517792160008890912">"פקס בעבודה"</string>
@@ -557,16 +557,16 @@
<string name="eventTypeAnniversary" msgid="3876779744518284000">"יום השנה"</string>
<string name="eventTypeOther" msgid="7388178939010143077">"אחר"</string>
<string name="emailTypeCustom" msgid="8525960257804213846">"מותאם אישית"</string>
- <string name="emailTypeHome" msgid="449227236140433919">"דף הבית"</string>
+ <string name="emailTypeHome" msgid="449227236140433919">"בית"</string>
<string name="emailTypeWork" msgid="3548058059601149973">"עבודה"</string>
<string name="emailTypeOther" msgid="2923008695272639549">"אחר"</string>
<string name="emailTypeMobile" msgid="119919005321166205">"סלולרי"</string>
<string name="postalTypeCustom" msgid="8903206903060479902">"מותאם אישית"</string>
- <string name="postalTypeHome" msgid="8165756977184483097">"דף הבית"</string>
+ <string name="postalTypeHome" msgid="8165756977184483097">"בית"</string>
<string name="postalTypeWork" msgid="5268172772387694495">"עבודה"</string>
<string name="postalTypeOther" msgid="2726111966623584341">"אחר"</string>
<string name="imTypeCustom" msgid="2074028755527826046">"מותאם אישית"</string>
- <string name="imTypeHome" msgid="6241181032954263892">"דף הבית"</string>
+ <string name="imTypeHome" msgid="6241181032954263892">"בית"</string>
<string name="imTypeWork" msgid="1371489290242433090">"עבודה"</string>
<string name="imTypeOther" msgid="5377007495735915478">"אחר"</string>
<string name="imProtocolCustom" msgid="6919453836618749992">"מותאם אישית"</string>
@@ -598,7 +598,7 @@
<string name="relationTypeSister" msgid="1735983554479076481">"אחות"</string>
<string name="relationTypeSpouse" msgid="394136939428698117">"בן/בת זוג"</string>
<string name="sipAddressTypeCustom" msgid="2473580593111590945">"מותאם אישית"</string>
- <string name="sipAddressTypeHome" msgid="6093598181069359295">"דף הבית"</string>
+ <string name="sipAddressTypeHome" msgid="6093598181069359295">"בית"</string>
<string name="sipAddressTypeWork" msgid="6920725730797099047">"עבודה"</string>
<string name="sipAddressTypeOther" msgid="4408436162950119849">"אחר"</string>
<string name="keyguard_password_enter_pin_code" msgid="3731488827218876115">"הזן קוד PIN"</string>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index aa43fe9..1c234c2 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -823,7 +823,7 @@
<string name="anr_activity_process" msgid="5420826626009561014">"Aktiviteten <xliff:g id="ACTIVITY">%1$s</xliff:g> (i processen <xliff:g id="PROCESS">%2$s</xliff:g>) svarar inte."</string>
<string name="anr_application_process" msgid="4185842666452210193">"Programmet <xliff:g id="APPLICATION">%1$s</xliff:g> (i processen <xliff:g id="PROCESS">%2$s</xliff:g>) svarar inte."</string>
<string name="anr_process" msgid="1246866008169975783">"Processen <xliff:g id="PROCESS">%1$s</xliff:g> svarar inte."</string>
- <string name="force_close" msgid="3653416315450806396">"Tvinga fram en stängning"</string>
+ <string name="force_close" msgid="3653416315450806396">"Tvinga stängning"</string>
<string name="report" msgid="4060218260984795706">"Rapportera"</string>
<string name="wait" msgid="7147118217226317732">"Vänta"</string>
<string name="launch_warning_title" msgid="8323761616052121936">"Programmet omdirigerades"</string>
diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestActivity.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestActivity.java
index 7756135..e138200 100644
--- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestActivity.java
+++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestActivity.java
@@ -21,30 +21,34 @@
import android.content.BroadcastReceiver;
import android.content.Intent;
import android.content.IntentFilter;
+import android.net.ConnectivityManager;
+import android.net.NetworkInfo;
+import android.net.NetworkInfo.State;
+import android.net.wifi.WifiConfiguration;
+import android.net.wifi.WifiManager;
+import android.net.wifi.WifiInfo;
+import android.net.wifi.ScanResult;
+import android.net.wifi.WifiConfiguration.KeyMgmt;
import android.os.Bundle;
+import android.os.Handler;
import android.os.IPowerManager;
+import android.os.Message;
import android.os.PowerManager;
import android.os.ServiceManager;
import android.os.SystemClock;
import android.provider.Settings;
import android.util.Log;
import android.view.KeyEvent;
+import android.widget.LinearLayout;
+
+import com.android.internal.util.AsyncChannel;
import java.io.IOException;
import java.io.InputStream;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.List;
-import android.widget.LinearLayout;
-import android.net.ConnectivityManager;
-import android.net.NetworkInfo;
-import android.net.NetworkInfo.State;
-import android.net.wifi.WifiConfiguration;
-import android.net.wifi.WifiManager;
-import android.net.wifi.WifiInfo;
-import android.net.wifi.ScanResult;
-import android.net.wifi.WifiConfiguration.KeyMgmt;
/**
* An activity registered with connectivity manager broadcast
@@ -180,6 +184,24 @@
}
}
+ private class WifiServiceHandler extends Handler {
+ @Override
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED:
+ if (msg.arg1 == AsyncChannel.STATUS_SUCCESSFUL) {
+ //AsyncChannel in msg.obj
+ } else {
+ log("Failed to establish AsyncChannel connection");
+ }
+ break;
+ default:
+ //Ignore
+ break;
+ }
+ }
+ }
+
public ConnectivityManagerTestActivity() {
mState = State.UNKNOWN;
scanResultAvailable = false;
@@ -216,6 +238,8 @@
mCM = (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
// Get an instance of WifiManager
mWifiManager =(WifiManager)getSystemService(Context.WIFI_SERVICE);
+ mWifiManager.asyncConnect(this, new WifiServiceHandler());
+
initializeNetworkStates();
if (mWifiManager.isWifiEnabled()) {
diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/WifiConnectionTest.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/WifiConnectionTest.java
index 9c72102..fe79e6c 100644
--- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/WifiConnectionTest.java
+++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/WifiConnectionTest.java
@@ -34,12 +34,15 @@
import android.net.DhcpInfo;
import android.net.NetworkInfo;
import android.net.NetworkInfo.State;
+import android.os.Handler;
+import android.os.Message;
import android.provider.Settings;
-
import android.test.suitebuilder.annotation.LargeTest;
import android.test.ActivityInstrumentationTestCase2;
import android.util.Log;
+import com.android.internal.util.AsyncChannel;
+
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
@@ -75,6 +78,7 @@
enabledNetworks = getEnabledNetworks(mWifiManager.getConfiguredNetworks());
mAct = getActivity();
+ mWifiManager.asyncConnect(mAct, new WifiServiceHandler());
networks = mAct.loadNetworkConfigurations();
if (DEBUG) {
printNetworkConfigurations();
@@ -89,6 +93,24 @@
assertTrue("wpa_supplicant is not started ", mAct.mWifiManager.pingSupplicant());
}
+ private class WifiServiceHandler extends Handler {
+ @Override
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED:
+ if (msg.arg1 == AsyncChannel.STATUS_SUCCESSFUL) {
+ //AsyncChannel in msg.obj
+ } else {
+ log("Failed to establish AsyncChannel connection");
+ }
+ break;
+ default:
+ //Ignore
+ break;
+ }
+ }
+ }
+
private void printNetworkConfigurations() {
log("==== print network configurations parsed from XML file ====");
log("number of access points: " + networks.size());
diff --git a/core/tests/coretests/AndroidManifest.xml b/core/tests/coretests/AndroidManifest.xml
index 01734f2..4be6995 100644
--- a/core/tests/coretests/AndroidManifest.xml
+++ b/core/tests/coretests/AndroidManifest.xml
@@ -44,6 +44,7 @@
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
+ <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
<uses-permission android:name="android.permission.BROADCAST_STICKY" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.CLEAR_APP_CACHE" />
diff --git a/core/tests/coretests/src/android/accounts/AccountManagerServiceTest.java b/core/tests/coretests/src/android/accounts/AccountManagerServiceTest.java
index 887b032..6efc61a 100644
--- a/core/tests/coretests/src/android/accounts/AccountManagerServiceTest.java
+++ b/core/tests/coretests/src/android/accounts/AccountManagerServiceTest.java
@@ -96,7 +96,7 @@
assertEquals(a21, accounts[1]);
assertEquals(a31, accounts[2]);
- mAms.removeAccount(a21);
+ mAms.removeAccountInternal(a21);
accounts = mAms.getAccounts("type1" );
Arrays.sort(accounts, new AccountSorter());
diff --git a/core/tests/coretests/src/android/bluetooth/BluetoothStressTest.java b/core/tests/coretests/src/android/bluetooth/BluetoothStressTest.java
index 672f252..5dedd4a 100644
--- a/core/tests/coretests/src/android/bluetooth/BluetoothStressTest.java
+++ b/core/tests/coretests/src/android/bluetooth/BluetoothStressTest.java
@@ -316,4 +316,34 @@
mTestUtils.disablePan(adapter);
mTestUtils.disable(adapter);
}
+
+ /**
+ * Stress test for verifying that AudioManager can open and close SCO connections.
+ * <p>
+ * In this test, a HSP connection is opened with an external headset and the SCO connection is
+ * repeatibly opened and closed.
+ */
+ public void testStartStopSco() {
+ int iterations = BluetoothTestRunner.sStartStopScoIterations;
+ if (iterations == 0) {
+ return;
+ }
+
+ BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
+ BluetoothDevice device = adapter.getRemoteDevice(BluetoothTestRunner.sHeadsetAddress);
+ mTestUtils.enable(adapter);
+ mTestUtils.pair(adapter, device, BluetoothTestRunner.sPairPasskey,
+ BluetoothTestRunner.sPairPin);
+ mTestUtils.connectProfile(adapter, device, BluetoothProfile.HEADSET);
+
+ for (int i = 0; i < iterations; i++) {
+ mTestUtils.writeOutput("startStopSco iteration " + (i + 1) + " of " + iterations);
+ mTestUtils.startSco(adapter, device);
+ mTestUtils.stopSco(adapter, device);
+ }
+
+ mTestUtils.disconnectProfile(adapter, device, BluetoothProfile.HEADSET);
+ mTestUtils.unpair(adapter, device);
+ mTestUtils.disable(adapter);
+ }
}
diff --git a/core/tests/coretests/src/android/bluetooth/BluetoothTestRunner.java b/core/tests/coretests/src/android/bluetooth/BluetoothTestRunner.java
index cede05a..1febc5c 100644
--- a/core/tests/coretests/src/android/bluetooth/BluetoothTestRunner.java
+++ b/core/tests/coretests/src/android/bluetooth/BluetoothTestRunner.java
@@ -39,6 +39,7 @@
* [-e connect_headset_iterations <iterations>] \
* [-e connect_input_iterations <iterations>] \
* [-e connect_pan_iterations <iterations>] \
+ * [-e start_stop_sco_iterations <iterations>] \
* [-e pair_address <address>] \
* [-e headset_address <address>] \
* [-e a2dp_address <address>] \
@@ -62,6 +63,7 @@
public static int sConnectA2dpIterations = 100;
public static int sConnectInputIterations = 100;
public static int sConnectPanIterations = 100;
+ public static int sStartStopScoIterations = 100;
public static String sPairAddress = "";
public static String sHeadsetAddress = "";
@@ -167,6 +169,14 @@
}
}
+ val = arguments.getString("start_stop_sco_iterations");
+ if (val != null) {
+ try {
+ sStartStopScoIterations = Integer.parseInt(val);
+ } catch (NumberFormatException e) {
+ // Invalid argument, fall back to default value
+ }
+ }
val = arguments.getString("pair_address");
if (val != null) {
sPairAddress = val;
@@ -214,6 +224,7 @@
Log.i(TAG, String.format("connect_headset_iterations=%d", sConnectHeadsetIterations));
Log.i(TAG, String.format("connect_input_iterations=%d", sConnectInputIterations));
Log.i(TAG, String.format("connect_pan_iterations=%d", sConnectPanIterations));
+ Log.i(TAG, String.format("start_stop_sco_iterations=%d", sStartStopScoIterations));
Log.i(TAG, String.format("pair_address=%s", sPairAddress));
Log.i(TAG, String.format("a2dp_address=%s", sA2dpAddress));
Log.i(TAG, String.format("headset_address=%s", sHeadsetAddress));
diff --git a/core/tests/coretests/src/android/bluetooth/BluetoothTestUtils.java b/core/tests/coretests/src/android/bluetooth/BluetoothTestUtils.java
index 85c5eaa..1741119 100644
--- a/core/tests/coretests/src/android/bluetooth/BluetoothTestUtils.java
+++ b/core/tests/coretests/src/android/bluetooth/BluetoothTestUtils.java
@@ -22,6 +22,7 @@
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
+import android.media.AudioManager;
import android.os.Environment;
import android.util.Log;
@@ -67,6 +68,11 @@
private static final int CONNECT_PROXY_TIMEOUT = 5000;
/**
+ * Timeout to start or stop a SCO channel in ms.
+ */
+ private static final int START_STOP_SCO_TIMEOUT = 10000;
+
+ /**
* Time between polls in ms.
*/
private static final int POLL_TIME = 100;
@@ -319,6 +325,32 @@
}
}
+ private class StartStopScoReceiver extends FlagReceiver {
+ private static final int STATE_CONNECTED_FLAG = 1;
+ private static final int STATE_DISCONNECTED_FLAG = 1 << 1;
+
+ public StartStopScoReceiver(int expectedFlags) {
+ super(expectedFlags);
+ }
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if (AudioManager.ACTION_SCO_AUDIO_STATE_CHANGED.equals(intent.getAction())) {
+ int state = intent.getIntExtra(AudioManager.EXTRA_SCO_AUDIO_STATE,
+ AudioManager.SCO_AUDIO_STATE_ERROR);
+ assertNotSame(AudioManager.SCO_AUDIO_STATE_ERROR, state);
+ switch(state) {
+ case AudioManager.SCO_AUDIO_STATE_CONNECTED:
+ setFiredFlag(STATE_CONNECTED_FLAG);
+ break;
+ case AudioManager.SCO_AUDIO_STATE_DISCONNECTED:
+ setFiredFlag(STATE_DISCONNECTED_FLAG);
+ break;
+ }
+ }
+ }
+ }
+
private BluetoothProfile.ServiceListener mServiceListener =
new BluetoothProfile.ServiceListener() {
public void onServiceConnected(int profile, BluetoothProfile proxy) {
@@ -1269,6 +1301,103 @@
}
/**
+ * Opens a SCO channel using {@link android.media.AudioManager#startBluetoothSco()} and checks
+ * to make sure that the channel is opened and that the correct actions were broadcast.
+ *
+ * @param adapter The BT adapter.
+ * @param device The remote device.
+ */
+ public void startSco(BluetoothAdapter adapter, BluetoothDevice device) {
+ startStopSco(adapter, device, true);
+ }
+
+ /**
+ * Closes a SCO channel using {@link android.media.AudioManager#stopBluetoothSco()} and checks
+ * to make sure that the channel is closed and that the correct actions were broadcast.
+ *
+ * @param adapter The BT adapter.
+ * @param device The remote device.
+ */
+ public void stopSco(BluetoothAdapter adapter, BluetoothDevice device) {
+ startStopSco(adapter, device, false);
+ }
+ /**
+ * Helper method for {@link #startSco(BluetoothAdapter, BluetoothDevice)} and
+ * {@link #stopSco(BluetoothAdapter, BluetoothDevice)}.
+ *
+ * @param adapter The BT adapter.
+ * @param device The remote device.
+ * @param isStart Whether the SCO channel should be opened.
+ */
+ private void startStopSco(BluetoothAdapter adapter, BluetoothDevice device, boolean isStart) {
+ long start = -1;
+ int mask;
+ String methodName;
+
+ if (isStart) {
+ methodName = "startSco()";
+ mask = StartStopScoReceiver.STATE_CONNECTED_FLAG;
+ } else {
+ methodName = "stopSco()";
+ mask = StartStopScoReceiver.STATE_DISCONNECTED_FLAG;
+ }
+
+ if (!adapter.isEnabled()) {
+ fail(String.format("%s bluetooth not enabled: device=%s, start=%b", methodName, device,
+ isStart));
+ }
+
+ if (!adapter.getBondedDevices().contains(device)) {
+ fail(String.format("%s device not paired: device=%s, start=%b", methodName, device,
+ isStart));
+ }
+
+ AudioManager manager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
+ assertNotNull(manager);
+
+ if (!manager.isBluetoothScoAvailableOffCall()) {
+ fail(String.format("%s device does not support SCO: device=%s, start=%b", methodName,
+ device, isStart));
+ }
+
+ boolean isScoOn = manager.isBluetoothScoOn();
+ if (isStart == isScoOn) {
+ return;
+ }
+
+ StartStopScoReceiver receiver = getStartStopScoReceiver(mask);
+ start = System.currentTimeMillis();
+ if (isStart) {
+ manager.startBluetoothSco();
+ } else {
+ manager.stopBluetoothSco();
+ }
+
+ long s = System.currentTimeMillis();
+ while (System.currentTimeMillis() - s < START_STOP_SCO_TIMEOUT) {
+ isScoOn = manager.isBluetoothScoOn();
+ if ((isStart == isScoOn) &&
+ (receiver.getFiredFlags() & mask) == mask) {
+ long finish = receiver.getCompletedTime();
+ if (start != -1 && finish != -1) {
+ writeOutput(String.format("%s completed in %d ms", methodName,
+ (finish - start)));
+ } else {
+ writeOutput(String.format("%s completed", methodName));
+ }
+ removeReceiver(receiver);
+ return;
+ }
+ sleep(POLL_TIME);
+ }
+
+ int firedFlags = receiver.getFiredFlags();
+ removeReceiver(receiver);
+ fail(String.format("%s timeout: start=%b (expected %b), flags=0x%x (expected 0x%x)",
+ methodName, isScoOn, isStart, firedFlags, mask));
+ }
+
+ /**
* Writes a string to the logcat and a file if a file has been specified in the constructor.
*
* @param s The string to be written.
@@ -1336,6 +1465,13 @@
return receiver;
}
+ private StartStopScoReceiver getStartStopScoReceiver(int expectedFlags) {
+ String[] actions = {AudioManager.ACTION_SCO_AUDIO_STATE_CHANGED};
+ StartStopScoReceiver receiver = new StartStopScoReceiver(expectedFlags);
+ addReceiver(receiver, actions);
+ return receiver;
+ }
+
private void removeReceiver(BroadcastReceiver receiver) {
mContext.unregisterReceiver(receiver);
mReceivers.remove(receiver);
diff --git a/core/tests/coretests/src/android/content/pm/PackageManagerTests.java b/core/tests/coretests/src/android/content/pm/PackageManagerTests.java
index 7af64e4..5d28ef7 100755
--- a/core/tests/coretests/src/android/content/pm/PackageManagerTests.java
+++ b/core/tests/coretests/src/android/content/pm/PackageManagerTests.java
@@ -769,9 +769,9 @@
return doneFlag;
}
- public void packageDeleted(boolean succeeded) throws RemoteException {
+ public void packageDeleted(String packageName, int returnCode) throws RemoteException {
synchronized(this) {
- this.succeeded = succeeded;
+ this.succeeded = returnCode == PackageManager.DELETE_SUCCEEDED;
doneFlag = true;
notifyAll();
}
diff --git a/include/gui/SurfaceTexture.h b/include/gui/SurfaceTexture.h
index 31615d0..9bf38f7 100644
--- a/include/gui/SurfaceTexture.h
+++ b/include/gui/SurfaceTexture.h
@@ -37,7 +37,8 @@
class SurfaceTexture : public BnSurfaceTexture {
public:
- enum { MIN_BUFFER_SLOTS = 3 };
+ enum { MIN_UNDEQUEUED_BUFFERS = 2 };
+ enum { MIN_BUFFER_SLOTS = MIN_UNDEQUEUED_BUFFERS + 1 };
enum { NUM_BUFFER_SLOTS = 32 };
struct FrameAvailableListener : public virtual RefBase {
diff --git a/include/gui/SurfaceTextureClient.h b/include/gui/SurfaceTextureClient.h
index ff2251d..4cdece9 100644
--- a/include/gui/SurfaceTextureClient.h
+++ b/include/gui/SurfaceTextureClient.h
@@ -40,40 +40,41 @@
SurfaceTextureClient(const SurfaceTextureClient& rhs);
// ANativeWindow hooks
- static int setSwapInterval(ANativeWindow* window, int interval);
- static int dequeueBuffer(ANativeWindow* window, android_native_buffer_t** buffer);
static int cancelBuffer(ANativeWindow* window, android_native_buffer_t* buffer);
+ static int dequeueBuffer(ANativeWindow* window, android_native_buffer_t** buffer);
static int lockBuffer(ANativeWindow* window, android_native_buffer_t* buffer);
- static int queueBuffer(ANativeWindow* window, android_native_buffer_t* buffer);
- static int query(ANativeWindow* window, int what, int* value);
static int perform(ANativeWindow* window, int operation, ...);
+ static int query(ANativeWindow* window, int what, int* value);
+ static int queueBuffer(ANativeWindow* window, android_native_buffer_t* buffer);
+ static int setSwapInterval(ANativeWindow* window, int interval);
- int setSwapInterval(int interval);
+ int cancelBuffer(android_native_buffer_t* buffer);
int dequeueBuffer(android_native_buffer_t** buffer);
int lockBuffer(android_native_buffer_t* buffer);
- int queueBuffer(android_native_buffer_t* buffer);
- int cancelBuffer(android_native_buffer_t* buffer);
- int query(int what, int* value);
int perform(int operation, va_list args);
+ int query(int what, int* value);
+ int queueBuffer(android_native_buffer_t* buffer);
+ int setSwapInterval(int interval);
- int dispatchSetUsage(va_list args);
int dispatchConnect(va_list args);
int dispatchDisconnect(va_list args);
- int dispatchSetCrop(va_list args);
int dispatchSetBufferCount(va_list args);
int dispatchSetBuffersGeometry(va_list args);
int dispatchSetBuffersTransform(va_list args);
+ int dispatchSetCrop(va_list args);
+ int dispatchSetUsage(va_list args);
int connect(int api);
int disconnect(int api);
- int setUsage(uint32_t reqUsage);
- int setCrop(Rect const* rect);
int setBufferCount(int bufferCount);
int setBuffersGeometry(int w, int h, int format);
int setBuffersTransform(int transform);
+ int setCrop(Rect const* rect);
+ int setUsage(uint32_t reqUsage);
void freeAllBuffers();
+ enum { MIN_UNDEQUEUED_BUFFERS = SurfaceTexture::MIN_UNDEQUEUED_BUFFERS };
enum { MIN_BUFFER_SLOTS = SurfaceTexture::MIN_BUFFER_SLOTS };
enum { NUM_BUFFER_SLOTS = SurfaceTexture::NUM_BUFFER_SLOTS };
enum { DEFAULT_FORMAT = PIXEL_FORMAT_RGBA_8888 };
diff --git a/include/media/IOMX.h b/include/media/IOMX.h
index cb36bbb..16a9342 100644
--- a/include/media/IOMX.h
+++ b/include/media/IOMX.h
@@ -85,6 +85,9 @@
virtual status_t enableGraphicBuffers(
node_id node, OMX_U32 port_index, OMX_BOOL enable) = 0;
+ virtual status_t getGraphicBufferUsage(
+ node_id node, OMX_U32 port_index, OMX_U32* usage) = 0;
+
virtual status_t useBuffer(
node_id node, OMX_U32 port_index, const sp<IMemory> ¶ms,
buffer_id *buffer) = 0;
diff --git a/include/media/MediaProfiles.h b/include/media/MediaProfiles.h
index aa97874..f2107ec 100644
--- a/include/media/MediaProfiles.h
+++ b/include/media/MediaProfiles.h
@@ -24,6 +24,7 @@
namespace android {
enum camcorder_quality {
+ CAMCORDER_QUALITY_LIST_START = 0,
CAMCORDER_QUALITY_LOW = 0,
CAMCORDER_QUALITY_HIGH = 1,
CAMCORDER_QUALITY_QCIF = 2,
@@ -31,14 +32,17 @@
CAMCORDER_QUALITY_480P = 4,
CAMCORDER_QUALITY_720P = 5,
CAMCORDER_QUALITY_1080P = 6,
+ CAMCORDER_QUALITY_LIST_END = 6,
+ CAMCORDER_QUALITY_TIME_LAPSE_LIST_START = 1000,
CAMCORDER_QUALITY_TIME_LAPSE_LOW = 1000,
CAMCORDER_QUALITY_TIME_LAPSE_HIGH = 1001,
CAMCORDER_QUALITY_TIME_LAPSE_QCIF = 1002,
CAMCORDER_QUALITY_TIME_LAPSE_CIF = 1003,
CAMCORDER_QUALITY_TIME_LAPSE_480P = 1004,
CAMCORDER_QUALITY_TIME_LAPSE_720P = 1005,
- CAMCORDER_QUALITY_TIME_LAPSE_1080P = 1006
+ CAMCORDER_QUALITY_TIME_LAPSE_1080P = 1006,
+ CAMCORDER_QUALITY_TIME_LAPSE_LIST_END = 1006,
};
enum video_decoder {
@@ -147,6 +151,11 @@
Vector<int> getImageEncodingQualityLevels(int cameraId) const;
private:
+ enum {
+ // Camcorder profiles (high/low) and timelapse profiles (high/low)
+ kNumRequiredProfiles = 4,
+ };
+
MediaProfiles& operator=(const MediaProfiles&); // Don't call me
MediaProfiles(const MediaProfiles&); // Don't call me
MediaProfiles() {} // Dummy default constructor
@@ -160,6 +169,14 @@
mFrameHeight(frameHeight),
mFrameRate(frameRate) {}
+ VideoCodec(const VideoCodec& copy) {
+ mCodec = copy.mCodec;
+ mBitRate = copy.mBitRate;
+ mFrameWidth = copy.mFrameWidth;
+ mFrameHeight = copy.mFrameHeight;
+ mFrameRate = copy.mFrameRate;
+ }
+
~VideoCodec() {}
video_encoder mCodec;
@@ -176,6 +193,13 @@
mSampleRate(sampleRate),
mChannels(channels) {}
+ AudioCodec(const AudioCodec& copy) {
+ mCodec = copy.mCodec;
+ mBitRate = copy.mBitRate;
+ mSampleRate = copy.mSampleRate;
+ mChannels = copy.mChannels;
+ }
+
~AudioCodec() {}
audio_encoder mCodec;
@@ -193,6 +217,15 @@
mVideoCodec(0),
mAudioCodec(0) {}
+ CamcorderProfile(const CamcorderProfile& copy) {
+ mCameraId = copy.mCameraId;
+ mFileFormat = copy.mFileFormat;
+ mQuality = copy.mQuality;
+ mDuration = copy.mDuration;
+ mVideoCodec = new VideoCodec(*copy.mVideoCodec);
+ mAudioCodec = new AudioCodec(*copy.mAudioCodec);
+ }
+
~CamcorderProfile() {
delete mVideoCodec;
delete mAudioCodec;
@@ -272,6 +305,8 @@
};
int getCamcorderProfileIndex(int cameraId, camcorder_quality quality) const;
+ void initRequiredProfileRefs(const Vector<int>& cameraIds);
+ int getRequiredProfileRefIndex(int cameraId);
// Debug
static void logVideoCodec(const VideoCodec& codec);
@@ -291,7 +326,10 @@
static VideoDecoderCap* createVideoDecoderCap(const char **atts);
static VideoEncoderCap* createVideoEncoderCap(const char **atts);
static AudioEncoderCap* createAudioEncoderCap(const char **atts);
- static CamcorderProfile* createCamcorderProfile(int cameraId, const char **atts);
+
+ static CamcorderProfile* createCamcorderProfile(
+ int cameraId, const char **atts, Vector<int>& cameraIds);
+
static int getCameraId(const char **atts);
ImageEncodingQualityLevels* findImageEncodingQualityLevels(int cameraId) const;
@@ -335,6 +373,21 @@
static int findTagForName(const NameToTagMap *map, size_t nMappings, const char *name);
+ /**
+ * Check on existing profiles with the following criteria:
+ * 1. Low quality profile must have the lowest video
+ * resolution product (width x height)
+ * 2. High quality profile must have the highest video
+ * resolution product (width x height)
+ *
+ * and add required low/high quality camcorder/timelapse
+ * profiles if they are not found. This allows to remove
+ * duplicate profile definitions in the media_profiles.xml
+ * file.
+ */
+ void checkAndAddRequiredProfilesIfNecessary();
+
+
// Mappings from name (for instance, codec name) to enum value
static const NameToTagMap sVideoEncoderNameMap[];
static const NameToTagMap sAudioEncoderNameMap[];
@@ -355,6 +408,20 @@
Vector<VideoDecoderCap*> mVideoDecoders;
Vector<output_format> mEncoderOutputFileFormats;
Vector<ImageEncodingQualityLevels *> mImageEncodingQualityLevels;
+
+ typedef struct {
+ bool mHasRefProfile; // Refers to an existing profile
+ int mRefProfileIndex; // Reference profile index
+ int mResolutionProduct; // width x height
+ } RequiredProfileRefInfo; // Required low and high profiles
+
+ typedef struct {
+ RequiredProfileRefInfo mRefs[kNumRequiredProfiles];
+ int mCameraId;
+ } RequiredProfiles;
+
+ RequiredProfiles *mRequiredProfileRefs;
+ Vector<int> mCameraIds;
};
}; // namespace android
diff --git a/include/media/stagefright/HardwareAPI.h b/include/media/stagefright/HardwareAPI.h
index 17908b4..d1ecaaf 100644
--- a/include/media/stagefright/HardwareAPI.h
+++ b/include/media/stagefright/HardwareAPI.h
@@ -87,6 +87,18 @@
const sp<android_native_buffer_t>& nativeBuffer;
};
+// A pointer to this struct is passed to OMX_GetParameter when the extension
+// index for the 'OMX.google.android.index.getAndroidNativeBufferUsage'
+// extension is given. The usage bits returned from this query will be used to
+// allocate the Gralloc buffers that get passed to the useAndroidNativeBuffer
+// command.
+struct GetAndroidNativeBufferUsageParams {
+ OMX_U32 nSize; // IN
+ OMX_VERSIONTYPE nVersion; // IN
+ OMX_U32 nPortIndex; // IN
+ OMX_U32 nUsage; // OUT
+};
+
} // namespace android
extern android::OMXPluginBase *createOMXPlugin();
diff --git a/include/private/surfaceflinger/SharedBufferStack.h b/include/private/surfaceflinger/SharedBufferStack.h
index eb599b5..717f837 100644
--- a/include/private/surfaceflinger/SharedBufferStack.h
+++ b/include/private/surfaceflinger/SharedBufferStack.h
@@ -65,7 +65,7 @@
// When changing these values, the COMPILE_TIME_ASSERT at the end of this
// file need to be updated.
static const unsigned int NUM_LAYERS_MAX = 31;
- static const unsigned int NUM_BUFFER_MAX = 16;
+ static const unsigned int NUM_BUFFER_MAX = 32;
static const unsigned int NUM_BUFFER_MIN = 2;
static const unsigned int NUM_DISPLAY_MAX = 4;
@@ -123,7 +123,7 @@
// ----------------------------------------------------------------------------
-// 32 KB max
+// 64 KB max
class SharedClient
{
public:
@@ -394,7 +394,7 @@
// ---------------------------------------------------------------------------
-COMPILE_TIME_ASSERT(sizeof(SharedClient) <= 32768)
+COMPILE_TIME_ASSERT(sizeof(SharedClient) <= 65536)
COMPILE_TIME_ASSERT(sizeof(surface_flinger_cblk_t) <= 4096)
// ---------------------------------------------------------------------------
diff --git a/include/surfaceflinger/Surface.h b/include/surfaceflinger/Surface.h
index d783caf..9e0b5bb 100644
--- a/include/surfaceflinger/Surface.h
+++ b/include/surfaceflinger/Surface.h
@@ -242,6 +242,10 @@
status_t validate(bool inCancelBuffer = false) const;
sp<ISurface> getISurface() const;
+ // When the buffer pool is a fixed size we want to make sure SurfaceFlinger
+ // won't stall clients, so we require an extra buffer.
+ enum { MIN_UNDEQUEUED_BUFFERS = 2 };
+
inline const GraphicBufferMapper& getBufferMapper() const { return mBufferMapper; }
inline GraphicBufferMapper& getBufferMapper() { return mBufferMapper; }
diff --git a/include/ui/egl/android_natives.h b/include/ui/egl/android_natives.h
index fdc8105..fd83f46 100644
--- a/include/ui/egl/android_natives.h
+++ b/include/ui/egl/android_natives.h
@@ -75,6 +75,26 @@
NATIVE_WINDOW_WIDTH = 0,
NATIVE_WINDOW_HEIGHT,
NATIVE_WINDOW_FORMAT,
+
+ /* The minimum number of buffers that must remain un-dequeued after a buffer
+ * has been queued. This value applies only if set_buffer_count was used to
+ * override the number of buffers and if a buffer has since been queued.
+ * Users of the set_buffer_count ANativeWindow method should query this
+ * value before calling set_buffer_count. If it is necessary to have N
+ * buffers simultaneously dequeued as part of the steady-state operation,
+ * and this query returns M then N+M buffers should be requested via
+ * native_window_set_buffer_count.
+ *
+ * Note that this value does NOT apply until a single buffer has been
+ * queued. In particular this means that it is possible to:
+ *
+ * 1. Query M = min undequeued buffers
+ * 2. Set the buffer count to N + M
+ * 3. Dequeue all N + M buffers
+ * 4. Cancel M buffers
+ * 5. Queue, dequeue, queue, dequeue, ad infinitum
+ */
+ NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
};
/* valid operations for the (*perform)() hook */
diff --git a/libs/gui/SurfaceTexture.cpp b/libs/gui/SurfaceTexture.cpp
index 223cf09..3bed959 100644
--- a/libs/gui/SurfaceTexture.cpp
+++ b/libs/gui/SurfaceTexture.cpp
@@ -96,6 +96,11 @@
status_t SurfaceTexture::setBufferCount(int bufferCount) {
LOGV("SurfaceTexture::setBufferCount");
+
+ if (bufferCount < MIN_BUFFER_SLOTS) {
+ return BAD_VALUE;
+ }
+
Mutex::Autolock lock(mMutex);
freeAllBuffers();
mBufferCount = bufferCount;
diff --git a/libs/gui/SurfaceTextureClient.cpp b/libs/gui/SurfaceTextureClient.cpp
index ee14ac9..43b330c 100644
--- a/libs/gui/SurfaceTextureClient.cpp
+++ b/libs/gui/SurfaceTextureClient.cpp
@@ -143,8 +143,21 @@
int SurfaceTextureClient::query(int what, int* value) {
LOGV("SurfaceTextureClient::query");
Mutex::Autolock lock(mMutex);
- // XXX: Implement this!
- return INVALID_OPERATION;
+ switch (what) {
+ case NATIVE_WINDOW_WIDTH:
+ case NATIVE_WINDOW_HEIGHT:
+ // XXX: How should SurfaceTexture behave if setBuffersGeometry didn't
+ // override the size?
+ *value = 0;
+ return NO_ERROR;
+ case NATIVE_WINDOW_FORMAT:
+ *value = DEFAULT_FORMAT;
+ return NO_ERROR;
+ case NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS:
+ *value = MIN_UNDEQUEUED_BUFFERS;
+ return NO_ERROR;
+ }
+ return BAD_VALUE;
}
int SurfaceTextureClient::perform(int operation, va_list args)
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index 48b3d6e..361815a 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -213,6 +213,17 @@
if (mDirtyClip) {
setScissorFromClip();
}
+
+#if RENDER_LAYERS_AS_REGIONS
+ // Since we don't know what the functor will draw, let's dirty
+ // tne entire clip region
+ if (hasLayer()) {
+ Rect clip(*mSnapshot->clipRect);
+ clip.snapToPixelBoundaries();
+ dirtyLayerUnchecked(clip, getRegion());
+ }
+#endif
+
status_t result = (*functor)();
resume();
return (result == 0) ? false : true;
diff --git a/libs/hwui/TextDropShadowCache.cpp b/libs/hwui/TextDropShadowCache.cpp
index 3256790..8f6f860 100644
--- a/libs/hwui/TextDropShadowCache.cpp
+++ b/libs/hwui/TextDropShadowCache.cpp
@@ -147,6 +147,9 @@
if (mDebugEnabled) {
LOGD("Shadow texture created, size = %d", texture->bitmapSize);
}
+
+ entry.copyTextLocally();
+
mSize += size;
mCache.put(entry, texture);
} else {
diff --git a/libs/hwui/TextDropShadowCache.h b/libs/hwui/TextDropShadowCache.h
index 1e065d1..62c4250 100644
--- a/libs/hwui/TextDropShadowCache.h
+++ b/libs/hwui/TextDropShadowCache.h
@@ -21,7 +21,7 @@
#include <SkPaint.h>
-#include <utils/String8.h>
+#include <utils/String16.h>
#include "utils/Compare.h"
#include "utils/GenerationCache.h"
@@ -37,18 +37,13 @@
ShadowText(SkPaint* paint, uint32_t radius, uint32_t len, const char* srcText):
radius(radius), len(len) {
- // The source text we receive is in UTF-16, convert to UTF-8
- str.setTo((const char16_t*) srcText, len >> 1);
+ // TODO: Propagate this through the API, we should not cast here
+ text = (const char16_t*) srcText;
textSize = paint->getTextSize();
typeface = paint->getTypeface();
}
- ShadowText(const ShadowText& shadow):
- radius(shadow.radius), len(shadow.len), textSize(shadow.textSize),
- typeface(shadow.typeface), str(shadow.str) {
- }
-
~ShadowText() {
}
@@ -56,16 +51,21 @@
uint32_t len;
float textSize;
SkTypeface* typeface;
- String8 str;
+ const char16_t* text;
+ String16 str;
+
+ void copyTextLocally() {
+ str.setTo((const char16_t*) text, len >> 1);
+ text = str.string();
+ }
// TODO: Should take into account fake bold and text skew
bool operator<(const ShadowText& rhs) const {
LTE_INT(len) {
LTE_INT(radius) {
LTE_FLOAT(textSize) {
- if (typeface < rhs.typeface) return true;
- else if (typeface == rhs.typeface) {
- return str.compare(rhs.str) < 0;
+ LTE_INT(typeface) {
+ return strncmp16(text, rhs.text, len >> 1) < 0;
}
}
}
diff --git a/libs/surfaceflinger_client/Surface.cpp b/libs/surfaceflinger_client/Surface.cpp
index 68611d6..818114a 100644
--- a/libs/surfaceflinger_client/Surface.cpp
+++ b/libs/surfaceflinger_client/Surface.cpp
@@ -709,6 +709,9 @@
case NATIVE_WINDOW_FORMAT:
*value = int(mFormat);
return NO_ERROR;
+ case NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS:
+ *value = MIN_UNDEQUEUED_BUFFERS;
+ return NO_ERROR;
}
return BAD_VALUE;
}
diff --git a/libs/usb/src/com/google/android/usb/UsbAccessory.java b/libs/usb/src/com/google/android/usb/UsbAccessory.java
index 91095f3..931f42e 100644
--- a/libs/usb/src/com/google/android/usb/UsbAccessory.java
+++ b/libs/usb/src/com/google/android/usb/UsbAccessory.java
@@ -26,7 +26,7 @@
private final String mType;
private final String mVersion;
- /* package */ UsbAccessory(android.hardware.UsbAccessory accessory) {
+ /* package */ UsbAccessory(android.hardware.usb.UsbAccessory accessory) {
mManufacturer = accessory.getManufacturer();
mModel = accessory.getModel();
mType = accessory.getType();
diff --git a/libs/usb/src/com/google/android/usb/UsbManager.java b/libs/usb/src/com/google/android/usb/UsbManager.java
index 1b9bff9..d7afb95 100644
--- a/libs/usb/src/com/google/android/usb/UsbManager.java
+++ b/libs/usb/src/com/google/android/usb/UsbManager.java
@@ -19,7 +19,7 @@
import android.content.Context;
import android.content.Intent;
-import android.hardware.IUsbManager;
+import android.hardware.usb.IUsbManager;
import android.os.IBinder;
import android.os.ParcelFileDescriptor;
import android.os.RemoteException;
@@ -43,7 +43,7 @@
* {@link com.google.android.usb.UsbAccessory} for the attached accessory.
*/
public static final String ACTION_USB_ACCESSORY_ATTACHED =
- "android.hardware.action.USB_ACCESSORY_ATTACHED";
+ "android.hardware.usb.action.USB_ACCESSORY_ATTACHED";
/**
* Broadcast Action: A broadcast for USB accessory detached event.
@@ -53,7 +53,7 @@
* {@link com.google.android.usb.UsbAccessory} for the attached accessory that was detached.
*/
public static final String ACTION_USB_ACCESSORY_DETACHED =
- "android.hardware.action.USB_ACCESSORY_DETACHED";
+ "android.hardware.usb.action.USB_ACCESSORY_DETACHED";
private final IUsbManager mService;
@@ -79,8 +79,8 @@
* @return UsbAccessory for the broadcast.
*/
public static UsbAccessory getAccessory(Intent intent) {
- android.hardware.UsbAccessory accessory =
- intent.getParcelableExtra(android.hardware.UsbManager.EXTRA_ACCESSORY);
+ android.hardware.usb.UsbAccessory accessory =
+ intent.getParcelableExtra(android.hardware.usb.UsbManager.EXTRA_ACCESSORY);
if (accessory == null) {
return null;
} else {
@@ -96,7 +96,7 @@
*/
public UsbAccessory[] getAccessoryList() {
try {
- android.hardware.UsbAccessory accessory = mService.getCurrentAccessory();
+ android.hardware.usb.UsbAccessory accessory = mService.getCurrentAccessory();
if (accessory == null) {
return null;
} else {
@@ -116,7 +116,7 @@
*/
public ParcelFileDescriptor openAccessory(UsbAccessory accessory) {
try {
- return mService.openAccessory(new android.hardware.UsbAccessory(
+ return mService.openAccessory(new android.hardware.usb.UsbAccessory(
accessory.getManufacturer(),accessory.getModel(),
accessory.getType(), accessory.getVersion()));
} catch (RemoteException e) {
diff --git a/libs/usb/tests/AccessoryChat/AndroidManifest.xml b/libs/usb/tests/AccessoryChat/AndroidManifest.xml
index b63999c..5922421 100644
--- a/libs/usb/tests/AccessoryChat/AndroidManifest.xml
+++ b/libs/usb/tests/AccessoryChat/AndroidManifest.xml
@@ -12,10 +12,10 @@
</intent-filter>
<intent-filter>
- <action android:name="android.hardware.action.USB_ACCESSORY_ATTACHED" />
+ <action android:name="android.hardware.usb.action.USB_ACCESSORY_ATTACHED" />
</intent-filter>
- <meta-data android:name="android.hardware.action.USB_ACCESSORY_ATTACHED"
+ <meta-data android:name="android.hardware.usb.action.USB_ACCESSORY_ATTACHED"
android:resource="@xml/accessory_filter" />
</activity>
</application>
diff --git a/media/java/android/mtp/MtpClient.java b/media/java/android/mtp/MtpClient.java
index a5ee77c..6c8b228 100644
--- a/media/java/android/mtp/MtpClient.java
+++ b/media/java/android/mtp/MtpClient.java
@@ -20,10 +20,10 @@
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
-import android.hardware.UsbConstants;
-import android.hardware.UsbDevice;
-import android.hardware.UsbInterface;
-import android.hardware.UsbManager;
+import android.hardware.usb.UsbConstants;
+import android.hardware.usb.UsbDevice;
+import android.hardware.usb.UsbInterface;
+import android.hardware.usb.UsbManager;
import android.os.ParcelFileDescriptor;
import android.util.Log;
@@ -95,7 +95,7 @@
}
/**
- * Tests to see if a {@link android.hardware.UsbDevice}
+ * Tests to see if a {@link android.hardware.usb.UsbDevice}
* supports the PTP protocol (typically used by digital cameras)
*
* @param device the device to test
@@ -140,7 +140,7 @@
}
/**
- * Opens the {@link android.hardware.UsbDevice} for an MTP or PTP
+ * Opens the {@link android.hardware.usb.UsbDevice} for an MTP or PTP
* device and return an {@link android.mtp.MtpDevice} for it.
*
* @param device the device to open
diff --git a/media/java/android/mtp/MtpDevice.java b/media/java/android/mtp/MtpDevice.java
index 78b2253..22961d7f 100644
--- a/media/java/android/mtp/MtpDevice.java
+++ b/media/java/android/mtp/MtpDevice.java
@@ -16,8 +16,8 @@
package android.mtp;
-import android.hardware.UsbDevice;
-import android.hardware.UsbManager;
+import android.hardware.usb.UsbDevice;
+import android.hardware.usb.UsbManager;
import android.os.ParcelFileDescriptor;
import android.util.Log;
@@ -37,7 +37,7 @@
/**
* MtpClient constructor
*
- * @param device the {@link android.hardware.UsbDevice} for the MTP or PTP device
+ * @param device the {@link android.hardware.usb.UsbDevice} for the MTP or PTP device
*/
public MtpDevice(UsbDevice device) {
mDevice = device;
@@ -46,7 +46,7 @@
/**
* Opens the MTP or PTP device and return an {@link android.mtp.MtpDevice} for it.
*
- * @param manager reference to {@link android.hardware.UsbManager}
+ * @param manager reference to {@link android.hardware.usb.UsbManager}
* @return true if the device was successfully opened.
*/
public boolean open(UsbManager manager) {
diff --git a/media/jni/mediaeditor/VideoEditorMain.cpp b/media/jni/mediaeditor/VideoEditorMain.cpp
index 9fe0266..8cda14e 100755
--- a/media/jni/mediaeditor/VideoEditorMain.cpp
+++ b/media/jni/mediaeditor/VideoEditorMain.cpp
@@ -453,7 +453,11 @@
case MSG_TYPE_OVERLAY_CLEAR:
isSendProgress = false;
- pContext->mOverlayFileName = NULL;
+ if (pContext->mOverlayFileName != NULL) {
+ M4OSA_free((M4OSA_MemAddr32)pContext->mOverlayFileName);
+ pContext->mOverlayFileName = NULL;
+ }
+
LOGV("MSG_TYPE_OVERLAY_CLEAR");
//argc is not used
pContext->mIsUpdateOverlay = true;
@@ -1760,6 +1764,17 @@
VIDEOEDIT_LOG_EDIT_SETTINGS(pContext->pEditSettings);
}
}
+ /* free previous allocations , if any */
+ if (pContext->mAudioSettings != M4OSA_NULL) {
+ if (pContext->mAudioSettings->pFile != NULL) {
+ M4OSA_free((M4OSA_MemAddr32)pContext->mAudioSettings->pFile);
+ pContext->mAudioSettings->pFile = M4OSA_NULL;
+ }
+ if (pContext->mAudioSettings->pPCMFilePath != NULL) {
+ M4OSA_free((M4OSA_MemAddr32)pContext->mAudioSettings->pPCMFilePath);
+ pContext->mAudioSettings->pPCMFilePath = M4OSA_NULL;
+ }
+ }
if (audioSettingObject != M4OSA_NULL) {
jclass audioSettingClazz = pEnv->FindClass(AUDIO_SETTINGS_CLASS_NAME);
@@ -1823,16 +1838,6 @@
= pEnv->GetIntField(audioSettingObject,fid);
M4OSA_TRACE1_1("fileType = %d",pContext->mAudioSettings->fileType);
- /* free previous allocations , if any */
- if (pContext->mAudioSettings->pFile != NULL) {
- M4OSA_free((M4OSA_MemAddr32)pContext->mAudioSettings->pFile);
- pContext->mAudioSettings->pFile = M4OSA_NULL;
- }
- if (pContext->mAudioSettings->pPCMFilePath != NULL) {
- M4OSA_free((M4OSA_MemAddr32)pContext->mAudioSettings->pPCMFilePath);
- pContext->mAudioSettings->pPCMFilePath = M4OSA_NULL;
- }
-
fid = pEnv->GetFieldID(audioSettingClazz,"pFile","Ljava/lang/String;");
strPath = (jstring)pEnv->GetObjectField(audioSettingObject,fid);
pTempChar = (M4OSA_Char*)pEnv->GetStringUTFChars(strPath, M4OSA_NULL);
@@ -3044,18 +3049,18 @@
pContext->mPreviewController = M4OSA_NULL;
}
- if (pContext->mAudioSettings->pFile != NULL) {
- M4OSA_free((M4OSA_MemAddr32)pContext->mAudioSettings->pFile);
- pContext->mAudioSettings->pFile = M4OSA_NULL;
- }
- if (pContext->mAudioSettings->pPCMFilePath != NULL) {
- M4OSA_free((M4OSA_MemAddr32)pContext->mAudioSettings->pPCMFilePath);
- pContext->mAudioSettings->pPCMFilePath = M4OSA_NULL;
- }
-
- // Free the context.
+ // Free the mAudioSettings context.
if(pContext->mAudioSettings != M4OSA_NULL)
{
+ if (pContext->mAudioSettings->pFile != NULL) {
+ M4OSA_free((M4OSA_MemAddr32)pContext->mAudioSettings->pFile);
+ pContext->mAudioSettings->pFile = M4OSA_NULL;
+ }
+ if (pContext->mAudioSettings->pPCMFilePath != NULL) {
+ M4OSA_free((M4OSA_MemAddr32)pContext->mAudioSettings->pPCMFilePath);
+ pContext->mAudioSettings->pPCMFilePath = M4OSA_NULL;
+ }
+
M4OSA_free((M4OSA_MemAddr32)pContext->mAudioSettings);
pContext->mAudioSettings = M4OSA_NULL;
}
diff --git a/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp b/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp
index ebe3302..0b061db 100644
--- a/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp
+++ b/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp
@@ -53,6 +53,11 @@
namespace android {
namespace {
+// Flag to allow a one time init of global memory, only happens on first call ever
+int LvmInitFlag = LVM_FALSE;
+SessionContext GlobalSessionMemory[LVM_MAX_SESSIONS];
+int SessionIndex[LVM_MAX_SESSIONS];
+
/* local functions */
#define CHECK_ARG(cond) { \
if (!(cond)) { \
@@ -61,11 +66,6 @@
} \
}
-// Flag to allow a one time init of global memory, only happens on first call ever
-int LvmInitFlag = LVM_FALSE;
-SessionContext GlobalSessionMemory[LVM_MAX_SESSIONS];
-
-int SessionIndex[LVM_MAX_SESSIONS];
// NXP SW BassBoost UUID
const effect_descriptor_t gBassBoostDescriptor = {
@@ -2588,9 +2588,11 @@
pContext->pBundledContext->SamplesToExitCountBb -= outBuffer->frameCount * 2; // STEREO
//LOGV("\tEffect_process: Waiting to turn off BASS_BOOST, %d samples left",
// pContext->pBundledContext->SamplesToExitCountBb);
- } else {
+ }
+ if(pContext->pBundledContext->SamplesToExitCountBb <= 0) {
status = -ENODATA;
pContext->pBundledContext->NumberEffectsEnabled--;
+ LOGV("\tEffect_process() this is the last frame for LVM_BASS_BOOST");
}
}
if ((pContext->pBundledContext->bVolumeEnabled == LVM_FALSE)&&
@@ -2606,9 +2608,11 @@
pContext->pBundledContext->SamplesToExitCountEq -= outBuffer->frameCount * 2; // STEREO
//LOGV("\tEffect_process: Waiting to turn off EQUALIZER, %d samples left",
// pContext->pBundledContext->SamplesToExitCountEq);
- } else {
+ }
+ if(pContext->pBundledContext->SamplesToExitCountEq <= 0) {
status = -ENODATA;
pContext->pBundledContext->NumberEffectsEnabled--;
+ LOGV("\tEffect_process() this is the last frame for LVM_EQUALIZER");
}
}
if ((pContext->pBundledContext->bVirtualizerEnabled == LVM_FALSE)&&
@@ -2618,9 +2622,11 @@
pContext->pBundledContext->SamplesToExitCountVirt -= outBuffer->frameCount * 2;// STEREO
//LOGV("\tEffect_process: Waiting for to turn off VIRTUALIZER, %d samples left",
// pContext->pBundledContext->SamplesToExitCountVirt);
- } else {
+ }
+ if(pContext->pBundledContext->SamplesToExitCountVirt <= 0) {
status = -ENODATA;
pContext->pBundledContext->NumberEffectsEnabled--;
+ LOGV("\tEffect_process() this is the last frame for LVM_VIRTUALIZER");
}
}
diff --git a/media/libmedia/IOMX.cpp b/media/libmedia/IOMX.cpp
index af67175..d6a1757 100644
--- a/media/libmedia/IOMX.cpp
+++ b/media/libmedia/IOMX.cpp
@@ -33,6 +33,7 @@
EMPTY_BUFFER,
GET_EXTENSION_INDEX,
OBSERVER_ON_MSG,
+ GET_GRAPHIC_BUFFER_USAGE,
};
class BpOMX : public BpInterface<IOMX> {
@@ -194,6 +195,19 @@
return err;
}
+ virtual status_t getGraphicBufferUsage(
+ node_id node, OMX_U32 port_index, OMX_U32* usage) {
+ Parcel data, reply;
+ data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
+ data.writeIntPtr((intptr_t)node);
+ data.writeInt32(port_index);
+ remote()->transact(GET_GRAPHIC_BUFFER_USAGE, data, &reply);
+
+ status_t err = reply.readInt32();
+ *usage = reply.readInt32();
+ return err;
+ }
+
virtual status_t useBuffer(
node_id node, OMX_U32 port_index, const sp<IMemory> ¶ms,
buffer_id *buffer) {
@@ -508,6 +522,21 @@
return NO_ERROR;
}
+ case GET_GRAPHIC_BUFFER_USAGE:
+ {
+ CHECK_INTERFACE(IOMX, data, reply);
+
+ node_id node = (void*)data.readIntPtr();
+ OMX_U32 port_index = data.readInt32();
+
+ OMX_U32 usage = 0;
+ status_t err = getGraphicBufferUsage(node, port_index, &usage);
+ reply->writeInt32(err);
+ reply->writeInt32(usage);
+
+ return NO_ERROR;
+ }
+
case USE_BUFFER:
{
CHECK_INTERFACE(IOMX, data, reply);
diff --git a/media/libmedia/MediaProfiles.cpp b/media/libmedia/MediaProfiles.cpp
index 9ad63f0..7fb7aed 100644
--- a/media/libmedia/MediaProfiles.cpp
+++ b/media/libmedia/MediaProfiles.cpp
@@ -284,8 +284,17 @@
return static_cast<output_format>(format);
}
+static bool isCameraIdFound(int cameraId, const Vector<int>& cameraIds) {
+ for (int i = 0, n = cameraIds.size(); i < n; ++i) {
+ if (cameraId == cameraIds[i]) {
+ return true;
+ }
+ }
+ return false;
+}
+
/*static*/ MediaProfiles::CamcorderProfile*
-MediaProfiles::createCamcorderProfile(int cameraId, const char **atts)
+MediaProfiles::createCamcorderProfile(int cameraId, const char **atts, Vector<int>& cameraIds)
{
CHECK(!strcmp("quality", atts[0]) &&
!strcmp("fileFormat", atts[2]) &&
@@ -301,6 +310,9 @@
MediaProfiles::CamcorderProfile *profile = new MediaProfiles::CamcorderProfile;
profile->mCameraId = cameraId;
+ if (!isCameraIdFound(cameraId, cameraIds)) {
+ cameraIds.add(cameraId);
+ }
profile->mFileFormat = static_cast<output_format>(fileFormat);
profile->mQuality = static_cast<camcorder_quality>(quality);
profile->mDuration = atoi(atts[5]);
@@ -370,12 +382,167 @@
profiles->mCurrentCameraId = getCameraId(atts);
} else if (strcmp("EncoderProfile", name) == 0) {
profiles->mCamcorderProfiles.add(
- createCamcorderProfile(profiles->mCurrentCameraId, atts));
+ createCamcorderProfile(profiles->mCurrentCameraId, atts, profiles->mCameraIds));
} else if (strcmp("ImageEncoding", name) == 0) {
profiles->addImageEncodingQualityLevel(profiles->mCurrentCameraId, atts);
}
}
+static bool isCamcorderProfile(camcorder_quality quality) {
+ return quality >= CAMCORDER_QUALITY_LIST_START &&
+ quality <= CAMCORDER_QUALITY_LIST_END;
+}
+
+static bool isTimelapseProfile(camcorder_quality quality) {
+ return quality >= CAMCORDER_QUALITY_TIME_LAPSE_LIST_START &&
+ quality <= CAMCORDER_QUALITY_TIME_LAPSE_LIST_END;
+}
+
+void MediaProfiles::initRequiredProfileRefs(const Vector<int>& cameraIds) {
+ LOGV("Number of camera ids: %d", cameraIds.size());
+ CHECK(cameraIds.size() > 0);
+ mRequiredProfileRefs = new RequiredProfiles[cameraIds.size()];
+ for (size_t i = 0, n = cameraIds.size(); i < n; ++i) {
+ mRequiredProfileRefs[i].mCameraId = cameraIds[i];
+ for (size_t j = 0; j < kNumRequiredProfiles; ++j) {
+ mRequiredProfileRefs[i].mRefs[j].mHasRefProfile = false;
+ mRequiredProfileRefs[i].mRefs[j].mRefProfileIndex = -1;
+ if ((j & 1) == 0) { // low resolution
+ mRequiredProfileRefs[i].mRefs[j].mResolutionProduct = 0x7FFFFFFF;
+ } else { // high resolution
+ mRequiredProfileRefs[i].mRefs[j].mResolutionProduct = 0;
+ }
+ }
+ }
+}
+
+int MediaProfiles::getRequiredProfileRefIndex(int cameraId) {
+ for (size_t i = 0, n = mCameraIds.size(); i < n; ++i) {
+ if (mCameraIds[i] == cameraId) {
+ return i;
+ }
+ }
+ return -1;
+}
+
+void MediaProfiles::checkAndAddRequiredProfilesIfNecessary() {
+ if (sIsInitialized) {
+ return;
+ }
+
+ initRequiredProfileRefs(mCameraIds);
+
+ for (size_t i = 0, n = mCamcorderProfiles.size(); i < n; ++i) {
+ int product = mCamcorderProfiles[i]->mVideoCodec->mFrameWidth *
+ mCamcorderProfiles[i]->mVideoCodec->mFrameHeight;
+
+ camcorder_quality quality = mCamcorderProfiles[i]->mQuality;
+ int cameraId = mCamcorderProfiles[i]->mCameraId;
+ int index = -1;
+ int refIndex = getRequiredProfileRefIndex(cameraId);
+ CHECK(refIndex != -1);
+ RequiredProfileRefInfo *info;
+ camcorder_quality refQuality;
+ VideoCodec *codec = NULL;
+
+ // Check high and low from either camcorder profile or timelapse profile
+ // but not both. Default, check camcorder profile
+ size_t j = 0;
+ size_t n = 2;
+ if (isTimelapseProfile(quality)) {
+ // Check timelapse profile instead.
+ j = 2;
+ n = kNumRequiredProfiles;
+ } else {
+ // Must be camcorder profile.
+ CHECK(isCamcorderProfile(quality));
+ }
+ for (; j < n; ++j) {
+ info = &(mRequiredProfileRefs[refIndex].mRefs[j]);
+ if ((j % 2 == 0 && product > info->mResolutionProduct) || // low
+ (j % 2 != 0 && product < info->mResolutionProduct)) { // high
+ continue;
+ }
+ switch (j) {
+ case 0:
+ refQuality = CAMCORDER_QUALITY_LOW;
+ break;
+ case 1:
+ refQuality = CAMCORDER_QUALITY_HIGH;
+ break;
+ case 2:
+ refQuality = CAMCORDER_QUALITY_TIME_LAPSE_LOW;
+ break;
+ case 3:
+ refQuality = CAMCORDER_QUALITY_TIME_LAPSE_HIGH;
+ break;
+ default:
+ CHECK(!"Should never reach here");
+ }
+
+ if (!info->mHasRefProfile) {
+ index = getCamcorderProfileIndex(cameraId, refQuality);
+ }
+ if (index == -1) {
+ // New high or low quality profile is found.
+ // Update its reference.
+ info->mHasRefProfile = true;
+ info->mRefProfileIndex = i;
+ info->mResolutionProduct = product;
+ }
+ }
+ }
+
+ for (size_t cameraId = 0; cameraId < mCameraIds.size(); ++cameraId) {
+ for (size_t j = 0; j < kNumRequiredProfiles; ++j) {
+ int refIndex = getRequiredProfileRefIndex(cameraId);
+ CHECK(refIndex != -1);
+ RequiredProfileRefInfo *info =
+ &mRequiredProfileRefs[refIndex].mRefs[j];
+
+ if (info->mHasRefProfile) {
+
+ CamcorderProfile *profile =
+ new CamcorderProfile(
+ *mCamcorderProfiles[info->mRefProfileIndex]);
+
+ // Overwrite the quality
+ switch (j % kNumRequiredProfiles) {
+ case 0:
+ profile->mQuality = CAMCORDER_QUALITY_LOW;
+ break;
+ case 1:
+ profile->mQuality = CAMCORDER_QUALITY_HIGH;
+ break;
+ case 2:
+ profile->mQuality = CAMCORDER_QUALITY_TIME_LAPSE_LOW;
+ break;
+ case 3:
+ profile->mQuality = CAMCORDER_QUALITY_TIME_LAPSE_HIGH;
+ break;
+ default:
+ CHECK(!"Should never come here");
+ }
+
+ int index = getCamcorderProfileIndex(cameraId, profile->mQuality);
+ if (index != -1) {
+ LOGV("Profile quality %d for camera %d already exists",
+ profile->mQuality, cameraId);
+ CHECK(index == refIndex);
+ continue;
+ }
+
+ // Insert the new profile
+ LOGV("Add a profile: quality %d=>%d for camera %d",
+ mCamcorderProfiles[info->mRefProfileIndex]->mQuality,
+ profile->mQuality, cameraId);
+
+ mCamcorderProfiles.add(profile);
+ }
+ }
+ }
+}
+
/*static*/ MediaProfiles*
MediaProfiles::getInstance()
{
@@ -396,6 +563,9 @@
} else {
sInstance = createInstanceFromXmlFile(value);
}
+ CHECK(sInstance != NULL);
+ sInstance->checkAndAddRequiredProfilesIfNecessary();
+ sIsInitialized = true;
}
return sInstance;
@@ -613,7 +783,6 @@
createDefaultAudioDecoders(profiles);
createDefaultEncoderOutputFileFormats(profiles);
createDefaultImageEncodingQualityLevels(profiles);
- sIsInitialized = true;
return profiles;
}
@@ -667,9 +836,6 @@
exit:
::XML_ParserFree(parser);
::fclose(fp);
- if (profiles) {
- sIsInitialized = true;
- }
return profiles;
}
diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp
index b0ae3d8..e43cdaa 100644
--- a/media/libstagefright/ACodec.cpp
+++ b/media/libstagefright/ACodec.cpp
@@ -440,10 +440,17 @@
}
// Set up the native window.
- // XXX TODO: Get the gralloc usage flags from the OMX plugin!
+ OMX_U32 usage = 0;
+ err = mOMX->getGraphicBufferUsage(mNode, kPortIndexOutput, &usage);
+ if (err != 0) {
+ LOGW("querying usage flags from OMX IL component failed: %d", err);
+ // XXX: Currently this error is logged, but not fatal.
+ usage = 0;
+ }
+
err = native_window_set_usage(
mNativeWindow.get(),
- GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_EXTERNAL_DISP);
+ usage | GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_EXTERNAL_DISP);
if (err != 0) {
LOGE("native_window_set_usage failed: %s (%d)", strerror(-err), -err);
@@ -459,16 +466,12 @@
return err;
}
- // XXX TODO: Do something so the ANativeWindow knows that we'll need to get
- // the same set of buffers.
-
LOGV("[%s] Allocating %lu buffers from a native window of size %lu on "
"output port",
mComponentName.c_str(), def.nBufferCountActual, def.nBufferSize);
// Dequeue buffers and send them to OMX
- OMX_U32 i;
- for (i = 0; i < def.nBufferCountActual; i++) {
+ for (OMX_U32 i = 0; i < def.nBufferCountActual; i++) {
android_native_buffer_t *buf;
err = mNativeWindow->dequeueBuffer(mNativeWindow.get(), &buf);
if (err != 0) {
@@ -477,23 +480,26 @@
}
sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(buf, false));
- IOMX::buffer_id bufferId;
- err = mOMX->useGraphicBuffer(mNode, kPortIndexOutput, graphicBuffer,
- &bufferId);
- if (err != 0) {
- break;
- }
-
- LOGV("[%s] Registered graphic buffer with ID %p (pointer = %p)",
- mComponentName.c_str(),
- bufferId, graphicBuffer.get());
-
BufferInfo info;
- info.mBufferID = bufferId;
info.mStatus = BufferInfo::OWNED_BY_US;
info.mData = new ABuffer(0);
info.mGraphicBuffer = graphicBuffer;
mBuffers[kPortIndexOutput].push(info);
+
+ IOMX::buffer_id bufferId;
+ err = mOMX->useGraphicBuffer(mNode, kPortIndexOutput, graphicBuffer,
+ &bufferId);
+ if (err != 0) {
+ LOGE("registering GraphicBuffer %lu with OMX IL component failed: "
+ "%d", i, err);
+ break;
+ }
+
+ mBuffers[kPortIndexOutput].editItemAt(i).mBufferID = bufferId;
+
+ LOGV("[%s] Registered graphic buffer with ID %p (pointer = %p)",
+ mComponentName.c_str(),
+ bufferId, graphicBuffer.get());
}
OMX_U32 cancelStart;
@@ -503,7 +509,7 @@
// If an error occurred while dequeuing we need to cancel any buffers
// that were dequeued.
cancelStart = 0;
- cancelEnd = i;
+ cancelEnd = mBuffers[kPortIndexOutput].size();
} else {
// Return the last two buffers to the native window.
// XXX TODO: The number of buffers the native window owns should
@@ -2286,4 +2292,3 @@
}
} // namespace android
-
diff --git a/media/libstagefright/OMXCodec.cpp b/media/libstagefright/OMXCodec.cpp
index 5d502e7..5f40893 100644
--- a/media/libstagefright/OMXCodec.cpp
+++ b/media/libstagefright/OMXCodec.cpp
@@ -1753,9 +1753,16 @@
}
// Set up the native window.
- // XXX TODO: Get the gralloc usage flags from the OMX plugin!
+ OMX_U32 usage = 0;
+ err = mOMX->getGraphicBufferUsage(mNode, kPortIndexOutput, &usage);
+ if (err != 0) {
+ LOGW("querying usage flags from OMX IL component failed: %d", err);
+ // XXX: Currently this error is logged, but not fatal.
+ usage = 0;
+ }
+
err = native_window_set_usage(
- mNativeWindow.get(), GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_EXTERNAL_DISP);
+ mNativeWindow.get(), usage | GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_EXTERNAL_DISP);
if (err != 0) {
LOGE("native_window_set_usage failed: %s (%d)", strerror(-err), -err);
return err;
@@ -1769,15 +1776,11 @@
return err;
}
- // XXX TODO: Do something so the ANativeWindow knows that we'll need to get
- // the same set of buffers.
-
CODEC_LOGI("allocating %lu buffers from a native window of size %lu on "
"output port", def.nBufferCountActual, def.nBufferSize);
// Dequeue buffers and send them to OMX
- OMX_U32 i;
- for (i = 0; i < def.nBufferCountActual; i++) {
+ for (OMX_U32 i = 0; i < def.nBufferCountActual; i++) {
android_native_buffer_t* buf;
err = mNativeWindow->dequeueBuffer(mNativeWindow.get(), &buf);
if (err != 0) {
@@ -1786,36 +1789,37 @@
}
sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(buf, false));
- IOMX::buffer_id bufferId;
- err = mOMX->useGraphicBuffer(mNode, kPortIndexOutput, graphicBuffer,
- &bufferId);
- if (err != 0) {
- break;
- }
-
- CODEC_LOGV("registered graphic buffer with ID %p (pointer = %p)",
- bufferId, graphicBuffer.get());
-
BufferInfo info;
info.mData = NULL;
info.mSize = def.nBufferSize;
- info.mBuffer = bufferId;
info.mStatus = OWNED_BY_US;
info.mMem = NULL;
info.mMediaBuffer = new MediaBuffer(graphicBuffer);
info.mMediaBuffer->setObserver(this);
-
mPortBuffers[kPortIndexOutput].push(info);
+
+ IOMX::buffer_id bufferId;
+ err = mOMX->useGraphicBuffer(mNode, kPortIndexOutput, graphicBuffer,
+ &bufferId);
+ if (err != 0) {
+ CODEC_LOGE("registering GraphicBuffer with OMX IL component "
+ "failed: %d", err);
+ break;
+ }
+
+ mPortBuffers[kPortIndexOutput].editItemAt(i).mBuffer = bufferId;
+
+ CODEC_LOGV("registered graphic buffer with ID %p (pointer = %p)",
+ bufferId, graphicBuffer.get());
}
OMX_U32 cancelStart;
OMX_U32 cancelEnd;
-
if (err != 0) {
// If an error occurred while dequeuing we need to cancel any buffers
// that were dequeued.
cancelStart = 0;
- cancelEnd = i;
+ cancelEnd = mPortBuffers[kPortIndexOutput].size();
} else {
// Return the last two buffers to the native window.
// XXX TODO: The number of buffers the native window owns should probably be
diff --git a/media/libstagefright/include/OMX.h b/media/libstagefright/include/OMX.h
index 5fed98a..ec3e5fa 100644
--- a/media/libstagefright/include/OMX.h
+++ b/media/libstagefright/include/OMX.h
@@ -62,6 +62,9 @@
virtual status_t enableGraphicBuffers(
node_id node, OMX_U32 port_index, OMX_BOOL enable);
+ virtual status_t getGraphicBufferUsage(
+ node_id node, OMX_U32 port_index, OMX_U32* usage);
+
virtual status_t storeMetaDataInBuffers(
node_id node, OMX_U32 port_index, OMX_BOOL enable);
diff --git a/media/libstagefright/include/OMXNodeInstance.h b/media/libstagefright/include/OMXNodeInstance.h
index 86c102c..ca2578f 100644
--- a/media/libstagefright/include/OMXNodeInstance.h
+++ b/media/libstagefright/include/OMXNodeInstance.h
@@ -50,6 +50,9 @@
status_t setConfig(OMX_INDEXTYPE index, const void *params, size_t size);
status_t enableGraphicBuffers(OMX_U32 portIndex, OMX_BOOL enable);
+
+ status_t getGraphicBufferUsage(OMX_U32 portIndex, OMX_U32* usage);
+
status_t storeMetaDataInBuffers(OMX_U32 portIndex, OMX_BOOL enable);
status_t useBuffer(
diff --git a/media/libstagefright/omx/OMX.cpp b/media/libstagefright/omx/OMX.cpp
index 3638f41..4b1c3a7 100644
--- a/media/libstagefright/omx/OMX.cpp
+++ b/media/libstagefright/omx/OMX.cpp
@@ -297,6 +297,11 @@
return findInstance(node)->enableGraphicBuffers(port_index, enable);
}
+status_t OMX::getGraphicBufferUsage(
+ node_id node, OMX_U32 port_index, OMX_U32* usage) {
+ return findInstance(node)->getGraphicBufferUsage(port_index, usage);
+}
+
status_t OMX::storeMetaDataInBuffers(
node_id node, OMX_U32 port_index, OMX_BOOL enable) {
return findInstance(node)->storeMetaDataInBuffers(port_index, enable);
diff --git a/media/libstagefright/omx/OMXNodeInstance.cpp b/media/libstagefright/omx/OMXNodeInstance.cpp
index c7c1409..6cbd599 100644
--- a/media/libstagefright/omx/OMXNodeInstance.cpp
+++ b/media/libstagefright/omx/OMXNodeInstance.cpp
@@ -302,6 +302,45 @@
return OK;
}
+status_t OMXNodeInstance::getGraphicBufferUsage(
+ OMX_U32 portIndex, OMX_U32* usage) {
+ Mutex::Autolock autoLock(mLock);
+
+ OMX_INDEXTYPE index;
+ OMX_ERRORTYPE err = OMX_GetExtensionIndex(
+ mHandle,
+ const_cast<OMX_STRING>(
+ "OMX.google.android.index.getAndroidNativeBufferUsage"),
+ &index);
+
+ if (err != OMX_ErrorNone) {
+ LOGE("OMX_GetExtensionIndex failed");
+
+ return StatusFromOMXError(err);
+ }
+
+ OMX_VERSIONTYPE ver;
+ ver.s.nVersionMajor = 1;
+ ver.s.nVersionMinor = 0;
+ ver.s.nRevision = 0;
+ ver.s.nStep = 0;
+ GetAndroidNativeBufferUsageParams params = {
+ sizeof(GetAndroidNativeBufferUsageParams), ver, portIndex, 0,
+ };
+
+ err = OMX_GetParameter(mHandle, index, ¶ms);
+
+ if (err != OMX_ErrorNone) {
+ LOGE("OMX_GetAndroidNativeBufferUsage failed with error %d (0x%08x)",
+ err, err);
+ return UNKNOWN_ERROR;
+ }
+
+ *usage = params.nUsage;
+
+ return OK;
+}
+
status_t OMXNodeInstance::storeMetaDataInBuffers(
OMX_U32 portIndex,
OMX_BOOL enable) {
diff --git a/media/tests/CameraBrowser/AndroidManifest.xml b/media/tests/CameraBrowser/AndroidManifest.xml
index fccb3ca..c35d12a 100644
--- a/media/tests/CameraBrowser/AndroidManifest.xml
+++ b/media/tests/CameraBrowser/AndroidManifest.xml
@@ -12,9 +12,9 @@
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
- <action android:name="android.hardware.action.USB_DEVICE_ATTACHED" />
+ <action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" />
</intent-filter>
- <meta-data android:name="android.hardware.action.USB_DEVICE_ATTACHED"
+ <meta-data android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED"
android:resource="@xml/device_filter" />
</activity>
diff --git a/media/tests/CameraBrowser/src/com/android/camerabrowser/DeviceDisconnectedReceiver.java b/media/tests/CameraBrowser/src/com/android/camerabrowser/DeviceDisconnectedReceiver.java
index 1155807..00222a6 100644
--- a/media/tests/CameraBrowser/src/com/android/camerabrowser/DeviceDisconnectedReceiver.java
+++ b/media/tests/CameraBrowser/src/com/android/camerabrowser/DeviceDisconnectedReceiver.java
@@ -21,8 +21,8 @@
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
-import android.hardware.UsbDevice;
-import android.hardware.UsbManager;
+import android.hardware.usb.UsbDevice;
+import android.hardware.usb.UsbManager;
import android.util.Log;
public class DeviceDisconnectedReceiver extends BroadcastReceiver {
diff --git a/packages/SystemUI/res/drawable-xlarge-mdpi/recents_thumbnail_bg_press.png b/packages/SystemUI/res/drawable-xlarge-mdpi/recents_thumbnail_bg_press.png
index 7f86fb3..a1c39e6 100644
--- a/packages/SystemUI/res/drawable-xlarge-mdpi/recents_thumbnail_bg_press.png
+++ b/packages/SystemUI/res/drawable-xlarge-mdpi/recents_thumbnail_bg_press.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable/recents_thumbnail_bg_holo.xml b/packages/SystemUI/res/drawable/recents_thumbnail_bg_holo.xml
new file mode 100644
index 0000000..f9bba2a
--- /dev/null
+++ b/packages/SystemUI/res/drawable/recents_thumbnail_bg_holo.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/* apps/common/assets/default/default/skins/StatusBar.xml
+**
+** Copyright 2011, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+<transition xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:drawable="@drawable/recents_thumbnail_bg_press"/>
+ <item android:drawable="@drawable/recents_thumbnail_bg_press"/>
+</transition>
diff --git a/packages/SystemUI/res/drawable/recents_thumbnail_bg_selector.xml b/packages/SystemUI/res/drawable/recents_thumbnail_bg_selector.xml
new file mode 100644
index 0000000..0e58e12
--- /dev/null
+++ b/packages/SystemUI/res/drawable/recents_thumbnail_bg_selector.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:exitFadeDuration="@android:integer/config_mediumAnimTime">
+
+ <item android:state_window_focused="false" android:drawable="@android:color/transparent" />
+
+ <!-- Even though these two point to the same resource, have two states so the drawable will invalidate itself when coming out of pressed state. -->
+ <item android:state_focused="true" android:state_pressed="true" android:drawable="@drawable/recents_thumbnail_bg_holo" />
+ <item android:state_focused="false" android:state_pressed="true" android:drawable="@drawable/recents_thumbnail_bg_holo" />
+ <item android:state_focused="true" android:drawable="@drawable/recents_thumbnail_bg_holo" />
+</selector>
+
diff --git a/packages/SystemUI/res/layout-xlarge/status_bar.xml b/packages/SystemUI/res/layout-xlarge/status_bar.xml
index 6c173c9..d9f3f23 100644
--- a/packages/SystemUI/res/layout-xlarge/status_bar.xml
+++ b/packages/SystemUI/res/layout-xlarge/status_bar.xml
@@ -32,7 +32,6 @@
android:id="@+id/bar_contents"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:animateLayoutChanges="true"
>
<!-- notification icons & panel access -->
diff --git a/packages/SystemUI/res/layout-xlarge/status_bar_input_methods_panel.xml b/packages/SystemUI/res/layout-xlarge/status_bar_input_methods_panel.xml
index efbf359..f6ed804 100644
--- a/packages/SystemUI/res/layout-xlarge/status_bar_input_methods_panel.xml
+++ b/packages/SystemUI/res/layout-xlarge/status_bar_input_methods_panel.xml
@@ -85,7 +85,9 @@
android:layout_height="wrap_content"
android:overScrollMode="ifContentScrolls"
android:layout_marginTop="3dip"
- android:layout_weight="1">
+ android:layout_weight="1"
+ android:scrollbarAlwaysDrawVerticalTrack="true"
+ android:scrollbarDefaultDelayBeforeFade="75000">
<LinearLayout
android:id="@+id/input_method_menu_list"
android:layout_width="wrap_content"
diff --git a/packages/SystemUI/res/layout-xlarge/status_bar_recent_panel.xml b/packages/SystemUI/res/layout-xlarge/status_bar_recent_panel.xml
index 4be57a2..eda19b7 100644
--- a/packages/SystemUI/res/layout-xlarge/status_bar_recent_panel.xml
+++ b/packages/SystemUI/res/layout-xlarge/status_bar_recent_panel.xml
@@ -36,7 +36,7 @@
<LinearLayout android:id="@+id/recents_glow"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_marginBottom="-52dip"
+ android:layout_marginBottom="-49dip"
android:layout_gravity="bottom"
android:background="@drawable/recents_blue_glow"
android:orientation="horizontal"
@@ -52,7 +52,7 @@
android:fadingEdge="vertical"
android:scrollbars="none"
android:fadingEdgeLength="30dip"
- android:listSelector="@drawable/recents_thumbnail_bg_press"
+ android:listSelector="@drawable/recents_thumbnail_bg_selector"
/>
</LinearLayout>
diff --git a/packages/SystemUI/res/layout-xlarge/status_bar_settings_view.xml b/packages/SystemUI/res/layout-xlarge/status_bar_settings_view.xml
index 75bbb3a..fbb3c78 100644
--- a/packages/SystemUI/res/layout-xlarge/status_bar_settings_view.xml
+++ b/packages/SystemUI/res/layout-xlarge/status_bar_settings_view.xml
@@ -21,7 +21,6 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
- android:paddingRight="48dp"
>
<!-- Airplane mode -->
diff --git a/packages/SystemUI/res/values-xlarge/styles.xml b/packages/SystemUI/res/values-xlarge/styles.xml
index c1cd533..12c8950 100644
--- a/packages/SystemUI/res/values-xlarge/styles.xml
+++ b/packages/SystemUI/res/values-xlarge/styles.xml
@@ -22,9 +22,11 @@
</style>
<style name="StatusBarPanelSettingsRow">
+ <item name="android:paddingRight">48dp</item>
<item name="android:layout_height">64dp</item>
<item name="android:layout_width">match_parent</item>
<item name="android:orientation">horizontal</item>
+ <item name="android:background">?android:attr/listChoiceBackgroundIndicator</item>
</style>
<style name="StatusBarPanelSettingsIcon">
@@ -43,6 +45,7 @@
</style>
<style name="StatusBarPanelSettingsPanelSeparator">
+ <item name="android:layout_marginRight">48dp</item>
<item name="android:layout_width">match_parent</item>
<item name="android:layout_height">1dp</item>
<item name="android:background">@android:drawable/divider_horizontal_dark</item>
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java
index 8ab231b..e81cec2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java
@@ -25,12 +25,14 @@
import android.os.ServiceManager;
import android.util.AttributeSet;
import android.util.Slog;
+import android.view.accessibility.AccessibilityEvent;
import android.view.HapticFeedbackConstants;
import android.view.IWindowManager;
import android.view.InputDevice;
import android.view.KeyCharacterMap;
import android.view.KeyEvent;
import android.view.MotionEvent;
+import android.view.SoundEffectConstants;
import android.view.ViewConfiguration;
import android.widget.ImageView;
import android.widget.RemoteViews.RemoteView;
@@ -45,6 +47,8 @@
boolean mSending;
int mCode;
int mRepeat;
+ int mTouchSlop;
+
Runnable mCheckLongPress = new Runnable() {
public void run() {
if (isPressed()) {
@@ -53,6 +57,9 @@
KeyEvent.FLAG_FROM_SYSTEM
| KeyEvent.FLAG_VIRTUAL_HARD_KEY
| KeyEvent.FLAG_LONG_PRESS);
+
+ sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_LONG_CLICKED);
+ //playSoundEffect(SoundEffectConstants.CLICK);
}
}
};
@@ -78,6 +85,7 @@
ServiceManager.getService(Context.WINDOW_SERVICE));
setClickable(true);
+ mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
}
public boolean onTouchEvent(MotionEvent ev) {
@@ -100,7 +108,10 @@
if (mSending) {
x = (int)ev.getX();
y = (int)ev.getY();
- setPressed(x >= 0 && x < getWidth() && y >= 0 && y < getHeight());
+ setPressed(x >= -mTouchSlop
+ && x < getWidth() + mTouchSlop
+ && y >= -mTouchSlop
+ && y < getHeight() + mTouchSlop);
}
break;
case MotionEvent.ACTION_CANCEL:
@@ -114,12 +125,18 @@
}
break;
case MotionEvent.ACTION_UP:
+ final boolean doIt = isPressed();
setPressed(false);
if (mSending) {
mSending = false;
- sendEvent(KeyEvent.ACTION_UP,
- KeyEvent.FLAG_FROM_SYSTEM | KeyEvent.FLAG_VIRTUAL_HARD_KEY);
removeCallbacks(mCheckLongPress);
+ if (doIt) {
+ sendEvent(KeyEvent.ACTION_UP,
+ KeyEvent.FLAG_FROM_SYSTEM | KeyEvent.FLAG_VIRTUAL_HARD_KEY);
+
+ sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_CLICKED);
+ playSoundEffect(SoundEffectConstants.CLICK);
+ }
}
break;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/RecentAppsPanel.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/RecentAppsPanel.java
index ebe1a7c..1135b73 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/RecentAppsPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/RecentAppsPanel.java
@@ -40,7 +40,6 @@
import android.graphics.Shader.TileMode;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
-import android.os.Parcelable;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.Log;
@@ -64,7 +63,6 @@
private static final boolean DEBUG = TabletStatusBar.DEBUG;
private static final int DISPLAY_TASKS = 20;
private static final int MAX_TASKS = DISPLAY_TASKS + 1; // allow extra for non-apps
- private static final int BOTTOM_OFFSET = 28; // TODO: Get from dimens.xml
private TabletStatusBar mBar;
private ArrayList<ActivityDescription> mActivityDescriptions;
private int mIconDpi;
@@ -104,7 +102,7 @@
}
};
- private static class ViewHolder {
+ /* package */ final static class ViewHolder {
private ImageView thumbnailView;
private ImageView iconView;
private TextView labelView;
@@ -112,7 +110,7 @@
private ActivityDescription activityDescription;
}
- private class ActvityDescriptionAdapter extends BaseAdapter {
+ /* package */ final class ActvityDescriptionAdapter extends BaseAdapter {
private LayoutInflater mInflater;
public ActvityDescriptionAdapter(Context context) {
@@ -361,7 +359,7 @@
View footer = inflater.inflate(R.layout.status_bar_recent_panel_footer,
mRecentsContainer, false);
mRecentsContainer.setScrollbarFadingEnabled(true);
- mRecentsContainer.addFooterView(footer);
+ mRecentsContainer.addFooterView(footer, null, false);
mRecentsContainer.setAdapter(mListAdapter = new ActvityDescriptionAdapter(mContext));
mRecentsContainer.setOnItemClickListener(this);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
index f0408a2..4557105 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
@@ -42,11 +42,13 @@
import android.os.ServiceManager;
import android.text.TextUtils;
import android.util.Slog;
+import android.view.accessibility.AccessibilityEvent;
import android.view.Gravity;
import android.view.IWindowManager;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.MotionEvent;
+import android.view.SoundEffectConstants;
import android.view.VelocityTracker;
import android.view.View;
import android.view.ViewConfiguration;
@@ -113,7 +115,7 @@
View mNotificationArea;
View mNotificationTrigger;
NotificationIconArea mNotificationIconArea;
- View mNavigationArea;
+ ViewGroup mNavigationArea;
boolean mNotificationDNDMode;
NotificationData.Entry mNotificationDNDDummyEntry;
@@ -144,7 +146,8 @@
LocationController mLocationController;
NetworkController mNetworkController;
- View mBarContents;
+ ViewGroup mBarContents;
+ LayoutTransition mBarContentsLayoutTransition;
// hide system chrome ("lights out") support
View mShadow;
@@ -344,7 +347,20 @@
sb.setHandler(mHandler);
- mBarContents = sb.findViewById(R.id.bar_contents);
+ mBarContents = (ViewGroup) sb.findViewById(R.id.bar_contents);
+ // layout transitions for the status bar's contents
+ mBarContentsLayoutTransition = new LayoutTransition();
+ // add/removal will fade as normal
+ mBarContentsLayoutTransition.setAnimator(LayoutTransition.APPEARING,
+ ObjectAnimator.ofFloat(null, "alpha", 0f, 1f));
+ mBarContentsLayoutTransition.setAnimator(LayoutTransition.DISAPPEARING,
+ ObjectAnimator.ofFloat(null, "alpha", 1f, 0f));
+ // no animations for siblings on change: just jump into place please
+ mBarContentsLayoutTransition.setAnimator(LayoutTransition.CHANGE_APPEARING, null);
+ mBarContentsLayoutTransition.setAnimator(LayoutTransition.CHANGE_DISAPPEARING, null);
+ // quick like bunny
+ mBarContentsLayoutTransition.setDuration(250 * (DEBUG?10:1));
+ mBarContents.setLayoutTransition(mBarContentsLayoutTransition);
// the whole right-hand side of the bar
mNotificationArea = sb.findViewById(R.id.notificationArea);
@@ -383,11 +399,12 @@
// The navigation buttons
mBackButton = (ImageView)sb.findViewById(R.id.back);
- mNavigationArea = sb.findViewById(R.id.navigationArea);
+ mNavigationArea = (ViewGroup) sb.findViewById(R.id.navigationArea);
mHomeButton = mNavigationArea.findViewById(R.id.home);
mMenuButton = mNavigationArea.findViewById(R.id.menu);
mRecentButton = mNavigationArea.findViewById(R.id.recent_apps);
mRecentButton.setOnClickListener(mOnClickListener);
+ mNavigationArea.setLayoutTransition(mBarContentsLayoutTransition);
// The bar contents buttons
mNotificationAndImeArea = (ViewGroup)sb.findViewById(R.id.notificationAndImeArea);
@@ -572,7 +589,7 @@
if (!mNotificationPanel.isShowing()) {
mNotificationPeekWindow.setVisibility(View.GONE);
mNotificationPanel.show(true, true);
- mNotificationArea.setVisibility(View.GONE);
+ mNotificationArea.setVisibility(View.INVISIBLE);
mTicker.halt();
}
break;
@@ -586,8 +603,7 @@
case MSG_OPEN_RECENTS_PANEL:
if (DEBUG) Slog.d(TAG, "opening recents panel");
if (mRecentsPanel != null) {
- disable(StatusBarManager.DISABLE_NAVIGATION
- | StatusBarManager.DISABLE_BACK);
+ disable(StatusBarManager.DISABLE_BACK);
mRecentsPanel.setVisibility(View.VISIBLE);
mRecentsPanel.show(true, true);
}
@@ -831,7 +847,7 @@
if ((diff & StatusBarManager.DISABLE_NAVIGATION) != 0) {
if ((state & StatusBarManager.DISABLE_NAVIGATION) != 0) {
Slog.i(TAG, "DISABLE_NAVIGATION: yes");
- mNavigationArea.setVisibility(View.GONE);
+ mNavigationArea.setVisibility(View.INVISIBLE);
mInputMethodSwitchButton.setScreenLocked(true);
} else {
Slog.i(TAG, "DISABLE_NAVIGATION: no");
@@ -1182,6 +1198,8 @@
// dragging off the bottom doesn't count
&& (int)event.getY() < v.getBottom()) {
animateExpand();
+ v.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_CLICKED);
+ v.playSoundEffect(SoundEffectConstants.CLICK);
}
mVT.recycle();
@@ -1265,17 +1283,23 @@
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
mHandler.removeMessages(MSG_OPEN_NOTIFICATION_PEEK);
- if (action == MotionEvent.ACTION_UP
- // was this a sloppy tap?
- && Math.abs(event.getX() - mInitialTouchX) < mTouchSlop
- && Math.abs(event.getY() - mInitialTouchY) < (mTouchSlop / 3)
- // dragging off the bottom doesn't count
- && (int)event.getY() < v.getBottom()) {
- Message peekMsg = mHandler.obtainMessage(MSG_OPEN_NOTIFICATION_PEEK);
- peekMsg.arg1 = mPeekIndex;
- mHandler.removeMessages(MSG_OPEN_NOTIFICATION_PEEK);
- mHandler.sendMessage(peekMsg);
- peeking = true; // not technically true yet, but the next line will run
+ if (!peeking) {
+ if (action == MotionEvent.ACTION_UP
+ // was this a sloppy tap?
+ && Math.abs(event.getX() - mInitialTouchX) < mTouchSlop
+ && Math.abs(event.getY() - mInitialTouchY) < (mTouchSlop / 3)
+ // dragging off the bottom doesn't count
+ && (int)event.getY() < v.getBottom()) {
+ Message peekMsg = mHandler.obtainMessage(MSG_OPEN_NOTIFICATION_PEEK);
+ peekMsg.arg1 = mPeekIndex;
+ mHandler.removeMessages(MSG_OPEN_NOTIFICATION_PEEK);
+ mHandler.sendMessage(peekMsg);
+
+ v.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_CLICKED);
+ v.playSoundEffect(SoundEffectConstants.CLICK);
+
+ peeking = true; // not technically true yet, but the next line will run
+ }
}
if (peeking) {
diff --git a/packages/SystemUI/src/com/android/systemui/usb/UsbStorageActivity.java b/packages/SystemUI/src/com/android/systemui/usb/UsbStorageActivity.java
index 1368baa..43dfb96 100644
--- a/packages/SystemUI/src/com/android/systemui/usb/UsbStorageActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/usb/UsbStorageActivity.java
@@ -30,7 +30,7 @@
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
-import android.hardware.UsbManager;
+import android.hardware.usb.UsbManager;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindow.java b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
index d342d66..ec89db3 100644
--- a/policy/src/com/android/internal/policy/impl/PhoneWindow.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
@@ -222,7 +222,7 @@
}
mLayoutInflater.inflate(layoutResID, mContentParent);
final Callback cb = getCallback();
- if (cb != null) {
+ if (cb != null && !isDestroyed()) {
cb.onContentChanged();
}
}
@@ -241,7 +241,7 @@
}
mContentParent.addView(view, params);
final Callback cb = getCallback();
- if (cb != null) {
+ if (cb != null && !isDestroyed()) {
cb.onContentChanged();
}
}
@@ -253,7 +253,7 @@
}
mContentParent.addView(view, params);
final Callback cb = getCallback();
- if (cb != null) {
+ if (cb != null && !isDestroyed()) {
cb.onContentChanged();
}
}
@@ -316,6 +316,10 @@
* returns false.
*/
public final boolean preparePanel(PanelFeatureState st, KeyEvent event) {
+ if (isDestroyed()) {
+ return false;
+ }
+
// Already prepared (isPrepared will be reset to false later)
if (st.isPrepared)
return true;
@@ -437,7 +441,7 @@
// System.out.println("Open panel: isOpen=" + st.isOpen);
// Already open, return
- if (st.isOpen) {
+ if (st.isOpen || isDestroyed()) {
return;
}
@@ -609,7 +613,7 @@
closed = true;
}
Callback cb = getCallback();
- if (cb != null && closed) {
+ if (cb != null && closed && !isDestroyed()) {
cb.onPanelClosed(FEATURE_ACTION_BAR, menu);
}
mClosingActionMenu = false;
@@ -688,7 +692,7 @@
if (mActionBar.getVisibility() == View.VISIBLE) {
if (!mActionBar.isOverflowMenuShowing()) {
final Callback cb = getCallback();
- if (cb != null &&
+ if (cb != null && !isDestroyed() &&
cb.onPreparePanel(featureId, st.createdPanelView, st.menu)) {
playSoundEffect = mActionBar.showOverflowMenu();
}
@@ -837,7 +841,7 @@
public boolean onMenuItemSelected(MenuBuilder menu, MenuItem item) {
final Callback cb = getCallback();
- if (cb != null) {
+ if (cb != null && !isDestroyed()) {
final PanelFeatureState panel = findMenuPanel(menu.getRootMenu());
if (panel != null) {
return cb.onMenuItemSelected(panel.featureId, item);
@@ -881,7 +885,7 @@
mActionButtonPopup = new ActionButtonSubmenu(getContext(), subMenu);
mActionButtonPopup.show();
Callback cb = getCallback();
- if (cb != null) {
+ if (cb != null && !isDestroyed()) {
cb.onMenuOpened(FEATURE_ACTION_BAR, subMenu);
}
}
@@ -902,7 +906,7 @@
if (mActionBar != null) {
final Callback cb = getCallback();
if (!mActionBar.isOverflowMenuShowing() || !toggleMenuMode) {
- if (cb != null && mActionBar.getVisibility() == View.VISIBLE) {
+ if (cb != null && !isDestroyed() && mActionBar.getVisibility() == View.VISIBLE) {
final PanelFeatureState st = getPanelState(FEATURE_OPTIONS_PANEL, true);
if (cb.onPreparePanel(FEATURE_OPTIONS_PANEL, st.createdPanelView, st.menu)) {
cb.onMenuOpened(FEATURE_ACTION_BAR, st.menu);
@@ -911,7 +915,7 @@
}
} else {
mActionBar.hideOverflowMenu();
- if (cb != null) {
+ if (cb != null && !isDestroyed()) {
final PanelFeatureState st = getPanelState(FEATURE_OPTIONS_PANEL, true);
cb.onPanelClosed(FEATURE_ACTION_BAR, st.menu);
}
@@ -1641,11 +1645,13 @@
return true;
}
- final Callback cb = getCallback();
- final boolean handled = cb != null && mFeatureId < 0 ? cb.dispatchKeyEvent(event)
- : super.dispatchKeyEvent(event);
- if (handled) {
- return true;
+ if (!isDestroyed()) {
+ final Callback cb = getCallback();
+ final boolean handled = cb != null && mFeatureId < 0 ? cb.dispatchKeyEvent(event)
+ : super.dispatchKeyEvent(event);
+ if (handled) {
+ return true;
+ }
}
return isDown ? PhoneWindow.this.onKeyDown(mFeatureId, event.getKeyCode(), event)
: PhoneWindow.this.onKeyUp(mFeatureId, event.getKeyCode(), event);
@@ -1667,29 +1673,29 @@
// Shortcut not handled by the panel. Dispatch to the view hierarchy.
final Callback cb = getCallback();
- return cb != null && mFeatureId < 0 ? cb.dispatchKeyShortcutEvent(ev) : super
- .dispatchKeyShortcutEvent(ev);
+ return cb != null && !isDestroyed() && mFeatureId < 0 ? cb.dispatchKeyShortcutEvent(ev)
+ : super.dispatchKeyShortcutEvent(ev);
}
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
final Callback cb = getCallback();
- return cb != null && mFeatureId < 0 ? cb.dispatchTouchEvent(ev) : super
- .dispatchTouchEvent(ev);
+ return cb != null && !isDestroyed() && mFeatureId < 0 ? cb.dispatchTouchEvent(ev)
+ : super.dispatchTouchEvent(ev);
}
@Override
public boolean dispatchTrackballEvent(MotionEvent ev) {
final Callback cb = getCallback();
- return cb != null && mFeatureId < 0 ? cb.dispatchTrackballEvent(ev) : super
- .dispatchTrackballEvent(ev);
+ return cb != null && !isDestroyed() && mFeatureId < 0 ? cb.dispatchTrackballEvent(ev)
+ : super.dispatchTrackballEvent(ev);
}
@Override
public boolean dispatchGenericMotionEvent(MotionEvent ev) {
final Callback cb = getCallback();
- return cb != null && mFeatureId < 0 ? cb.dispatchGenericMotionEvent(ev) : super
- .dispatchGenericMotionEvent(ev);
+ return cb != null && !isDestroyed() && mFeatureId < 0 ? cb.dispatchGenericMotionEvent(ev)
+ : super.dispatchGenericMotionEvent(ev);
}
public boolean superDispatchKeyEvent(KeyEvent event) {
@@ -1822,7 +1828,7 @@
@Override
public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
final Callback cb = getCallback();
- if (cb != null) {
+ if (cb != null && !isDestroyed()) {
if (cb.dispatchPopulateAccessibilityEvent(event)) {
return true;
}
@@ -1953,10 +1959,12 @@
final ActionMode.Callback wrappedCallback = new ActionModeCallbackWrapper(callback);
ActionMode mode = null;
- try {
- mode = getCallback().onWindowStartingActionMode(wrappedCallback);
- } catch (AbstractMethodError ame) {
- // Older apps might not implement this callback method.
+ if (getCallback() != null && !isDestroyed()) {
+ try {
+ mode = getCallback().onWindowStartingActionMode(wrappedCallback);
+ } catch (AbstractMethodError ame) {
+ // Older apps might not implement this callback method.
+ }
}
if (mode != null) {
mActionMode = mode;
@@ -2008,7 +2016,7 @@
}
}
}
- if (mActionMode != null) {
+ if (mActionMode != null && getCallback() != null && !isDestroyed()) {
try {
getCallback().onActionModeStarted(mActionMode);
} catch (AbstractMethodError ame) {
@@ -2140,7 +2148,7 @@
}
final Callback cb = getCallback();
- if (cb != null && mFeatureId < 0) {
+ if (cb != null && !isDestroyed() && mFeatureId < 0) {
cb.onWindowFocusChanged(hasWindowFocus);
}
}
@@ -2158,7 +2166,7 @@
updateWindowResizeState();
final Callback cb = getCallback();
- if (cb != null && mFeatureId < 0) {
+ if (cb != null && !isDestroyed() && mFeatureId < 0) {
cb.onAttachedToWindow();
}
@@ -2179,7 +2187,7 @@
super.onDetachedFromWindow();
final Callback cb = getCallback();
- if (cb != null && mFeatureId < 0) {
+ if (cb != null && !isDestroyed() && mFeatureId < 0) {
cb.onDetachedFromWindow();
}
@@ -2268,10 +2276,12 @@
if (mActionModeView != null) {
mActionModeView.removeAllViews();
}
- try {
- getCallback().onActionModeFinished(mActionMode);
- } catch (AbstractMethodError ame) {
- // Older apps might not implement this callback method.
+ if (getCallback() != null && !isDestroyed()) {
+ try {
+ getCallback().onActionModeFinished(mActionMode);
+ } catch (AbstractMethodError ame) {
+ // Older apps might not implement this callback method.
+ }
}
mActionMode = null;
}
@@ -2820,7 +2830,9 @@
if ((panel != null) && (!panel.isOpen))
return;
- cb.onPanelClosed(featureId, menu);
+ if (!isDestroyed()) {
+ cb.onPanelClosed(featureId, menu);
+ }
}
/**
@@ -2831,7 +2843,7 @@
*/
private boolean launchDefaultSearch() {
final Callback cb = getCallback();
- if (cb == null) {
+ if (cb == null || isDestroyed()) {
return false;
} else {
sendCloseSystemWindows("search");
@@ -3065,7 +3077,9 @@
public void onCloseMenu(MenuBuilder menu, boolean allMenusAreClosing) {
if (allMenusAreClosing) {
Callback callback = getCallback();
- if (callback != null) callback.onPanelClosed(mFeatureId, menu);
+ if (callback != null && !isDestroyed()) {
+ callback.onPanelClosed(mFeatureId, menu);
+ }
if (menu == mContextMenu) {
dismissContextMenu();
@@ -3081,12 +3095,15 @@
public void onCloseSubMenu(SubMenuBuilder menu) {
Callback callback = getCallback();
- if (callback != null) callback.onPanelClosed(mFeatureId, menu.getRootMenu());
+ if (callback != null && !isDestroyed()) {
+ callback.onPanelClosed(mFeatureId, menu.getRootMenu());
+ }
}
public boolean onMenuItemSelected(MenuBuilder menu, MenuItem item) {
Callback callback = getCallback();
- return (callback != null) && callback.onMenuItemSelected(mFeatureId, item);
+ return (callback != null && !isDestroyed())
+ && callback.onMenuItemSelected(mFeatureId, item);
}
public void onMenuModeChange(MenuBuilder menu) {
@@ -3145,7 +3162,7 @@
public void run() {
if (tryShow()) {
Callback cb = getCallback();
- if (cb != null) {
+ if (cb != null && !isDestroyed()) {
cb.onMenuOpened(FEATURE_ACTION_BAR, mSubMenu);
}
}
diff --git a/policy/src/com/android/internal/policy/impl/StatusView.java b/policy/src/com/android/internal/policy/impl/StatusView.java
index 2aff4a8..46ce5a3 100644
--- a/policy/src/com/android/internal/policy/impl/StatusView.java
+++ b/policy/src/com/android/internal/policy/impl/StatusView.java
@@ -20,7 +20,7 @@
class StatusView {
public static final int LOCK_ICON = 0; // R.drawable.ic_lock_idle_lock;
- public static final int ALARM_ICON = 0; // R.drawable.ic_lock_idle_alarm;
+ public static final int ALARM_ICON = R.drawable.ic_lock_idle_alarm;
public static final int CHARGING_ICON = 0; //R.drawable.ic_lock_idle_charging;
public static final int BATTERY_LOW_ICON = 0; //R.drawable.ic_lock_idle_low_battery;
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index 704da72..a07ebfc 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -1629,6 +1629,7 @@
track->mState = TrackBase::ACTIVE;
param = AudioMixer::RAMP_VOLUME;
}
+ mAudioMixer->setParameter(AudioMixer::RESAMPLE, AudioMixer::RESET, NULL);
} else if (cblk->server != 0) {
// If the track is stopped before the first frame was mixed,
// do not apply ramp
@@ -3855,9 +3856,12 @@
mActiveTrack.clear();
return status;
}
- mActiveTrack->mState = TrackBase::RESUMING;
mRsmpInIndex = mFrameCount;
mBytesRead = 0;
+ if (mResampler != NULL) {
+ mResampler->reset();
+ }
+ mActiveTrack->mState = TrackBase::RESUMING;
// signal thread to start
LOGV("Signal record thread");
mWaitWorkCV.signal();
diff --git a/services/audioflinger/AudioMixer.cpp b/services/audioflinger/AudioMixer.cpp
index 433f1f7..50dcda7 100644
--- a/services/audioflinger/AudioMixer.cpp
+++ b/services/audioflinger/AudioMixer.cpp
@@ -220,6 +220,12 @@
return NO_ERROR;
}
}
+ if (name == RESET) {
+ track_t& track = mState.tracks[ mActiveTrack ];
+ track.resetResampler();
+ invalidateState(1<<mActiveTrack);
+ return NO_ERROR;
+ }
break;
case RAMP_VOLUME:
case VOLUME:
@@ -289,6 +295,13 @@
return resampler != 0;
}
+void AudioMixer::track_t::resetResampler()
+{
+ if (resampler != 0) {
+ resampler->reset();
+ }
+}
+
inline
void AudioMixer::track_t::adjustVolumeRamp(bool aux)
{
diff --git a/services/audioflinger/AudioMixer.h b/services/audioflinger/AudioMixer.h
index aee3e17..88408a7 100644
--- a/services/audioflinger/AudioMixer.h
+++ b/services/audioflinger/AudioMixer.h
@@ -67,6 +67,7 @@
AUX_BUFFER = 0x4003,
// for TARGET RESAMPLE
SAMPLE_RATE = 0x4100,
+ RESET = 0x4101,
// for TARGET VOLUME (8 channels max)
VOLUME0 = 0x4200,
VOLUME1 = 0x4201,
@@ -163,6 +164,7 @@
bool setResampler(uint32_t sampleRate, uint32_t devSampleRate);
bool doesResample() const;
+ void resetResampler();
void adjustVolumeRamp(bool aux);
};
diff --git a/services/audioflinger/AudioResampler.cpp b/services/audioflinger/AudioResampler.cpp
index 5dabacb..5c3b43fc 100644
--- a/services/audioflinger/AudioResampler.cpp
+++ b/services/audioflinger/AudioResampler.cpp
@@ -148,6 +148,12 @@
mVolume[1] = right;
}
+void AudioResampler::reset() {
+ mInputIndex = 0;
+ mPhaseFraction = 0;
+ mBuffer.frameCount = 0;
+}
+
// ----------------------------------------------------------------------------
void AudioResamplerOrder1::resample(int32_t* out, size_t outFrameCount,
diff --git a/services/audioflinger/AudioResampler.h b/services/audioflinger/AudioResampler.h
index 2dfac76..9f06c1c 100644
--- a/services/audioflinger/AudioResampler.h
+++ b/services/audioflinger/AudioResampler.h
@@ -53,6 +53,8 @@
virtual void resample(int32_t* out, size_t outFrameCount,
AudioBufferProvider* provider) = 0;
+ virtual void reset();
+
protected:
// number of bits for phase fraction - 30 bits allows nearly 2x downsampling
static const int kNumPhaseBits = 30;
diff --git a/services/java/com/android/server/NotificationManagerService.java b/services/java/com/android/server/NotificationManagerService.java
index 47dce41..e738145 100755
--- a/services/java/com/android/server/NotificationManagerService.java
+++ b/services/java/com/android/server/NotificationManagerService.java
@@ -37,7 +37,7 @@
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.Resources;
import android.database.ContentObserver;
-import android.hardware.UsbManager;
+import android.hardware.usb.UsbManager;
import android.media.AudioManager;
import android.net.Uri;
import android.os.Binder;
diff --git a/services/java/com/android/server/PackageManagerService.java b/services/java/com/android/server/PackageManagerService.java
index f1a6e15..461a3e5 100644
--- a/services/java/com/android/server/PackageManagerService.java
+++ b/services/java/com/android/server/PackageManagerService.java
@@ -6204,10 +6204,10 @@
mHandler.post(new Runnable() {
public void run() {
mHandler.removeCallbacks(this);
- final boolean succeded = deletePackageX(packageName, true, true, flags);
+ final int returnCode = deletePackageX(packageName, true, true, flags);
if (observer != null) {
try {
- observer.packageDeleted(succeded);
+ observer.packageDeleted(packageName, returnCode);
} catch (RemoteException e) {
Log.i(TAG, "Observer no longer exists.");
} //end catch
@@ -6230,17 +6230,17 @@
* persisting settings for later use
* sending a broadcast if necessary
*/
- private boolean deletePackageX(String packageName, boolean sendBroadCast,
+ private int deletePackageX(String packageName, boolean sendBroadCast,
boolean deleteCodeAndResources, int flags) {
- PackageRemovedInfo info = new PackageRemovedInfo();
- boolean res;
+ final PackageRemovedInfo info = new PackageRemovedInfo();
+ final boolean res;
IDevicePolicyManager dpm = IDevicePolicyManager.Stub.asInterface(
ServiceManager.getService(Context.DEVICE_POLICY_SERVICE));
try {
if (dpm != null && dpm.packageHasActiveAdmins(packageName)) {
Slog.w(TAG, "Not removing package " + packageName + ": has active device admin");
- return false;
+ return PackageManager.DELETE_FAILED_DEVICE_POLICY_MANAGER;
}
} catch (RemoteException e) {
}
@@ -6250,7 +6250,7 @@
flags | REMOVE_CHATTY, info, true);
}
- if(res && sendBroadCast) {
+ if (res && sendBroadCast) {
boolean systemUpdate = info.isRemovedPackageSystemUpdate;
info.sendBroadcast(deleteCodeAndResources, systemUpdate);
@@ -6278,7 +6278,8 @@
info.args.doPostDeleteLI(deleteCodeAndResources);
}
}
- return res;
+
+ return res ? PackageManager.DELETE_SUCCEEDED : PackageManager.DELETE_FAILED_INTERNAL_ERROR;
}
static class PackageRemovedInfo {
diff --git a/services/java/com/android/server/WifiService.java b/services/java/com/android/server/WifiService.java
index f9b94a3..adc49ae 100644
--- a/services/java/com/android/server/WifiService.java
+++ b/services/java/com/android/server/WifiService.java
@@ -144,9 +144,6 @@
private static final String ACTION_DEVICE_IDLE =
"com.android.server.WifiManager.action.DEVICE_IDLE";
- private static final int CMD_ENABLE_TRAFFIC_STATS_POLL = 1;
- private static final int CMD_TRAFFIC_STATS_POLL = 2;
-
private boolean mIsReceiverRegistered = false;
@@ -237,24 +234,45 @@
ac.connect(mContext, this, msg.replyTo);
break;
}
- case CMD_ENABLE_TRAFFIC_STATS_POLL: {
+ case WifiManager.CMD_ENABLE_TRAFFIC_STATS_POLL: {
mEnableTrafficStatsPoll = (msg.arg1 == 1);
mTrafficStatsPollToken++;
if (mEnableTrafficStatsPoll) {
notifyOnDataActivity();
- sendMessageDelayed(Message.obtain(this, CMD_TRAFFIC_STATS_POLL,
+ sendMessageDelayed(Message.obtain(this, WifiManager.CMD_TRAFFIC_STATS_POLL,
mTrafficStatsPollToken, 0), POLL_TRAFFIC_STATS_INTERVAL_MSECS);
}
break;
}
- case CMD_TRAFFIC_STATS_POLL: {
+ case WifiManager.CMD_TRAFFIC_STATS_POLL: {
if (msg.arg1 == mTrafficStatsPollToken) {
notifyOnDataActivity();
- sendMessageDelayed(Message.obtain(this, CMD_TRAFFIC_STATS_POLL,
+ sendMessageDelayed(Message.obtain(this, WifiManager.CMD_TRAFFIC_STATS_POLL,
mTrafficStatsPollToken, 0), POLL_TRAFFIC_STATS_INTERVAL_MSECS);
}
break;
}
+ case WifiManager.CMD_CONNECT_NETWORK: {
+ if (msg.obj != null) {
+ mWifiStateMachine.connectNetwork((WifiConfiguration)msg.obj);
+ } else {
+ mWifiStateMachine.connectNetwork(msg.arg1);
+ }
+ break;
+ }
+ case WifiManager.CMD_SAVE_NETWORK: {
+ mWifiStateMachine.saveNetwork((WifiConfiguration)msg.obj);
+ break;
+ }
+ case WifiManager.CMD_FORGET_NETWORK: {
+ mWifiStateMachine.forgetNetwork(msg.arg1);
+ break;
+ }
+ case WifiManager.CMD_START_WPS: {
+ //replyTo has the original source
+ mWifiStateMachine.startWps(msg.replyTo, (WpsConfiguration)msg.obj);
+ break;
+ }
default: {
Slog.d(TAG, "WifiServicehandler.handleMessage ignoring msg=" + msg);
break;
@@ -844,42 +862,19 @@
mWifiStateMachine.clearBlacklist();
}
- public void connectNetworkWithId(int networkId) {
- enforceChangePermission();
- mWifiStateMachine.connectNetwork(networkId);
- }
- public void connectNetworkWithConfig(WifiConfiguration config) {
- enforceChangePermission();
- mWifiStateMachine.connectNetwork(config);
- }
-
- public void saveNetwork(WifiConfiguration config) {
- enforceChangePermission();
- mWifiStateMachine.saveNetwork(config);
- }
-
- public void forgetNetwork(int netId) {
- enforceChangePermission();
- mWifiStateMachine.forgetNetwork(netId);
- }
-
- public WpsResult startWps(WpsConfiguration config) {
- enforceChangePermission();
- if (mWifiStateMachineChannel != null) {
- return mWifiStateMachine.startWps(mWifiStateMachineChannel, config);
- } else {
- Slog.e(TAG, "mWifiStateMachineChannel is not initialized");
- return new WpsResult(WpsResult.Status.FAILURE);
- }
- }
/**
* Get a reference to handler. This is used by a client to establish
* an AsyncChannel communication with WifiService
*/
public Messenger getMessenger() {
+ /* Enforce the highest permissions
+ TODO: when we consider exposing the asynchronous API, think about
+ how to provide both access and change permissions seperately
+ */
enforceAccessPermission();
+ enforceChangePermission();
return new Messenger(mAsyncServiceHandler);
}
@@ -1530,9 +1525,11 @@
private void evaluateTrafficStatsPolling() {
Message msg;
if (mNetworkInfo.getDetailedState() == DetailedState.CONNECTED && !mScreenOff) {
- msg = Message.obtain(mAsyncServiceHandler, CMD_ENABLE_TRAFFIC_STATS_POLL, 1, 0);
+ msg = Message.obtain(mAsyncServiceHandler,
+ WifiManager.CMD_ENABLE_TRAFFIC_STATS_POLL, 1, 0);
} else {
- msg = Message.obtain(mAsyncServiceHandler, CMD_ENABLE_TRAFFIC_STATS_POLL, 0, 0);
+ msg = Message.obtain(mAsyncServiceHandler,
+ WifiManager.CMD_ENABLE_TRAFFIC_STATS_POLL, 0, 0);
}
msg.sendToTarget();
}
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index 8d30868..ea49661 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -9114,15 +9114,17 @@
ServiceRecord.StartItem si = r.pendingStarts.remove(0);
if (DEBUG_SERVICE) Slog.v(TAG, "Sending arguments to: "
+ r + " " + r.intent + " args=" + si.intent);
- if (si.intent == null) {
- // If somehow we got a dummy start at the front, then
- // just drop it here.
+ if (si.intent == null && N > 1) {
+ // If somehow we got a dummy null intent in the middle,
+ // then skip it. DO NOT skip a null intent when it is
+ // the only one in the list -- this is to support the
+ // onStartCommand(null) case.
continue;
}
si.deliveredTime = SystemClock.uptimeMillis();
r.deliveredStarts.add(si);
si.deliveryCount++;
- if (si.targetPermissionUid >= 0) {
+ if (si.targetPermissionUid >= 0 && si.intent != null) {
grantUriPermissionUncheckedFromIntentLocked(si.targetPermissionUid,
r.packageName, si.intent, si.getUriPermissionsLocked());
}
diff --git a/services/java/com/android/server/connectivity/Tethering.java b/services/java/com/android/server/connectivity/Tethering.java
index f24f96c..1eb5141 100644
--- a/services/java/com/android/server/connectivity/Tethering.java
+++ b/services/java/com/android/server/connectivity/Tethering.java
@@ -26,7 +26,7 @@
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.content.res.Resources;
-import android.hardware.UsbManager;
+import android.hardware.usb.UsbManager;
import android.net.ConnectivityManager;
import android.net.InterfaceConfiguration;
import android.net.IConnectivityManager;
diff --git a/services/java/com/android/server/usb/UsbDeviceSettingsManager.java b/services/java/com/android/server/usb/UsbDeviceSettingsManager.java
index 21eb7dc..9a96e7f 100644
--- a/services/java/com/android/server/usb/UsbDeviceSettingsManager.java
+++ b/services/java/com/android/server/usb/UsbDeviceSettingsManager.java
@@ -25,10 +25,10 @@
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.ResolveInfo;
import android.content.res.XmlResourceParser;
-import android.hardware.UsbAccessory;
-import android.hardware.UsbDevice;
-import android.hardware.UsbInterface;
-import android.hardware.UsbManager;
+import android.hardware.usb.UsbAccessory;
+import android.hardware.usb.UsbDevice;
+import android.hardware.usb.UsbInterface;
+import android.hardware.usb.UsbManager;
import android.os.Binder;
import android.os.FileUtils;
import android.os.Process;
@@ -64,18 +64,20 @@
private final Context mContext;
// maps UID to user approved USB devices
- final SparseArray<ArrayList<DeviceFilter>> mDevicePermissionMap =
+ private final SparseArray<ArrayList<DeviceFilter>> mDevicePermissionMap =
new SparseArray<ArrayList<DeviceFilter>>();
// maps UID to user approved USB accessories
- final SparseArray<ArrayList<AccessoryFilter>> mAccessoryPermissionMap =
+ private final SparseArray<ArrayList<AccessoryFilter>> mAccessoryPermissionMap =
new SparseArray<ArrayList<AccessoryFilter>>();
// Maps DeviceFilter to user preferred application package
- final HashMap<DeviceFilter, String> mDevicePreferenceMap =
+ private final HashMap<DeviceFilter, String> mDevicePreferenceMap =
new HashMap<DeviceFilter, String>();
// Maps DeviceFilter to user preferred application package
- final HashMap<AccessoryFilter, String> mAccessoryPreferenceMap =
+ private final HashMap<AccessoryFilter, String> mAccessoryPreferenceMap =
new HashMap<AccessoryFilter, String>();
+ private final Object mLock = new Object();
+
// This class is used to describe a USB device.
// When used in HashMaps all values must be specified,
// but wildcards can be used for any of the fields in
@@ -343,16 +345,20 @@
private class MyPackageMonitor extends PackageMonitor {
public void onPackageRemoved(String packageName, int uid) {
- // clear all activity preferences for the package
- if (clearPackageDefaults(packageName)) {
- writeSettings();
+ synchronized (mLock) {
+ // clear all activity preferences for the package
+ if (clearPackageDefaultsLocked(packageName)) {
+ writeSettingsLocked();
+ }
}
}
public void onUidRemoved(int uid) {
- // clear all permissions for the UID
- if (clearUidDefaults(uid)) {
- writeSettings();
+ synchronized (mLock) {
+ // clear all permissions for the UID
+ if (clearUidDefaultsLocked(uid)) {
+ writeSettingsLocked();
+ }
}
}
}
@@ -360,7 +366,9 @@
public UsbDeviceSettingsManager(Context context) {
mContext = context;
- readSettings();
+ synchronized (mLock) {
+ readSettingsLocked();
+ }
mPackageMonitor.register(context, true);
}
@@ -423,7 +431,7 @@
XmlUtils.nextElement(parser);
}
- private void readSettings() {
+ private void readSettingsLocked() {
FileInputStream stream = null;
try {
stream = new FileInputStream(sSettingsFile);
@@ -458,7 +466,7 @@
}
}
- private void writeSettings() {
+ private void writeSettingsLocked() {
FileOutputStream fos = null;
try {
FileOutputStream fstr = new FileOutputStream(sSettingsFile);
@@ -524,7 +532,7 @@
// Checks to see if a package matches a device or accessory.
// Only one of device and accessory should be non-null.
- private boolean packageMatches(ResolveInfo info, String metaDataName,
+ private boolean packageMatchesLocked(ResolveInfo info, String metaDataName,
UsbDevice device, UsbAccessory accessory) {
ActivityInfo ai = info.activityInfo;
PackageManager pm = mContext.getPackageManager();
@@ -562,7 +570,7 @@
return false;
}
- private final ArrayList<ResolveInfo> getDeviceMatches(UsbDevice device, Intent intent) {
+ private final ArrayList<ResolveInfo> getDeviceMatchesLocked(UsbDevice device, Intent intent) {
ArrayList<ResolveInfo> matches = new ArrayList<ResolveInfo>();
PackageManager pm = mContext.getPackageManager();
List<ResolveInfo> resolveInfos = pm.queryIntentActivities(intent,
@@ -570,14 +578,15 @@
int count = resolveInfos.size();
for (int i = 0; i < count; i++) {
ResolveInfo resolveInfo = resolveInfos.get(i);
- if (packageMatches(resolveInfo, intent.getAction(), device, null)) {
+ if (packageMatchesLocked(resolveInfo, intent.getAction(), device, null)) {
matches.add(resolveInfo);
}
}
return matches;
}
- private final ArrayList<ResolveInfo> getAccessoryMatches(UsbAccessory accessory, Intent intent) {
+ private final ArrayList<ResolveInfo> getAccessoryMatchesLocked(
+ UsbAccessory accessory, Intent intent) {
ArrayList<ResolveInfo> matches = new ArrayList<ResolveInfo>();
PackageManager pm = mContext.getPackageManager();
List<ResolveInfo> resolveInfos = pm.queryIntentActivities(intent,
@@ -585,7 +594,7 @@
int count = resolveInfos.size();
for (int i = 0; i < count; i++) {
ResolveInfo resolveInfo = resolveInfos.get(i);
- if (packageMatches(resolveInfo, intent.getAction(), null, accessory)) {
+ if (packageMatchesLocked(resolveInfo, intent.getAction(), null, accessory)) {
matches.add(resolveInfo);
}
}
@@ -597,10 +606,15 @@
deviceIntent.putExtra(UsbManager.EXTRA_DEVICE, device);
deviceIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- ArrayList<ResolveInfo> matches = getDeviceMatches(device, deviceIntent);
- // Launch our default activity directly, if we have one.
- // Otherwise we will start the UsbResolverActivity to allow the user to choose.
- String defaultPackage = mDevicePreferenceMap.get(new DeviceFilter(device));
+ ArrayList<ResolveInfo> matches;
+ String defaultPackage;
+ synchronized (mLock) {
+ matches = getDeviceMatchesLocked(device, deviceIntent);
+ // Launch our default activity directly, if we have one.
+ // Otherwise we will start the UsbResolverActivity to allow the user to choose.
+ defaultPackage = mDevicePreferenceMap.get(new DeviceFilter(device));
+ }
+
if (defaultPackage != null) {
int count = matches.size();
for (int i = 0; i < count; i++) {
@@ -623,8 +637,7 @@
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.putExtra(Intent.EXTRA_INTENT, deviceIntent);
- intent.putParcelableArrayListExtra(UsbResolverActivity.EXTRA_RESOLVE_INFOS,
- matches);
+ intent.putParcelableArrayListExtra(UsbResolverActivity.EXTRA_RESOLVE_INFOS, matches);
try {
mContext.startActivity(intent);
} catch (ActivityNotFoundException e) {
@@ -644,10 +657,15 @@
accessoryIntent.putExtra(UsbManager.EXTRA_ACCESSORY, accessory);
accessoryIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- ArrayList<ResolveInfo> matches = getAccessoryMatches(accessory, accessoryIntent);
- // Launch our default activity directly, if we have one.
- // Otherwise we will start the UsbResolverActivity to allow the user to choose.
- String defaultPackage = mAccessoryPreferenceMap.get(new AccessoryFilter(accessory));
+ ArrayList<ResolveInfo> matches;
+ String defaultPackage;
+ synchronized (mLock) {
+ matches = getAccessoryMatchesLocked(accessory, accessoryIntent);
+ // Launch our default activity directly, if we have one.
+ // Otherwise we will start the UsbResolverActivity to allow the user to choose.
+ defaultPackage = mAccessoryPreferenceMap.get(new AccessoryFilter(accessory));
+ }
+
if (defaultPackage != null) {
int count = matches.size();
for (int i = 0; i < count; i++) {
@@ -670,8 +688,7 @@
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.putExtra(Intent.EXTRA_INTENT, accessoryIntent);
- intent.putParcelableArrayListExtra(UsbResolverActivity.EXTRA_RESOLVE_INFOS,
- matches);
+ intent.putParcelableArrayListExtra(UsbResolverActivity.EXTRA_RESOLVE_INFOS, matches);
try {
mContext.startActivity(intent);
} catch (ActivityNotFoundException e) {
@@ -688,14 +705,16 @@
public void checkPermission(UsbDevice device) {
if (device == null) return;
- ArrayList<DeviceFilter> filterList = mDevicePermissionMap.get(Binder.getCallingUid());
- if (filterList != null) {
- int count = filterList.size();
- for (int i = 0; i < count; i++) {
- DeviceFilter filter = filterList.get(i);
- if (filter.equals(device)) {
- // permission allowed
- return;
+ synchronized (mLock) {
+ ArrayList<DeviceFilter> filterList = mDevicePermissionMap.get(Binder.getCallingUid());
+ if (filterList != null) {
+ int count = filterList.size();
+ for (int i = 0; i < count; i++) {
+ DeviceFilter filter = filterList.get(i);
+ if (filter.equals(device)) {
+ // permission allowed
+ return;
+ }
}
}
}
@@ -704,14 +723,16 @@
public void checkPermission(UsbAccessory accessory) {
if (accessory == null) return;
- ArrayList<AccessoryFilter> filterList = mAccessoryPermissionMap.get(Binder.getCallingUid());
- if (filterList != null) {
- int count = filterList.size();
- for (int i = 0; i < count; i++) {
- AccessoryFilter filter = filterList.get(i);
- if (filter.equals(accessory)) {
- // permission allowed
- return;
+ synchronized (mLock) {
+ ArrayList<AccessoryFilter> filterList = mAccessoryPermissionMap.get(Binder.getCallingUid());
+ if (filterList != null) {
+ int count = filterList.size();
+ for (int i = 0; i < count; i++) {
+ AccessoryFilter filter = filterList.get(i);
+ if (filter.equals(accessory)) {
+ // permission allowed
+ return;
+ }
}
}
}
@@ -720,73 +741,95 @@
public void setDevicePackage(UsbDevice device, String packageName) {
DeviceFilter filter = new DeviceFilter(device);
- if (packageName == null) {
- mDevicePreferenceMap.remove(filter);
- } else {
- mDevicePreferenceMap.put(filter, packageName);
+ boolean changed = false;
+ synchronized (mLock) {
+ if (packageName == null) {
+ changed = (mDevicePreferenceMap.remove(filter) != null);
+ } else {
+ changed = !packageName.equals(mDevicePreferenceMap.get(filter));
+ if (changed) {
+ mDevicePreferenceMap.put(filter, packageName);
+ }
+ }
+ if (changed) {
+ writeSettingsLocked();
+ }
}
- // FIXME - only if changed
- writeSettings();
}
public void setAccessoryPackage(UsbAccessory accessory, String packageName) {
AccessoryFilter filter = new AccessoryFilter(accessory);
- if (packageName == null) {
- mAccessoryPreferenceMap.remove(filter);
- } else {
- mAccessoryPreferenceMap.put(filter, packageName);
+ boolean changed = false;
+ synchronized (mLock) {
+ if (packageName == null) {
+ changed = (mAccessoryPreferenceMap.remove(filter) != null);
+ } else {
+ changed = !packageName.equals(mAccessoryPreferenceMap.get(filter));
+ if (changed) {
+ mAccessoryPreferenceMap.put(filter, packageName);
+ }
+ }
+ if (changed) {
+ writeSettingsLocked();
+ }
}
- // FIXME - only if changed
- writeSettings();
}
public void grantDevicePermission(UsbDevice device, int uid) {
- ArrayList<DeviceFilter> filterList = mDevicePermissionMap.get(uid);
- if (filterList == null) {
- filterList = new ArrayList<DeviceFilter>();
- mDevicePermissionMap.put(uid, filterList);
- } else {
- int count = filterList.size();
- for (int i = 0; i < count; i++) {
- if (filterList.get(i).equals(device)) return;
+ synchronized (mLock) {
+ ArrayList<DeviceFilter> filterList = mDevicePermissionMap.get(uid);
+ if (filterList == null) {
+ filterList = new ArrayList<DeviceFilter>();
+ mDevicePermissionMap.put(uid, filterList);
+ } else {
+ int count = filterList.size();
+ for (int i = 0; i < count; i++) {
+ if (filterList.get(i).equals(device)) return;
+ }
}
+ filterList.add(new DeviceFilter(device));
+ writeSettingsLocked();
}
- filterList.add(new DeviceFilter(device));
- writeSettings();
}
public void grantAccessoryPermission(UsbAccessory accessory, int uid) {
- ArrayList<AccessoryFilter> filterList = mAccessoryPermissionMap.get(uid);
- if (filterList == null) {
- filterList = new ArrayList<AccessoryFilter>();
- mAccessoryPermissionMap.put(uid, filterList);
- } else {
- int count = filterList.size();
- for (int i = 0; i < count; i++) {
- if (filterList.get(i).equals(accessory)) return;
+ synchronized (mLock) {
+ ArrayList<AccessoryFilter> filterList = mAccessoryPermissionMap.get(uid);
+ if (filterList == null) {
+ filterList = new ArrayList<AccessoryFilter>();
+ mAccessoryPermissionMap.put(uid, filterList);
+ } else {
+ int count = filterList.size();
+ for (int i = 0; i < count; i++) {
+ if (filterList.get(i).equals(accessory)) return;
+ }
}
+ filterList.add(new AccessoryFilter(accessory));
+ writeSettingsLocked();
}
- filterList.add(new AccessoryFilter(accessory));
- writeSettings();
}
public boolean hasDefaults(String packageName, int uid) {
- if (mDevicePermissionMap.get(uid) != null) return true;
- if (mAccessoryPermissionMap.get(uid) != null) return true;
- if (mDevicePreferenceMap.values().contains(packageName)) return true;
- if (mAccessoryPreferenceMap.values().contains(packageName)) return true;
- return false;
- }
-
- public void clearDefaults(String packageName, int uid) {
- boolean packageCleared = clearPackageDefaults(packageName);
- boolean uidCleared = clearUidDefaults(uid);
- if (packageCleared || uidCleared) {
- writeSettings();
+ synchronized (mLock) {
+ if (mDevicePermissionMap.get(uid) != null) return true;
+ if (mAccessoryPermissionMap.get(uid) != null) return true;
+ if (mDevicePreferenceMap.values().contains(packageName)) return true;
+ if (mAccessoryPreferenceMap.values().contains(packageName)) return true;
+ return false;
}
}
- private boolean clearUidDefaults(int uid) {
+ public void clearDefaults(String packageName, int uid) {
+ synchronized (mLock) {
+ boolean packageCleared = clearPackageDefaultsLocked(packageName);
+ boolean uidCleared = clearUidDefaultsLocked(uid);
+ if (packageCleared || uidCleared) {
+ writeSettingsLocked();
+ }
+ }
+ }
+
+ private boolean clearUidDefaultsLocked(int uid) {
boolean cleared = false;
int index = mDevicePermissionMap.indexOfKey(uid);
if (index >= 0) {
@@ -801,61 +844,65 @@
return cleared;
}
- private boolean clearPackageDefaults(String packageName) {
+ private boolean clearPackageDefaultsLocked(String packageName) {
boolean cleared = false;
- if (mDevicePreferenceMap.containsValue(packageName)) {
- // make a copy of the key set to avoid ConcurrentModificationException
- Object[] keys = mDevicePreferenceMap.keySet().toArray();
- for (int i = 0; i < keys.length; i++) {
- Object key = keys[i];
- if (packageName.equals(mDevicePreferenceMap.get(key))) {
- mDevicePreferenceMap.remove(key);
- cleared = true;
+ synchronized (mLock) {
+ if (mDevicePreferenceMap.containsValue(packageName)) {
+ // make a copy of the key set to avoid ConcurrentModificationException
+ Object[] keys = mDevicePreferenceMap.keySet().toArray();
+ for (int i = 0; i < keys.length; i++) {
+ Object key = keys[i];
+ if (packageName.equals(mDevicePreferenceMap.get(key))) {
+ mDevicePreferenceMap.remove(key);
+ cleared = true;
+ }
}
}
- }
- if (mAccessoryPreferenceMap.containsValue(packageName)) {
- // make a copy of the key set to avoid ConcurrentModificationException
- Object[] keys = mAccessoryPreferenceMap.keySet().toArray();
- for (int i = 0; i < keys.length; i++) {
- Object key = keys[i];
- if (packageName.equals(mAccessoryPreferenceMap.get(key))) {
- mAccessoryPreferenceMap.remove(key);
- cleared = true;
+ if (mAccessoryPreferenceMap.containsValue(packageName)) {
+ // make a copy of the key set to avoid ConcurrentModificationException
+ Object[] keys = mAccessoryPreferenceMap.keySet().toArray();
+ for (int i = 0; i < keys.length; i++) {
+ Object key = keys[i];
+ if (packageName.equals(mAccessoryPreferenceMap.get(key))) {
+ mAccessoryPreferenceMap.remove(key);
+ cleared = true;
+ }
}
}
+ return cleared;
}
- return cleared;
}
public void dump(FileDescriptor fd, PrintWriter pw) {
- pw.println(" Device permissions:");
- int count = mDevicePermissionMap.size();
- for (int i = 0; i < count; i++) {
- int uid = mDevicePermissionMap.keyAt(i);
- pw.println(" " + "uid " + uid + ":");
- ArrayList<DeviceFilter> filters = mDevicePermissionMap.valueAt(i);
- for (DeviceFilter filter : filters) {
- pw.println(" " + filter);
+ synchronized (mLock) {
+ pw.println(" Device permissions:");
+ int count = mDevicePermissionMap.size();
+ for (int i = 0; i < count; i++) {
+ int uid = mDevicePermissionMap.keyAt(i);
+ pw.println(" " + "uid " + uid + ":");
+ ArrayList<DeviceFilter> filters = mDevicePermissionMap.valueAt(i);
+ for (DeviceFilter filter : filters) {
+ pw.println(" " + filter);
+ }
}
- }
- pw.println(" Accessory permissions:");
- count = mAccessoryPermissionMap.size();
- for (int i = 0; i < count; i++) {
- int uid = mAccessoryPermissionMap.keyAt(i);
- pw.println(" " + "uid " + uid + ":");
- ArrayList<AccessoryFilter> filters = mAccessoryPermissionMap.valueAt(i);
- for (AccessoryFilter filter : filters) {
- pw.println(" " + filter);
+ pw.println(" Accessory permissions:");
+ count = mAccessoryPermissionMap.size();
+ for (int i = 0; i < count; i++) {
+ int uid = mAccessoryPermissionMap.keyAt(i);
+ pw.println(" " + "uid " + uid + ":");
+ ArrayList<AccessoryFilter> filters = mAccessoryPermissionMap.valueAt(i);
+ for (AccessoryFilter filter : filters) {
+ pw.println(" " + filter);
+ }
}
- }
- pw.println(" Device preferences:");
- for (DeviceFilter filter : mDevicePreferenceMap.keySet()) {
- pw.println(" " + filter + ": " + mDevicePreferenceMap.get(filter));
- }
- pw.println(" Accessory preferences:");
- for (AccessoryFilter filter : mAccessoryPreferenceMap.keySet()) {
- pw.println(" " + filter + ": " + mAccessoryPreferenceMap.get(filter));
+ pw.println(" Device preferences:");
+ for (DeviceFilter filter : mDevicePreferenceMap.keySet()) {
+ pw.println(" " + filter + ": " + mDevicePreferenceMap.get(filter));
+ }
+ pw.println(" Accessory preferences:");
+ for (AccessoryFilter filter : mAccessoryPreferenceMap.keySet()) {
+ pw.println(" " + filter + ": " + mAccessoryPreferenceMap.get(filter));
+ }
}
}
}
diff --git a/services/java/com/android/server/usb/UsbResolverActivity.java b/services/java/com/android/server/usb/UsbResolverActivity.java
index 1bb3c21..e8a09a5 100644
--- a/services/java/com/android/server/usb/UsbResolverActivity.java
+++ b/services/java/com/android/server/usb/UsbResolverActivity.java
@@ -21,10 +21,10 @@
import android.content.ActivityNotFoundException;
import android.content.Intent;
import android.content.pm.ResolveInfo;
-import android.hardware.IUsbManager;
-import android.hardware.UsbAccessory;
-import android.hardware.UsbDevice;
-import android.hardware.UsbManager;
+import android.hardware.usb.IUsbManager;
+import android.hardware.usb.UsbAccessory;
+import android.hardware.usb.UsbDevice;
+import android.hardware.usb.UsbManager;
import android.os.Bundle;
import android.os.IBinder;
import android.os.Parcelable;
diff --git a/services/java/com/android/server/usb/UsbService.java b/services/java/com/android/server/usb/UsbService.java
index a093d95..94c25e9 100644
--- a/services/java/com/android/server/usb/UsbService.java
+++ b/services/java/com/android/server/usb/UsbService.java
@@ -20,13 +20,13 @@
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
-import android.hardware.IUsbManager;
-import android.hardware.UsbAccessory;
-import android.hardware.UsbConstants;
-import android.hardware.UsbDevice;
-import android.hardware.UsbEndpoint;
-import android.hardware.UsbInterface;
-import android.hardware.UsbManager;
+import android.hardware.usb.IUsbManager;
+import android.hardware.usb.UsbAccessory;
+import android.hardware.usb.UsbConstants;
+import android.hardware.usb.UsbDevice;
+import android.hardware.usb.UsbEndpoint;
+import android.hardware.usb.UsbInterface;
+import android.hardware.usb.UsbManager;
import android.net.Uri;
import android.os.Binder;
import android.os.Bundle;
@@ -454,45 +454,33 @@
}
public void setDevicePackage(UsbDevice device, String packageName) {
- synchronized (mLock) {
- mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USB, null);
- mDeviceManager.setDevicePackage(device, packageName);
- }
+ mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USB, null);
+ mDeviceManager.setDevicePackage(device, packageName);
}
public void setAccessoryPackage(UsbAccessory accessory, String packageName) {
- synchronized (mLock) {
- mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USB, null);
- mDeviceManager.setAccessoryPackage(accessory, packageName);
- }
+ mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USB, null);
+ mDeviceManager.setAccessoryPackage(accessory, packageName);
}
public void grantDevicePermission(UsbDevice device, int uid) {
- synchronized (mLock) {
- mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USB, null);
- mDeviceManager.grantDevicePermission(device, uid);
- }
+ mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USB, null);
+ mDeviceManager.grantDevicePermission(device, uid);
}
public void grantAccessoryPermission(UsbAccessory accessory, int uid) {
- synchronized (mLock) {
- mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USB, null);
- mDeviceManager.grantAccessoryPermission(accessory, uid);
- }
+ mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USB, null);
+ mDeviceManager.grantAccessoryPermission(accessory, uid);
}
public boolean hasDefaults(String packageName, int uid) {
- synchronized (mLock) {
- mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USB, null);
- return mDeviceManager.hasDefaults(packageName, uid);
- }
+ mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USB, null);
+ return mDeviceManager.hasDefaults(packageName, uid);
}
public void clearDefaults(String packageName, int uid) {
- synchronized (mLock) {
- mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USB, null);
- mDeviceManager.clearDefaults(packageName, uid);
- }
+ mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USB, null);
+ mDeviceManager.clearDefaults(packageName, uid);
}
/*
diff --git a/wifi/java/android/net/wifi/IWifiManager.aidl b/wifi/java/android/net/wifi/IWifiManager.aidl
index 7a9276d..1d115b1 100644
--- a/wifi/java/android/net/wifi/IWifiManager.aidl
+++ b/wifi/java/android/net/wifi/IWifiManager.aidl
@@ -103,16 +103,6 @@
void clearBlacklist();
- void connectNetworkWithConfig(in WifiConfiguration wifiConfig);
-
- void connectNetworkWithId(int networkId);
-
- void saveNetwork(in WifiConfiguration wifiConfig);
-
- void forgetNetwork(int networkId);
-
- WpsResult startWps(in WpsConfiguration config);
-
Messenger getMessenger();
}
diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java
index 0807a24..5238899 100644
--- a/wifi/java/android/net/wifi/WifiManager.java
+++ b/wifi/java/android/net/wifi/WifiManager.java
@@ -18,6 +18,7 @@
import android.annotation.SdkConstant;
import android.annotation.SdkConstant.SdkConstantType;
+import android.content.Context;
import android.net.DhcpInfo;
import android.os.Binder;
import android.os.IBinder;
@@ -26,6 +27,8 @@
import android.os.WorkSource;
import android.os.Messenger;
+import com.android.internal.util.AsyncChannel;
+
import java.util.List;
/**
@@ -447,6 +450,9 @@
/* Number of currently active WifiLocks and MulticastLocks */
private int mActiveLockCount;
+ /* For communication with WifiService */
+ private AsyncChannel mAsyncChannel = new AsyncChannel();
+
/**
* Create a new WifiManager instance.
* Applications will almost always want to use
@@ -1032,6 +1038,37 @@
}
/* TODO: deprecate synchronous API and open up the following API */
+
+ /* Commands to WifiService */
+ /** @hide */
+ public static final int CMD_CONNECT_NETWORK = 1;
+ /** @hide */
+ public static final int CMD_FORGET_NETWORK = 2;
+ /** @hide */
+ public static final int CMD_SAVE_NETWORK = 3;
+ /** @hide */
+ public static final int CMD_START_WPS = 4;
+
+ /* Events from WifiService */
+ /** @hide */
+ public static final int CMD_WPS_COMPLETED = 11;
+
+ /* For system use only */
+ /** @hide */
+ public static final int CMD_ENABLE_TRAFFIC_STATS_POLL = 21;
+ /** @hide */
+ public static final int CMD_TRAFFIC_STATS_POLL = 22;
+
+ /**
+ * Initiate an asynchronous channel connection setup
+ * @param srcContext is the context of the source
+ * @param srcHandler is the handler on which the source receives messages
+ * @hide
+ */
+ public void asyncConnect(Context srcContext, Handler srcHandler) {
+ mAsyncChannel.connect(srcContext, srcHandler, getMessenger());
+ }
+
/**
* Connect to a network with the given configuration. The network also
* gets added to the supplicant configuration.
@@ -1048,9 +1085,7 @@
if (config == null) {
return;
}
- try {
- mService.connectNetworkWithConfig(config);
- } catch (RemoteException e) { }
+ mAsyncChannel.sendMessage(CMD_CONNECT_NETWORK, config);
}
/**
@@ -1067,9 +1102,7 @@
if (networkId < 0) {
return;
}
- try {
- mService.connectNetworkWithId(networkId);
- } catch (RemoteException e) { }
+ mAsyncChannel.sendMessage(CMD_CONNECT_NETWORK, networkId);
}
/**
@@ -1091,9 +1124,8 @@
if (config == null) {
return;
}
- try {
- mService.saveNetwork(config);
- } catch (RemoteException e) { }
+
+ mAsyncChannel.sendMessage(CMD_SAVE_NETWORK, config);
}
/**
@@ -1110,25 +1142,22 @@
if (netId < 0) {
return;
}
- try {
- mService.forgetNetwork(netId);
- } catch (RemoteException e) { }
+
+ mAsyncChannel.sendMessage(CMD_FORGET_NETWORK, netId);
}
/**
* Start Wi-fi Protected Setup
*
* @param config WPS configuration
- * @return WpsResult containing pin and status
* @hide
- * TODO: with use of AsyncChannel, return value should go away
*/
- public WpsResult startWps(WpsConfiguration config) {
- try {
- return mService.startWps(config);
- } catch (RemoteException e) {
- return new WpsResult(WpsResult.Status.FAILURE);
+ public void startWps(WpsConfiguration config) {
+ if (config == null) {
+ return;
}
+
+ mAsyncChannel.sendMessage(CMD_START_WPS, config);
}
/**
diff --git a/wifi/java/android/net/wifi/WifiStateMachine.java b/wifi/java/android/net/wifi/WifiStateMachine.java
index f9d2772..d6f8e51 100644
--- a/wifi/java/android/net/wifi/WifiStateMachine.java
+++ b/wifi/java/android/net/wifi/WifiStateMachine.java
@@ -59,6 +59,7 @@
import android.os.IBinder;
import android.os.INetworkManagementService;
import android.os.Message;
+import android.os.Messenger;
import android.os.PowerManager;
import android.os.Process;
import android.os.RemoteException;
@@ -805,22 +806,10 @@
sendMessage(obtainMessage(CMD_FORGET_NETWORK, netId, 0));
}
- public WpsResult startWps(AsyncChannel channel, WpsConfiguration config) {
- WpsResult result;
- switch (config.setup) {
- case PIN_FROM_DEVICE:
- case PBC:
- case PIN_FROM_ACCESS_POINT:
- //TODO: will go away with AsyncChannel use from settings
- Message resultMsg = channel.sendMessageSynchronously(CMD_START_WPS, config);
- result = (WpsResult) resultMsg.obj;
- resultMsg.recycle();
- break;
- default:
- result = new WpsResult(Status.FAILURE);
- break;
- }
- return result;
+ public void startWps(Messenger replyTo, WpsConfiguration config) {
+ Message msg = obtainMessage(CMD_START_WPS, config);
+ msg.replyTo = replyTo;
+ sendMessage(msg);
}
public void enableRssiPolling(boolean enabled) {
@@ -1588,7 +1577,7 @@
break;
case CMD_START_WPS:
/* Return failure when the state machine cannot handle WPS initiation*/
- mReplyChannel.replyToMessage(message, message.what,
+ mReplyChannel.replyToMessage(message, WifiManager.CMD_WPS_COMPLETED,
new WpsResult(Status.FAILURE));
break;
default:
diff --git a/wifi/java/android/net/wifi/WpsStateMachine.java b/wifi/java/android/net/wifi/WpsStateMachine.java
index 92f9f57..32d77a1 100644
--- a/wifi/java/android/net/wifi/WpsStateMachine.java
+++ b/wifi/java/android/net/wifi/WpsStateMachine.java
@@ -110,7 +110,7 @@
Log.e(TAG, "Invalid setup for WPS");
break;
}
- mReplyChannel.replyToMessage(message, message.what, result);
+ mReplyChannel.replyToMessage(message, WifiManager.CMD_WPS_COMPLETED, result);
if (result.status == Status.SUCCESS) {
transitionTo(mActiveState);
} else {
@@ -172,7 +172,7 @@
break;
case WifiStateMachine.CMD_START_WPS:
/* Ignore request and send an in progress message */
- mReplyChannel.replyToMessage(message, message.what,
+ mReplyChannel.replyToMessage(message, WifiManager.CMD_WPS_COMPLETED,
new WpsResult(Status.IN_PROGRESS));
break;
default: