summaryrefslogtreecommitdiffstats
path: root/core/java/android
diff options
context:
space:
mode:
Diffstat (limited to 'core/java/android')
-rw-r--r--core/java/android/accounts/AccountAuthenticatorCache.java7
-rw-r--r--core/java/android/accounts/AccountManagerService.java187
-rw-r--r--core/java/android/accounts/IAccountAuthenticatorCache.java14
-rw-r--r--core/java/android/app/ActivityManager.java2
-rw-r--r--core/java/android/app/ActivityManagerNative.java6
-rw-r--r--core/java/android/app/ContextImpl.java14
-rw-r--r--core/java/android/app/IActivityManager.java2
-rwxr-xr-xcore/java/android/bluetooth/BluetoothA2dp.java13
-rwxr-xr-xcore/java/android/bluetooth/BluetoothHeadset.java23
-rw-r--r--core/java/android/bluetooth/BluetoothHealth.java11
-rwxr-xr-xcore/java/android/bluetooth/BluetoothInputDevice.java19
-rw-r--r--core/java/android/bluetooth/BluetoothPan.java13
-rwxr-xr-xcore/java/android/bluetooth/BluetoothPbap.java13
-rw-r--r--core/java/android/bluetooth/BluetoothSocket.java37
-rw-r--r--core/java/android/bluetooth/BluetoothTetheringDataTracker.java20
-rw-r--r--core/java/android/content/ContentService.java5
-rw-r--r--core/java/android/content/SyncManager.java244
-rw-r--r--core/java/android/content/SyncQueue.java42
-rw-r--r--core/java/android/content/pm/RegisteredServicesCache.java247
-rw-r--r--core/java/android/content/pm/RegisteredServicesCacheListener.java4
-rw-r--r--core/java/android/hardware/Camera.java36
-rw-r--r--core/java/android/os/UserManager.java35
-rw-r--r--core/java/android/provider/Settings.java44
-rw-r--r--core/java/android/service/dreams/DreamService.java2
-rw-r--r--core/java/android/view/ScaleGestureDetector.java9
-rw-r--r--core/java/android/view/Surface.java18
-rw-r--r--core/java/android/view/View.java18
-rw-r--r--core/java/android/widget/LinearLayout.java6
28 files changed, 661 insertions, 430 deletions
diff --git a/core/java/android/accounts/AccountAuthenticatorCache.java b/core/java/android/accounts/AccountAuthenticatorCache.java
index 7214c50..f937cde 100644
--- a/core/java/android/accounts/AccountAuthenticatorCache.java
+++ b/core/java/android/accounts/AccountAuthenticatorCache.java
@@ -16,17 +16,18 @@
package android.accounts;
+import android.content.Context;
import android.content.pm.PackageManager;
import android.content.pm.RegisteredServicesCache;
import android.content.pm.XmlSerializerAndParser;
import android.content.res.Resources;
import android.content.res.TypedArray;
-import android.content.Context;
-import android.util.AttributeSet;
import android.text.TextUtils;
+import android.util.AttributeSet;
+
import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlSerializer;
import org.xmlpull.v1.XmlPullParserException;
+import org.xmlpull.v1.XmlSerializer;
import java.io.IOException;
diff --git a/core/java/android/accounts/AccountManagerService.java b/core/java/android/accounts/AccountManagerService.java
index fc569e0..5cde65c 100644
--- a/core/java/android/accounts/AccountManagerService.java
+++ b/core/java/android/accounts/AccountManagerService.java
@@ -18,7 +18,7 @@ package android.accounts;
import android.Manifest;
import android.app.ActivityManager;
-import android.app.AppGlobals;
+import android.app.ActivityManagerNative;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
@@ -32,10 +32,10 @@ import android.content.ServiceConnection;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.RegisteredServicesCache;
import android.content.pm.RegisteredServicesCacheListener;
import android.content.pm.UserInfo;
-import android.content.res.Resources;
import android.database.Cursor;
import android.database.DatabaseUtils;
import android.database.sqlite.SQLiteDatabase;
@@ -55,10 +55,13 @@ import android.os.UserManager;
import android.text.TextUtils;
import android.util.Log;
import android.util.Pair;
+import android.util.Slog;
import android.util.SparseArray;
import com.android.internal.R;
import com.android.internal.util.IndentingPrintWriter;
+import com.google.android.collect.Lists;
+import com.google.android.collect.Sets;
import java.io.File;
import java.io.FileDescriptor;
@@ -67,6 +70,7 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
@@ -243,8 +247,7 @@ public class AccountManagerService
}
public void systemReady() {
- mAuthenticatorCache.generateServicesMap();
- initUser(0);
+ initUser(UserHandle.USER_OWNER);
}
private UserManager getUserManager() {
@@ -261,7 +264,7 @@ public class AccountManagerService
accounts = new UserAccounts(mContext, userId);
mUsers.append(userId, accounts);
purgeOldGrants(accounts);
- validateAccountsAndPopulateCache(accounts);
+ validateAccountsInternal(accounts, true /* invalidateAuthenticatorCache */);
}
return accounts;
}
@@ -299,7 +302,34 @@ public class AccountManagerService
}
}
- private void validateAccountsAndPopulateCache(UserAccounts accounts) {
+ /**
+ * Validate internal set of accounts against installed authenticators for
+ * given user. Clears cached authenticators before validating.
+ */
+ public void validateAccounts(int userId) {
+ final UserAccounts accounts = getUserAccounts(userId);
+
+ // Invalidate user-specific cache to make sure we catch any
+ // removed authenticators.
+ validateAccountsInternal(accounts, true /* invalidateAuthenticatorCache */);
+ }
+
+ /**
+ * Validate internal set of accounts against installed authenticators for
+ * given user. Clear cached authenticators before validating when requested.
+ */
+ private void validateAccountsInternal(
+ UserAccounts accounts, boolean invalidateAuthenticatorCache) {
+ if (invalidateAuthenticatorCache) {
+ mAuthenticatorCache.invalidateCache(accounts.userId);
+ }
+
+ final HashSet<AuthenticatorDescription> knownAuth = Sets.newHashSet();
+ for (RegisteredServicesCache.ServiceInfo<AuthenticatorDescription> service :
+ mAuthenticatorCache.getAllServices(accounts.userId)) {
+ knownAuth.add(service.type);
+ }
+
synchronized (accounts.cacheLock) {
final SQLiteDatabase db = accounts.openHelper.getWritableDatabase();
boolean accountDeleted = false;
@@ -314,9 +344,9 @@ public class AccountManagerService
final long accountId = cursor.getLong(0);
final String accountType = cursor.getString(1);
final String accountName = cursor.getString(2);
- if (mAuthenticatorCache.getServiceInfo(
- AuthenticatorDescription.newKey(accountType)) == null) {
- Log.d(TAG, "deleting account " + accountName + " because type "
+
+ if (!knownAuth.contains(AuthenticatorDescription.newKey(accountType))) {
+ Slog.w(TAG, "deleting account " + accountName + " because type "
+ accountType + " no longer has a registered authenticator");
db.delete(TABLE_ACCOUNTS, ACCOUNTS_ID + "=" + accountId, null);
accountDeleted = true;
@@ -390,20 +420,10 @@ public class AccountManagerService
}
}
- private List<UserInfo> getAllUsers() {
- return getUserManager().getUsers();
- }
-
- public void onServiceChanged(AuthenticatorDescription desc, boolean removed) {
- // Validate accounts for all users
- List<UserInfo> users = getAllUsers();
- if (users == null) {
- validateAccountsAndPopulateCache(getUserAccountsForCaller());
- } else {
- for (UserInfo user : users) {
- validateAccountsAndPopulateCache(getUserAccounts(user.id));
- }
- }
+ @Override
+ public void onServiceChanged(AuthenticatorDescription desc, int userId, boolean removed) {
+ Slog.d(TAG, "onServiceChanged() for userId " + userId);
+ validateAccountsInternal(getUserAccounts(userId), false /* invalidateAuthenticatorCache */);
}
public String getPassword(Account account) {
@@ -470,10 +490,11 @@ public class AccountManagerService
+ "caller's uid " + Binder.getCallingUid()
+ ", pid " + Binder.getCallingPid());
}
- long identityToken = clearCallingIdentity();
+ final int userId = UserHandle.getCallingUserId();
+ final long identityToken = clearCallingIdentity();
try {
Collection<AccountAuthenticatorCache.ServiceInfo<AuthenticatorDescription>>
- authenticatorCollection = mAuthenticatorCache.getAllServices();
+ authenticatorCollection = mAuthenticatorCache.getAllServices(userId);
AuthenticatorDescription[] types =
new AuthenticatorDescription[authenticatorCollection.size()];
int i = 0;
@@ -1055,9 +1076,9 @@ public class AccountManagerService
if (authTokenType == null) throw new IllegalArgumentException("authTokenType is null");
checkBinderPermission(Manifest.permission.USE_CREDENTIALS);
final UserAccounts accounts = getUserAccountsForCaller();
- AccountAuthenticatorCache.ServiceInfo<AuthenticatorDescription> authenticatorInfo =
- mAuthenticatorCache.getServiceInfo(
- AuthenticatorDescription.newKey(account.type));
+ final RegisteredServicesCache.ServiceInfo<AuthenticatorDescription> authenticatorInfo;
+ authenticatorInfo = mAuthenticatorCache.getServiceInfo(
+ AuthenticatorDescription.newKey(account.type), accounts.userId);
final boolean customTokens =
authenticatorInfo != null && authenticatorInfo.type.customTokens;
@@ -1074,7 +1095,7 @@ public class AccountManagerService
if (notifyOnAuthFailure) {
loginOptions.putBoolean(AccountManager.KEY_NOTIFY_ON_FAILURE, true);
}
-
+
long identityToken = clearCallingIdentity();
try {
// if the caller has permission, do the peek. otherwise go the more expensive
@@ -1183,28 +1204,6 @@ public class AccountManagerService
account, authTokenType, uid), n, user);
}
- String getAccountLabel(String accountType) {
- RegisteredServicesCache.ServiceInfo<AuthenticatorDescription> serviceInfo =
- mAuthenticatorCache.getServiceInfo(
- AuthenticatorDescription.newKey(accountType));
- if (serviceInfo == null) {
- throw new IllegalArgumentException("unknown account type: " + accountType);
- }
-
- final Context authContext;
- try {
- authContext = mContext.createPackageContext(
- serviceInfo.type.packageName, 0);
- } catch (PackageManager.NameNotFoundException e) {
- throw new IllegalArgumentException("unknown account type: " + accountType);
- }
- try {
- return authContext.getString(serviceInfo.type.labelId);
- } catch (Resources.NotFoundException e) {
- throw new IllegalArgumentException("unknown account type: " + accountType);
- }
- }
-
private Intent newGrantCredentialsPermissionIntent(Account account, int uid,
AccountAuthenticatorResponse response, String authTokenType, String authTokenLabel) {
@@ -1506,28 +1505,48 @@ public class AccountManagerService
}
/**
- * Returns all the accounts qualified by user.
+ * Returns accounts for all running users.
+ *
* @hide
*/
+ public AccountAndUser[] getRunningAccounts() {
+ final int[] runningUserIds;
+ try {
+ runningUserIds = ActivityManagerNative.getDefault().getRunningUserIds();
+ } catch (RemoteException e) {
+ // Running in system_server; should never happen
+ throw new RuntimeException(e);
+ }
+ return getAccounts(runningUserIds);
+ }
+
+ /** {@hide} */
public AccountAndUser[] getAllAccounts() {
- ArrayList<AccountAndUser> allAccounts = new ArrayList<AccountAndUser>();
- List<UserInfo> users = getAllUsers();
- if (users == null) return new AccountAndUser[0];
+ final List<UserInfo> users = getUserManager().getUsers();
+ final int[] userIds = new int[users.size()];
+ for (int i = 0; i < userIds.length; i++) {
+ userIds[i] = users.get(i).id;
+ }
+ return getAccounts(userIds);
+ }
- synchronized(mUsers) {
- for (UserInfo user : users) {
- UserAccounts userAccounts = getUserAccounts(user.id);
+ private AccountAndUser[] getAccounts(int[] userIds) {
+ final ArrayList<AccountAndUser> runningAccounts = Lists.newArrayList();
+ synchronized (mUsers) {
+ for (int userId : userIds) {
+ UserAccounts userAccounts = getUserAccounts(userId);
if (userAccounts == null) continue;
synchronized (userAccounts.cacheLock) {
Account[] accounts = getAccountsFromCacheLocked(userAccounts, null);
for (int a = 0; a < accounts.length; a++) {
- allAccounts.add(new AccountAndUser(accounts[a], user.id));
+ runningAccounts.add(new AccountAndUser(accounts[a], userId));
}
}
}
}
- AccountAndUser[] accountsArray = new AccountAndUser[allAccounts.size()];
- return allAccounts.toArray(accountsArray);
+
+ AccountAndUser[] accountsArray = new AccountAndUser[runningAccounts.size()];
+ return runningAccounts.toArray(accountsArray);
}
public Account[] getAccounts(String type) {
@@ -1836,9 +1855,9 @@ public class AccountManagerService
* if no authenticator or the bind fails then return false, otherwise return true
*/
private boolean bindToAuthenticator(String authenticatorType) {
- AccountAuthenticatorCache.ServiceInfo<AuthenticatorDescription> authenticatorInfo =
- mAuthenticatorCache.getServiceInfo(
- AuthenticatorDescription.newKey(authenticatorType));
+ final AccountAuthenticatorCache.ServiceInfo<AuthenticatorDescription> authenticatorInfo;
+ authenticatorInfo = mAuthenticatorCache.getServiceInfo(
+ AuthenticatorDescription.newKey(authenticatorType), mAccounts.userId);
if (authenticatorInfo == null) {
if (Log.isLoggable(TAG, Log.VERBOSE)) {
Log.v(TAG, "there is no authenticator for " + authenticatorType
@@ -2024,6 +2043,7 @@ public class AccountManagerService
return false;
}
+ @Override
protected void dump(FileDescriptor fd, PrintWriter fout, String[] args) {
if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
!= PackageManager.PERMISSION_GRANTED) {
@@ -2033,17 +2053,15 @@ public class AccountManagerService
return;
}
final boolean isCheckinRequest = scanArgs(args, "--checkin") || scanArgs(args, "-c");
+ final IndentingPrintWriter ipw = new IndentingPrintWriter(fout, " ");
- fout = new IndentingPrintWriter(fout, " ");
- int size = mUsers.size();
- for (int i = 0; i < size; i++) {
- fout.println("User " + mUsers.keyAt(i) + ":");
- ((IndentingPrintWriter) fout).increaseIndent();
- dumpUser(mUsers.valueAt(i), fd, fout, args, isCheckinRequest);
- ((IndentingPrintWriter) fout).decreaseIndent();
- if (i < size - 1) {
- fout.println();
- }
+ final List<UserInfo> users = getUserManager().getUsers();
+ for (UserInfo user : users) {
+ ipw.println("User " + user + ":");
+ ipw.increaseIndent();
+ dumpUser(getUserAccounts(user.id), fd, ipw, args, isCheckinRequest);
+ ipw.println();
+ ipw.decreaseIndent();
}
}
@@ -2083,7 +2101,7 @@ public class AccountManagerService
}
fout.println();
- mAuthenticatorCache.dump(fd, fout, args);
+ mAuthenticatorCache.dump(fd, fout, args, userAccounts.userId);
}
}
}
@@ -2154,11 +2172,21 @@ public class AccountManagerService
throw new SecurityException(msg);
}
- private boolean inSystemImage(int callerUid) {
- String[] packages = mPackageManager.getPackagesForUid(callerUid);
+ private boolean inSystemImage(int callingUid) {
+ final int callingUserId = UserHandle.getUserId(callingUid);
+
+ final PackageManager userPackageManager;
+ try {
+ userPackageManager = mContext.createPackageContextAsUser(
+ "android", 0, new UserHandle(callingUserId)).getPackageManager();
+ } catch (NameNotFoundException e) {
+ return false;
+ }
+
+ String[] packages = userPackageManager.getPackagesForUid(callingUid);
for (String name : packages) {
try {
- PackageInfo packageInfo = mPackageManager.getPackageInfo(name, 0 /* flags */);
+ PackageInfo packageInfo = userPackageManager.getPackageInfo(name, 0 /* flags */);
if (packageInfo != null
&& (packageInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
return true;
@@ -2186,8 +2214,9 @@ public class AccountManagerService
}
private boolean hasAuthenticatorUid(String accountType, int callingUid) {
+ final int callingUserId = UserHandle.getUserId(callingUid);
for (RegisteredServicesCache.ServiceInfo<AuthenticatorDescription> serviceInfo :
- mAuthenticatorCache.getAllServices()) {
+ mAuthenticatorCache.getAllServices(callingUserId)) {
if (serviceInfo.type.type.equals(accountType)) {
return (serviceInfo.uid == callingUid) ||
(mPackageManager.checkSignatures(serviceInfo.uid, callingUid)
diff --git a/core/java/android/accounts/IAccountAuthenticatorCache.java b/core/java/android/accounts/IAccountAuthenticatorCache.java
index 20dd585..06c2106 100644
--- a/core/java/android/accounts/IAccountAuthenticatorCache.java
+++ b/core/java/android/accounts/IAccountAuthenticatorCache.java
@@ -39,18 +39,19 @@ public interface IAccountAuthenticatorCache {
* matches the account type or null if none is present
*/
RegisteredServicesCache.ServiceInfo<AuthenticatorDescription> getServiceInfo(
- AuthenticatorDescription type);
+ AuthenticatorDescription type, int userId);
/**
* @return A copy of a Collection of all the current Authenticators.
*/
- Collection<RegisteredServicesCache.ServiceInfo<AuthenticatorDescription>> getAllServices();
+ Collection<RegisteredServicesCache.ServiceInfo<AuthenticatorDescription>> getAllServices(
+ int userId);
/**
* Dumps the state of the cache. See
* {@link android.os.Binder#dump(java.io.FileDescriptor, java.io.PrintWriter, String[])}
*/
- void dump(FileDescriptor fd, PrintWriter fout, String[] args);
+ void dump(FileDescriptor fd, PrintWriter fout, String[] args, int userId);
/**
* Sets a listener that will be notified whenever the authenticator set changes
@@ -61,8 +62,5 @@ public interface IAccountAuthenticatorCache {
void setListener(RegisteredServicesCacheListener<AuthenticatorDescription> listener,
Handler handler);
- /**
- * Refreshes the authenticator cache.
- */
- void generateServicesMap();
-} \ No newline at end of file
+ void invalidateCache(int userId);
+}
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index 0eda6b4..594be68 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -1981,7 +1981,7 @@ public class ActivityManager {
*/
public boolean isUserRunning(int userid) {
try {
- return ActivityManagerNative.getDefault().isUserRunning(userid);
+ return ActivityManagerNative.getDefault().isUserRunning(userid, false);
} catch (RemoteException e) {
return false;
}
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index bb62c9e..7492629 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -1608,7 +1608,8 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM
case IS_USER_RUNNING_TRANSACTION: {
data.enforceInterface(IActivityManager.descriptor);
int userid = data.readInt();
- boolean result = isUserRunning(userid);
+ boolean orStopping = data.readInt() != 0;
+ boolean result = isUserRunning(userid, orStopping);
reply.writeNoException();
reply.writeInt(result ? 1 : 0);
return true;
@@ -3865,11 +3866,12 @@ class ActivityManagerProxy implements IActivityManager
return userInfo;
}
- public boolean isUserRunning(int userid) throws RemoteException {
+ public boolean isUserRunning(int userid, boolean orStopping) throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
data.writeInterfaceToken(IActivityManager.descriptor);
data.writeInt(userid);
+ data.writeInt(orStopping ? 1 : 0);
mRemote.transact(IS_USER_RUNNING_TRANSACTION, data, reply, 0);
reply.readException();
boolean result = reply.readInt() != 0;
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index c324da9..3e1e358 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -1352,10 +1352,16 @@ class ContextImpl extends Context {
ComponentName cn = ActivityManagerNative.getDefault().startService(
mMainThread.getApplicationThread(), service,
service.resolveTypeIfNeeded(getContentResolver()), user.getIdentifier());
- if (cn != null && cn.getPackageName().equals("!")) {
- throw new SecurityException(
- "Not allowed to start service " + service
- + " without permission " + cn.getClassName());
+ if (cn != null) {
+ if (cn.getPackageName().equals("!")) {
+ throw new SecurityException(
+ "Not allowed to start service " + service
+ + " without permission " + cn.getClassName());
+ } else if (cn.getPackageName().equals("!!")) {
+ throw new SecurityException(
+ "Unable to start service " + service
+ + ": " + cn.getClassName());
+ }
}
return cn;
} catch (RemoteException e) {
diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java
index da844ef..97250e9 100644
--- a/core/java/android/app/IActivityManager.java
+++ b/core/java/android/app/IActivityManager.java
@@ -326,7 +326,7 @@ public interface IActivityManager extends IInterface {
public boolean switchUser(int userid) throws RemoteException;
public int stopUser(int userid, IStopUserCallback callback) throws RemoteException;
public UserInfo getCurrentUser() throws RemoteException;
- public boolean isUserRunning(int userid) throws RemoteException;
+ public boolean isUserRunning(int userid, boolean orStopping) throws RemoteException;
public int[] getRunningUserIds() throws RemoteException;
public boolean removeSubTask(int taskId, int subTaskIndex) throws RemoteException;
diff --git a/core/java/android/bluetooth/BluetoothA2dp.java b/core/java/android/bluetooth/BluetoothA2dp.java
index 6e2278d..6fdf3b4 100755
--- a/core/java/android/bluetooth/BluetoothA2dp.java
+++ b/core/java/android/bluetooth/BluetoothA2dp.java
@@ -45,6 +45,7 @@ import java.util.List;
public final class BluetoothA2dp implements BluetoothProfile {
private static final String TAG = "BluetoothA2dp";
private static final boolean DBG = true;
+ private static final boolean VDBG = false;
/**
* Intent used to broadcast the change in connection state of the A2DP
@@ -113,7 +114,7 @@ public final class BluetoothA2dp implements BluetoothProfile {
public void onBluetoothStateChange(boolean up) {
if (DBG) Log.d(TAG, "onBluetoothStateChange: up=" + up);
if (!up) {
- if (DBG) Log.d(TAG,"Unbinding service...");
+ if (VDBG) Log.d(TAG,"Unbinding service...");
synchronized (mConnection) {
try {
mService = null;
@@ -126,7 +127,7 @@ public final class BluetoothA2dp implements BluetoothProfile {
synchronized (mConnection) {
try {
if (mService == null) {
- if (DBG) Log.d(TAG,"Binding service...");
+ if (VDBG) Log.d(TAG,"Binding service...");
if (!mContext.bindService(new Intent(IBluetoothA2dp.class.getName()), mConnection, 0)) {
Log.e(TAG, "Could not bind to Bluetooth A2DP Service");
}
@@ -269,7 +270,7 @@ public final class BluetoothA2dp implements BluetoothProfile {
* {@inheritDoc}
*/
public List<BluetoothDevice> getConnectedDevices() {
- if (DBG) log("getConnectedDevices()");
+ if (VDBG) log("getConnectedDevices()");
if (mService != null && isEnabled()) {
try {
return mService.getConnectedDevices();
@@ -286,7 +287,7 @@ public final class BluetoothA2dp implements BluetoothProfile {
* {@inheritDoc}
*/
public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
- if (DBG) log("getDevicesMatchingStates()");
+ if (VDBG) log("getDevicesMatchingStates()");
if (mService != null && isEnabled()) {
try {
return mService.getDevicesMatchingConnectionStates(states);
@@ -303,7 +304,7 @@ public final class BluetoothA2dp implements BluetoothProfile {
* {@inheritDoc}
*/
public int getConnectionState(BluetoothDevice device) {
- if (DBG) log("getState(" + device + ")");
+ if (VDBG) log("getState(" + device + ")");
if (mService != null && isEnabled()
&& isValidDevice(device)) {
try {
@@ -365,7 +366,7 @@ public final class BluetoothA2dp implements BluetoothProfile {
* @hide
*/
public int getPriority(BluetoothDevice device) {
- if (DBG) log("getPriority(" + device + ")");
+ if (VDBG) log("getPriority(" + device + ")");
if (mService != null && isEnabled()
&& isValidDevice(device)) {
try {
diff --git a/core/java/android/bluetooth/BluetoothHeadset.java b/core/java/android/bluetooth/BluetoothHeadset.java
index 541b69f..793d798 100755
--- a/core/java/android/bluetooth/BluetoothHeadset.java
+++ b/core/java/android/bluetooth/BluetoothHeadset.java
@@ -46,6 +46,7 @@ import java.util.List;
public final class BluetoothHeadset implements BluetoothProfile {
private static final String TAG = "BluetoothHeadset";
private static final boolean DBG = true;
+ private static final boolean VDBG = false;
/**
* Intent used to broadcast the change in connection state of the Headset
@@ -226,7 +227,7 @@ public final class BluetoothHeadset implements BluetoothProfile {
public void onBluetoothStateChange(boolean up) {
if (DBG) Log.d(TAG, "onBluetoothStateChange: up=" + up);
if (!up) {
- if (DBG) Log.d(TAG,"Unbinding service...");
+ if (VDBG) Log.d(TAG,"Unbinding service...");
synchronized (mConnection) {
try {
mService = null;
@@ -239,7 +240,7 @@ public final class BluetoothHeadset implements BluetoothProfile {
synchronized (mConnection) {
try {
if (mService == null) {
- if (DBG) Log.d(TAG,"Binding service...");
+ if (VDBG) Log.d(TAG,"Binding service...");
if (!mContext.bindService(new Intent(IBluetoothHeadset.class.getName()), mConnection, 0)) {
Log.e(TAG, "Could not bind to Bluetooth Headset Service");
}
@@ -281,7 +282,7 @@ public final class BluetoothHeadset implements BluetoothProfile {
* are ok.
*/
/*package*/ void close() {
- if (DBG) log("close()");
+ if (VDBG) log("close()");
IBluetoothManager mgr = mAdapter.getBluetoothManager();
if (mgr != null) {
@@ -387,7 +388,7 @@ public final class BluetoothHeadset implements BluetoothProfile {
* {@inheritDoc}
*/
public List<BluetoothDevice> getConnectedDevices() {
- if (DBG) log("getConnectedDevices()");
+ if (VDBG) log("getConnectedDevices()");
if (mService != null && isEnabled()) {
try {
return mService.getConnectedDevices();
@@ -404,7 +405,7 @@ public final class BluetoothHeadset implements BluetoothProfile {
* {@inheritDoc}
*/
public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
- if (DBG) log("getDevicesMatchingStates()");
+ if (VDBG) log("getDevicesMatchingStates()");
if (mService != null && isEnabled()) {
try {
return mService.getDevicesMatchingConnectionStates(states);
@@ -421,7 +422,7 @@ public final class BluetoothHeadset implements BluetoothProfile {
* {@inheritDoc}
*/
public int getConnectionState(BluetoothDevice device) {
- if (DBG) log("getConnectionState(" + device + ")");
+ if (VDBG) log("getConnectionState(" + device + ")");
if (mService != null && isEnabled() &&
isValidDevice(device)) {
try {
@@ -483,7 +484,7 @@ public final class BluetoothHeadset implements BluetoothProfile {
* @hide
*/
public int getPriority(BluetoothDevice device) {
- if (DBG) log("getPriority(" + device + ")");
+ if (VDBG) log("getPriority(" + device + ")");
if (mService != null && isEnabled() &&
isValidDevice(device)) {
try {
@@ -566,7 +567,7 @@ public final class BluetoothHeadset implements BluetoothProfile {
* false otherwise or on error
*/
public boolean isAudioConnected(BluetoothDevice device) {
- if (DBG) log("isAudioConnected()");
+ if (VDBG) log("isAudioConnected()");
if (mService != null && isEnabled() &&
isValidDevice(device)) {
try {
@@ -594,7 +595,7 @@ public final class BluetoothHeadset implements BluetoothProfile {
* @hide
*/
public int getBatteryUsageHint(BluetoothDevice device) {
- if (DBG) log("getBatteryUsageHint()");
+ if (VDBG) log("getBatteryUsageHint()");
if (mService != null && isEnabled() &&
isValidDevice(device)) {
try {
@@ -661,7 +662,7 @@ public final class BluetoothHeadset implements BluetoothProfile {
* @hide
*/
public int getAudioState(BluetoothDevice device) {
- if (DBG) log("getAudioState");
+ if (VDBG) log("getAudioState");
if (mService != null && !isDisabled()) {
try {
return mService.getAudioState(device);
@@ -683,7 +684,7 @@ public final class BluetoothHeadset implements BluetoothProfile {
* @hide
*/
public boolean isAudioOn() {
- if (DBG) log("isAudioOn()");
+ if (VDBG) log("isAudioOn()");
if (mService != null && isEnabled()) {
try {
return mService.isAudioOn();
diff --git a/core/java/android/bluetooth/BluetoothHealth.java b/core/java/android/bluetooth/BluetoothHealth.java
index 4a0bc7e..cb23662 100644
--- a/core/java/android/bluetooth/BluetoothHealth.java
+++ b/core/java/android/bluetooth/BluetoothHealth.java
@@ -58,6 +58,7 @@ import java.util.List;
public final class BluetoothHealth implements BluetoothProfile {
private static final String TAG = "BluetoothHealth";
private static final boolean DBG = true;
+ private static final boolean VDBG = false;
/**
* Health Profile Source Role - the health device.
@@ -102,7 +103,7 @@ public final class BluetoothHealth implements BluetoothProfile {
public void onBluetoothStateChange(boolean up) {
if (DBG) Log.d(TAG, "onBluetoothStateChange: up=" + up);
if (!up) {
- if (DBG) Log.d(TAG,"Unbinding service...");
+ if (VDBG) Log.d(TAG,"Unbinding service...");
synchronized (mConnection) {
try {
mService = null;
@@ -115,7 +116,7 @@ public final class BluetoothHealth implements BluetoothProfile {
synchronized (mConnection) {
try {
if (mService == null) {
- if (DBG) Log.d(TAG,"Binding service...");
+ if (VDBG) Log.d(TAG,"Binding service...");
if (!mContext.bindService(new Intent(IBluetoothHealth.class.getName()), mConnection, 0)) {
Log.e(TAG, "Could not bind to Bluetooth Health Service");
}
@@ -148,7 +149,7 @@ public final class BluetoothHealth implements BluetoothProfile {
BluetoothHealthCallback callback) {
if (!isEnabled() || name == null) return false;
- if (DBG) log("registerSinkApplication(" + name + ":" + dataType + ")");
+ if (VDBG) log("registerSinkApplication(" + name + ":" + dataType + ")");
return registerAppConfiguration(name, dataType, SINK_ROLE,
CHANNEL_TYPE_ANY, callback);
}
@@ -174,7 +175,7 @@ public final class BluetoothHealth implements BluetoothProfile {
boolean result = false;
if (!isEnabled() || !checkAppParam(name, role, channelType, callback)) return result;
- if (DBG) log("registerApplication(" + name + ":" + dataType + ")");
+ if (VDBG) log("registerApplication(" + name + ":" + dataType + ")");
BluetoothHealthCallbackWrapper wrapper = new BluetoothHealthCallbackWrapper(callback);
BluetoothHealthAppConfiguration config =
new BluetoothHealthAppConfiguration(name, dataType, role, channelType);
@@ -488,7 +489,7 @@ public final class BluetoothHealth implements BluetoothProfile {
}
/*package*/ void close() {
- if (DBG) log("close()");
+ if (VDBG) log("close()");
IBluetoothManager mgr = mAdapter.getBluetoothManager();
if (mgr != null) {
try {
diff --git a/core/java/android/bluetooth/BluetoothInputDevice.java b/core/java/android/bluetooth/BluetoothInputDevice.java
index bff966d..db7e424 100755
--- a/core/java/android/bluetooth/BluetoothInputDevice.java
+++ b/core/java/android/bluetooth/BluetoothInputDevice.java
@@ -45,6 +45,7 @@ import java.util.List;
public final class BluetoothInputDevice implements BluetoothProfile {
private static final String TAG = "BluetoothInputDevice";
private static final boolean DBG = true;
+ private static final boolean VDBG = false;
/**
* Intent used to broadcast the change in connection state of the Input
@@ -191,7 +192,7 @@ public final class BluetoothInputDevice implements BluetoothProfile {
public void onBluetoothStateChange(boolean up) {
if (DBG) Log.d(TAG, "onBluetoothStateChange: up=" + up);
if (!up) {
- if (DBG) Log.d(TAG,"Unbinding service...");
+ if (VDBG) Log.d(TAG,"Unbinding service...");
synchronized (mConnection) {
try {
mService = null;
@@ -204,7 +205,7 @@ public final class BluetoothInputDevice implements BluetoothProfile {
synchronized (mConnection) {
try {
if (mService == null) {
- if (DBG) Log.d(TAG,"Binding service...");
+ if (VDBG) Log.d(TAG,"Binding service...");
if (!mContext.bindService(new Intent(IBluetoothInputDevice.class.getName()), mConnection, 0)) {
Log.e(TAG, "Could not bind to Bluetooth HID Service");
}
@@ -243,7 +244,7 @@ public final class BluetoothInputDevice implements BluetoothProfile {
}
/*package*/ void close() {
- if (DBG) log("close()");
+ if (VDBG) log("close()");
IBluetoothManager mgr = mAdapter.getBluetoothManager();
if (mgr != null) {
try {
@@ -344,7 +345,7 @@ public final class BluetoothInputDevice implements BluetoothProfile {
* {@inheritDoc}
*/
public List<BluetoothDevice> getConnectedDevices() {
- if (DBG) log("getConnectedDevices()");
+ if (VDBG) log("getConnectedDevices()");
if (mService != null && isEnabled()) {
try {
return mService.getConnectedDevices();
@@ -361,7 +362,7 @@ public final class BluetoothInputDevice implements BluetoothProfile {
* {@inheritDoc}
*/
public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
- if (DBG) log("getDevicesMatchingStates()");
+ if (VDBG) log("getDevicesMatchingStates()");
if (mService != null && isEnabled()) {
try {
return mService.getDevicesMatchingConnectionStates(states);
@@ -378,7 +379,7 @@ public final class BluetoothInputDevice implements BluetoothProfile {
* {@inheritDoc}
*/
public int getConnectionState(BluetoothDevice device) {
- if (DBG) log("getState(" + device + ")");
+ if (VDBG) log("getState(" + device + ")");
if (mService != null && isEnabled() && isValidDevice(device)) {
try {
return mService.getConnectionState(device);
@@ -438,7 +439,7 @@ public final class BluetoothInputDevice implements BluetoothProfile {
* @hide
*/
public int getPriority(BluetoothDevice device) {
- if (DBG) log("getPriority(" + device + ")");
+ if (VDBG) log("getPriority(" + device + ")");
if (mService != null && isEnabled() && isValidDevice(device)) {
try {
return mService.getPriority(device);
@@ -519,7 +520,7 @@ public final class BluetoothInputDevice implements BluetoothProfile {
* @hide
*/
public boolean getProtocolMode(BluetoothDevice device) {
- if (DBG) log("getProtocolMode(" + device + ")");
+ if (VDBG) log("getProtocolMode(" + device + ")");
if (mService != null && isEnabled() && isValidDevice(device)) {
try {
return mService.getProtocolMode(device);
@@ -570,7 +571,7 @@ public final class BluetoothInputDevice implements BluetoothProfile {
* @hide
*/
public boolean getReport(BluetoothDevice device, byte reportType, byte reportId, int bufferSize) {
- if (DBG) log("getReport(" + device + "), reportType=" + reportType + " reportId=" + reportId + "bufferSize=" + bufferSize);
+ if (VDBG) log("getReport(" + device + "), reportType=" + reportType + " reportId=" + reportId + "bufferSize=" + bufferSize);
if (mService != null && isEnabled() && isValidDevice(device)) {
try {
return mService.getReport(device, reportType, reportId, bufferSize);
diff --git a/core/java/android/bluetooth/BluetoothPan.java b/core/java/android/bluetooth/BluetoothPan.java
index cae7a73..e25ec86 100644
--- a/core/java/android/bluetooth/BluetoothPan.java
+++ b/core/java/android/bluetooth/BluetoothPan.java
@@ -44,6 +44,7 @@ import java.util.List;
public final class BluetoothPan implements BluetoothProfile {
private static final String TAG = "BluetoothPan";
private static final boolean DBG = true;
+ private static final boolean VDBG = false;
/**
* Intent used to broadcast the change in connection state of the Pan
@@ -145,7 +146,7 @@ public final class BluetoothPan implements BluetoothProfile {
}
/*package*/ void close() {
- if (DBG) log("close()");
+ if (VDBG) log("close()");
if (mConnection != null) {
mContext.unbindService(mConnection);
mConnection = null;
@@ -175,7 +176,7 @@ public final class BluetoothPan implements BluetoothProfile {
}
Log.d(TAG, "BluetoothPan(), bindService called");
} else {
- if (DBG) Log.d(TAG,"Unbinding service...");
+ if (VDBG) Log.d(TAG,"Unbinding service...");
synchronized (mConnection) {
try {
mPanService = null;
@@ -266,7 +267,7 @@ public final class BluetoothPan implements BluetoothProfile {
* {@inheritDoc}
*/
public List<BluetoothDevice> getConnectedDevices() {
- if (DBG) log("getConnectedDevices()");
+ if (VDBG) log("getConnectedDevices()");
if (mPanService != null && isEnabled()) {
try {
return mPanService.getConnectedDevices();
@@ -283,7 +284,7 @@ public final class BluetoothPan implements BluetoothProfile {
* {@inheritDoc}
*/
public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
- if (DBG) log("getDevicesMatchingStates()");
+ if (VDBG) log("getDevicesMatchingStates()");
if (mPanService != null && isEnabled()) {
try {
return mPanService.getDevicesMatchingConnectionStates(states);
@@ -300,7 +301,7 @@ public final class BluetoothPan implements BluetoothProfile {
* {@inheritDoc}
*/
public int getConnectionState(BluetoothDevice device) {
- if (DBG) log("getState(" + device + ")");
+ if (VDBG) log("getState(" + device + ")");
if (mPanService != null && isEnabled()
&& isValidDevice(device)) {
try {
@@ -324,7 +325,7 @@ public final class BluetoothPan implements BluetoothProfile {
}
public boolean isTetheringOn() {
- if (DBG) log("isTetheringOn()");
+ if (VDBG) log("isTetheringOn()");
try {
return mPanService.isTetheringOn();
} catch (RemoteException e) {
diff --git a/core/java/android/bluetooth/BluetoothPbap.java b/core/java/android/bluetooth/BluetoothPbap.java
index 7de2ef6..b5280e5 100755
--- a/core/java/android/bluetooth/BluetoothPbap.java
+++ b/core/java/android/bluetooth/BluetoothPbap.java
@@ -51,7 +51,8 @@ import android.util.Log;
public class BluetoothPbap {
private static final String TAG = "BluetoothPbap";
- private static final boolean DBG = false;
+ private static final boolean DBG = true;
+ private static final boolean VDBG = false;
/** int extra for PBAP_STATE_CHANGED_ACTION */
public static final String PBAP_STATE =
@@ -114,7 +115,7 @@ public class BluetoothPbap {
public void onBluetoothStateChange(boolean up) {
if (DBG) Log.d(TAG, "onBluetoothStateChange: up=" + up);
if (!up) {
- if (DBG) Log.d(TAG,"Unbinding service...");
+ if (VDBG) Log.d(TAG,"Unbinding service...");
synchronized (mConnection) {
try {
mService = null;
@@ -127,7 +128,7 @@ public class BluetoothPbap {
synchronized (mConnection) {
try {
if (mService == null) {
- if (DBG) Log.d(TAG,"Binding service...");
+ if (VDBG) Log.d(TAG,"Binding service...");
if (!mContext.bindService(
new Intent(IBluetoothPbap.class.getName()),
mConnection, 0)) {
@@ -206,7 +207,7 @@ public class BluetoothPbap {
* object is currently not connected to the Pbap service.
*/
public int getState() {
- if (DBG) log("getState()");
+ if (VDBG) log("getState()");
if (mService != null) {
try {
return mService.getState();
@@ -225,7 +226,7 @@ public class BluetoothPbap {
* the Pbap service.
*/
public BluetoothDevice getClient() {
- if (DBG) log("getClient()");
+ if (VDBG) log("getClient()");
if (mService != null) {
try {
return mService.getClient();
@@ -243,7 +244,7 @@ public class BluetoothPbap {
* object is not currently connected to the Pbap service.
*/
public boolean isConnected(BluetoothDevice device) {
- if (DBG) log("isConnected(" + device + ")");
+ if (VDBG) log("isConnected(" + device + ")");
if (mService != null) {
try {
return mService.isConnected(device);
diff --git a/core/java/android/bluetooth/BluetoothSocket.java b/core/java/android/bluetooth/BluetoothSocket.java
index 1bc640f..aba8710 100644
--- a/core/java/android/bluetooth/BluetoothSocket.java
+++ b/core/java/android/bluetooth/BluetoothSocket.java
@@ -72,6 +72,8 @@ import java.nio.ByteBuffer;
*/
public final class BluetoothSocket implements Closeable {
private static final String TAG = "BluetoothSocket";
+ private static final boolean DBG = true;
+ private static final boolean VDBG = false;
/** @hide */
public static final int MAX_RFCOMM_CHANNEL = 30;
@@ -172,7 +174,7 @@ public final class BluetoothSocket implements Closeable {
BluetoothSocket as = new BluetoothSocket(this);
as.mSocketState = SocketState.CONNECTED;
FileDescriptor[] fds = mSocket.getAncillaryFileDescriptors();
- Log.d(TAG, "socket fd passed by stack fds: " + fds);
+ if (VDBG) Log.d(TAG, "socket fd passed by stack fds: " + fds);
if(fds == null || fds.length != 1) {
Log.e(TAG, "socket fd passed from stack failed, fds: " + fds);
throw new IOException("bt socket acept failed");
@@ -291,7 +293,7 @@ public final class BluetoothSocket implements Closeable {
mUuid, mPort, getSecurityFlags());
synchronized(this)
{
- Log.d(TAG, "connect(), SocketState: " + mSocketState + ", mPfd: " + mPfd);
+ if (DBG) Log.d(TAG, "connect(), SocketState: " + mSocketState + ", mPfd: " + mPfd);
if (mSocketState == SocketState.CLOSED) throw new IOException("socket closed");
if (mPfd == null) throw new IOException("bt socket connect failed");
FileDescriptor fd = mPfd.getFileDescriptor();
@@ -339,23 +341,24 @@ public final class BluetoothSocket implements Closeable {
// read out port number
try {
synchronized(this) {
- Log.d(TAG, "bindListen(), SocketState: " + mSocketState + ", mPfd: " + mPfd);
+ if (VDBG) Log.d(TAG, "bindListen(), SocketState: " + mSocketState + ", mPfd: " +
+ mPfd);
if(mSocketState != SocketState.INIT) return EBADFD;
if(mPfd == null) return -1;
FileDescriptor fd = mPfd.getFileDescriptor();
- Log.d(TAG, "bindListen(), new LocalSocket ");
+ if (VDBG) Log.d(TAG, "bindListen(), new LocalSocket ");
mSocket = new LocalSocket(fd);
- Log.d(TAG, "bindListen(), new LocalSocket.getInputStream() ");
+ if (VDBG) Log.d(TAG, "bindListen(), new LocalSocket.getInputStream() ");
mSocketIS = mSocket.getInputStream();
mSocketOS = mSocket.getOutputStream();
}
- Log.d(TAG, "bindListen(), readInt mSocketIS: " + mSocketIS);
+ if (VDBG) Log.d(TAG, "bindListen(), readInt mSocketIS: " + mSocketIS);
int channel = readInt(mSocketIS);
synchronized(this) {
if(mSocketState == SocketState.INIT)
mSocketState = SocketState.LISTENING;
}
- Log.d(TAG, "channel: " + channel);
+ if (VDBG) Log.d(TAG, "channel: " + channel);
if (mPort == -1) {
mPort = channel;
} // else ASSERT(mPort == channel)
@@ -385,26 +388,26 @@ public final class BluetoothSocket implements Closeable {
}
/*package*/ int available() throws IOException {
- Log.d(TAG, "available: " + mSocketIS);
+ if (VDBG) Log.d(TAG, "available: " + mSocketIS);
return mSocketIS.available();
}
/*package*/ int read(byte[] b, int offset, int length) throws IOException {
- Log.d(TAG, "read in: " + mSocketIS + " len: " + length);
+ if (VDBG) Log.d(TAG, "read in: " + mSocketIS + " len: " + length);
int ret = mSocketIS.read(b, offset, length);
if(ret < 0)
throw new IOException("bt socket closed, read return: " + ret);
- Log.d(TAG, "read out: " + mSocketIS + " ret: " + ret);
+ if (VDBG) Log.d(TAG, "read out: " + mSocketIS + " ret: " + ret);
return ret;
}
/*package*/ int write(byte[] b, int offset, int length) throws IOException {
- Log.d(TAG, "write: " + mSocketOS + " length: " + length);
+ if (VDBG) Log.d(TAG, "write: " + mSocketOS + " length: " + length);
mSocketOS.write(b, offset, length);
// There is no good way to confirm since the entire process is asynchronous anyway
- Log.d(TAG, "write out: " + mSocketOS + " length: " + length);
+ if (VDBG) Log.d(TAG, "write out: " + mSocketOS + " length: " + length);
return length;
}
@@ -420,10 +423,10 @@ public final class BluetoothSocket implements Closeable {
if(mSocketState == SocketState.CLOSED)
return;
mSocketState = SocketState.CLOSED;
- Log.d(TAG, "close() this: " + this + ", channel: " + mPort + ", mSocketIS: " + mSocketIS +
+ if (VDBG) Log.d(TAG, "close() this: " + this + ", channel: " + mPort + ", mSocketIS: " + mSocketIS +
", mSocketOS: " + mSocketOS + "mSocket: " + mSocket);
if(mSocket != null) {
- Log.d(TAG, "Closing mSocket: " + mSocket);
+ if (VDBG) Log.d(TAG, "Closing mSocket: " + mSocket);
mSocket.shutdownInput();
mSocket.shutdownOutput();
mSocket.close();
@@ -449,7 +452,7 @@ public final class BluetoothSocket implements Closeable {
private String waitSocketSignal(InputStream is) throws IOException {
byte [] sig = new byte[SOCK_SIGNAL_SIZE];
int ret = readAll(is, sig);
- Log.d(TAG, "waitSocketSignal read 16 bytes signal ret: " + ret);
+ if (VDBG) Log.d(TAG, "waitSocketSignal read 16 bytes signal ret: " + ret);
ByteBuffer bb = ByteBuffer.wrap(sig);
bb.order(ByteOrder.nativeOrder());
int size = bb.getShort();
@@ -458,7 +461,7 @@ public final class BluetoothSocket implements Closeable {
int channel = bb.getInt();
int status = bb.getInt();
String RemoteAddr = convertAddr(addr);
- Log.d(TAG, "waitSocketSignal: sig size: " + size + ", remote addr: "
+ if (VDBG) Log.d(TAG, "waitSocketSignal: sig size: " + size + ", remote addr: "
+ RemoteAddr + ", channel: " + channel + ", status: " + status);
if(status != 0)
throw new IOException("Connection failure, status: " + status);
@@ -481,7 +484,7 @@ public final class BluetoothSocket implements Closeable {
private int readInt(InputStream is) throws IOException {
byte[] ibytes = new byte[4];
int ret = readAll(is, ibytes);
- Log.d(TAG, "inputStream.read ret: " + ret);
+ if (VDBG) Log.d(TAG, "inputStream.read ret: " + ret);
ByteBuffer bb = ByteBuffer.wrap(ibytes);
bb.order(ByteOrder.nativeOrder());
return bb.getInt();
diff --git a/core/java/android/bluetooth/BluetoothTetheringDataTracker.java b/core/java/android/bluetooth/BluetoothTetheringDataTracker.java
index 30406e9..063e5a8 100644
--- a/core/java/android/bluetooth/BluetoothTetheringDataTracker.java
+++ b/core/java/android/bluetooth/BluetoothTetheringDataTracker.java
@@ -51,6 +51,8 @@ import java.util.concurrent.atomic.AtomicInteger;
public class BluetoothTetheringDataTracker implements NetworkStateTracker {
private static final String NETWORKTYPE = "BLUETOOTH_TETHER";
private static final String TAG = "BluetoothTethering";
+ private static final boolean DBG = true;
+ private static final boolean VDBG = false;
private AtomicBoolean mTeardownRequested = new AtomicBoolean(false);
private AtomicBoolean mPrivateDnsRouteSet = new AtomicBoolean(false);
@@ -99,10 +101,10 @@ public class BluetoothTetheringDataTracker implements NetworkStateTracker {
* Begin monitoring connectivity
*/
public void startMonitoring(Context context, Handler target) {
- Log.d(TAG, "startMonitoring: target: " + target);
+ if (DBG) Log.d(TAG, "startMonitoring: target: " + target);
mContext = context;
mCsHandler = target;
- Log.d(TAG, "startMonitoring: mCsHandler: " + mCsHandler);
+ if (VDBG) Log.d(TAG, "startMonitoring: mCsHandler: " + mCsHandler);
BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
if (adapter != null) {
adapter.getProfileProxy(mContext, mProfileServiceListener, BluetoothProfile.PAN);
@@ -310,31 +312,31 @@ public class BluetoothTetheringDataTracker implements NetworkStateTracker {
}
public synchronized void startReverseTether(String iface) {
mIface = iface;
- Log.d(TAG, "startReverseTether mCsHandler: " + mCsHandler);
+ if (DBG) Log.d(TAG, "startReverseTether mCsHandler: " + mCsHandler);
mDhcpThread = new Thread(new Runnable() {
public void run() {
//TODO(): Add callbacks for failure and success case.
//Currently this thread runs independently.
- Log.d(TAG, "startReverseTether mCsHandler: " + mCsHandler);
+ if (DBG) Log.d(TAG, "startReverseTether mCsHandler: " + mCsHandler);
String DhcpResultName = "dhcp." + mIface + ".result";;
String result = "";
- Log.d(TAG, "waiting for change of sys prop dhcp result: " + DhcpResultName);
+ if (VDBG) Log.d(TAG, "waiting for change of sys prop dhcp result: " + DhcpResultName);
for(int i = 0; i < 30*5; i++) {
try { Thread.sleep(200); } catch (InterruptedException ie) { return;}
result = SystemProperties.get(DhcpResultName);
- Log.d(TAG, "read " + DhcpResultName + ": " + result);
+ if (VDBG) Log.d(TAG, "read " + DhcpResultName + ": " + result);
if(result.equals("failed")) {
Log.e(TAG, "startReverseTether, failed to start dhcp service");
return;
}
if(result.equals("ok")) {
- Log.d(TAG, "startReverseTether, dhcp resut: " + result);
+ if (VDBG) Log.d(TAG, "startReverseTether, dhcp resut: " + result);
if(readLinkProperty(mIface)) {
mNetworkInfo.setIsAvailable(true);
mNetworkInfo.setDetailedState(DetailedState.CONNECTED, null, null);
- Log.d(TAG, "startReverseTether mCsHandler: " + mCsHandler);
+ if (VDBG) Log.d(TAG, "startReverseTether mCsHandler: " + mCsHandler);
if(mCsHandler != null) {
Message msg = mCsHandler.obtainMessage(EVENT_CONFIGURATION_CHANGED, mNetworkInfo);
msg.sendToTarget();
@@ -346,7 +348,7 @@ public class BluetoothTetheringDataTracker implements NetworkStateTracker {
return;
}
}
- Log.d(TAG, "startReverseTether, dhcp failed, resut: " + result);
+ Log.e(TAG, "startReverseTether, dhcp failed, resut: " + result);
}
});
mDhcpThread.start();
diff --git a/core/java/android/content/ContentService.java b/core/java/android/content/ContentService.java
index 0f6488a..4512e82 100644
--- a/core/java/android/content/ContentService.java
+++ b/core/java/android/content/ContentService.java
@@ -345,10 +345,11 @@ public final class ContentService extends IContentService.Stub {
public SyncAdapterType[] getSyncAdapterTypes() {
// This makes it so that future permission checks will be in the context of this
// process rather than the caller's process. We will restore this before returning.
- long identityToken = clearCallingIdentity();
+ final int userId = UserHandle.getCallingUserId();
+ final long identityToken = clearCallingIdentity();
try {
SyncManager syncManager = getSyncManager();
- return syncManager.getSyncAdapterTypes();
+ return syncManager.getSyncAdapterTypes(userId);
} finally {
restoreCallingIdentity(identityToken);
}
diff --git a/core/java/android/content/SyncManager.java b/core/java/android/content/SyncManager.java
index 564a804..93c9526 100644
--- a/core/java/android/content/SyncManager.java
+++ b/core/java/android/content/SyncManager.java
@@ -20,8 +20,8 @@ import android.accounts.Account;
import android.accounts.AccountAndUser;
import android.accounts.AccountManager;
import android.accounts.AccountManagerService;
-import android.accounts.OnAccountsUpdateListener;
import android.app.ActivityManager;
+import android.app.ActivityManagerNative;
import android.app.AlarmManager;
import android.app.Notification;
import android.app.NotificationManager;
@@ -58,6 +58,7 @@ import android.util.Log;
import android.util.Pair;
import com.android.internal.R;
+import com.android.internal.util.IndentingPrintWriter;
import com.google.android.collect.Lists;
import com.google.android.collect.Maps;
import com.google.android.collect.Sets;
@@ -81,7 +82,7 @@ import java.util.concurrent.CountDownLatch;
/**
* @hide
*/
-public class SyncManager implements OnAccountsUpdateListener {
+public class SyncManager {
private static final String TAG = "SyncManager";
/** Delay a sync due to local changes this long. In milliseconds */
@@ -141,7 +142,8 @@ public class SyncManager implements OnAccountsUpdateListener {
private static final AccountAndUser[] INITIAL_ACCOUNTS_ARRAY = new AccountAndUser[0];
- private volatile AccountAndUser[] mAccounts = INITIAL_ACCOUNTS_ARRAY;
+ // TODO: add better locking around mRunningAccounts
+ private volatile AccountAndUser[] mRunningAccounts = INITIAL_ACCOUNTS_ARRAY;
volatile private PowerManager.WakeLock mHandleAlarmWakeLock;
volatile private PowerManager.WakeLock mSyncManagerWakeLock;
@@ -205,7 +207,10 @@ public class SyncManager implements OnAccountsUpdateListener {
private BroadcastReceiver mAccountsUpdatedReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
- onAccountsUpdated(null);
+ updateRunningAccounts();
+
+ // Kick off sync for everyone, since this was a radical account change
+ scheduleSync(null, UserHandle.USER_ALL, null, null, 0 /* no delay */, false);
}
};
@@ -242,33 +247,14 @@ public class SyncManager implements OnAccountsUpdateListener {
return found;
}
- public void onAccountsUpdated(Account[] accounts) {
- // remember if this was the first time this was called after an update
- final boolean justBootedUp = mAccounts == INITIAL_ACCOUNTS_ARRAY;
-
- List<UserInfo> users = getAllUsers();
- if (users == null) return;
-
- int count = 0;
-
- // Get accounts from AccountManager for all the users on the system
- // TODO: Limit this to active users, when such a concept exists.
- AccountAndUser[] allAccounts = AccountManagerService.getSingleton().getAllAccounts();
- for (UserInfo user : users) {
- if (mBootCompleted) {
- Account[] accountsForUser =
- AccountManagerService.getSingleton().getAccounts(user.id);
- mSyncStorageEngine.doDatabaseCleanup(accountsForUser, user.id);
- }
- }
-
- mAccounts = allAccounts;
+ public void updateRunningAccounts() {
+ mRunningAccounts = AccountManagerService.getSingleton().getRunningAccounts();
for (ActiveSyncContext currentSyncContext : mActiveSyncContexts) {
- if (!containsAccountAndUser(allAccounts,
+ if (!containsAccountAndUser(mRunningAccounts,
currentSyncContext.mSyncOperation.account,
currentSyncContext.mSyncOperation.userId)) {
- Log.d(TAG, "canceling sync since the account has been removed");
+ Log.d(TAG, "canceling sync since the account is no longer running");
sendSyncFinishedOrCanceledMessage(currentSyncContext,
null /* no result since this is a cancel */);
}
@@ -277,26 +263,6 @@ public class SyncManager implements OnAccountsUpdateListener {
// we must do this since we don't bother scheduling alarms when
// the accounts are not set yet
sendCheckAlarmsMessage();
-
- if (allAccounts.length > 0) {
- // If this is the first time this was called after a bootup then
- // the accounts haven't really changed, instead they were just loaded
- // from the AccountManager. Otherwise at least one of the accounts
- // has a change.
- //
- // If there was a real account change then force a sync of all accounts.
- // This is a bit of overkill, but at least it will end up retrying syncs
- // that failed due to an authentication failure and thus will recover if the
- // account change was a password update.
- //
- // If this was the bootup case then don't sync everything, instead only
- // sync those that have an unknown syncable state, which will give them
- // a chance to set their syncable state.
-
- boolean onlyThoseWithUnkownSyncableState = justBootedUp;
- scheduleSync(null, UserHandle.USER_ALL, null, null, 0 /* no delay */,
- onlyThoseWithUnkownSyncableState);
- }
}
private BroadcastReceiver mConnectivityIntentReceiver =
@@ -336,19 +302,18 @@ public class SyncManager implements OnAccountsUpdateListener {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
- final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1);
+ final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
+ if (userId == UserHandle.USER_NULL) return;
+
if (Intent.ACTION_USER_REMOVED.equals(action)) {
- Log.i(TAG, "User removed - cleanup: u" + userId);
- onUserRemoved(intent);
- } else if (Intent.ACTION_USER_STARTED.equals(action)) {
- Log.i(TAG, "User started - check alarms: u" + userId);
- sendCheckAlarmsMessage();
- } else if (Intent.ACTION_USER_STOPPED.equals(action)) {
- Log.i(TAG, "User stopped - stop syncs: u" + userId);
- cancelActiveSync(
- null /* any account */,
- userId,
- null /* any authority */);
+ Log.i(TAG, "User removed: u" + userId);
+ onUserRemoved(userId);
+ } else if (Intent.ACTION_USER_STARTING.equals(action)) {
+ Log.i(TAG, "User starting: u" + userId);
+ onUserStarting(userId);
+ } else if (Intent.ACTION_USER_STOPPING.equals(action)) {
+ Log.i(TAG, "User stopping: u" + userId);
+ onUserStopping(userId);
}
}
};
@@ -390,7 +355,8 @@ public class SyncManager implements OnAccountsUpdateListener {
mSyncHandler = new SyncHandler(syncThread.getLooper());
mSyncAdapters.setListener(new RegisteredServicesCacheListener<SyncAdapterType>() {
- public void onServiceChanged(SyncAdapterType type, boolean removed) {
+ @Override
+ public void onServiceChanged(SyncAdapterType type, int userId, boolean removed) {
if (!removed) {
scheduleSync(null, UserHandle.USER_ALL, type.authority, null, 0 /* no delay */,
false /* onlyThoseWithUnkownSyncableState */);
@@ -422,7 +388,8 @@ public class SyncManager implements OnAccountsUpdateListener {
intentFilter = new IntentFilter();
intentFilter.addAction(Intent.ACTION_USER_REMOVED);
- intentFilter.addAction(Intent.ACTION_USER_STARTED);
+ intentFilter.addAction(Intent.ACTION_USER_STARTING);
+ intentFilter.addAction(Intent.ACTION_USER_STOPPING);
mContext.registerReceiverAsUser(
mUserIntentReceiver, UserHandle.ALL, intentFilter, null, null);
@@ -467,8 +434,9 @@ public class SyncManager implements OnAccountsUpdateListener {
UserHandle.ALL,
new IntentFilter(AccountManager.LOGIN_ACCOUNTS_CHANGED_ACTION),
null, null);
+
// do this synchronously to ensure we have the accounts before this call returns
- onAccountsUpdated(null);
+ onUserStarting(UserHandle.USER_OWNER);
}
// Pick a random second in a day to seed all periodic syncs
@@ -548,7 +516,7 @@ public class SyncManager implements OnAccountsUpdateListener {
} else {
// if the accounts aren't configured yet then we can't support an account-less
// sync request
- accounts = mAccounts;
+ accounts = mRunningAccounts;
if (accounts.length == 0) {
if (isLoggable) {
Log.v(TAG, "scheduleSync: no accounts configured, dropping");
@@ -579,32 +547,33 @@ public class SyncManager implements OnAccountsUpdateListener {
source = SyncStorageEngine.SOURCE_SERVER;
}
- // Compile a list of authorities that have sync adapters.
- // For each authority sync each account that matches a sync adapter.
- final HashSet<String> syncableAuthorities = new HashSet<String>();
- for (RegisteredServicesCache.ServiceInfo<SyncAdapterType> syncAdapter :
- mSyncAdapters.getAllServices()) {
- syncableAuthorities.add(syncAdapter.type.authority);
- }
+ for (AccountAndUser account : accounts) {
+ // Compile a list of authorities that have sync adapters.
+ // For each authority sync each account that matches a sync adapter.
+ final HashSet<String> syncableAuthorities = new HashSet<String>();
+ for (RegisteredServicesCache.ServiceInfo<SyncAdapterType> syncAdapter :
+ mSyncAdapters.getAllServices(account.userId)) {
+ syncableAuthorities.add(syncAdapter.type.authority);
+ }
- // if the url was specified then replace the list of authorities with just this authority
- // or clear it if this authority isn't syncable
- if (requestedAuthority != null) {
- final boolean hasSyncAdapter = syncableAuthorities.contains(requestedAuthority);
- syncableAuthorities.clear();
- if (hasSyncAdapter) syncableAuthorities.add(requestedAuthority);
- }
+ // if the url was specified then replace the list of authorities
+ // with just this authority or clear it if this authority isn't
+ // syncable
+ if (requestedAuthority != null) {
+ final boolean hasSyncAdapter = syncableAuthorities.contains(requestedAuthority);
+ syncableAuthorities.clear();
+ if (hasSyncAdapter) syncableAuthorities.add(requestedAuthority);
+ }
- for (String authority : syncableAuthorities) {
- for (AccountAndUser account : accounts) {
+ for (String authority : syncableAuthorities) {
int isSyncable = mSyncStorageEngine.getIsSyncable(account.account, account.userId,
authority);
if (isSyncable == 0) {
continue;
}
- final RegisteredServicesCache.ServiceInfo<SyncAdapterType> syncAdapterInfo =
- mSyncAdapters.getServiceInfo(
- SyncAdapterType.newKey(authority, account.account.type));
+ final RegisteredServicesCache.ServiceInfo<SyncAdapterType> syncAdapterInfo;
+ syncAdapterInfo = mSyncAdapters.getServiceInfo(
+ SyncAdapterType.newKey(authority, account.account.type), account.userId);
if (syncAdapterInfo == null) {
continue;
}
@@ -681,10 +650,9 @@ public class SyncManager implements OnAccountsUpdateListener {
false /* onlyThoseWithUnkownSyncableState */);
}
- public SyncAdapterType[] getSyncAdapterTypes() {
- final Collection<RegisteredServicesCache.ServiceInfo<SyncAdapterType>>
- serviceInfos =
- mSyncAdapters.getAllServices();
+ public SyncAdapterType[] getSyncAdapterTypes(int userId) {
+ final Collection<RegisteredServicesCache.ServiceInfo<SyncAdapterType>> serviceInfos;
+ serviceInfos = mSyncAdapters.getAllServices(userId);
SyncAdapterType[] types = new SyncAdapterType[serviceInfos.size()];
int i = 0;
for (RegisteredServicesCache.ServiceInfo<SyncAdapterType> serviceInfo : serviceInfos) {
@@ -920,16 +888,42 @@ public class SyncManager implements OnAccountsUpdateListener {
}
}
- private void onUserRemoved(Intent intent) {
- int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1);
- if (userId == -1) return;
- removeUser(userId);
+ private void onUserStarting(int userId) {
+ // Make sure that accounts we're about to use are valid
+ AccountManagerService.getSingleton().validateAccounts(userId);
+
+ mSyncAdapters.invalidateCache(userId);
+
+ updateRunningAccounts();
+
+ final Account[] accounts = AccountManagerService.getSingleton().getAccounts(userId);
+ mSyncStorageEngine.doDatabaseCleanup(accounts, userId);
+
+ mSyncQueue.addPendingOperations(userId);
+
+ // Schedule sync for any accounts under started user
+ for (Account account : accounts) {
+ scheduleSync(account, userId, null, null, 0 /* no delay */,
+ true /* onlyThoseWithUnknownSyncableState */);
+ }
+
+ sendCheckAlarmsMessage();
+ }
+
+ private void onUserStopping(int userId) {
+ updateRunningAccounts();
+
+ cancelActiveSync(
+ null /* any account */,
+ userId,
+ null /* any authority */);
}
- private void removeUser(int userId) {
+ private void onUserRemoved(int userId) {
+ updateRunningAccounts();
+
// Clean up the storage engine database
mSyncStorageEngine.doDatabaseCleanup(new Account[0], userId);
- onAccountsUpdated(null);
synchronized (mSyncQueue) {
mSyncQueue.removeUser(userId);
}
@@ -1062,14 +1056,10 @@ public class SyncManager implements OnAccountsUpdateListener {
}
protected void dump(FileDescriptor fd, PrintWriter pw) {
- dumpSyncState(pw);
- dumpSyncHistory(pw);
-
- pw.println();
- pw.println("SyncAdapters:");
- for (RegisteredServicesCache.ServiceInfo info : mSyncAdapters.getAllServices()) {
- pw.println(" " + info);
- }
+ final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " ");
+ dumpSyncState(ipw);
+ dumpSyncHistory(ipw);
+ dumpSyncAdapters(ipw);
}
static String formatTime(long time) {
@@ -1085,13 +1075,13 @@ public class SyncManager implements OnAccountsUpdateListener {
if (users != null) {
for (UserInfo user : users) {
pw.print("u" + user.id + "="
- + mSyncStorageEngine.getMasterSyncAutomatically(user.id));
+ + mSyncStorageEngine.getMasterSyncAutomatically(user.id) + " ");
}
pw.println();
}
pw.print("memory low: "); pw.println(mStorageIsLow);
- final AccountAndUser[] accounts = mAccounts;
+ final AccountAndUser[] accounts = AccountManagerService.getSingleton().getAllAccounts();
pw.print("accounts: ");
if (accounts != INITIAL_ACCOUNTS_ARRAY) {
@@ -1153,7 +1143,7 @@ public class SyncManager implements OnAccountsUpdateListener {
pw.print(" "); pw.print(account.account.type);
pw.println(":");
for (RegisteredServicesCache.ServiceInfo<SyncAdapterType> syncAdapterType :
- mSyncAdapters.getAllServices()) {
+ mSyncAdapters.getAllServices(account.userId)) {
if (!syncAdapterType.type.accountType.equals(account.account.type)) {
continue;
}
@@ -1530,6 +1520,23 @@ public class SyncManager implements OnAccountsUpdateListener {
}
}
+ private void dumpSyncAdapters(IndentingPrintWriter pw) {
+ pw.println();
+ final List<UserInfo> users = getAllUsers();
+ if (users != null) {
+ for (UserInfo user : users) {
+ pw.println("Sync adapters for " + user + ":");
+ pw.increaseIndent();
+ for (RegisteredServicesCache.ServiceInfo<?> info :
+ mSyncAdapters.getAllServices(user.id)) {
+ pw.println(info);
+ }
+ pw.decreaseIndent();
+ pw.println();
+ }
+ }
+ }
+
private static class AuthoritySyncStats {
String name;
long elapsedTime;
@@ -1613,18 +1620,10 @@ public class SyncManager implements OnAccountsUpdateListener {
Maps.newHashMap();
private volatile CountDownLatch mReadyToRunLatch = new CountDownLatch(1);
+
public void onBootCompleted() {
mBootCompleted = true;
- // TODO: Handle bootcompleted event for specific user. Now let's just iterate through
- // all the users.
- List<UserInfo> users = getAllUsers();
- if (users != null) {
- for (UserInfo user : users) {
- mSyncStorageEngine.doDatabaseCleanup(
- AccountManagerService.getSingleton().getAccounts(user.id),
- user.id);
- }
- }
+
if (mReadyToRunLatch != null) {
mReadyToRunLatch.countDown();
}
@@ -1814,7 +1813,7 @@ public class SyncManager implements OnAccountsUpdateListener {
return earliestFuturePollTime;
}
- AccountAndUser[] accounts = mAccounts;
+ AccountAndUser[] accounts = mRunningAccounts;
final long nowAbsolute = System.currentTimeMillis();
final long shiftedNowAbsolute = (0 < nowAbsolute - mSyncRandomOffsetMillis)
@@ -1869,9 +1868,10 @@ public class SyncManager implements OnAccountsUpdateListener {
// Sync now
final Pair<Long, Long> backoff = mSyncStorageEngine.getBackoff(
info.account, info.userId, info.authority);
- final RegisteredServicesCache.ServiceInfo<SyncAdapterType> syncAdapterInfo =
- mSyncAdapters.getServiceInfo(
- SyncAdapterType.newKey(info.authority, info.account.type));
+ final RegisteredServicesCache.ServiceInfo<SyncAdapterType> syncAdapterInfo;
+ syncAdapterInfo = mSyncAdapters.getServiceInfo(
+ SyncAdapterType.newKey(info.authority, info.account.type),
+ info.userId);
if (syncAdapterInfo == null) {
continue;
}
@@ -1927,7 +1927,7 @@ public class SyncManager implements OnAccountsUpdateListener {
// If the accounts aren't known yet then we aren't ready to run. We will be kicked
// when the account lookup request does complete.
- AccountAndUser[] accounts = mAccounts;
+ AccountAndUser[] accounts = mRunningAccounts;
if (accounts == INITIAL_ACCOUNTS_ARRAY) {
if (isLoggable) {
Log.v(TAG, "maybeStartNextSync: accounts not known, skipping");
@@ -1998,7 +1998,7 @@ public class SyncManager implements OnAccountsUpdateListener {
final RegisteredServicesCache.ServiceInfo<SyncAdapterType> syncAdapterInfo;
syncAdapterInfo = mSyncAdapters.getServiceInfo(
- SyncAdapterType.newKey(op.authority, op.account.type));
+ SyncAdapterType.newKey(op.authority, op.account.type), op.userId);
// only proceed if network is connected for requesting UID
final boolean uidNetworkConnected;
@@ -2030,7 +2030,7 @@ public class SyncManager implements OnAccountsUpdateListener {
for (Integer user : removedUsers) {
// if it's still removed
if (mUserManager.getUserInfo(user) == null) {
- removeUser(user);
+ onUserRemoved(user);
}
}
}
@@ -2167,8 +2167,8 @@ public class SyncManager implements OnAccountsUpdateListener {
// connect to the sync adapter
SyncAdapterType syncAdapterType = SyncAdapterType.newKey(op.authority, op.account.type);
- RegisteredServicesCache.ServiceInfo<SyncAdapterType> syncAdapterInfo =
- mSyncAdapters.getServiceInfo(syncAdapterType);
+ final RegisteredServicesCache.ServiceInfo<SyncAdapterType> syncAdapterInfo;
+ syncAdapterInfo = mSyncAdapters.getServiceInfo(syncAdapterType, op.userId);
if (syncAdapterInfo == null) {
Log.d(TAG, "can't find a sync adapter for " + syncAdapterType
+ ", removing settings for it");
diff --git a/core/java/android/content/SyncQueue.java b/core/java/android/content/SyncQueue.java
index c18c86b..395658c 100644
--- a/core/java/android/content/SyncQueue.java
+++ b/core/java/android/content/SyncQueue.java
@@ -16,14 +16,15 @@
package android.content;
-import com.google.android.collect.Maps;
-
-import android.content.pm.RegisteredServicesCache;
+import android.accounts.Account;
+import android.content.pm.RegisteredServicesCache.ServiceInfo;
import android.os.SystemClock;
+import android.os.UserHandle;
import android.text.format.DateUtils;
-import android.util.Pair;
import android.util.Log;
-import android.accounts.Account;
+import android.util.Pair;
+
+import com.google.android.collect.Maps;
import java.util.ArrayList;
import java.util.HashMap;
@@ -36,7 +37,9 @@ import java.util.Map;
*/
public class SyncQueue {
private static final String TAG = "SyncManager";
- private SyncStorageEngine mSyncStorageEngine;
+
+ private final SyncStorageEngine mSyncStorageEngine;
+ private final SyncAdaptersCache mSyncAdapters;
// A Map of SyncOperations operationKey -> SyncOperation that is designed for
// quick lookup of an enqueued SyncOperation.
@@ -44,23 +47,28 @@ public class SyncQueue {
public SyncQueue(SyncStorageEngine syncStorageEngine, final SyncAdaptersCache syncAdapters) {
mSyncStorageEngine = syncStorageEngine;
- ArrayList<SyncStorageEngine.PendingOperation> ops
- = mSyncStorageEngine.getPendingOperations();
- final int N = ops.size();
- for (int i=0; i<N; i++) {
- SyncStorageEngine.PendingOperation op = ops.get(i);
- final Pair<Long, Long> backoff =
- syncStorageEngine.getBackoff(op.account, op.userId, op.authority);
- final RegisteredServicesCache.ServiceInfo<SyncAdapterType> syncAdapterInfo =
- syncAdapters.getServiceInfo(
- SyncAdapterType.newKey(op.authority, op.account.type));
+ mSyncAdapters = syncAdapters;
+
+ addPendingOperations(UserHandle.USER_OWNER);
+ }
+
+ public void addPendingOperations(int userId) {
+ for (SyncStorageEngine.PendingOperation op : mSyncStorageEngine.getPendingOperations()) {
+ if (op.userId != userId) continue;
+
+ final Pair<Long, Long> backoff = mSyncStorageEngine.getBackoff(
+ op.account, op.userId, op.authority);
+ final ServiceInfo<SyncAdapterType> syncAdapterInfo = mSyncAdapters.getServiceInfo(
+ SyncAdapterType.newKey(op.authority, op.account.type), op.userId);
if (syncAdapterInfo == null) {
+ Log.w(TAG, "Missing sync adapter info for authority " + op.authority + ", userId "
+ + op.userId);
continue;
}
SyncOperation syncOperation = new SyncOperation(
op.account, op.userId, op.syncSource, op.authority, op.extras, 0 /* delay */,
backoff != null ? backoff.first : 0,
- syncStorageEngine.getDelayUntilTime(op.account, op.userId, op.authority),
+ mSyncStorageEngine.getDelayUntilTime(op.account, op.userId, op.authority),
syncAdapterInfo.type.allowParallelSyncs());
syncOperation.expedited = op.expedited;
syncOperation.pendingOperation = op;
diff --git a/core/java/android/content/pm/RegisteredServicesCache.java b/core/java/android/content/pm/RegisteredServicesCache.java
index 7642670..0b91786 100644
--- a/core/java/android/content/pm/RegisteredServicesCache.java
+++ b/core/java/android/content/pm/RegisteredServicesCache.java
@@ -16,49 +16,54 @@
package android.content.pm;
-import android.content.Context;
import android.content.BroadcastReceiver;
+import android.content.ComponentName;
+import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
-import android.content.ComponentName;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.Resources;
import android.content.res.XmlResourceParser;
import android.os.Environment;
import android.os.Handler;
+import android.os.UserHandle;
import android.util.AtomicFile;
-import android.util.Log;
import android.util.AttributeSet;
+import android.util.Log;
+import android.util.Slog;
+import android.util.SparseArray;
import android.util.Xml;
-import java.util.Map;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.ArrayList;
-import java.util.concurrent.atomic.AtomicReference;
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-import java.io.IOException;
-import java.io.FileInputStream;
-
import com.android.internal.util.FastXmlSerializer;
-
-import com.google.android.collect.Maps;
import com.google.android.collect.Lists;
+import com.google.android.collect.Maps;
-import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlSerializer;
+import java.io.File;
+import java.io.FileDescriptor;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
/**
- * A cache of registered services. This cache
- * is built by interrogating the {@link PackageManager} and is updated as packages are added,
- * removed and changed. The services are referred to by type V and
- * are made available via the {@link #getServiceInfo} method.
+ * Cache of registered services. This cache is lazily built by interrogating
+ * {@link PackageManager} on a per-user basis. It's updated as packages are
+ * added, removed and changed. Users are responsible for calling
+ * {@link #invalidateCache(int)} when a user is started, since
+ * {@link PackageManager} broadcasts aren't sent for stopped users.
+ * <p>
+ * The services are referred to by type V and are made available via the
+ * {@link #getServiceInfo} method.
+ *
* @hide
*/
public abstract class RegisteredServicesCache<V> {
@@ -69,15 +74,29 @@ public abstract class RegisteredServicesCache<V> {
private final String mMetaDataName;
private final String mAttributesName;
private final XmlSerializerAndParser<V> mSerializerAndParser;
- private final AtomicReference<BroadcastReceiver> mReceiver;
private final Object mServicesLock = new Object();
- // synchronized on mServicesLock
- private HashMap<V, Integer> mPersistentServices;
- // synchronized on mServicesLock
- private Map<V, ServiceInfo<V>> mServices;
- // synchronized on mServicesLock
+
+ // @GuardedBy("mServicesLock")
private boolean mPersistentServicesFileDidNotExist;
+ // @GuardedBy("mServicesLock")
+ private final SparseArray<UserServices<V>> mUserServices = new SparseArray<UserServices<V>>();
+
+ private static class UserServices<V> {
+ // @GuardedBy("mServicesLock")
+ public final Map<V, Integer> persistentServices = Maps.newHashMap();
+ // @GuardedBy("mServicesLock")
+ public Map<V, ServiceInfo<V>> services = null;
+ }
+
+ private UserServices<V> findOrCreateUserLocked(int userId) {
+ UserServices<V> services = mUserServices.get(userId);
+ if (services == null) {
+ services = new UserServices<V>();
+ mUserServices.put(userId, services);
+ }
+ return services;
+ }
/**
* This file contains the list of known services. We would like to maintain this forever
@@ -102,36 +121,59 @@ public abstract class RegisteredServicesCache<V> {
File syncDir = new File(systemDir, "registered_services");
mPersistentServicesFile = new AtomicFile(new File(syncDir, interfaceName + ".xml"));
- generateServicesMap();
+ // Load persisted services from disk
+ readPersistentServicesLocked();
- final BroadcastReceiver receiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context1, Intent intent) {
- generateServicesMap();
- }
- };
- mReceiver = new AtomicReference<BroadcastReceiver>(receiver);
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(Intent.ACTION_PACKAGE_ADDED);
intentFilter.addAction(Intent.ACTION_PACKAGE_CHANGED);
intentFilter.addAction(Intent.ACTION_PACKAGE_REMOVED);
intentFilter.addDataScheme("package");
- mContext.registerReceiver(receiver, intentFilter);
+ mContext.registerReceiverAsUser(mPackageReceiver, UserHandle.ALL, intentFilter, null, null);
+
// Register for events related to sdcard installation.
IntentFilter sdFilter = new IntentFilter();
sdFilter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE);
sdFilter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE);
- mContext.registerReceiver(receiver, sdFilter);
+ mContext.registerReceiver(mExternalReceiver, sdFilter);
}
- public void dump(FileDescriptor fd, PrintWriter fout, String[] args) {
- Map<V, ServiceInfo<V>> services;
+ private final BroadcastReceiver mPackageReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ final int uid = intent.getIntExtra(Intent.EXTRA_UID, -1);
+ if (uid != -1) {
+ generateServicesMap(UserHandle.getUserId(uid));
+ }
+ }
+ };
+
+ private final BroadcastReceiver mExternalReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ // External apps can't coexist with multi-user, so scan owner
+ generateServicesMap(UserHandle.USER_OWNER);
+ }
+ };
+
+ public void invalidateCache(int userId) {
synchronized (mServicesLock) {
- services = mServices;
+ final UserServices<V> user = findOrCreateUserLocked(userId);
+ user.services = null;
}
- fout.println("RegisteredServicesCache: " + services.size() + " services");
- for (ServiceInfo info : services.values()) {
- fout.println(" " + info);
+ }
+
+ public void dump(FileDescriptor fd, PrintWriter fout, String[] args, int userId) {
+ synchronized (mServicesLock) {
+ final UserServices<V> user = findOrCreateUserLocked(userId);
+ if (user.services != null) {
+ fout.println("RegisteredServicesCache: " + user.services.size() + " services");
+ for (ServiceInfo<?> info : user.services.values()) {
+ fout.println(" " + info);
+ }
+ } else {
+ fout.println("RegisteredServicesCache: services not loaded");
+ }
}
}
@@ -151,7 +193,7 @@ public abstract class RegisteredServicesCache<V> {
}
}
- private void notifyListener(final V type, final boolean removed) {
+ private void notifyListener(final V type, final int userId, final boolean removed) {
if (Log.isLoggable(TAG, Log.VERBOSE)) {
Log.d(TAG, "notifyListener: " + type + " is " + (removed ? "removed" : "added"));
}
@@ -168,7 +210,7 @@ public abstract class RegisteredServicesCache<V> {
final RegisteredServicesCacheListener<V> listener2 = listener;
handler.post(new Runnable() {
public void run() {
- listener2.onServiceChanged(type, removed);
+ listener2.onServiceChanged(type, userId, removed);
}
});
}
@@ -200,9 +242,14 @@ public abstract class RegisteredServicesCache<V> {
* @param type the account type of the authenticator
* @return the AuthenticatorInfo that matches the account type or null if none is present
*/
- public ServiceInfo<V> getServiceInfo(V type) {
+ public ServiceInfo<V> getServiceInfo(V type, int userId) {
synchronized (mServicesLock) {
- return mServices.get(type);
+ // Find user and lazily populate cache
+ final UserServices<V> user = findOrCreateUserLocked(userId);
+ if (user.services == null) {
+ generateServicesMap(userId);
+ }
+ return user.services.get(type);
}
}
@@ -210,29 +257,15 @@ public abstract class RegisteredServicesCache<V> {
* @return a collection of {@link RegisteredServicesCache.ServiceInfo} objects for all
* registered authenticators.
*/
- public Collection<ServiceInfo<V>> getAllServices() {
+ public Collection<ServiceInfo<V>> getAllServices(int userId) {
synchronized (mServicesLock) {
- return Collections.unmodifiableCollection(mServices.values());
- }
- }
-
- /**
- * Stops the monitoring of package additions, removals and changes.
- */
- public void close() {
- final BroadcastReceiver receiver = mReceiver.getAndSet(null);
- if (receiver != null) {
- mContext.unregisterReceiver(receiver);
- }
- }
-
- @Override
- protected void finalize() throws Throwable {
- if (mReceiver.get() != null) {
- Log.e(TAG, "RegisteredServicesCache finalized without being closed");
+ // Find user and lazily populate cache
+ final UserServices<V> user = findOrCreateUserLocked(userId);
+ if (user.services == null) {
+ generateServicesMap(userId);
+ }
+ return Collections.unmodifiableCollection(user.services.values());
}
- close();
- super.finalize();
}
private boolean inSystemImage(int callerUid) {
@@ -251,11 +284,17 @@ public abstract class RegisteredServicesCache<V> {
return false;
}
- public void generateServicesMap() {
- PackageManager pm = mContext.getPackageManager();
- ArrayList<ServiceInfo<V>> serviceInfos = new ArrayList<ServiceInfo<V>>();
- List<ResolveInfo> resolveInfos = pm.queryIntentServices(new Intent(mInterfaceName),
- PackageManager.GET_META_DATA);
+ /**
+ * Populate {@link UserServices#services} by scanning installed packages for
+ * given {@link UserHandle}.
+ */
+ private void generateServicesMap(int userId) {
+ Slog.d(TAG, "generateServicesMap() for " + userId);
+
+ final PackageManager pm = mContext.getPackageManager();
+ final ArrayList<ServiceInfo<V>> serviceInfos = new ArrayList<ServiceInfo<V>>();
+ final List<ResolveInfo> resolveInfos = pm.queryIntentServicesAsUser(
+ new Intent(mInterfaceName), PackageManager.GET_META_DATA, userId);
for (ResolveInfo resolveInfo : resolveInfos) {
try {
ServiceInfo<V> info = parseServiceInfo(resolveInfo);
@@ -272,10 +311,14 @@ public abstract class RegisteredServicesCache<V> {
}
synchronized (mServicesLock) {
- if (mPersistentServices == null) {
- readPersistentServicesLocked();
+ final UserServices<V> user = findOrCreateUserLocked(userId);
+ final boolean firstScan = user.services == null;
+ if (firstScan) {
+ user.services = Maps.newHashMap();
+ } else {
+ user.services.clear();
}
- mServices = Maps.newHashMap();
+
StringBuilder changes = new StringBuilder();
for (ServiceInfo<V> info : serviceInfos) {
// four cases:
@@ -287,19 +330,19 @@ public abstract class RegisteredServicesCache<V> {
// - ignore
// - exists, the UID is different, and the new one is a system package
// - add, notify user that it was added
- Integer previousUid = mPersistentServices.get(info.type);
+ Integer previousUid = user.persistentServices.get(info.type);
if (previousUid == null) {
changes.append(" New service added: ").append(info).append("\n");
- mServices.put(info.type, info);
- mPersistentServices.put(info.type, info.uid);
- if (!mPersistentServicesFileDidNotExist) {
- notifyListener(info.type, false /* removed */);
+ user.services.put(info.type, info);
+ user.persistentServices.put(info.type, info.uid);
+ if (!(mPersistentServicesFileDidNotExist && firstScan)) {
+ notifyListener(info.type, userId, false /* removed */);
}
} else if (previousUid == info.uid) {
if (Log.isLoggable(TAG, Log.VERBOSE)) {
changes.append(" Existing service (nop): ").append(info).append("\n");
}
- mServices.put(info.type, info);
+ user.services.put(info.type, info);
} else if (inSystemImage(info.uid)
|| !containsTypeAndUid(serviceInfos, info.type, previousUid)) {
if (inSystemImage(info.uid)) {
@@ -309,9 +352,9 @@ public abstract class RegisteredServicesCache<V> {
changes.append(" Existing service replacing a removed service: ")
.append(info).append("\n");
}
- mServices.put(info.type, info);
- mPersistentServices.put(info.type, info.uid);
- notifyListener(info.type, false /* removed */);
+ user.services.put(info.type, info);
+ user.persistentServices.put(info.type, info.uid);
+ notifyListener(info.type, userId, false /* removed */);
} else {
// ignore
changes.append(" Existing service with new uid ignored: ").append(info)
@@ -320,15 +363,15 @@ public abstract class RegisteredServicesCache<V> {
}
ArrayList<V> toBeRemoved = Lists.newArrayList();
- for (V v1 : mPersistentServices.keySet()) {
+ for (V v1 : user.persistentServices.keySet()) {
if (!containsType(serviceInfos, v1)) {
toBeRemoved.add(v1);
}
}
for (V v1 : toBeRemoved) {
- mPersistentServices.remove(v1);
+ user.persistentServices.remove(v1);
changes.append(" Service removed: ").append(v1).append("\n");
- notifyListener(v1, true /* removed */);
+ notifyListener(v1, userId, true /* removed */);
}
if (changes.length() > 0) {
if (Log.isLoggable(TAG, Log.VERBOSE)) {
@@ -342,7 +385,6 @@ public abstract class RegisteredServicesCache<V> {
serviceInfos.size() + " services unchanged");
}
}
- mPersistentServicesFileDidNotExist = false;
}
}
@@ -415,7 +457,7 @@ public abstract class RegisteredServicesCache<V> {
* Read all sync status back in to the initial engine state.
*/
private void readPersistentServicesLocked() {
- mPersistentServices = Maps.newHashMap();
+ mUserServices.clear();
if (mSerializerAndParser == null) {
return;
}
@@ -444,8 +486,10 @@ public abstract class RegisteredServicesCache<V> {
break;
}
String uidString = parser.getAttributeValue(null, "uid");
- int uid = Integer.parseInt(uidString);
- mPersistentServices.put(service, uid);
+ final int uid = Integer.parseInt(uidString);
+ final int userId = UserHandle.getUserId(uid);
+ final UserServices<V> user = findOrCreateUserLocked(userId);
+ user.persistentServices.put(service, uid);
}
}
eventType = parser.next();
@@ -478,11 +522,14 @@ public abstract class RegisteredServicesCache<V> {
out.startDocument(null, true);
out.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
out.startTag(null, "services");
- for (Map.Entry<V, Integer> service : mPersistentServices.entrySet()) {
- out.startTag(null, "service");
- out.attribute(null, "uid", Integer.toString(service.getValue()));
- mSerializerAndParser.writeAsXml(service.getKey(), out);
- out.endTag(null, "service");
+ for (int i = 0; i < mUserServices.size(); i++) {
+ final UserServices<V> user = mUserServices.valueAt(i);
+ for (Map.Entry<V, Integer> service : user.persistentServices.entrySet()) {
+ out.startTag(null, "service");
+ out.attribute(null, "uid", Integer.toString(service.getValue()));
+ mSerializerAndParser.writeAsXml(service.getKey(), out);
+ out.endTag(null, "service");
+ }
}
out.endTag(null, "services");
out.endDocument();
diff --git a/core/java/android/content/pm/RegisteredServicesCacheListener.java b/core/java/android/content/pm/RegisteredServicesCacheListener.java
index 7095229..df79544 100644
--- a/core/java/android/content/pm/RegisteredServicesCacheListener.java
+++ b/core/java/android/content/pm/RegisteredServicesCacheListener.java
@@ -16,8 +16,6 @@
package android.content.pm;
-import android.os.Parcelable;
-
/**
* Listener for changes to the set of registered services managed by a RegisteredServicesCache.
* @hide
@@ -28,5 +26,5 @@ public interface RegisteredServicesCacheListener<V> {
* @param type the type of registered service
* @param removed true if the service was removed
*/
- void onServiceChanged(V type, boolean removed);
+ void onServiceChanged(V type, int userId, boolean removed);
}
diff --git a/core/java/android/hardware/Camera.java b/core/java/android/hardware/Camera.java
index 1e8671b..6624eb8 100644
--- a/core/java/android/hardware/Camera.java
+++ b/core/java/android/hardware/Camera.java
@@ -18,13 +18,18 @@ package android.hardware;
import android.annotation.SdkConstant;
import android.annotation.SdkConstant.SdkConstantType;
+import android.content.Context;
import android.graphics.ImageFormat;
import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.SurfaceTexture;
+import android.media.IAudioService;
import android.os.Handler;
+import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
+import android.os.RemoteException;
+import android.os.ServiceManager;
import android.util.Log;
import android.text.TextUtils;
import android.view.Surface;
@@ -192,7 +197,21 @@ public class Camera {
* Returns the information about a particular camera.
* If {@link #getNumberOfCameras()} returns N, the valid id is 0 to N-1.
*/
- public native static void getCameraInfo(int cameraId, CameraInfo cameraInfo);
+ public static void getCameraInfo(int cameraId, CameraInfo cameraInfo) {
+ _getCameraInfo(cameraId, cameraInfo);
+ IBinder b = ServiceManager.getService(Context.AUDIO_SERVICE);
+ IAudioService audioService = IAudioService.Stub.asInterface(b);
+ try {
+ if (audioService.isCameraSoundForced()) {
+ // Only set this when sound is forced; otherwise let native code
+ // decide.
+ cameraInfo.canDisableShutterSound = false;
+ }
+ } catch (RemoteException e) {
+ Log.e(TAG, "Audio service is unavailable for queries");
+ }
+ }
+ private native static void _getCameraInfo(int cameraId, CameraInfo cameraInfo);
/**
* Information about a camera
@@ -1185,7 +1204,20 @@ public class Camera {
* @see CameraInfo#canDisableShutterSound
* @see ShutterCallback
*/
- public native final boolean enableShutterSound(boolean enabled);
+ public final boolean enableShutterSound(boolean enabled) {
+ if (!enabled) {
+ IBinder b = ServiceManager.getService(Context.AUDIO_SERVICE);
+ IAudioService audioService = IAudioService.Stub.asInterface(b);
+ try {
+ if (audioService.isCameraSoundForced()) return false;
+ } catch (RemoteException e) {
+ Log.e(TAG, "Audio service is unavailable for queries");
+ }
+ }
+ return _enableShutterSound(enabled);
+ }
+
+ private native final boolean _enableShutterSound(boolean enabled);
/**
* Callback interface for zoom changes during a smooth zoom operation.
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index 83a0c78..2739cac 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -16,6 +16,8 @@
package android.os;
import com.android.internal.R;
+
+import android.app.ActivityManagerNative;
import android.content.Context;
import android.content.pm.UserInfo;
import android.graphics.Bitmap;
@@ -82,6 +84,39 @@ public class UserManager {
}
/**
+ * Return whether the given user is actively running. This means that
+ * the user is in the "started" state, not "stopped" -- it is currently
+ * allowed to run code through scheduled alarms, receiving broadcasts,
+ * etc. A started user may be either the current foreground user or a
+ * background user; the result here does not distinguish between the two.
+ * @param user The user to retrieve the running state for.
+ */
+ public boolean isUserRunning(UserHandle user) {
+ try {
+ return ActivityManagerNative.getDefault().isUserRunning(
+ user.getIdentifier(), false);
+ } catch (RemoteException e) {
+ return false;
+ }
+ }
+
+ /**
+ * Return whether the given user is actively running <em>or</em> stopping.
+ * This is like {@link #isUserRunning(UserHandle)}, but will also return
+ * true if the user had been running but is in the process of being stopped
+ * (but is not yet fully stopped, and still running some code).
+ * @param user The user to retrieve the running state for.
+ */
+ public boolean isUserRunningOrStopping(UserHandle user) {
+ try {
+ return ActivityManagerNative.getDefault().isUserRunning(
+ user.getIdentifier(), true);
+ } catch (RemoteException e) {
+ return false;
+ }
+ }
+
+ /**
* Returns the UserInfo object describing a specific user.
* Requires {@link android.Manifest.permission#MANAGE_USERS} permission.
* @param userHandle the user handle of the user whose information is being requested.
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 3bbdf36..00ea873 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -3197,10 +3197,16 @@ public final class Settings {
public static final String LOCK_PATTERN_VISIBLE = "lock_pattern_visible_pattern";
/**
- * Whether lock pattern will vibrate as user enters (0 = false, 1 = true)
+ * Whether lock pattern will vibrate as user enters (0 = false, 1 =
+ * true)
+ *
+ * @deprecated Starting in {@link VERSION_CODES#JELLY_BEAN_MR1} the
+ * lockscreen uses
+ * {@link Settings.System#HAPTIC_FEEDBACK_ENABLED}.
*/
- public static final String LOCK_PATTERN_TACTILE_FEEDBACK_ENABLED =
- "lock_pattern_tactile_feedback_enabled";
+ @Deprecated
+ public static final String
+ LOCK_PATTERN_TACTILE_FEEDBACK_ENABLED = "lock_pattern_tactile_feedback_enabled";
/**
* This preference allows the device to be locked given time after screen goes off,
@@ -4052,7 +4058,20 @@ public final class Settings {
* @return true if the provider is enabled
*/
public static final boolean isLocationProviderEnabled(ContentResolver cr, String provider) {
- String allowedProviders = Settings.Secure.getString(cr, LOCATION_PROVIDERS_ALLOWED);
+ return isLocationProviderEnabledForUser(cr, provider, UserHandle.myUserId());
+ }
+
+ /**
+ * Helper method for determining if a location provider is enabled.
+ * @param cr the content resolver to use
+ * @param provider the location provider to query
+ * @param userId the userId to query
+ * @return true if the provider is enabled
+ * @hide
+ */
+ public static final boolean isLocationProviderEnabledForUser(ContentResolver cr, String provider, int userId) {
+ String allowedProviders = Settings.Secure.getStringForUser(cr,
+ LOCATION_PROVIDERS_ALLOWED, userId);
return TextUtils.delimitedStringContains(allowedProviders, ',', provider);
}
@@ -4064,6 +4083,19 @@ public final class Settings {
*/
public static final void setLocationProviderEnabled(ContentResolver cr,
String provider, boolean enabled) {
+ setLocationProviderEnabledForUser(cr, provider, enabled, UserHandle.myUserId());
+ }
+
+ /**
+ * Thread-safe method for enabling or disabling a single location provider.
+ * @param cr the content resolver to use
+ * @param provider the location provider to enable or disable
+ * @param enabled true if the provider should be enabled
+ * @param userId the userId for which to enable/disable providers
+ * @hide
+ */
+ public static final void setLocationProviderEnabledForUser(ContentResolver cr,
+ String provider, boolean enabled, int userId) {
// to ensure thread safety, we write the provider name with a '+' or '-'
// and let the SettingsProvider handle it rather than reading and modifying
// the list of enabled providers.
@@ -4072,7 +4104,8 @@ public final class Settings {
} else {
provider = "-" + provider;
}
- putString(cr, Settings.Secure.LOCATION_PROVIDERS_ALLOWED, provider);
+ putStringForUser(cr, Settings.Secure.LOCATION_PROVIDERS_ALLOWED, provider,
+ userId);
}
}
@@ -5294,6 +5327,7 @@ public final class Settings {
ENABLE_ACCESSIBILITY_GLOBAL_GESTURE_ENABLED,
WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON,
WIFI_NETWORKS_AVAILABLE_REPEAT_DELAY,
+ WIFI_WATCHDOG_POOR_NETWORK_TEST_ENABLED,
WIFI_NUM_OPEN_NETWORKS_KEPT,
EMERGENCY_TONE,
CALL_AUTO_RETRY,
diff --git a/core/java/android/service/dreams/DreamService.java b/core/java/android/service/dreams/DreamService.java
index cb78763..f865455 100644
--- a/core/java/android/service/dreams/DreamService.java
+++ b/core/java/android/service/dreams/DreamService.java
@@ -120,7 +120,7 @@ public class DreamService extends Service implements Window.Callback {
private boolean mInteractive = false;
private boolean mLowProfile = true;
private boolean mFullscreen = false;
- private boolean mScreenBright = false;
+ private boolean mScreenBright = true;
private boolean mFinished;
private boolean mDebug = false;
diff --git a/core/java/android/view/ScaleGestureDetector.java b/core/java/android/view/ScaleGestureDetector.java
index a74e438..ee3f5d8 100644
--- a/core/java/android/view/ScaleGestureDetector.java
+++ b/core/java/android/view/ScaleGestureDetector.java
@@ -17,6 +17,7 @@
package android.view;
import android.content.Context;
+import android.content.res.Resources;
import android.os.SystemClock;
import android.util.FloatMath;
@@ -162,9 +163,11 @@ public class ScaleGestureDetector {
mContext = context;
mListener = listener;
mSpanSlop = ViewConfiguration.get(context).getScaledTouchSlop() * 2;
- mTouchMinMajor =
- (int) (context.getResources().getDisplayMetrics().density * TOUCH_MIN_MAJOR + 0.5f);
- mMinSpan = context.getResources().getDimensionPixelSize(
+
+ final Resources res = context.getResources();
+ mTouchMinMajor = res.getDimensionPixelSize(
+ com.android.internal.R.dimen.config_minScalingTouchMajor);
+ mMinSpan = res.getDimensionPixelSize(
com.android.internal.R.dimen.config_minScalingSpan);
}
diff --git a/core/java/android/view/Surface.java b/core/java/android/view/Surface.java
index 8f4626f..07bb8f9 100644
--- a/core/java/android/view/Surface.java
+++ b/core/java/android/view/Surface.java
@@ -266,6 +266,8 @@ public class Surface implements Parcelable {
IBinder displayToken, int orientation, Rect layerStackRect, Rect displayRect);
private static native boolean nativeGetDisplayInfo(
IBinder displayToken, PhysicalDisplayInfo outInfo);
+ private static native void nativeBlankDisplay(IBinder displayToken);
+ private static native void nativeUnblankDisplay(IBinder displayToken);
private native void nativeCopyFrom(Surface other);
private native void nativeTransferFrom(Surface other);
@@ -638,6 +640,22 @@ public class Surface implements Parcelable {
return nativeGetDisplayInfo(displayToken, outInfo);
}
+ /** @hide */
+ public static void blankDisplay(IBinder displayToken) {
+ if (displayToken == null) {
+ throw new IllegalArgumentException("displayToken must not be null");
+ }
+ nativeBlankDisplay(displayToken);
+ }
+
+ /** @hide */
+ public static void unblankDisplay(IBinder displayToken) {
+ if (displayToken == null) {
+ throw new IllegalArgumentException("displayToken must not be null");
+ }
+ nativeUnblankDisplay(displayToken);
+ }
+
/**
* Copy another surface to this one. This surface now holds a reference
* to the same data as the original surface, and is -not- the owner.
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index ae51c1d..0d76eac 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -6858,12 +6858,12 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
/**
* Performs the specified accessibility action on the view. For
* possible accessibility actions look at {@link AccessibilityNodeInfo}.
- * <p>
- * If an {@link AccessibilityDelegate} has been specified via calling
- * {@link #setAccessibilityDelegate(AccessibilityDelegate)} its
- * {@link AccessibilityDelegate#performAccessibilityAction(View, int, Bundle)}
- * is responsible for handling this call.
- * </p>
+ * <p>
+ * If an {@link AccessibilityDelegate} has been specified via calling
+ * {@link #setAccessibilityDelegate(AccessibilityDelegate)} its
+ * {@link AccessibilityDelegate#performAccessibilityAction(View, int, Bundle)}
+ * is responsible for handling this call.
+ * </p>
*
* @param action The action to perform.
* @param arguments Optional action arguments.
@@ -6886,12 +6886,14 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
switch (action) {
case AccessibilityNodeInfo.ACTION_CLICK: {
if (isClickable()) {
- return performClick();
+ performClick();
+ return true;
}
} break;
case AccessibilityNodeInfo.ACTION_LONG_CLICK: {
if (isLongClickable()) {
- return performLongClick();
+ performLongClick();
+ return true;
}
} break;
case AccessibilityNodeInfo.ACTION_FOCUS: {
diff --git a/core/java/android/widget/LinearLayout.java b/core/java/android/widget/LinearLayout.java
index b6f0862..2f31ebd 100644
--- a/core/java/android/widget/LinearLayout.java
+++ b/core/java/android/widget/LinearLayout.java
@@ -648,6 +648,8 @@ public class LinearLayout extends ViewGroup {
int largestChildHeight = Integer.MIN_VALUE;
+ final int layoutDirection = getLayoutDirection();
+
// See how tall everyone is. Also remember max width.
for (int i = 0; i < count; ++i) {
final View child = getVirtualChildAt(i);
@@ -667,6 +669,7 @@ public class LinearLayout extends ViewGroup {
}
LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) child.getLayoutParams();
+ lp.onResolveLayoutDirection(layoutDirection);
totalWeight += lp.weight;
@@ -989,6 +992,8 @@ public class LinearLayout extends ViewGroup {
int largestChildWidth = Integer.MIN_VALUE;
+ final int layoutDirection = getLayoutDirection();
+
// See how wide everyone is. Also remember max height.
for (int i = 0; i < count; ++i) {
final View child = getVirtualChildAt(i);
@@ -1009,6 +1014,7 @@ public class LinearLayout extends ViewGroup {
final LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams)
child.getLayoutParams();
+ lp.onResolveLayoutDirection(layoutDirection);
totalWeight += lp.weight;