diff options
71 files changed, 845 insertions, 507 deletions
diff --git a/api/current.txt b/api/current.txt index 88ddd91..2cbf02d 100644 --- a/api/current.txt +++ b/api/current.txt @@ -5440,8 +5440,8 @@ package android.content { field public static final int MODE_ENABLE_WRITE_AHEAD_LOGGING = 8; // 0x8 field public static final int MODE_MULTI_PROCESS = 4; // 0x4 field public static final int MODE_PRIVATE = 0; // 0x0 - field public static final int MODE_WORLD_READABLE = 1; // 0x1 - field public static final int MODE_WORLD_WRITEABLE = 2; // 0x2 + field public static final deprecated int MODE_WORLD_READABLE = 1; // 0x1 + field public static final deprecated int MODE_WORLD_WRITEABLE = 2; // 0x2 field public static final java.lang.String NFC_SERVICE = "nfc"; field public static final java.lang.String NOTIFICATION_SERVICE = "notification"; field public static final java.lang.String NSD_SERVICE = "servicediscovery"; @@ -13948,6 +13948,14 @@ package android.nfc.tech { method public byte[] transceive(byte[]) throws java.io.IOException; } + public final class NfcBarcode extends android.nfc.tech.BasicTagTechnology { + method public static android.nfc.tech.NfcBarcode get(android.nfc.Tag); + method public byte[] getBarcode(); + method public int getType(); + field public static final int TYPE_KOVIO = 1; // 0x1 + field public static final int TYPE_UNKNOWN = -1; // 0xffffffff + } + public final class NfcF extends android.nfc.tech.BasicTagTechnology { method public static android.nfc.tech.NfcF get(android.nfc.Tag); method public byte[] getManufacturer(); @@ -17179,6 +17187,7 @@ package android.provider { field public static final int CAL_ACCESS_ROOT = 800; // 0x320 field public static final java.lang.String CAN_MODIFY_TIME_ZONE = "canModifyTimeZone"; field public static final java.lang.String CAN_ORGANIZER_RESPOND = "canOrganizerRespond"; + field public static final java.lang.String IS_PRIMARY = "isPrimary"; field public static final java.lang.String MAX_REMINDERS = "maxReminders"; field public static final java.lang.String OWNER_ACCOUNT = "ownerAccount"; field public static final java.lang.String SYNC_EVENTS = "sync_events"; @@ -17270,6 +17279,7 @@ package android.provider { field public static final java.lang.String HAS_ALARM = "hasAlarm"; field public static final java.lang.String HAS_ATTENDEE_DATA = "hasAttendeeData"; field public static final java.lang.String HAS_EXTENDED_PROPERTIES = "hasExtendedProperties"; + field public static final java.lang.String IS_ORGANIZER = "isOrganizer"; field public static final java.lang.String LAST_DATE = "lastDate"; field public static final java.lang.String LAST_SYNCED = "lastSynced"; field public static final java.lang.String ORGANIZER = "organizer"; @@ -17295,6 +17305,7 @@ package android.provider { field public static final java.lang.String SYNC_DATA8 = "sync_data8"; field public static final java.lang.String SYNC_DATA9 = "sync_data9"; field public static final java.lang.String TITLE = "title"; + field public static final java.lang.String UID_2445 = "uid2445"; } public static final class CalendarContract.EventsEntity implements android.provider.BaseColumns android.provider.CalendarContract.EventsColumns android.provider.CalendarContract.SyncColumns { @@ -18787,7 +18798,7 @@ package android.provider { method public static int getInt(android.content.ContentResolver, java.lang.String) throws android.provider.Settings.SettingNotFoundException; method public static long getLong(android.content.ContentResolver, java.lang.String, long); method public static long getLong(android.content.ContentResolver, java.lang.String) throws android.provider.Settings.SettingNotFoundException; - method public static synchronized java.lang.String getString(android.content.ContentResolver, java.lang.String); + method public static java.lang.String getString(android.content.ContentResolver, java.lang.String); method public static android.net.Uri getUriFor(java.lang.String); method public static boolean putFloat(android.content.ContentResolver, java.lang.String, float); method public static boolean putInt(android.content.ContentResolver, java.lang.String, int); @@ -18843,7 +18854,7 @@ package android.provider { method public static int getInt(android.content.ContentResolver, java.lang.String) throws android.provider.Settings.SettingNotFoundException; method public static long getLong(android.content.ContentResolver, java.lang.String, long); method public static long getLong(android.content.ContentResolver, java.lang.String) throws android.provider.Settings.SettingNotFoundException; - method public static synchronized java.lang.String getString(android.content.ContentResolver, java.lang.String); + method public static java.lang.String getString(android.content.ContentResolver, java.lang.String); method public static android.net.Uri getUriFor(java.lang.String); method public static final boolean isLocationProviderEnabled(android.content.ContentResolver, java.lang.String); method public static boolean putFloat(android.content.ContentResolver, java.lang.String, float); @@ -18926,7 +18937,7 @@ package android.provider { method public static long getLong(android.content.ContentResolver, java.lang.String, long); method public static long getLong(android.content.ContentResolver, java.lang.String) throws android.provider.Settings.SettingNotFoundException; method public static deprecated boolean getShowGTalkServiceStatus(android.content.ContentResolver); - method public static synchronized java.lang.String getString(android.content.ContentResolver, java.lang.String); + method public static java.lang.String getString(android.content.ContentResolver, java.lang.String); method public static android.net.Uri getUriFor(java.lang.String); method public static boolean putConfiguration(android.content.ContentResolver, android.content.res.Configuration); method public static boolean putFloat(android.content.ContentResolver, java.lang.String, float); @@ -24953,7 +24964,6 @@ package android.view { method public android.view.ViewParent getParentForAccessibility(); method public float getPivotX(); method public float getPivotY(); - method public int getResolvedTextAlignment(); method public android.content.res.Resources getResources(); method public final int getRight(); method protected float getRightFadingEdgeStrength(); diff --git a/cmds/installd/commands.c b/cmds/installd/commands.c index 2934261..a9945b7 100644 --- a/cmds/installd/commands.c +++ b/cmds/installd/commands.c @@ -338,13 +338,32 @@ int free_cache(int64_t free_size) closedir(d); } - // Collect cache files on external storage (if it is mounted as part + // Collect cache files on external storage for all users (if it is mounted as part // of the internal storage). strcpy(tmpdir, android_media_dir.path); - if (lookup_media_dir(tmpdir, "Android") == 0 - && lookup_media_dir(tmpdir, "data") == 0) { - //ALOGI("adding cache files from %s\n", tmpdir); - add_cache_files(cache, tmpdir, "cache"); + dirpos = tmpdir + strlen(tmpdir); + d = opendir(tmpdir); + if (d != NULL) { + while ((de = readdir(d))) { + if (de->d_type == DT_DIR) { + const char *name = de->d_name; + /* skip any dir that doesn't start with a number, so not a user */ + if (name[0] < '0' || name[0] > '9') { + continue; + } + if ((strlen(name)+(dirpos-tmpdir)) < (sizeof(tmpdir)-1)) { + strcpy(dirpos, name); + if (lookup_media_dir(tmpdir, "Android") == 0 + && lookup_media_dir(tmpdir, "data") == 0) { + //ALOGI("adding cache files from %s\n", tmpdir); + add_cache_files(cache, tmpdir, "cache"); + } + } else { + ALOGW("Path exceeds limit: %s%s", tmpdir, name); + } + } + } + closedir(d); } clear_cache_files(cache, free_size); diff --git a/core/java/android/accounts/AccountManagerService.java b/core/java/android/accounts/AccountManagerService.java index 9caf84f..fc569e0 100644 --- a/core/java/android/accounts/AccountManagerService.java +++ b/core/java/android/accounts/AccountManagerService.java @@ -647,16 +647,17 @@ public class AccountManagerService if (response == null) throw new IllegalArgumentException("response is null"); if (account == null) throw new IllegalArgumentException("account is null"); checkManageAccountsPermission(); + UserHandle user = Binder.getCallingUserHandle(); UserAccounts accounts = getUserAccountsForCaller(); long identityToken = clearCallingIdentity(); - cancelNotification(getSigninRequiredNotificationId(accounts, account)); + cancelNotification(getSigninRequiredNotificationId(accounts, account), user); synchronized(accounts.credentialsPermissionNotificationIds) { for (Pair<Pair<Account, String>, Integer> pair: accounts.credentialsPermissionNotificationIds.keySet()) { if (account.equals(pair.first.first)) { int id = accounts.credentialsPermissionNotificationIds.get(pair); - cancelNotification(id); + cancelNotification(id, user); } } } @@ -789,7 +790,8 @@ public class AccountManagerService if (account == null || type == null) { return false; } - cancelNotification(getSigninRequiredNotificationId(accounts, account)); + cancelNotification(getSigninRequiredNotificationId(accounts, account), + new UserHandle(accounts.userId)); synchronized (accounts.cacheLock) { final SQLiteDatabase db = accounts.openHelper.getWritableDatabase(); db.beginTransaction(); @@ -1173,11 +1175,12 @@ public class AccountManagerService title = titleAndSubtitle.substring(0, index); subtitle = titleAndSubtitle.substring(index + 1); } + UserHandle user = new UserHandle(userId); n.setLatestEventInfo(mContext, title, subtitle, PendingIntent.getActivityAsUser(mContext, 0, intent, - PendingIntent.FLAG_CANCEL_CURRENT, - null, new UserHandle(userId))); - installNotification(getCredentialPermissionNotificationId(account, authTokenType, uid), n); + PendingIntent.FLAG_CANCEL_CURRENT, null, user)); + installNotification(getCredentialPermissionNotificationId( + account, authTokenType, uid), n, user); } String getAccountLabel(String accountType) { @@ -1763,7 +1766,8 @@ public class AccountManagerService String accountType = result.getString(AccountManager.KEY_ACCOUNT_TYPE); if (!TextUtils.isEmpty(accountName) && !TextUtils.isEmpty(accountType)) { Account account = new Account(accountName, accountType); - cancelNotification(getSigninRequiredNotificationId(mAccounts, account)); + cancelNotification(getSigninRequiredNotificationId(mAccounts, account), + new UserHandle(mAccounts.userId)); } } IAccountManagerResponse response; @@ -2101,30 +2105,32 @@ public class AccountManagerService intent.addCategory(String.valueOf(notificationId)); Notification n = new Notification(android.R.drawable.stat_sys_warning, null, 0 /* when */); + UserHandle user = new UserHandle(userId); final String notificationTitleFormat = mContext.getText(R.string.notification_title).toString(); n.setLatestEventInfo(mContext, String.format(notificationTitleFormat, account.name), message, PendingIntent.getActivityAsUser( mContext, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT, - null, new UserHandle(userId))); - installNotification(notificationId, n); + null, user)); + installNotification(notificationId, n, user); } } finally { restoreCallingIdentity(identityToken); } } - protected void installNotification(final int notificationId, final Notification n) { + protected void installNotification(final int notificationId, final Notification n, + UserHandle user) { ((NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE)) - .notify(notificationId, n); + .notifyAsUser(null, notificationId, n, user); } - protected void cancelNotification(int id) { + protected void cancelNotification(int id, UserHandle user) { long identityToken = clearCallingIdentity(); try { ((NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE)) - .cancel(id); + .cancelAsUser(null, id, user); } finally { restoreCallingIdentity(identityToken); } @@ -2289,7 +2295,8 @@ public class AccountManagerService } finally { db.endTransaction(); } - cancelNotification(getCredentialPermissionNotificationId(account, authTokenType, uid)); + cancelNotification(getCredentialPermissionNotificationId(account, authTokenType, uid), + new UserHandle(accounts.userId)); } } @@ -2323,7 +2330,8 @@ public class AccountManagerService } finally { db.endTransaction(); } - cancelNotification(getCredentialPermissionNotificationId(account, authTokenType, uid)); + cancelNotification(getCredentialPermissionNotificationId(account, authTokenType, uid), + new UserHandle(accounts.userId)); } } diff --git a/core/java/android/app/PendingIntent.java b/core/java/android/app/PendingIntent.java index 8fb6948..9d57467 100644 --- a/core/java/android/app/PendingIntent.java +++ b/core/java/android/app/PendingIntent.java @@ -265,6 +265,8 @@ public final class PendingIntent implements Parcelable { /** * @hide + * Note that UserHandle.CURRENT will be interpreted at the time the + * activity is started, not when the pending intent is created. */ public static PendingIntent getActivityAsUser(Context context, int requestCode, Intent intent, int flags, Bundle options, UserHandle user) { @@ -417,7 +419,11 @@ public final class PendingIntent implements Parcelable { new UserHandle(UserHandle.myUserId())); } - /** @hide */ + /** + * @hide + * Note that UserHandle.CURRENT will be interpreted at the time the + * broadcast is sent, not when the pending intent is created. + */ public static PendingIntent getBroadcastAsUser(Context context, int requestCode, Intent intent, int flags, UserHandle userHandle) { String packageName = context.getPackageName(); diff --git a/core/java/android/app/TaskStackBuilder.java b/core/java/android/app/TaskStackBuilder.java index cadf5e4..83f7abf 100644 --- a/core/java/android/app/TaskStackBuilder.java +++ b/core/java/android/app/TaskStackBuilder.java @@ -128,7 +128,11 @@ public class TaskStackBuilder { if (parent != null) { // We have the actual parent intent, build the rest from static metadata // then add the direct parent intent to the end. - addParentStack(parent.getComponent()); + ComponentName target = parent.getComponent(); + if (target == null) { + target = parent.resolveActivity(mSourceContext.getPackageManager()); + } + addParentStack(target); addNextIntent(parent); } return this; diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java index 524962cb..9162d29 100644 --- a/core/java/android/content/Context.java +++ b/core/java/android/content/Context.java @@ -63,18 +63,34 @@ public abstract class Context { */ public static final int MODE_PRIVATE = 0x0000; /** + * @deprecated Creating world-readable files is very dangerous, and likely + * to cause security holes in applications. It is strongly discouraged; + * instead, applications should use more formal mechanism for interactions + * such as {@link ContentProvider}, {@link BroadcastReceiver}, and + * {@link android.app.Service}. There are no guarantees that this + * access mode will remain on a file, such as when it goes through a + * backup and restore. * File creation mode: allow all other applications to have read access * to the created file. * @see #MODE_PRIVATE * @see #MODE_WORLD_WRITEABLE */ + @Deprecated public static final int MODE_WORLD_READABLE = 0x0001; /** + * @deprecated Creating world-writable files is very dangerous, and likely + * to cause security holes in applications. It is strongly discouraged; + * instead, applications should use more formal mechanism for interactions + * such as {@link ContentProvider}, {@link BroadcastReceiver}, and + * {@link android.app.Service}. There are no guarantees that this + * access mode will remain on a file, such as when it goes through a + * backup and restore. * File creation mode: allow all other applications to have write access * to the created file. * @see #MODE_PRIVATE * @see #MODE_WORLD_READABLE */ + @Deprecated public static final int MODE_WORLD_WRITEABLE = 0x0002; /** * File creation mode: for use with {@link #openFileOutput}, if the file @@ -645,8 +661,12 @@ public abstract class Context { * are some important differences: * * <ul> - * <li>The platform does not monitor the space available in external storage, - * and thus will not automatically delete these files. Note that you should + * <li>The platform does not always monitor the space available in external + * storage, and thus may not automatically delete these files. Currently + * the only time files here will be deleted by the platform is when running + * on {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR1} or later and + * {@link android.os.Environment#isExternalStorageEmulated() + * Environment.isExternalStorageEmulated()} returns true. Note that you should * be managing the maximum space you will use for these anyway, just like * with {@link #getCacheDir()}. * <li>External files are not always available: they will disappear if the diff --git a/core/java/android/content/SyncManager.java b/core/java/android/content/SyncManager.java index 6b5e6e2..4257e0e 100644 --- a/core/java/android/content/SyncManager.java +++ b/core/java/android/content/SyncManager.java @@ -16,10 +16,6 @@ package android.content; -import com.android.internal.R; -import com.google.android.collect.Lists; -import com.google.android.collect.Maps; - import android.accounts.Account; import android.accounts.AccountAndUser; import android.accounts.AccountManager; @@ -27,7 +23,6 @@ import android.accounts.AccountManagerService; import android.accounts.OnAccountsUpdateListener; import android.app.ActivityManager; import android.app.AlarmManager; -import android.app.AppGlobals; import android.app.Notification; import android.app.NotificationManager; import android.app.PendingIntent; @@ -62,6 +57,11 @@ import android.util.EventLog; import android.util.Log; import android.util.Pair; +import com.android.internal.R; +import com.google.android.collect.Lists; +import com.google.android.collect.Maps; +import com.google.android.collect.Sets; + import java.io.FileDescriptor; import java.io.PrintWriter; import java.util.ArrayList; @@ -75,6 +75,7 @@ import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Random; +import java.util.Set; import java.util.concurrent.CountDownLatch; /** @@ -151,7 +152,7 @@ public class SyncManager implements OnAccountsUpdateListener { private AlarmManager mAlarmService = null; private SyncStorageEngine mSyncStorageEngine; - public SyncQueue mSyncQueue; + final public SyncQueue mSyncQueue; protected final ArrayList<ActiveSyncContext> mActiveSyncContexts = Lists.newArrayList(); @@ -328,7 +329,21 @@ public class SyncManager implements OnAccountsUpdateListener { private BroadcastReceiver mUserIntentReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { - onUserRemoved(intent); + String action = intent.getAction(); + final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1); + 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 */); + } } }; @@ -401,7 +416,9 @@ public class SyncManager implements OnAccountsUpdateListener { intentFilter = new IntentFilter(); intentFilter.addAction(Intent.ACTION_USER_REMOVED); - mContext.registerReceiver(mUserIntentReceiver, intentFilter); + intentFilter.addAction(Intent.ACTION_USER_STARTED); + mContext.registerReceiverAsUser( + mUserIntentReceiver, UserHandle.ALL, intentFilter, null, null); if (!factoryTest) { mNotificationMgr = (NotificationManager) @@ -897,7 +914,10 @@ 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 removeUser(int userId) { // Clean up the storage engine database mSyncStorageEngine.doDatabaseCleanup(new Account[0], userId); onAccountsUpdated(null); @@ -1267,7 +1287,8 @@ public class SyncManager implements OnAccountsUpdateListener { final String accountKey; if (authority != null) { authorityName = authority.authority; - accountKey = authority.account.name + "/" + authority.account.type; + accountKey = authority.account.name + "/" + authority.account.type + + " u" + authority.userId; } else { authorityName = "Unknown"; accountKey = "Unknown"; @@ -1394,7 +1415,8 @@ public class SyncManager implements OnAccountsUpdateListener { final String accountKey; if (authority != null) { authorityName = authority.authority; - accountKey = authority.account.name + "/" + authority.account.type; + accountKey = authority.account.name + "/" + authority.account.type + + " u" + authority.userId; } else { authorityName = "Unknown"; accountKey = "Unknown"; @@ -1924,6 +1946,10 @@ public class SyncManager implements OnAccountsUpdateListener { } Iterator<SyncOperation> operationIterator = mSyncQueue.mOperationsMap.values().iterator(); + + final ActivityManager activityManager + = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE); + final Set<Integer> removedUsers = Sets.newHashSet(); while (operationIterator.hasNext()) { final SyncOperation op = operationIterator.next(); @@ -1943,6 +1969,15 @@ public class SyncManager implements OnAccountsUpdateListener { continue; } + // if the user in not running, drop the request + if (!activityManager.isUserRunning(op.userId)) { + final UserInfo userInfo = mUserManager.getUserInfo(op.userId); + if (userInfo == null) { + removedUsers.add(op.userId); + } + continue; + } + // if the next run time is in the future, meaning there are no syncs ready // to run, return the time if (op.effectiveRunTime > now) { @@ -1983,6 +2018,12 @@ public class SyncManager implements OnAccountsUpdateListener { operations.add(op); } + for (Integer user : removedUsers) { + // if it's still removed + if (mUserManager.getUserInfo(user) == null) { + removeUser(user); + } + } } // find the next operation to dispatch, if one is ready @@ -2168,13 +2209,13 @@ public class SyncManager implements OnAccountsUpdateListener { new ArrayList<ActiveSyncContext>(mActiveSyncContexts); for (ActiveSyncContext activeSyncContext : activeSyncs) { if (activeSyncContext != null) { - // if an authority was specified then only cancel the sync if it matches + // if an account was specified then only cancel the sync if it matches if (account != null) { if (!account.equals(activeSyncContext.mSyncOperation.account)) { continue; } } - // if an account was specified then only cancel the sync if it matches + // if an authority was specified then only cancel the sync if it matches if (authority != null) { if (!authority.equals(activeSyncContext.mSyncOperation.authority)) { continue; diff --git a/core/java/android/content/SyncOperation.java b/core/java/android/content/SyncOperation.java index 9fcc22d..6611fcd 100644 --- a/core/java/android/content/SyncOperation.java +++ b/core/java/android/content/SyncOperation.java @@ -95,13 +95,18 @@ public class SyncOperation implements Comparable { } public String dump(boolean useOneLine) { - StringBuilder sb = new StringBuilder(); - sb.append(account.name); - sb.append(" (" + account.type + ")"); - sb.append(", " + authority); - sb.append(", "); - sb.append(SyncStorageEngine.SOURCES[syncSource]); - sb.append(", earliestRunTime " + earliestRunTime); + StringBuilder sb = new StringBuilder() + .append(account.name) + .append(" u") + .append(userId).append(" (") + .append(account.type) + .append(")") + .append(", ") + .append(authority) + .append(", ") + .append(SyncStorageEngine.SOURCES[syncSource]) + .append(", earliestRunTime ") + .append(earliestRunTime); if (expedited) { sb.append(", EXPEDITED"); } diff --git a/core/java/android/content/pm/PackageCleanItem.java b/core/java/android/content/pm/PackageCleanItem.java index eea3b9c..b1896aa 100644 --- a/core/java/android/content/pm/PackageCleanItem.java +++ b/core/java/android/content/pm/PackageCleanItem.java @@ -21,10 +21,12 @@ import android.os.Parcelable; /** @hide */ public class PackageCleanItem { + public final int userId; public final String packageName; public final boolean andCode; - public PackageCleanItem(String packageName, boolean andCode) { + public PackageCleanItem(int userId, String packageName, boolean andCode) { + this.userId = userId; this.packageName = packageName; this.andCode = andCode; } @@ -37,7 +39,8 @@ public class PackageCleanItem { try { if (obj != null) { PackageCleanItem other = (PackageCleanItem)obj; - return packageName.equals(other.packageName) && andCode == other.andCode; + return userId == other.userId && packageName.equals(other.packageName) + && andCode == other.andCode; } } catch (ClassCastException e) { } @@ -47,6 +50,7 @@ public class PackageCleanItem { @Override public int hashCode() { int result = 17; + result = 31 * result + userId; result = 31 * result + packageName.hashCode(); result = 31 * result + (andCode ? 1 : 0); return result; @@ -57,6 +61,7 @@ public class PackageCleanItem { } public void writeToParcel(Parcel dest, int parcelableFlags) { + dest.writeInt(userId); dest.writeString(packageName); dest.writeInt(andCode ? 1 : 0); } @@ -73,6 +78,7 @@ public class PackageCleanItem { }; private PackageCleanItem(Parcel source) { + userId = source.readInt(); packageName = source.readString(); andCode = source.readInt() != 0; } diff --git a/core/java/android/hardware/Camera.java b/core/java/android/hardware/Camera.java index 375d788..1e8671b 100644 --- a/core/java/android/hardware/Camera.java +++ b/core/java/android/hardware/Camera.java @@ -1161,25 +1161,28 @@ public class Camera { public native final void setDisplayOrientation(int degrees); /** - * Enable or disable the default shutter sound when taking a picture. + * <p>Enable or disable the default shutter sound when taking a picture.</p> * - * By default, the camera plays the system-defined camera shutter sound when - * {@link #takePicture} is called. Using this method, the shutter sound can - * be disabled. It is strongly recommended that an alternative shutter sound - * is played in the {@link ShutterCallback} when the system shutter sound is - * disabled. + * <p>By default, the camera plays the system-defined camera shutter sound + * when {@link #takePicture} is called. Using this method, the shutter sound + * can be disabled. It is strongly recommended that an alternative shutter + * sound is played in the {@link ShutterCallback} when the system shutter + * sound is disabled.</p> * - * Note that devices may not always allow control of the camera shutter - * sound. If the shutter sound cannot be controlled, this method will return - * false. + * <p>Note that devices may not always allow disabling the camera shutter + * sound. If the shutter sound state cannot be set to the desired value, + * this method will return false. {@link CameraInfo#canDisableShutterSound} + * can be used to determine whether the device will allow the shutter sound + * to be disabled.</p> * * @param enabled whether the camera should play the system shutter sound * when {@link #takePicture takePicture} is called. - * @return true if the shutter sound state was successfully changed. False - * if the shutter sound cannot be controlled; in this case, the - * application should not play its own shutter sound since the - * system shutter sound will play when a picture is taken. + * @return {@code true} if the shutter sound state was successfully + * changed. {@code false} if the shutter sound state could not be + * changed. {@code true} is also returned if shutter sound playback + * is already set to the requested state. * @see #takePicture + * @see CameraInfo#canDisableShutterSound * @see ShutterCallback */ public native final boolean enableShutterSound(boolean enabled); diff --git a/core/java/android/nfc/Tag.java b/core/java/android/nfc/Tag.java index f9b765c..f2cd232 100644 --- a/core/java/android/nfc/Tag.java +++ b/core/java/android/nfc/Tag.java @@ -24,6 +24,7 @@ import android.nfc.tech.Ndef; import android.nfc.tech.NdefFormatable; import android.nfc.tech.NfcA; import android.nfc.tech.NfcB; +import android.nfc.tech.NfcBarcode; import android.nfc.tech.NfcF; import android.nfc.tech.NfcV; import android.nfc.tech.TagTechnology; @@ -184,6 +185,9 @@ public final class Tag implements Parcelable { case TagTechnology.NFC_V: strings[i] = NfcV.class.getName(); break; + case TagTechnology.NFC_BARCODE: + strings[i] = NfcBarcode.class.getName(); + break; default: throw new IllegalArgumentException("Unknown tech type " + techList[i]); } diff --git a/core/java/android/nfc/tech/Ndef.java b/core/java/android/nfc/tech/Ndef.java index a31cb9c..64aa299 100644 --- a/core/java/android/nfc/tech/Ndef.java +++ b/core/java/android/nfc/tech/Ndef.java @@ -140,8 +140,8 @@ public final class Ndef extends BasicTagTechnology { * * <p>Does not cause any RF activity and does not block. * - * @param tag an MIFARE Classic compatible tag - * @return MIFARE Classic object + * @param tag an NDEF compatible tag + * @return Ndef object */ public static Ndef get(Tag tag) { if (!tag.hasTech(TagTechnology.NDEF)) return null; diff --git a/core/java/android/nfc/tech/NfcBarcode.java b/core/java/android/nfc/tech/NfcBarcode.java new file mode 100644 index 0000000..3149857 --- /dev/null +++ b/core/java/android/nfc/tech/NfcBarcode.java @@ -0,0 +1,102 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.nfc.tech; + +import android.nfc.Tag; +import android.os.Bundle; +import android.os.RemoteException; + +/** + * Provides access to tags containing just a barcode. + * + * <p>Acquire an {@link NfcBarcode} object using {@link #get}. + * + */ +public final class NfcBarcode extends BasicTagTechnology { + + /** Kovio Tags */ + public static final int TYPE_KOVIO = 1; + public static final int TYPE_UNKNOWN = -1; + + /** @hide */ + public static final String EXTRA_BARCODE_TYPE = "barcodetype"; + + private int mType; + + /** + * Get an instance of {@link NfcBarcode} for the given tag. + * + * <p>Returns null if {@link NfcBarcode} was not enumerated in {@link Tag#getTechList}. + * + * <p>Does not cause any RF activity and does not block. + * + * @param tag an NfcBarcode compatible tag + * @return NfcBarcode object + */ + public static NfcBarcode get(Tag tag) { + if (!tag.hasTech(TagTechnology.NFC_BARCODE)) return null; + try { + return new NfcBarcode(tag); + } catch (RemoteException e) { + return null; + } + } + + /** + * Internal constructor, to be used by NfcAdapter + * @hide + */ + public NfcBarcode(Tag tag) throws RemoteException { + super(tag, TagTechnology.NFC_BARCODE); + Bundle extras = tag.getTechExtras(TagTechnology.NFC_BARCODE); + if (extras != null) { + mType = extras.getInt(EXTRA_BARCODE_TYPE); + } else { + throw new NullPointerException("NfcBarcode tech extras are null."); + } + } + + /** + * Returns the NFC Barcode tag type. + * + * <p>Currently only one of {@link #TYPE_KOVIO} or {@link #TYPE_UNKNOWN}. + * + * <p>Does not cause any RF activity and does not block. + * + * @return the NFC Barcode tag type + */ + public int getType() { + return mType; + } + + /** + * Returns the barcode of an NfcBarcode tag. + * + * <p>Does not cause any RF activity and does not block. + * + * @return a byte array containing the barcode + */ + public byte[] getBarcode() { + switch (mType) { + case TYPE_KOVIO: + // For Kovio tags the barcode matches the ID + return mTag.getId(); + default: + return null; + } + } +} diff --git a/core/java/android/nfc/tech/TagTechnology.java b/core/java/android/nfc/tech/TagTechnology.java index be5cbd2..3493ea7 100644 --- a/core/java/android/nfc/tech/TagTechnology.java +++ b/core/java/android/nfc/tech/TagTechnology.java @@ -148,6 +148,15 @@ public interface TagTechnology extends Closeable { public static final int MIFARE_ULTRALIGHT = 9; /** + * This technology is an instance of {@link NfcBarcode}. + * <p>Support for this technology type is optional. If a stack doesn't support this technology + * type tags using it must still be discovered and present the lower level radio interface + * technologies in use. + * @hide + */ + public static final int NFC_BARCODE = 10; + + /** * Get the {@link Tag} object backing this {@link TagTechnology} object. * @return the {@link Tag} backing this {@link TagTechnology} object. */ diff --git a/core/java/android/provider/CalendarContract.java b/core/java/android/provider/CalendarContract.java index a28585c..af6e88e9 100644 --- a/core/java/android/provider/CalendarContract.java +++ b/core/java/android/provider/CalendarContract.java @@ -467,6 +467,13 @@ public final class CalendarContract { * */ public static final String ALLOWED_ATTENDEE_TYPES = "allowedAttendeeTypes"; + + /** + * Is this the primary calendar for this account. If this column is not explicitly set, the + * provider will return 1 if {@link Calendars#ACCOUNT_NAME} is equal to + * {@link Calendars#OWNER_ACCOUNT}. + */ + public static final String IS_PRIMARY = "isPrimary"; } /** @@ -1206,6 +1213,14 @@ public final class CalendarContract { public static final String ORGANIZER = "organizer"; /** + * Are we the organizer of this event. If this column is not explicitly set, the provider + * will return 1 if {@link #ORGANIZER} is equal to {@link Calendars#OWNER_ACCOUNT}. + * Column name. + * <P>Type: STRING</P> + */ + public static final String IS_ORGANIZER = "isOrganizer"; + + /** * Whether the user can invite others to the event. The * GUESTS_CAN_INVITE_OTHERS is a setting that applies to an arbitrary * guest, while CAN_INVITE_OTHERS indicates if the user can invite @@ -1230,6 +1245,12 @@ public final class CalendarContract { */ public static final String CUSTOM_APP_URI = "customAppUri"; + /** + * The UID for events added from the RFC 2445 iCalendar format. + * Column name. + * <P>Type: TEXT</P> + */ + public static final String UID_2445 = "uid2445"; } /** @@ -1367,7 +1388,9 @@ public final class CalendarContract { DatabaseUtils.cursorIntToContentValuesIfPresent(cursor, cv, GUESTS_CAN_SEE_GUESTS); DatabaseUtils.cursorStringToContentValuesIfPresent(cursor, cv, CUSTOM_APP_PACKAGE); DatabaseUtils.cursorStringToContentValuesIfPresent(cursor, cv, CUSTOM_APP_URI); + DatabaseUtils.cursorStringToContentValuesIfPresent(cursor, cv, UID_2445); DatabaseUtils.cursorStringToContentValuesIfPresent(cursor, cv, ORGANIZER); + DatabaseUtils.cursorStringToContentValuesIfPresent(cursor, cv, IS_ORGANIZER); DatabaseUtils.cursorStringToContentValuesIfPresent(cursor, cv, _SYNC_ID); DatabaseUtils.cursorLongToContentValuesIfPresent(cursor, cv, DIRTY); DatabaseUtils.cursorLongToContentValuesIfPresent(cursor, cv, LAST_SYNCED); @@ -1571,6 +1594,7 @@ public final class CalendarContract { * <li>{@link #GUESTS_CAN_SEE_GUESTS}</li> * <li>{@link #CUSTOM_APP_PACKAGE}</li> * <li>{@link #CUSTOM_APP_URI}</li> + * <li>{@link #UID_2445}</li> * </ul> * The following Events columns are writable only by a sync adapter * <ul> diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index 7864302..9aae1ec 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -764,10 +764,6 @@ public final class Settings { return true; } - public boolean putString(ContentResolver cr, String name, String value) { - return putStringForUser(cr, name, value, UserHandle.myUserId()); - } - public String getStringForUser(ContentResolver cr, String name, final int userHandle) { final boolean isSelf = (userHandle == UserHandle.myUserId()); if (isSelf) { @@ -855,10 +851,6 @@ public final class Settings { if (c != null) c.close(); } } - - public String getString(ContentResolver cr, String name) { - return getStringForUser(cr, name, UserHandle.myUserId()); - } } /** @@ -869,8 +861,17 @@ public final class Settings { public static final class System extends NameValueTable { public static final String SYS_PROP_SETTING_VERSION = "sys.settings_system_version"; - // Populated lazily, guarded by class object: - private static NameValueCache sNameValueCache = null; + /** + * The content:// style URL for this table + */ + public static final Uri CONTENT_URI = + Uri.parse("content://" + AUTHORITY + "/system"); + + private static final NameValueCache sNameValueCache = new NameValueCache( + SYS_PROP_SETTING_VERSION, + CONTENT_URI, + CALL_METHOD_GET_SYSTEM, + CALL_METHOD_PUT_SYSTEM); private static final HashSet<String> MOVED_TO_SECURE; static { @@ -937,28 +938,18 @@ public final class Settings { MOVED_TO_GLOBAL.add(Settings.Global.MODE_RINGER); } - private static void lazyInitCache() { - if (sNameValueCache == null) { - sNameValueCache = new NameValueCache( - SYS_PROP_SETTING_VERSION + '_' + UserHandle.myUserId(), - CONTENT_URI, - CALL_METHOD_GET_SYSTEM, - CALL_METHOD_PUT_SYSTEM); - } - } - /** * Look up a name in the database. * @param resolver to access the database with * @param name to look up in the table * @return the corresponding value, or null if not present */ - public synchronized static String getString(ContentResolver resolver, String name) { + public static String getString(ContentResolver resolver, String name) { return getStringForUser(resolver, name, UserHandle.myUserId()); } /** @hide */ - public synchronized static String getStringForUser(ContentResolver resolver, String name, + public static String getStringForUser(ContentResolver resolver, String name, int userHandle) { if (MOVED_TO_SECURE.contains(name)) { Log.w(TAG, "Setting " + name + " has moved from android.provider.Settings.System" @@ -970,7 +961,6 @@ public final class Settings { + " to android.provider.Settings.Global, returning read-only value."); return Global.getStringForUser(resolver, name, userHandle); } - lazyInitCache(); return sNameValueCache.getStringForUser(resolver, name, userHandle); } @@ -998,7 +988,6 @@ public final class Settings { + " to android.provider.Settings.Global, value is unchanged."); return false; } - lazyInitCache(); return sNameValueCache.putStringForUser(resolver, name, value, userHandle); } @@ -1368,12 +1357,6 @@ public final class Settings { } /** - * The content:// style URL for this table - */ - public static final Uri CONTENT_URI = - Uri.parse("content://" + AUTHORITY + "/system"); - - /** * @deprecated Use {@link android.provider.Settings.Global#STAY_ON_WHILE_PLUGGED_IN} instead */ @Deprecated @@ -2549,8 +2532,18 @@ public final class Settings { public static final class Secure extends NameValueTable { public static final String SYS_PROP_SETTING_VERSION = "sys.settings_secure_version"; + /** + * The content:// style URL for this table + */ + public static final Uri CONTENT_URI = + Uri.parse("content://" + AUTHORITY + "/secure"); + // Populated lazily, guarded by class object: - private static NameValueCache sNameValueCache = null; + private static final NameValueCache sNameValueCache = new NameValueCache( + SYS_PROP_SETTING_VERSION, + CONTENT_URI, + CALL_METHOD_GET_SECURE, + CALL_METHOD_PUT_SECURE); private static ILockSettings sLockSettings = null; @@ -2654,28 +2647,18 @@ public final class Settings { MOVED_TO_GLOBAL.add(Settings.Global.WTF_IS_FATAL); } - private static void lazyInitCache() { - if (sNameValueCache == null) { - sNameValueCache = new NameValueCache( - SYS_PROP_SETTING_VERSION + '_' + UserHandle.myUserId(), - CONTENT_URI, - CALL_METHOD_GET_SECURE, - CALL_METHOD_PUT_SECURE); - } - } - /** * Look up a name in the database. * @param resolver to access the database with * @param name to look up in the table * @return the corresponding value, or null if not present */ - public synchronized static String getString(ContentResolver resolver, String name) { + public static String getString(ContentResolver resolver, String name) { return getStringForUser(resolver, name, UserHandle.myUserId()); } /** @hide */ - public synchronized static String getStringForUser(ContentResolver resolver, String name, + public static String getStringForUser(ContentResolver resolver, String name, int userHandle) { if (MOVED_TO_GLOBAL.contains(name)) { Log.w(TAG, "Setting " + name + " has moved from android.provider.Settings.Secure" @@ -2683,21 +2666,23 @@ public final class Settings { return Global.getStringForUser(resolver, name, userHandle); } - if (sLockSettings == null) { - sLockSettings = ILockSettings.Stub.asInterface( - (IBinder) ServiceManager.getService("lock_settings")); - sIsSystemProcess = Process.myUid() == Process.SYSTEM_UID; - } - if (sLockSettings != null && !sIsSystemProcess - && MOVED_TO_LOCK_SETTINGS.contains(name)) { - try { - return sLockSettings.getString(name, "0", userHandle); - } catch (RemoteException re) { - // Fall through + if (MOVED_TO_LOCK_SETTINGS.contains(name)) { + synchronized (Secure.class) { + if (sLockSettings == null) { + sLockSettings = ILockSettings.Stub.asInterface( + (IBinder) ServiceManager.getService("lock_settings")); + sIsSystemProcess = Process.myUid() == Process.SYSTEM_UID; + } + } + if (sLockSettings != null && !sIsSystemProcess) { + try { + return sLockSettings.getString(name, "0", userHandle); + } catch (RemoteException re) { + // Fall through + } } } - lazyInitCache(); return sNameValueCache.getStringForUser(resolver, name, userHandle); } @@ -2720,7 +2705,6 @@ public final class Settings { + " to android.provider.Settings.Global"); return Global.putStringForUser(resolver, name, value, userHandle); } - lazyInitCache(); return sNameValueCache.putStringForUser(resolver, name, value, userHandle); } @@ -3001,12 +2985,6 @@ public final class Settings { } /** - * The content:// style URL for this table - */ - public static final Uri CONTENT_URI = - Uri.parse("content://" + AUTHORITY + "/secure"); - - /** * @deprecated Use {@link android.provider.Settings.Global#DEVELOPMENT_SETTINGS_ENABLED} * instead */ @@ -5467,11 +5445,21 @@ public final class Settings { /** * Used to disable SMS short code confirmation - defaults to true. + * True indcates we will do the check, etc. Set to false to disable. * @see com.android.internal.telephony.SmsUsageMonitor * @hide */ public static final String SMS_SHORT_CODE_CONFIRMATION = "sms_short_code_confirmation"; + /** + * Used to select which country we use to determine premium sms codes. + * One of com.android.internal.telephony.SMSDispatcher.PREMIUM_RULE_USE_SIM, + * com.android.internal.telephony.SMSDispatcher.PREMIUM_RULE_USE_NETWORK, + * or com.android.internal.telephony.SMSDispatcher.PREMIUM_RULE_USE_BOTH. + * @hide + */ + public static final String SMS_SHORT_CODE_RULE = "sms_short_code_rule"; + /** * Prefix for SMS short code regex patterns (country code is appended). * @see com.android.internal.telephony.SmsUsageMonitor @@ -5755,17 +5743,11 @@ public final class Settings { // Populated lazily, guarded by class object: - private static NameValueCache sNameValueCache = null; - - private static void lazyInitCache() { - if (sNameValueCache == null) { - sNameValueCache = new NameValueCache( - SYS_PROP_SETTING_VERSION, - CONTENT_URI, - CALL_METHOD_GET_GLOBAL, - CALL_METHOD_PUT_GLOBAL); - } - } + private static NameValueCache sNameValueCache = new NameValueCache( + SYS_PROP_SETTING_VERSION, + CONTENT_URI, + CALL_METHOD_GET_GLOBAL, + CALL_METHOD_PUT_GLOBAL); /** * Look up a name in the database. @@ -5773,14 +5755,13 @@ public final class Settings { * @param name to look up in the table * @return the corresponding value, or null if not present */ - public synchronized static String getString(ContentResolver resolver, String name) { + public static String getString(ContentResolver resolver, String name) { return getStringForUser(resolver, name, UserHandle.myUserId()); } /** @hide */ - public synchronized static String getStringForUser(ContentResolver resolver, String name, + public static String getStringForUser(ContentResolver resolver, String name, int userHandle) { - lazyInitCache(); return sNameValueCache.getStringForUser(resolver, name, userHandle); } @@ -5799,7 +5780,6 @@ public final class Settings { /** @hide */ public static boolean putStringForUser(ContentResolver resolver, String name, String value, int userHandle) { - lazyInitCache(); if (LOCAL_LOGV) { Log.v(TAG, "Global.putString(name=" + name + ", value=" + value + " for " + userHandle); diff --git a/core/java/android/view/HardwareRenderer.java b/core/java/android/view/HardwareRenderer.java index bafab21..49f9e9d 100644 --- a/core/java/android/view/HardwareRenderer.java +++ b/core/java/android/view/HardwareRenderer.java @@ -864,6 +864,12 @@ public abstract class HardwareRenderer { if (mEglContext == null) { mEglContext = createContext(sEgl, sEglDisplay, sEglConfig); + if (mEglContext == null) { + //noinspection ConstantConditions + throw new IllegalStateException("Could not create an EGL context. " + + "eglCreateContext failed with error: " + + GLUtils.getEGLErrorString(sEgl.eglGetError())); + } sEglContextStorage.set(createManagedContext(mEglContext)); } } diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index c007142..30b8b85 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -16668,6 +16668,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * {@link #TEXT_ALIGNMENT_TEXT_END}, * {@link #TEXT_ALIGNMENT_VIEW_START}, * {@link #TEXT_ALIGNMENT_VIEW_END} + * + * @hide */ @ViewDebug.ExportedProperty(category = "text", mapping = { @ViewDebug.IntToString(from = TEXT_ALIGNMENT_INHERIT, to = "INHERIT"), @@ -16678,7 +16680,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, @ViewDebug.IntToString(from = TEXT_ALIGNMENT_VIEW_START, to = "VIEW_START"), @ViewDebug.IntToString(from = TEXT_ALIGNMENT_VIEW_END, to = "VIEW_END") }) - public int getTextAlignment() { + public int getRawTextAlignment() { return (mPrivateFlags2 & PFLAG2_TEXT_ALIGNMENT_MASK) >> PFLAG2_TEXT_ALIGNMENT_MASK_SHIFT; } @@ -16698,7 +16700,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * @attr ref android.R.styleable#View_textAlignment */ public void setTextAlignment(int textAlignment) { - if (textAlignment != getTextAlignment()) { + if (textAlignment != getRawTextAlignment()) { // Reset the current and resolved text alignment mPrivateFlags2 &= ~PFLAG2_TEXT_ALIGNMENT_MASK; resetResolvedTextAlignment(); @@ -16737,7 +16739,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, @ViewDebug.IntToString(from = TEXT_ALIGNMENT_VIEW_START, to = "VIEW_START"), @ViewDebug.IntToString(from = TEXT_ALIGNMENT_VIEW_END, to = "VIEW_END") }) - public int getResolvedTextAlignment() { + public int getTextAlignment() { // If text alignment is not resolved, then resolve it if ((mPrivateFlags2 & PFLAG2_TEXT_ALIGNMENT_RESOLVED) != PFLAG2_TEXT_ALIGNMENT_RESOLVED) { resolveTextAlignment(); @@ -16756,14 +16758,14 @@ public class View implements Drawable.Callback, KeyEvent.Callback, if (hasRtlSupport()) { // Set resolved text alignment flag depending on text alignment flag - final int textAlignment = getTextAlignment(); + final int textAlignment = getRawTextAlignment(); switch (textAlignment) { case TEXT_ALIGNMENT_INHERIT: // Check if we can resolve the text alignment if (canResolveTextAlignment() && mParent instanceof View) { View view = (View) mParent; - final int parentResolvedTextAlignment = view.getResolvedTextAlignment(); + final int parentResolvedTextAlignment = view.getTextAlignment(); switch (parentResolvedTextAlignment) { case TEXT_ALIGNMENT_GRAVITY: case TEXT_ALIGNMENT_TEXT_START: @@ -16814,7 +16816,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * @return true if text alignment resolution can be done otherwise return false. */ private boolean canResolveTextAlignment() { - switch (getTextAlignment()) { + switch (getRawTextAlignment()) { case TEXT_DIRECTION_INHERIT: return (mParent != null); default: @@ -16833,6 +16835,13 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } /** + * @hide + */ + public boolean isTextAlignmentInherited() { + return (getRawTextAlignment() == TEXT_ALIGNMENT_INHERIT); + } + + /** * Generate a value suitable for use in {@link #setId(int)}. * This value will not collide with ID values generated at build time by aapt for R.id. * diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java index d40eef9..34411ea 100644 --- a/core/java/android/view/ViewGroup.java +++ b/core/java/android/view/ViewGroup.java @@ -5274,7 +5274,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager if (child.isTextDirectionInherited()) { child.resetResolvedTextDirection(); } - if (child.getTextAlignment() == TEXT_ALIGNMENT_INHERIT) { + if (child.isTextAlignmentInherited()) { child.resetResolvedTextAlignment(); } } diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java index e6f643f..2937166 100644 --- a/core/java/android/widget/TextView.java +++ b/core/java/android/widget/TextView.java @@ -5646,7 +5646,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener private Layout.Alignment getLayoutAlignment() { if (mLayoutAlignment == null) { - mResolvedTextAlignment = getResolvedTextAlignment(); + mResolvedTextAlignment = getTextAlignment(); switch (mResolvedTextAlignment) { case TEXT_ALIGNMENT_GRAVITY: switch (mGravity & Gravity.RELATIVE_HORIZONTAL_GRAVITY_MASK) { diff --git a/core/java/com/android/internal/statusbar/StatusBarNotification.java b/core/java/com/android/internal/statusbar/StatusBarNotification.java index f9a38a5..a91aa3c 100644 --- a/core/java/com/android/internal/statusbar/StatusBarNotification.java +++ b/core/java/com/android/internal/statusbar/StatusBarNotification.java @@ -48,6 +48,7 @@ public class StatusBarNotification implements Parcelable { public final int score; public final UserHandle user; + /** This is temporarily needed for the JB MR1 PDK. */ @Deprecated public StatusBarNotification(String pkg, int id, String tag, int uid, int initialPid, int score, Notification notification) { @@ -143,6 +144,6 @@ public class StatusBarNotification implements Parcelable { /** Returns a userHandle for the instance of the app that posted this notification. */ public int getUserId() { - return UserHandle.getUserId(this.uid); + return this.user.getIdentifier(); } } diff --git a/core/java/com/android/internal/widget/multiwaveview/GlowPadView.java b/core/java/com/android/internal/widget/multiwaveview/GlowPadView.java index 7c1f266..549d74c 100644 --- a/core/java/com/android/internal/widget/multiwaveview/GlowPadView.java +++ b/core/java/com/android/internal/widget/multiwaveview/GlowPadView.java @@ -196,6 +196,7 @@ public class GlowPadView extends View { private Tweener mBackgroundAnimator; private PointCloud mPointCloud; private float mInnerRadius; + private int mPointerId; public GlowPadView(Context context) { this(context, null); @@ -736,9 +737,10 @@ public class GlowPadView extends View { @Override public boolean onTouchEvent(MotionEvent event) { - final int action = event.getAction(); + final int action = event.getActionMasked(); boolean handled = false; switch (action) { + case MotionEvent.ACTION_POINTER_DOWN: case MotionEvent.ACTION_DOWN: if (DEBUG) Log.v(TAG, "*** DOWN ***"); handleDown(event); @@ -752,6 +754,7 @@ public class GlowPadView extends View { handled = true; break; + case MotionEvent.ACTION_POINTER_UP: case MotionEvent.ACTION_UP: if (DEBUG) Log.v(TAG, "*** UP ***"); handleMove(event); @@ -765,6 +768,7 @@ public class GlowPadView extends View { handleCancel(event); handled = true; break; + } invalidate(); return handled ? true : super.onTouchEvent(event); @@ -776,19 +780,24 @@ public class GlowPadView extends View { } private void handleDown(MotionEvent event) { - float eventX = event.getX(); - float eventY = event.getY(); + int actionIndex = event.getActionIndex(); + float eventX = event.getX(actionIndex); + float eventY = event.getY(actionIndex); switchToState(STATE_START, eventX, eventY); if (!trySwitchToFirstTouchState(eventX, eventY)) { mDragging = false; } else { + mPointerId = event.getPointerId(actionIndex); updateGlowPosition(eventX, eventY); } } private void handleUp(MotionEvent event) { if (DEBUG && mDragging) Log.v(TAG, "** Handle RELEASE"); - switchToState(STATE_FINISH, event.getX(), event.getY()); + int actionIndex = event.getActionIndex(); + if (event.getPointerId(actionIndex) == mPointerId) { + switchToState(STATE_FINISH, event.getX(actionIndex), event.getY(actionIndex)); + } } private void handleCancel(MotionEvent event) { @@ -801,7 +810,9 @@ public class GlowPadView extends View { // mActiveTarget = -1; // Drop the active target if canceled. - switchToState(STATE_FINISH, event.getX(), event.getY()); + int actionIndex = event.findPointerIndex(mPointerId); + actionIndex = actionIndex == -1 ? 0 : actionIndex; + switchToState(STATE_FINISH, event.getX(actionIndex), event.getY(actionIndex)); } private void handleMove(MotionEvent event) { @@ -811,9 +822,17 @@ public class GlowPadView extends View { int ntargets = targets.size(); float x = 0.0f; float y = 0.0f; + int actionIndex = event.findPointerIndex(mPointerId); + + if (actionIndex == -1) { + return; // no data for this pointer + } + for (int k = 0; k < historySize + 1; k++) { - float eventX = k < historySize ? event.getHistoricalX(k) : event.getX(); - float eventY = k < historySize ? event.getHistoricalY(k) : event.getY(); + float eventX = k < historySize ? event.getHistoricalX(actionIndex, k) + : event.getX(actionIndex); + float eventY = k < historySize ? event.getHistoricalY(actionIndex, k) + : event.getY(actionIndex); // tx and ty are relative to wave center float tx = eventX - mWaveCenterX; float ty = eventY - mWaveCenterY; diff --git a/core/jni/android_view_GLES20Canvas.cpp b/core/jni/android_view_GLES20Canvas.cpp index b91eb28..a3834ac 100644 --- a/core/jni/android_view_GLES20Canvas.cpp +++ b/core/jni/android_view_GLES20Canvas.cpp @@ -116,7 +116,9 @@ static void android_view_GLES20Canvas_terminateCaches(JNIEnv* env, jobject clazz static OpenGLRenderer* android_view_GLES20Canvas_createRenderer(JNIEnv* env, jobject clazz) { RENDERER_LOGD("Create OpenGLRenderer"); - return new OpenGLRenderer; + OpenGLRenderer* renderer = new OpenGLRenderer(); + renderer->initProperties(); + return renderer; } static void android_view_GLES20Canvas_destroyRenderer(JNIEnv* env, jobject clazz, @@ -734,7 +736,9 @@ static void android_view_GLES20Canvas_resume(JNIEnv* env, jobject clazz, static OpenGLRenderer* android_view_GLES20Canvas_createLayerRenderer(JNIEnv* env, jobject clazz, Layer* layer) { if (layer) { - return new LayerRenderer(layer); + OpenGLRenderer* renderer = new LayerRenderer(layer); + renderer->initProperties(); + return renderer; } return NULL; } diff --git a/core/tests/coretests/src/android/accounts/AccountManagerServiceTest.java b/core/tests/coretests/src/android/accounts/AccountManagerServiceTest.java index 33a73b5..1d7576f 100644 --- a/core/tests/coretests/src/android/accounts/AccountManagerServiceTest.java +++ b/core/tests/coretests/src/android/accounts/AccountManagerServiceTest.java @@ -23,6 +23,7 @@ import android.content.pm.RegisteredServicesCache.ServiceInfo; import android.content.pm.RegisteredServicesCacheListener; import android.os.Bundle; import android.os.Handler; +import android.os.UserHandle; import android.test.AndroidTestCase; import android.test.IsolatedContext; import android.test.RenamingDelegatingContext; @@ -243,11 +244,11 @@ public class AccountManagerServiceTest extends AndroidTestCase { } @Override - protected void installNotification(final int notificationId, final Notification n) { + protected void installNotification(final int notificationId, final Notification n, UserHandle user) { } @Override - protected void cancelNotification(final int id) { + protected void cancelNotification(final int id, UserHandle user) { } } } diff --git a/data/fonts/DroidSansFallback.ttf b/data/fonts/DroidSansFallback.ttf Binary files differindex cfbc66a..2b75113 100644 --- a/data/fonts/DroidSansFallback.ttf +++ b/data/fonts/DroidSansFallback.ttf diff --git a/data/fonts/DroidSansFallbackFull.ttf b/data/fonts/DroidSansFallbackFull.ttf Binary files differindex 0cacabe..a9df005 100644 --- a/data/fonts/DroidSansFallbackFull.ttf +++ b/data/fonts/DroidSansFallbackFull.ttf diff --git a/data/fonts/fallback_fonts.xml b/data/fonts/fallback_fonts.xml index 2c9a0c8..50ff437 100644 --- a/data/fonts/fallback_fonts.xml +++ b/data/fonts/fallback_fonts.xml @@ -93,6 +93,11 @@ </family> <family> <fileset> + <file>NanumGothic.ttf</file> + </fileset> + </family> + <family> + <fileset> <file>AndroidEmoji.ttf</file> </fileset> </family> diff --git a/libs/hwui/Layer.cpp b/libs/hwui/Layer.cpp index 76b274b..fb525ee 100644 --- a/libs/hwui/Layer.cpp +++ b/libs/hwui/Layer.cpp @@ -50,6 +50,13 @@ Layer::~Layer() { deleteTexture(); } +void Layer::freeResourcesLocked() { + if (colorFilter) { + Caches::getInstance().resourceCache.decrementRefcountLocked(colorFilter); + colorFilter = NULL; + } +} + void Layer::setPaint(SkPaint* paint) { OpenGLRenderer::getAlphaAndModeDirect(paint, &alpha, &mode); } diff --git a/libs/hwui/Layer.h b/libs/hwui/Layer.h index 420073a..d2cd440 100644 --- a/libs/hwui/Layer.h +++ b/libs/hwui/Layer.h @@ -45,10 +45,11 @@ class DisplayList; * A layer has dimensions and is backed by an OpenGL texture or FBO. */ struct Layer { - Layer(const uint32_t layerWidth, const uint32_t layerHeight); ~Layer(); + void freeResourcesLocked(); + /** * Sets this layer's region to a rectangle. Computes the appropriate * texture coordinates. diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp index a4403c8..d0d1d93 100644 --- a/libs/hwui/OpenGLRenderer.cpp +++ b/libs/hwui/OpenGLRenderer.cpp @@ -34,6 +34,7 @@ #include "OpenGLRenderer.h" #include "DisplayListRenderer.h" #include "PathRenderer.h" +#include "Properties.h" #include "Vector.h" namespace android { @@ -117,6 +118,8 @@ OpenGLRenderer::OpenGLRenderer(): mCaches(Caches::getInstance()) { memcpy(mMeshVertices, gMeshVertices, sizeof(gMeshVertices)); mFirstSnapshot = new Snapshot; + + mScissorOptimizationDisabled = false; } OpenGLRenderer::~OpenGLRenderer() { @@ -124,16 +127,15 @@ OpenGLRenderer::~OpenGLRenderer() { // GL APIs. All GL state should be kept in Caches.h } -/////////////////////////////////////////////////////////////////////////////// -// Debug -/////////////////////////////////////////////////////////////////////////////// - -void OpenGLRenderer::startMark(const char* name) const { - mCaches.startMark(0, name); -} - -void OpenGLRenderer::endMark() const { - mCaches.endMark(); +void OpenGLRenderer::initProperties() { + char property[PROPERTY_VALUE_MAX]; + if (property_get(PROPERTY_DISABLE_SCISSOR_OPTIMIZATION, property, "false")) { + mScissorOptimizationDisabled = !strcasecmp(property, "true"); + INIT_LOGD(" Scissor optimization %s", + mScissorOptimizationDisabled ? "disabled" : "enabled"); + } else { + INIT_LOGD(" Scissor optimization enabled"); + } } /////////////////////////////////////////////////////////////////////////////// @@ -268,40 +270,6 @@ void OpenGLRenderer::finish() { } } -void OpenGLRenderer::debugOverdraw(bool enable, bool clear) { - if (mCaches.debugOverdraw && getTargetFbo() == 0) { - if (clear) { - mCaches.disableScissor(); - mCaches.stencil.clear(); - } - if (enable) { - mCaches.stencil.enableDebugWrite(); - } else { - mCaches.stencil.disable(); - } - } -} - -void OpenGLRenderer::renderOverdraw() { - if (mCaches.debugOverdraw && getTargetFbo() == 0) { - const Rect* clip = mTilingSnapshot->clipRect; - - mCaches.enableScissor(); - mCaches.setScissor(clip->left, mTilingSnapshot->height - clip->bottom, - clip->right - clip->left, clip->bottom - clip->top); - - mCaches.stencil.enableDebugTest(2); - drawColor(0x2f0000ff, SkXfermode::kSrcOver_Mode); - mCaches.stencil.enableDebugTest(3); - drawColor(0x2f00ff00, SkXfermode::kSrcOver_Mode); - mCaches.stencil.enableDebugTest(4); - drawColor(0x3fff0000, SkXfermode::kSrcOver_Mode); - mCaches.stencil.enableDebugTest(4, true); - drawColor(0x7fff0000, SkXfermode::kSrcOver_Mode); - mCaches.stencil.disable(); - } -} - void OpenGLRenderer::interrupt() { if (mCaches.currentProgram) { if (mCaches.currentProgram->isInUse()) { @@ -439,6 +407,52 @@ status_t OpenGLRenderer::callDrawGLFunction(Functor* functor, Rect& dirty) { } /////////////////////////////////////////////////////////////////////////////// +// Debug +/////////////////////////////////////////////////////////////////////////////// + +void OpenGLRenderer::startMark(const char* name) const { + mCaches.startMark(0, name); +} + +void OpenGLRenderer::endMark() const { + mCaches.endMark(); +} + +void OpenGLRenderer::debugOverdraw(bool enable, bool clear) { + if (mCaches.debugOverdraw && getTargetFbo() == 0) { + if (clear) { + mCaches.disableScissor(); + mCaches.stencil.clear(); + } + if (enable) { + mCaches.stencil.enableDebugWrite(); + } else { + mCaches.stencil.disable(); + } + } +} + +void OpenGLRenderer::renderOverdraw() { + if (mCaches.debugOverdraw && getTargetFbo() == 0) { + const Rect* clip = mTilingSnapshot->clipRect; + + mCaches.enableScissor(); + mCaches.setScissor(clip->left, mTilingSnapshot->height - clip->bottom, + clip->right - clip->left, clip->bottom - clip->top); + + mCaches.stencil.enableDebugTest(2); + drawColor(0x2f0000ff, SkXfermode::kSrcOver_Mode); + mCaches.stencil.enableDebugTest(3); + drawColor(0x2f00ff00, SkXfermode::kSrcOver_Mode); + mCaches.stencil.enableDebugTest(4); + drawColor(0x3fff0000, SkXfermode::kSrcOver_Mode); + mCaches.stencil.enableDebugTest(4, true); + drawColor(0x7fff0000, SkXfermode::kSrcOver_Mode); + mCaches.stencil.disable(); + } +} + +/////////////////////////////////////////////////////////////////////////////// // Layers /////////////////////////////////////////////////////////////////////////////// @@ -1248,7 +1262,7 @@ bool OpenGLRenderer::quickReject(float left, float top, float right, float botto bool rejected = !clipRect.intersects(r); if (!isDeferred() && !rejected) { - mCaches.setScissorEnabled(!clipRect.contains(r)); + mCaches.setScissorEnabled(mScissorOptimizationDisabled || !clipRect.contains(r)); } return rejected; @@ -1384,8 +1398,8 @@ void OpenGLRenderer::setupDrawBlending(bool blend, SkXfermode::Mode mode, bool s // When the blending mode is kClear_Mode, we need to use a modulate color // argb=1,0,0,0 accountForClear(mode); - chooseBlending(blend || (mColorSet && mColorA < 1.0f) || (mShader && mShader->blend()), mode, - mDescription, swapSrcDst); + chooseBlending(blend || (mColorSet && mColorA < 1.0f) || (mShader && mShader->blend()) || + (mColorFilter && mColorFilter->blend()), mode, mDescription, swapSrcDst); } void OpenGLRenderer::setupDrawProgram() { @@ -2711,7 +2725,7 @@ status_t OpenGLRenderer::drawLayer(Layer* layer, float x, float y, SkPaint* pain debugLayerUpdate = mCaches.debugLayersUpdates; } - mCaches.setScissorEnabled(!clip.contains(transformed)); + mCaches.setScissorEnabled(mScissorOptimizationDisabled || !clip.contains(transformed)); mCaches.activeTexture(0); if (CC_LIKELY(!layer->region.isEmpty())) { diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h index 46e66cb..c29e3fb 100644 --- a/libs/hwui/OpenGLRenderer.h +++ b/libs/hwui/OpenGLRenderer.h @@ -64,6 +64,12 @@ public: virtual ~OpenGLRenderer(); /** + * Read externally defined properties to control the behavior + * of the renderer. + */ + ANDROID_API void initProperties(); + + /** * Indicates whether this renderer executes drawing commands immediately. * If this method returns true, the drawing commands will be executed * later. @@ -804,6 +810,10 @@ private: // Indicate whether we are drawing an opaque frame bool mOpaqueFrame; + // See PROPERTY_DISABLE_SCISSOR_OPTIMIZATION in + // Properties.h + bool mScissorOptimizationDisabled; + friend class DisplayListRenderer; }; // class OpenGLRenderer diff --git a/libs/hwui/ProgramCache.cpp b/libs/hwui/ProgramCache.cpp index c81319e..7bc2b37 100644 --- a/libs/hwui/ProgramCache.cpp +++ b/libs/hwui/ProgramCache.cpp @@ -347,7 +347,6 @@ const char* gFS_Main_ApplyColorOp[4] = { // None "", // Matrix - // TODO: Fix premultiplied alpha computations for color matrix " fragColor *= colorMatrix;\n" " fragColor += colorMatrixVector;\n" " fragColor.rgb *= fragColor.a;\n", diff --git a/libs/hwui/Properties.h b/libs/hwui/Properties.h index 31e60e4..1e8765b 100644 --- a/libs/hwui/Properties.h +++ b/libs/hwui/Properties.h @@ -67,6 +67,21 @@ enum DebugLevel { */ #define PROPERTY_DEBUG_OVERDRAW "debug.hwui.show_overdraw" +/** + * Used to enable/disable scissor optimization. The accepted values are + * "true" and "false". The default value is "false". + * + * When scissor optimization is enabled, OpenGLRenderer will attempt to + * minimize the use of scissor by selectively enabling and disabling the + * GL scissor test. + * When the optimization is disabled, OpenGLRenderer will keep the GL + * scissor test enabled and change the scissor rect as needed. + * Some GPUs (for instance the SGX 540) perform better when changing + * the scissor rect often than when enabling/disabling the scissor test + * often. + */ +#define PROPERTY_DISABLE_SCISSOR_OPTIMIZATION "ro.hwui.disable_scissor_opt" + // These properties are defined in mega-bytes #define PROPERTY_TEXTURE_CACHE_SIZE "ro.hwui.texture_cache_size" #define PROPERTY_LAYER_CACHE_SIZE "ro.hwui.layer_cache_size" diff --git a/libs/hwui/ResourceCache.cpp b/libs/hwui/ResourceCache.cpp index 1c83ea4..18d8324 100644 --- a/libs/hwui/ResourceCache.cpp +++ b/libs/hwui/ResourceCache.cpp @@ -155,7 +155,7 @@ void ResourceCache::decrementRefcountLocked(void* resource) { } ref->refCount--; if (ref->refCount == 0) { - deleteResourceReference(resource, ref); + deleteResourceReferenceLocked(resource, ref); } } @@ -201,7 +201,7 @@ void ResourceCache::destructorLocked(SkPath* resource) { } ref->destroyed = true; if (ref->refCount == 0) { - deleteResourceReference(resource, ref); + deleteResourceReferenceLocked(resource, ref); } } @@ -223,7 +223,7 @@ void ResourceCache::destructorLocked(SkBitmap* resource) { } ref->destroyed = true; if (ref->refCount == 0) { - deleteResourceReference(resource, ref); + deleteResourceReferenceLocked(resource, ref); } } @@ -242,7 +242,7 @@ void ResourceCache::destructorLocked(SkiaShader* resource) { } ref->destroyed = true; if (ref->refCount == 0) { - deleteResourceReference(resource, ref); + deleteResourceReferenceLocked(resource, ref); } } @@ -261,7 +261,7 @@ void ResourceCache::destructorLocked(SkiaColorFilter* resource) { } ref->destroyed = true; if (ref->refCount == 0) { - deleteResourceReference(resource, ref); + deleteResourceReferenceLocked(resource, ref); } } @@ -284,7 +284,7 @@ void ResourceCache::recycleLocked(SkBitmap* resource) { } ref->recycled = true; if (ref->refCount == 0) { - deleteResourceReference(resource, ref); + deleteResourceReferenceLocked(resource, ref); } } @@ -292,7 +292,7 @@ void ResourceCache::recycleLocked(SkBitmap* resource) { * This method should only be called while the mLock mutex is held (that mutex is grabbed * by the various destructor() and recycle() methods which call this method). */ -void ResourceCache::deleteResourceReference(void* resource, ResourceReference* ref) { +void ResourceCache::deleteResourceReferenceLocked(void* resource, ResourceReference* ref) { if (ref->recycled && ref->resourceType == kBitmap) { ((SkBitmap*) resource)->setPixels(NULL, NULL); } @@ -326,6 +326,7 @@ void ResourceCache::deleteResourceReference(void* resource, ResourceReference* r break; case kLayer: { Layer* layer = (Layer*) resource; + layer->freeResourcesLocked(); delete layer; } break; diff --git a/libs/hwui/ResourceCache.h b/libs/hwui/ResourceCache.h index 2053d96..a80670c 100644 --- a/libs/hwui/ResourceCache.h +++ b/libs/hwui/ResourceCache.h @@ -103,7 +103,7 @@ public: void recycleLocked(SkBitmap* resource); private: - void deleteResourceReference(void* resource, ResourceReference* ref); + void deleteResourceReferenceLocked(void* resource, ResourceReference* ref); void incrementRefcount(void* resource, ResourceType resourceType); void incrementRefcountLocked(void* resource, ResourceType resourceType); diff --git a/libs/hwui/SkiaColorFilter.cpp b/libs/hwui/SkiaColorFilter.cpp index b86bbc5..f754388 100644 --- a/libs/hwui/SkiaColorFilter.cpp +++ b/libs/hwui/SkiaColorFilter.cpp @@ -34,13 +34,10 @@ SkiaColorFilter::~SkiaColorFilter() { // Color matrix filter /////////////////////////////////////////////////////////////////////////////// -SkiaColorMatrixFilter::SkiaColorMatrixFilter(SkColorFilter *skFilter, float* matrix, float* vector): +SkiaColorMatrixFilter::SkiaColorMatrixFilter(SkColorFilter* skFilter, float* matrix, float* vector): SkiaColorFilter(skFilter, kColorMatrix, true), mMatrix(matrix), mVector(vector) { - // Skia uses the range [0..255] for the addition vector, but we need - // the [0..1] range to apply the vector in GLSL - for (int i = 0; i < 4; i++) { - mVector[i] /= 255.0f; - } + // TODO: We should be smarter about this + mBlend = true; } SkiaColorMatrixFilter::~SkiaColorMatrixFilter() { @@ -62,7 +59,7 @@ void SkiaColorMatrixFilter::setupProgram(Program* program) { // Lighting color filter /////////////////////////////////////////////////////////////////////////////// -SkiaLightingFilter::SkiaLightingFilter(SkColorFilter *skFilter, int multiply, int add): +SkiaLightingFilter::SkiaLightingFilter(SkColorFilter* skFilter, int multiply, int add): SkiaColorFilter(skFilter, kLighting, true) { mMulR = ((multiply >> 16) & 0xFF) / 255.0f; mMulG = ((multiply >> 8) & 0xFF) / 255.0f; @@ -71,6 +68,9 @@ SkiaLightingFilter::SkiaLightingFilter(SkColorFilter *skFilter, int multiply, in mAddR = ((add >> 16) & 0xFF) / 255.0f; mAddG = ((add >> 8) & 0xFF) / 255.0f; mAddB = ((add ) & 0xFF) / 255.0f; + + // A lighting filter always ignores alpha + mBlend = false; } void SkiaLightingFilter::describe(ProgramDescription& description, const Extensions& extensions) { @@ -86,13 +86,16 @@ void SkiaLightingFilter::setupProgram(Program* program) { // Blend color filter /////////////////////////////////////////////////////////////////////////////// -SkiaBlendFilter::SkiaBlendFilter(SkColorFilter *skFilter, int color, SkXfermode::Mode mode): +SkiaBlendFilter::SkiaBlendFilter(SkColorFilter* skFilter, int color, SkXfermode::Mode mode): SkiaColorFilter(skFilter, kBlend, true), mMode(mode) { const int alpha = (color >> 24) & 0xFF; mA = alpha / 255.0f; mR = mA * ((color >> 16) & 0xFF) / 255.0f; mG = mA * ((color >> 8) & 0xFF) / 255.0f; mB = mA * ((color ) & 0xFF) / 255.0f; + + // TODO: We should do something smarter here + mBlend = true; } void SkiaBlendFilter::describe(ProgramDescription& description, const Extensions& extensions) { diff --git a/media/java/android/media/AudioService.java b/media/java/android/media/AudioService.java index cee8da8..c366a8d 100644 --- a/media/java/android/media/AudioService.java +++ b/media/java/android/media/AudioService.java @@ -154,6 +154,7 @@ public class AudioService extends IAudioService.Stub implements OnFinished { private static final int MSG_SET_RSX_CONNECTION_STATE = 23; // change remote submix connection private static final int MSG_SET_FORCE_RSX_USE = 24; // force remote submix audio routing private static final int MSG_CHECK_MUSIC_ACTIVE = 25; + private static final int MSG_BROADCAST_AUDIO_BECOMING_NOISY = 26; // flags for MSG_PERSIST_VOLUME indicating if current and/or last audible volume should be // persisted @@ -3252,6 +3253,10 @@ public class AudioService extends IAudioService.Stub implements OnFinished { case MSG_CHECK_MUSIC_ACTIVE: onCheckMusicActive(); break; + + case MSG_BROADCAST_AUDIO_BECOMING_NOISY: + onSendBecomingNoisyIntent(); + break; } } } @@ -3308,7 +3313,7 @@ public class AudioService extends IAudioService.Stub implements OnFinished { address); } - private void sendBecomingNoisyIntent() { + private void onSendBecomingNoisyIntent() { sendBroadcastToAll(new Intent(AudioManager.ACTION_AUDIO_BECOMING_NOISY)); } @@ -3443,8 +3448,14 @@ public class AudioService extends IAudioService.Stub implements OnFinished { } } if (devices == device) { + sendMsg(mAudioHandler, + MSG_BROADCAST_AUDIO_BECOMING_NOISY, + SENDMSG_REPLACE, + 0, + 0, + null, + 0); delay = 1000; - sendBecomingNoisyIntent(); } } @@ -3710,6 +3721,15 @@ public class AudioService extends IAudioService.Stub implements OnFinished { } else if (action.equalsIgnoreCase(Intent.ACTION_CONFIGURATION_CHANGED)) { handleConfigurationChanged(context); } else if (action.equals(Intent.ACTION_USER_SWITCHED)) { + // attempt to stop music playabck for background user + sendMsg(mAudioHandler, + MSG_BROADCAST_AUDIO_BECOMING_NOISY, + SENDMSG_REPLACE, + 0, + 0, + null, + 0); + // load volume settings for new user readAudioSettings(true /*userSwitch*/); // preserve STREAM_MUSIC volume from one user to the next. sendMsg(mAudioHandler, diff --git a/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java b/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java index b36bd55..24a9d71 100644 --- a/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java +++ b/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java @@ -35,6 +35,7 @@ import android.content.res.ObbInfo; import android.content.res.ObbScanner; import android.net.Uri; import android.os.Environment; +import android.os.Environment.UserEnvironment; import android.os.FileUtils; import android.os.IBinder; import android.os.ParcelFileDescriptor; @@ -268,15 +269,16 @@ public class DefaultContainerService extends IntentService { @Override protected void onHandleIntent(Intent intent) { if (PackageManager.ACTION_CLEAN_EXTERNAL_STORAGE.equals(intent.getAction())) { - IPackageManager pm = IPackageManager.Stub.asInterface( + final IPackageManager pm = IPackageManager.Stub.asInterface( ServiceManager.getService("package")); - PackageCleanItem pkg = null; + PackageCleanItem item = null; try { - while ((pkg=pm.nextPackageToClean(pkg)) != null) { - eraseFiles(Environment.getExternalStorageAppDataDirectory(pkg.packageName)); - eraseFiles(Environment.getExternalStorageAppMediaDirectory(pkg.packageName)); - if (pkg.andCode) { - eraseFiles(Environment.getExternalStorageAppObbDirectory(pkg.packageName)); + while ((item = pm.nextPackageToClean(item)) != null) { + final UserEnvironment userEnv = new UserEnvironment(item.userId); + eraseFiles(userEnv.getExternalStorageAppDataDirectory(item.packageName)); + eraseFiles(userEnv.getExternalStorageAppMediaDirectory(item.packageName)); + if (item.andCode) { + eraseFiles(userEnv.getExternalStorageAppObbDirectory(item.packageName)); } } } catch (RemoteException e) { diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java index f0b8812..3a9b068 100644 --- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java +++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java @@ -315,10 +315,10 @@ public class SettingsProvider extends ContentProvider { String property = null, table = uri.getPathSegments().get(0); final boolean isGlobal = table.equals(TABLE_GLOBAL); if (table.equals(TABLE_SYSTEM)) { - property = Settings.System.SYS_PROP_SETTING_VERSION + '_' + userHandle; + property = Settings.System.SYS_PROP_SETTING_VERSION; backedUpDataChanged = true; } else if (table.equals(TABLE_SECURE)) { - property = Settings.Secure.SYS_PROP_SETTING_VERSION + '_' + userHandle; + property = Settings.Secure.SYS_PROP_SETTING_VERSION; backedUpDataChanged = true; } else if (isGlobal) { property = Settings.Global.SYS_PROP_SETTING_VERSION; // this one is global @@ -447,11 +447,6 @@ public class SettingsProvider extends ContentProvider { sSystemCaches.delete(userHandle); sSecureCaches.delete(userHandle); sKnownMutationsInFlight.delete(userHandle); - - String property = Settings.System.SYS_PROP_SETTING_VERSION + '_' + userHandle; - SystemProperties.set(property, ""); - property = Settings.Secure.SYS_PROP_SETTING_VERSION + '_' + userHandle; - SystemProperties.set(property, ""); } } diff --git a/packages/SystemUI/src/com/android/systemui/BeanBagDream.java b/packages/SystemUI/src/com/android/systemui/BeanBagDream.java index 12e45c7..6b5c9c0 100644 --- a/packages/SystemUI/src/com/android/systemui/BeanBagDream.java +++ b/packages/SystemUI/src/com/android/systemui/BeanBagDream.java @@ -19,7 +19,7 @@ public class BeanBagDream extends Dream { public void onAttachedToWindow() { super.onAttachedToWindow(); setContentView(mBoard); - lightsOut(); + setFullscreen(true); mBoard.startAnimation(); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java index ecb8fed..ec67c15 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java @@ -143,7 +143,7 @@ public abstract class BaseStatusBar extends SystemUI implements return mBarService; } - protected boolean isDeviceProvisioned() { + public boolean isDeviceProvisioned() { return mDeviceProvisioned; } @@ -293,7 +293,8 @@ public abstract class BaseStatusBar extends SystemUI implements Slog.v(TAG, String.format("%s: current userid: %d, notification userid: %d", n, thisUserId, notificationUserId)); } - return thisUserId == notificationUserId; + return notificationUserId == UserHandle.USER_ALL + || thisUserId == notificationUserId; } protected View updateNotificationVetoButton(View row, StatusBarNotification n) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java index a4a3a6a..57528a5 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java @@ -381,15 +381,6 @@ public class PanelView extends FrameLayout { mBar = panelBar; } - public void setImeWindowStatus(boolean visible) { - // To be implemented by classes extending PanelView - } - - public void setup(NetworkController network, BluetoothController bt, BatteryController batt, - LocationController location) { - // To be implemented by classes extending PanelView - } - public void collapse() { // TODO: abort animation or ongoing touch if (!isFullyCollapsed()) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java index c55da5d..7e44b16 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java @@ -171,7 +171,7 @@ public class PhoneStatusBar extends BaseStatusBar { TextView mNotificationPanelDebugText; // settings - PanelView mSettingsPanel; + SettingsPanelView mSettingsPanel; int mSettingsPanelGravity; // top bar @@ -426,8 +426,9 @@ public class PhoneStatusBar extends BaseStatusBar { } // Quick Settings (WIP) - mSettingsPanel = (PanelView) mStatusBarWindow.findViewById(R.id.settings_panel); + mSettingsPanel = (SettingsPanelView) mStatusBarWindow.findViewById(R.id.settings_panel); mSettingsPanel.setBar(mStatusBarView); + mSettingsPanel.setService(this); mSettingsPanel.setup(mNetworkController, mBluetoothController, mBatteryController, mLocationController); @@ -1854,7 +1855,7 @@ public class PhoneStatusBar extends BaseStatusBar { } // Update the QuickSettings container - ((SettingsPanelView) mSettingsPanel).updateResources(); + mSettingsPanel.updateResources(); loadDimens(); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettings.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettings.java index 37fa524..160cf8f 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettings.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettings.java @@ -16,6 +16,7 @@ package com.android.systemui.statusbar.phone; +import android.app.ActivityManagerNative; import android.app.AlertDialog; import android.app.Dialog; import android.app.PendingIntent; @@ -36,6 +37,7 @@ import android.hardware.display.DisplayManager; import android.hardware.display.WifiDisplayStatus; import android.net.Uri; import android.os.Handler; +import android.os.RemoteException; import android.os.SystemProperties; import android.os.UserHandle; import android.provider.ContactsContract; @@ -75,6 +77,7 @@ class QuickSettings { private DisplayManager mDisplayManager; private WifiDisplayStatus mWifiDisplayStatus; + private PhoneStatusBar mStatusBarService; private BrightnessController mBrightnessController; private BluetoothController mBluetoothController; @@ -129,6 +132,14 @@ class QuickSettings { mBar = bar; } + public void setService(PhoneStatusBar phoneStatusBar) { + mStatusBarService = phoneStatusBar; + } + + public PhoneStatusBar getService() { + return mStatusBarService; + } + public void setImeWindowStatus(boolean visible) { mModel.onImeWindowStatusChanged(visible); } @@ -203,10 +214,21 @@ class QuickSettings { Intent intent = new Intent(action); startSettingsActivity(intent); } + private void startSettingsActivity(Intent intent) { + startSettingsActivity(intent, true); + } + + private void startSettingsActivity(Intent intent, boolean onlyProvisioned) { + if (onlyProvisioned && !getService().isDeviceProvisioned()) return; + try { + // Dismiss the lock screen when Settings starts. + ActivityManagerNative.getDefault().dismissKeyguardOnNextActivity(); + } catch (RemoteException e) { + } intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP); - mBar.collapseAllPanels(true); - mContext.startActivityAsUser(intent, UserHandle.CURRENT); + mContext.startActivityAsUser(intent, new UserHandle(UserHandle.USER_CURRENT)); + getService().animateCollapse(); } private void addUserTiles(ViewGroup parent, LayoutInflater inflater) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SettingsPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SettingsPanelView.java index 4a7a424..2ed450dd 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SettingsPanelView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SettingsPanelView.java @@ -58,18 +58,14 @@ public class SettingsPanelView extends PanelView { } } - @Override public void setImeWindowStatus(boolean visible) { if (mQS != null) { mQS.setImeWindowStatus(visible); } } - @Override public void setup(NetworkController networkController, BluetoothController bluetoothController, BatteryController batteryController, LocationController locationController) { - super.setup(networkController, bluetoothController, batteryController, locationController); - if (mQS != null) { mQS.setup(networkController, bluetoothController, batteryController, locationController); @@ -93,4 +89,10 @@ public class SettingsPanelView extends PanelView { "settings,v=" + vel); super.fling(vel, always); } + + public void setService(PhoneStatusBar phoneStatusBar) { + if (mQS != null) { + mQS.setService(phoneStatusBar); + } + } } diff --git a/packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java b/packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java index 7dff549..c55b5bc 100644 --- a/packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java +++ b/packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java @@ -25,6 +25,7 @@ import android.content.res.Resources; import android.os.Environment; import android.os.Handler; import android.os.HandlerThread; +import android.os.UserHandle; import android.os.storage.StorageEventListener; import android.os.storage.StorageManager; import android.provider.Settings; @@ -311,7 +312,8 @@ public class StorageNotification extends StorageEventListener { mUsbStorageNotification.tickerText = title; if (pi == null) { Intent intent = new Intent(); - pi = PendingIntent.getBroadcast(mContext, 0, intent, 0); + pi = PendingIntent.getBroadcastAsUser(mContext, 0, intent, 0, + UserHandle.CURRENT); } mUsbStorageNotification.setLatestEventInfo(mContext, title, message, pi); @@ -336,9 +338,10 @@ public class StorageNotification extends StorageEventListener { final int notificationId = mUsbStorageNotification.icon; if (visible) { - notificationManager.notify(notificationId, mUsbStorageNotification); + notificationManager.notifyAsUser(null, notificationId, mUsbStorageNotification, + UserHandle.ALL); } else { - notificationManager.cancel(notificationId); + notificationManager.cancelAsUser(null, notificationId, UserHandle.ALL); } } @@ -398,7 +401,8 @@ public class StorageNotification extends StorageEventListener { mMediaStorageNotification.tickerText = title; if (pi == null) { Intent intent = new Intent(); - pi = PendingIntent.getBroadcast(mContext, 0, intent, 0); + pi = PendingIntent.getBroadcastAsUser(mContext, 0, intent, 0, + UserHandle.CURRENT); } mMediaStorageNotification.icon = icon; @@ -407,9 +411,10 @@ public class StorageNotification extends StorageEventListener { final int notificationId = mMediaStorageNotification.icon; if (visible) { - notificationManager.notify(notificationId, mMediaStorageNotification); + notificationManager.notifyAsUser(null, notificationId, + mMediaStorageNotification, UserHandle.ALL); } else { - notificationManager.cancel(notificationId); + notificationManager.cancelAsUser(null, notificationId, UserHandle.ALL); } } } diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardPasswordView.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardPasswordView.java index 01f7af3..92bc93c 100644 --- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardPasswordView.java +++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardPasswordView.java @@ -32,7 +32,6 @@ import com.android.internal.widget.PasswordEntryKeyboardView; import android.os.CountDownTimer; import android.os.SystemClock; -import android.security.KeyStore; import android.text.Editable; import android.text.InputType; import android.text.TextWatcher; @@ -270,7 +269,6 @@ public class KeyguardPasswordView extends LinearLayout String entry = mPasswordEntry.getText().toString(); if (mLockPatternUtils.checkPassword(entry)) { mCallback.reportSuccessfulUnlockAttempt(); - KeyStore.getInstance().password(entry); mCallback.dismiss(true); } else if (entry.length() > MINIMUM_PASSWORD_LENGTH_BEFORE_REPORT ) { // to avoid accidental lockout, only count attempts that are long enough to be a diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardPatternView.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardPatternView.java index 6e16bb4..780f117 100644 --- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardPatternView.java +++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardPatternView.java @@ -26,7 +26,6 @@ import android.graphics.Rect; import android.os.Bundle; import android.os.CountDownTimer; import android.os.SystemClock; -import android.security.KeyStore; import android.util.AttributeSet; import android.util.Log; import android.view.MotionEvent; @@ -239,7 +238,6 @@ public class KeyguardPatternView extends GridLayout implements KeyguardSecurityV if (mLockPatternUtils.checkPattern(pattern)) { mCallback.reportSuccessfulUnlockAttempt(); mLockPatternView.setDisplayMode(LockPatternView.DisplayMode.Correct); - KeyStore.getInstance().password(LockPatternUtils.patternToString(pattern)); mTotalFailedPatternAttempts = 0; mCallback.dismiss(true); } else { diff --git a/preloaded-classes b/preloaded-classes index b505dbd..10c5c9e 100644 --- a/preloaded-classes +++ b/preloaded-classes @@ -568,7 +568,6 @@ android.media.MediaRecorder android.media.MediaScanner android.media.RemoteDisplay android.media.ToneGenerator -android.media.videoeditor.MediaArtistNativeHelper android.net.ConnectivityManager android.net.Credentials android.net.DhcpInfoInternal diff --git a/services/java/com/android/server/AppWidgetServiceImpl.java b/services/java/com/android/server/AppWidgetServiceImpl.java index fcc8a06..fa8f4b4 100644 --- a/services/java/com/android/server/AppWidgetServiceImpl.java +++ b/services/java/com/android/server/AppWidgetServiceImpl.java @@ -1398,8 +1398,7 @@ class AppWidgetServiceImpl { int enforceSystemOrCallingUid(String packageName) throws IllegalArgumentException { int callingUid = Binder.getCallingUid(); - int uid = Process.myUid(); - if (UserHandle.getAppId(uid) == Process.SYSTEM_UID || uid == 0) { + if (UserHandle.getAppId(callingUid) == Process.SYSTEM_UID || callingUid == 0) { return callingUid; } return enforceCallingUid(packageName); diff --git a/services/java/com/android/server/DeviceStorageMonitorService.java b/services/java/com/android/server/DeviceStorageMonitorService.java index c919595..750a2fb 100644 --- a/services/java/com/android/server/DeviceStorageMonitorService.java +++ b/services/java/com/android/server/DeviceStorageMonitorService.java @@ -396,13 +396,15 @@ public class DeviceStorageMonitorService extends Binder { com.android.internal.R.string.low_internal_storage_view_title); CharSequence details = mContext.getText( com.android.internal.R.string.low_internal_storage_view_text); - PendingIntent intent = PendingIntent.getActivity(mContext, 0, lowMemIntent, 0); + PendingIntent intent = PendingIntent.getActivityAsUser(mContext, 0, lowMemIntent, 0, + null, UserHandle.CURRENT); Notification notification = new Notification(); notification.icon = com.android.internal.R.drawable.stat_notify_disk_full; notification.tickerText = title; notification.flags |= Notification.FLAG_NO_CLEAR; notification.setLatestEventInfo(mContext, title, details, intent); - mNotificationMgr.notify(LOW_MEMORY_NOTIFICATION_ID, notification); + mNotificationMgr.notifyAsUser(null, LOW_MEMORY_NOTIFICATION_ID, notification, + UserHandle.ALL); mContext.sendStickyBroadcast(mStorageLowIntent); } @@ -415,7 +417,7 @@ public class DeviceStorageMonitorService extends Binder { (NotificationManager)mContext.getSystemService( Context.NOTIFICATION_SERVICE); //cancel notification since memory has been freed - mNotificationMgr.cancel(LOW_MEMORY_NOTIFICATION_ID); + mNotificationMgr.cancelAsUser(null, LOW_MEMORY_NOTIFICATION_ID, UserHandle.ALL); mContext.removeStickyBroadcastAsUser(mStorageLowIntent, UserHandle.ALL); mContext.sendBroadcastAsUser(mStorageOkIntent, UserHandle.ALL); diff --git a/services/java/com/android/server/LocationManagerService.java b/services/java/com/android/server/LocationManagerService.java index 840d432..b834a84 100644 --- a/services/java/com/android/server/LocationManagerService.java +++ b/services/java/com/android/server/LocationManagerService.java @@ -601,6 +601,23 @@ public class LocationManagerService extends ILocationManager.Stub implements Run } } + private boolean isAllowedProviderSafe(String provider) { + if (LocationManager.GPS_PROVIDER.equals(provider) || + LocationManager.PASSIVE_PROVIDER.equals(provider)) { + // gps and passive providers require FINE permission + return mContext.checkCallingOrSelfPermission(ACCESS_FINE_LOCATION) + == PackageManager.PERMISSION_GRANTED; + } else if (LocationManager.NETWORK_PROVIDER.equals(provider) || + LocationManager.FUSED_PROVIDER.equals(provider)) { + // network and fused providers are ok with COARSE or FINE + return (mContext.checkCallingOrSelfPermission(ACCESS_FINE_LOCATION) + == PackageManager.PERMISSION_GRANTED) || + (mContext.checkCallingOrSelfPermission(ACCESS_COARSE_LOCATION) + == PackageManager.PERMISSION_GRANTED); + } + return false; + } + /** * Returns all providers by name, including passive, but excluding * fused. @@ -632,8 +649,6 @@ public class LocationManagerService extends ILocationManager.Stub implements Run */ @Override public List<String> getProviders(Criteria criteria, boolean enabledOnly) { - checkPermission(); - ArrayList<String> out; synchronized (mLock) { out = new ArrayList<String>(mProviders.size()); @@ -642,14 +657,16 @@ public class LocationManagerService extends ILocationManager.Stub implements Run if (LocationManager.FUSED_PROVIDER.equals(name)) { continue; } - if (enabledOnly && !isAllowedBySettingsLocked(name)) { - continue; - } - if (criteria != null && !LocationProvider.propertiesMeetCriteria( - name, provider.getProperties(), criteria)) { - continue; + if (isAllowedProviderSafe(name)) { + if (enabledOnly && !isAllowedBySettingsLocked(name)) { + continue; + } + if (criteria != null && !LocationProvider.propertiesMeetCriteria( + name, provider.getProperties(), criteria)) { + continue; + } + out.add(name); } - out.add(name); } } @@ -660,23 +677,22 @@ public class LocationManagerService extends ILocationManager.Stub implements Run /** * Return the name of the best provider given a Criteria object. * This method has been deprecated from the public API, - * and the whole LoactionProvider (including #meetsCriteria) + * and the whole LocationProvider (including #meetsCriteria) * has been deprecated as well. So this method now uses * some simplified logic. */ @Override public String getBestProvider(Criteria criteria, boolean enabledOnly) { String result = null; - checkPermission(); List<String> providers = getProviders(criteria, enabledOnly); - if (providers.size() < 1) { + if (!providers.isEmpty()) { result = pickBest(providers); if (D) Log.d(TAG, "getBestProvider(" + criteria + ", " + enabledOnly + ")=" + result); return result; } providers = getProviders(null, enabledOnly); - if (providers.size() >= 1) { + if (!providers.isEmpty()) { result = pickBest(providers); if (D) Log.d(TAG, "getBestProvider(" + criteria + ", " + enabledOnly + ")=" + result); return result; diff --git a/services/java/com/android/server/NotificationManagerService.java b/services/java/com/android/server/NotificationManagerService.java index 71e6e66..bab4f7a 100755 --- a/services/java/com/android/server/NotificationManagerService.java +++ b/services/java/com/android/server/NotificationManagerService.java @@ -53,7 +53,6 @@ import android.os.ServiceManager; import android.os.UserHandle; import android.os.Vibrator; import android.provider.Settings; -import android.service.dreams.IDreamManager; import android.telephony.TelephonyManager; import android.text.TextUtils; import android.util.AtomicFile; @@ -890,7 +889,7 @@ public class NotificationManagerService extends INotificationManager.Stub final boolean isSystemNotification = ("android".equals(pkg)); userId = ActivityManager.handleIncomingUser(callingPid, - callingUid, userId, false, true, "enqueueNotification", pkg); + callingUid, userId, true, true, "enqueueNotification", pkg); // Limit the number of notifications that any given package except the android // package can enqueue. Prevents DOS attacks and deals with leaks. @@ -900,7 +899,7 @@ public class NotificationManagerService extends INotificationManager.Stub final int N = mNotificationList.size(); for (int i=0; i<N; i++) { final NotificationRecord r = mNotificationList.get(i); - if (r.pkg.equals(pkg)) { + if (r.pkg.equals(pkg) && r.userId == userId) { count++; if (count >= MAX_PACKAGE_NOTIFICATIONS) { Slog.e(TAG, "Package has already posted " + count @@ -1261,7 +1260,7 @@ public class NotificationManagerService extends INotificationManager.Stub public void cancelNotificationWithTag(String pkg, String tag, int id, int userId) { checkCallerIsSystemOrSameApp(pkg); userId = ActivityManager.handleIncomingUser(Binder.getCallingPid(), - Binder.getCallingUid(), userId, false, true, "cancelNotificationWithTag", pkg); + Binder.getCallingUid(), userId, true, true, "cancelNotificationWithTag", pkg); // Don't allow client applications to cancel foreground service notis. cancelNotification(pkg, tag, id, 0, Binder.getCallingUid() == Process.SYSTEM_UID diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java index fb1d530..eeab757 100644 --- a/services/java/com/android/server/SystemServer.java +++ b/services/java/com/android/server/SystemServer.java @@ -768,6 +768,12 @@ class ServerThread extends Thread { reportWtf("making Vibrator Service ready", e); } + try { + lockSettings.systemReady(); + } catch (Throwable e) { + reportWtf("making Lock Settings Service ready", e); + } + if (devicePolicy != null) { try { devicePolicy.systemReady(); @@ -785,12 +791,6 @@ class ServerThread extends Thread { } try { - lockSettings.systemReady(); - } catch (Throwable e) { - reportWtf("making Lock Settings Service ready", e); - } - - try { wm.systemReady(); } catch (Throwable e) { reportWtf("making Window Manager Service ready", e); diff --git a/services/java/com/android/server/ThrottleService.java b/services/java/com/android/server/ThrottleService.java index 49f39fe..f36d73a 100644 --- a/services/java/com/android/server/ThrottleService.java +++ b/services/java/com/android/server/ThrottleService.java @@ -670,7 +670,8 @@ public class ThrottleService extends IThrottleManager.Stub { intent.setClassName("com.android.phone", "com.android.phone.DataUsage"); intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY); - PendingIntent pi = PendingIntent.getActivity(mContext, 0, intent, 0); + PendingIntent pi = PendingIntent.getActivityAsUser(mContext, 0, intent, 0, + null, UserHandle.CURRENT); Resources r = Resources.getSystem(); CharSequence title = r.getText(titleInt); @@ -686,7 +687,8 @@ public class ThrottleService extends IThrottleManager.Stub { mThrottlingNotification.tickerText = title; mThrottlingNotification.setLatestEventInfo(mContext, title, message, pi); - mNotificationManager.notify(mThrottlingNotification.icon, mThrottlingNotification); + mNotificationManager.notifyAsUser(null, mThrottlingNotification.icon, + mThrottlingNotification, UserHandle.ALL); } @@ -701,7 +703,8 @@ public class ThrottleService extends IThrottleManager.Stub { Intent broadcast = new Intent(ThrottleManager.THROTTLE_ACTION); broadcast.putExtra(ThrottleManager.EXTRA_THROTTLE_LEVEL, -1); mContext.sendStickyBroadcastAsUser(broadcast, UserHandle.ALL); - mNotificationManager.cancel(R.drawable.stat_sys_throttled); + mNotificationManager.cancelAsUser(null, R.drawable.stat_sys_throttled, + UserHandle.ALL); mWarningNotificationSent = false; } } diff --git a/services/java/com/android/server/UiModeManagerService.java b/services/java/com/android/server/UiModeManagerService.java index 3e83baa..85a6e41 100644 --- a/services/java/com/android/server/UiModeManagerService.java +++ b/services/java/com/android/server/UiModeManagerService.java @@ -521,10 +521,13 @@ class UiModeManagerService extends IUiModeManager.Stub { mContext, mContext.getString(R.string.car_mode_disable_notification_title), mContext.getString(R.string.car_mode_disable_notification_message), - PendingIntent.getActivity(mContext, 0, carModeOffIntent, 0)); - mNotificationManager.notify(0, n); + PendingIntent.getActivityAsUser(mContext, 0, carModeOffIntent, 0, + null, UserHandle.CURRENT)); + mNotificationManager.notifyAsUser(null, + R.string.car_mode_disable_notification_title, n, UserHandle.ALL); } else { - mNotificationManager.cancel(0); + mNotificationManager.cancelAsUser(null, + R.string.car_mode_disable_notification_title, UserHandle.ALL); } } } diff --git a/services/java/com/android/server/WifiService.java b/services/java/com/android/server/WifiService.java index 5c38e63..024c8fd 100644 --- a/services/java/com/android/server/WifiService.java +++ b/services/java/com/android/server/WifiService.java @@ -1766,8 +1766,9 @@ public class WifiService extends IWifiManager.Stub { mNotification.when = 0; mNotification.icon = ICON_NETWORKS_AVAILABLE; mNotification.flags = Notification.FLAG_AUTO_CANCEL; - mNotification.contentIntent = PendingIntent.getActivity(mContext, 0, - new Intent(WifiManager.ACTION_PICK_WIFI_NETWORK), 0); + mNotification.contentIntent = PendingIntent.getActivityAsUser(mContext, 0, + new Intent(WifiManager.ACTION_PICK_WIFI_NETWORK), 0, + null, UserHandle.CURRENT); } CharSequence title = mContext.getResources().getQuantityText( @@ -1779,9 +1780,10 @@ public class WifiService extends IWifiManager.Stub { mNotificationRepeatTime = System.currentTimeMillis() + NOTIFICATION_REPEAT_DELAY_MS; - notificationManager.notify(ICON_NETWORKS_AVAILABLE, mNotification); + notificationManager.notifyAsUser(null, ICON_NETWORKS_AVAILABLE, mNotification, + UserHandle.ALL); } else { - notificationManager.cancel(ICON_NETWORKS_AVAILABLE); + notificationManager.cancelAsUser(null, ICON_NETWORKS_AVAILABLE, UserHandle.ALL); } mNotificationShown = visible; diff --git a/services/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/java/com/android/server/accessibility/AccessibilityManagerService.java index 20c89ad..0e101e1 100644 --- a/services/java/com/android/server/accessibility/AccessibilityManagerService.java +++ b/services/java/com/android/server/accessibility/AccessibilityManagerService.java @@ -79,7 +79,6 @@ import android.view.accessibility.IAccessibilityManagerClient; import com.android.internal.R; import com.android.internal.content.PackageMonitor; -import com.android.internal.os.SomeArgs; import com.android.internal.statusbar.IStatusBarService; import org.xmlpull.v1.XmlPullParserException; @@ -472,13 +471,18 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { // If necessary enable accessibility and announce that. if (!userState.mIsAccessibilityEnabled) { userState.mIsAccessibilityEnabled = true; - scheduleSendStateToClientsLocked(userState); } + // No touch exploration. + userState.mIsTouchExplorationEnabled = false; + + // Hook the automation service up. + mUiAutomationService = new Service(mCurrentUserId, componentName, + accessibilityServiceInfo, true); + mUiAutomationService.onServiceConnected(componentName, serviceClient.asBinder()); + + updateInputFilterLocked(userState); + scheduleSendStateToClientsLocked(userState); } - // Hook the automation service up. - mUiAutomationService = new Service(mCurrentUserId, componentName, - accessibilityServiceInfo, true); - mUiAutomationService.onServiceConnected(componentName, serviceClient.asBinder()); } public void unregisterUiTestAutomationService(IAccessibilityServiceClient serviceClient) { @@ -591,16 +595,6 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { // Recreate the internal state for the new user. mMainHandler.obtainMessage(MainHandler.MSG_SEND_RECREATE_INTERNAL_STATE, mCurrentUserId, 0).sendToTarget(); - - // Re-register the test automation service after the new state is recreated. - if (mUiAutomationService != null) { - unregisterUiTestAutomationService(mUiAutomationService.mServiceInterface); - SomeArgs args = SomeArgs.obtain(); - args.arg1 = mUiAutomationService.mServiceInterface; - args.arg2 = mUiAutomationService.mAccessibilityServiceInfo; - mMainHandler.obtainMessage(MainHandler.MSG_REGISTER_UI_TEST_AUTOMATION_SERVICE, - args).sendToTarget(); - } } } @@ -1166,7 +1160,6 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { public static final int MSG_SEND_STATE_TO_CLIENTS = 2; public static final int MSG_SEND_CLEARED_STATE_TO_CLIENTS_FOR_USER = 3; public static final int MSG_SEND_RECREATE_INTERNAL_STATE = 4; - public static final int MSG_REGISTER_UI_TEST_AUTOMATION_SERVICE = 5; public MainHandler(Looper looper) { super(looper); @@ -1202,17 +1195,6 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { recreateInternalStateLocked(userState); } } break; - case MSG_REGISTER_UI_TEST_AUTOMATION_SERVICE: { - SomeArgs args = (SomeArgs) msg.obj; - try { - IAccessibilityServiceClient client = - (IAccessibilityServiceClient) args.arg1; - AccessibilityServiceInfo info = (AccessibilityServiceInfo) args.arg2; - registerUiTestAutomationService(client, info); - } finally { - args.recycle(); - } - } break; } } diff --git a/services/java/com/android/server/am/ActiveServices.java b/services/java/com/android/server/am/ActiveServices.java index aefc264..0c0f00c 100644 --- a/services/java/com/android/server/am/ActiveServices.java +++ b/services/java/com/android/server/am/ActiveServices.java @@ -706,7 +706,7 @@ public class ActiveServices { if (DEBUG_SERVICE) Slog.v(TAG, "retrieveServiceLocked: " + service + " type=" + resolvedType + " callingUid=" + callingUid); - userId = mAm.handleIncomingUserLocked(callingPid, callingUid, userId, + userId = mAm.handleIncomingUser(callingPid, callingUid, userId, false, true, "service", null); if (service.getComponent() != null) { diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java index a6f2974..904c98e 100644 --- a/services/java/com/android/server/am/ActivityManagerService.java +++ b/services/java/com/android/server/am/ActivityManagerService.java @@ -2448,7 +2448,7 @@ public final class ActivityManagerService extends ActivityManagerNative String resultWho, int requestCode, int startFlags, String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) { enforceNotIsolatedCaller("startActivity"); - userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), userId, + userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, false, true, "startActivity", null); return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, @@ -2460,7 +2460,7 @@ public final class ActivityManagerService extends ActivityManagerNative String resultWho, int requestCode, int startFlags, String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) { enforceNotIsolatedCaller("startActivityAndWait"); - userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), userId, + userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, false, true, "startActivityAndWait", null); WaitResult res = new WaitResult(); mMainStack.startActivityMayWait(caller, -1, intent, resolvedType, @@ -2474,7 +2474,7 @@ public final class ActivityManagerService extends ActivityManagerNative String resultWho, int requestCode, int startFlags, Configuration config, Bundle options, int userId) { enforceNotIsolatedCaller("startActivityWithConfig"); - userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), userId, + userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, false, true, "startActivityWithConfig", null); int ret = mMainStack.startActivityMayWait(caller, -1, intent, resolvedType, resultTo, resultWho, requestCode, startFlags, @@ -2613,7 +2613,7 @@ public final class ActivityManagerService extends ActivityManagerNative Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, int startFlags, Bundle options, int userId) { - userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), userId, + userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, false, true, "startActivityInPackage", null); int ret = mMainStack.startActivityMayWait(null, uid, intent, resolvedType, @@ -2634,7 +2634,7 @@ public final class ActivityManagerService extends ActivityManagerNative Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options, int userId) { - userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), userId, + userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, false, true, "startActivityInPackage", null); int ret = mMainStack.startActivities(null, uid, intents, resolvedTypes, resultTo, options, userId); @@ -3460,7 +3460,7 @@ public final class ActivityManagerService extends ActivityManagerNative enforceNotIsolatedCaller("clearApplicationUserData"); int uid = Binder.getCallingUid(); int pid = Binder.getCallingPid(); - userId = handleIncomingUserLocked(pid, uid, + userId = handleIncomingUser(pid, uid, userId, false, true, "clearApplicationUserData", null); long callingId = Binder.clearCallingIdentity(); try { @@ -3516,7 +3516,7 @@ public final class ActivityManagerService extends ActivityManagerNative throw new SecurityException(msg); } - userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), + userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, true, true, "killBackgroundProcesses", null); long callingId = Binder.clearCallingIdentity(); try { @@ -3591,7 +3591,7 @@ public final class ActivityManagerService extends ActivityManagerNative Slog.w(TAG, msg); throw new SecurityException(msg); } - userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), + userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, true, true, "forceStopPackage", null); long callingId = Binder.clearCallingIdentity(); try { @@ -4595,8 +4595,16 @@ public final class ActivityManagerService extends ActivityManagerNative synchronized(this) { int callingUid = Binder.getCallingUid(); - userId = handleIncomingUserLocked(Binder.getCallingPid(), callingUid, userId, - false, true, "getIntentSender", null); + int origUserId = userId; + userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, + type == ActivityManager.INTENT_SENDER_BROADCAST, true, + "getIntentSender", null); + if (origUserId == UserHandle.USER_CURRENT) { + // We don't want to evaluate this until the pending intent is + // actually executed. However, we do want to always do the + // security checking for it above. + userId = UserHandle.USER_CURRENT; + } try { if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { int uid = AppGlobals.getPackageManager() @@ -5748,26 +5756,8 @@ public final class ActivityManagerService extends ActivityManagerNative public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) { - final int callingUid = Binder.getCallingUid(); - if (userId != UserHandle.getCallingUserId()) { - // Check if the caller is holding permissions for cross-user requests. - if (checkComponentPermission( - android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, - Binder.getCallingPid(), callingUid, -1, true) - != PackageManager.PERMISSION_GRANTED) { - String msg = "Permission Denial: " - + "Request to get recent tasks for user " + userId - + " but is calling from user " + UserHandle.getUserId(callingUid) - + "; this requires " - + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; - Slog.w(TAG, msg); - throw new SecurityException(msg); - } else { - if (userId == UserHandle.USER_CURRENT) { - userId = mCurrentUserId; - } - } - } + userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, + false, true, "getRecentTasks", null); synchronized (this) { enforceCallingPermission(android.Manifest.permission.GET_TASKS, @@ -6671,7 +6661,7 @@ public final class ActivityManagerService extends ActivityManagerNative throw new SecurityException(msg); } - userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), userId, + userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, false, true, "getContentProvider", null); return getContentProviderImpl(caller, name, null, stable, userId); } @@ -6680,7 +6670,7 @@ public final class ActivityManagerService extends ActivityManagerNative String name, int userId, IBinder token) { enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, "Do not have permission in call getContentProviderExternal()"); - userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), userId, + userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, false, true, "getContentProvider", null); return getContentProviderExternalUnchecked(name, token, userId); } @@ -6945,7 +6935,7 @@ public final class ActivityManagerService extends ActivityManagerNative */ public String getProviderMimeType(Uri uri, int userId) { enforceNotIsolatedCaller("getProviderMimeType"); - userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), + userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, false, true, "getProviderMimeType", null); final String name = uri.getAuthority(); final long ident = Binder.clearCallingIdentity(); @@ -10918,14 +10908,6 @@ public final class ActivityManagerService extends ActivityManagerNative public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, boolean requireFull, String name, String callerPackage) { - synchronized(this) { - return handleIncomingUserLocked(callingPid, callingUid, userId, allowAll, - requireFull, name, callerPackage); - } - } - - int handleIncomingUserLocked(int callingPid, int callingUid, int userId, boolean allowAll, - boolean requireFull, String name, String callerPackage) { final int callingUserId = UserHandle.getUserId(callingUid); if (callingUserId != userId) { if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { @@ -10966,6 +10948,10 @@ public final class ActivityManagerService extends ActivityManagerNative } if (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF) { + // Note that we may be accessing this outside of a lock... + // shouldn't be a big deal, if this is being called outside + // of a locked context there is intrinsically a race with + // the value the caller will receive and someone else changing it. userId = mCurrentUserId; } if (!allowAll && userId < 0) { @@ -11272,7 +11258,7 @@ public final class ActivityManagerService extends ActivityManagerNative callingPid = Binder.getCallingPid(); } - userId = this.handleIncomingUserLocked(callingPid, callingUid, userId, + userId = this.handleIncomingUser(callingPid, callingUid, userId, true, true, "registerReceiver", callerPackage); List allSticky = null; @@ -11507,7 +11493,7 @@ public final class ActivityManagerService extends ActivityManagerNative Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); } - userId = handleIncomingUserLocked(callingPid, callingUid, userId, + userId = handleIncomingUser(callingPid, callingUid, userId, true, false, "broadcast", callerPackage); // Make sure that the user who is receiving this broadcast is started. @@ -11920,7 +11906,7 @@ public final class ActivityManagerService extends ActivityManagerNative throw new IllegalArgumentException("File descriptors passed in Intent"); } - userId = handleIncomingUserLocked(Binder.getCallingPid(), + userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null); synchronized(this) { @@ -12008,7 +11994,7 @@ public final class ActivityManagerService extends ActivityManagerNative String profileFile, int flags, Bundle arguments, IInstrumentationWatcher watcher, int userId) { enforceNotIsolatedCaller("startInstrumentation"); - userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), + userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, false, true, "startInstrumentation", null); // Refuse possible leaked file descriptors if (arguments != null && arguments.hasFileDescriptors()) { @@ -13854,7 +13840,7 @@ public final class ActivityManagerService extends ActivityManagerNative } private ProcessRecord findProcessLocked(String process, int userId, String callName) { - userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), + userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, true, true, callName, null); ProcessRecord proc = null; try { @@ -14303,6 +14289,10 @@ public final class ActivityManagerService extends ActivityManagerNative } } + int getCurrentUserIdLocked() { + return mCurrentUserId; + } + @Override public boolean isUserRunning(int userId) { if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) diff --git a/services/java/com/android/server/am/PendingIntentRecord.java b/services/java/com/android/server/am/PendingIntentRecord.java index c61f13c..8ee303f 100644 --- a/services/java/com/android/server/am/PendingIntentRecord.java +++ b/services/java/com/android/server/am/PendingIntentRecord.java @@ -25,6 +25,7 @@ import android.os.Binder; import android.os.Bundle; import android.os.IBinder; import android.os.RemoteException; +import android.os.UserHandle; import android.util.Slog; import java.io.PrintWriter; @@ -220,6 +221,10 @@ class PendingIntentRecord extends IIntentSender.Stub { final long origId = Binder.clearCallingIdentity(); boolean sendFinish = finishedReceiver != null; + int userId = key.userId; + if (userId == UserHandle.USER_CURRENT) { + userId = owner.getCurrentUserIdLocked(); + } switch (key.type) { case ActivityManager.INTENT_SENDER_ACTIVITY: if (options == null) { @@ -242,10 +247,10 @@ class PendingIntentRecord extends IIntentSender.Stub { allIntents[allIntents.length-1] = finalIntent; allResolvedTypes[allResolvedTypes.length-1] = resolvedType; owner.startActivitiesInPackage(uid, allIntents, - allResolvedTypes, resultTo, options, key.userId); + allResolvedTypes, resultTo, options, userId); } else { owner.startActivityInPackage(uid, finalIntent, resolvedType, - resultTo, resultWho, requestCode, 0, options, key.userId); + resultTo, resultWho, requestCode, 0, options, userId); } } catch (RuntimeException e) { Slog.w(ActivityManagerService.TAG, @@ -263,7 +268,7 @@ class PendingIntentRecord extends IIntentSender.Stub { owner.broadcastIntentInPackage(key.packageName, uid, finalIntent, resolvedType, finishedReceiver, code, null, null, - requiredPermission, (finishedReceiver != null), false, key.userId); + requiredPermission, (finishedReceiver != null), false, userId); sendFinish = false; } catch (RuntimeException e) { Slog.w(ActivityManagerService.TAG, @@ -273,7 +278,7 @@ class PendingIntentRecord extends IIntentSender.Stub { case ActivityManager.INTENT_SENDER_SERVICE: try { owner.startServiceInPackage(uid, - finalIntent, resolvedType, key.userId); + finalIntent, resolvedType, userId); } catch (RuntimeException e) { Slog.w(ActivityManagerService.TAG, "Unable to send startService intent", e); diff --git a/services/java/com/android/server/connectivity/Tethering.java b/services/java/com/android/server/connectivity/Tethering.java index 79fb458..d8f3546 100644 --- a/services/java/com/android/server/connectivity/Tethering.java +++ b/services/java/com/android/server/connectivity/Tethering.java @@ -461,7 +461,8 @@ public class Tethering extends INetworkManagementEventObserver.Stub { intent.setClassName("com.android.settings", "com.android.settings.TetherSettings"); intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY); - PendingIntent pi = PendingIntent.getActivity(mContext, 0, intent, 0); + PendingIntent pi = PendingIntent.getActivityAsUser(mContext, 0, intent, 0, + null, UserHandle.CURRENT); Resources r = Resources.getSystem(); CharSequence title = r.getText(com.android.internal.R.string.tethered_notification_title); @@ -478,14 +479,16 @@ public class Tethering extends INetworkManagementEventObserver.Stub { mTetheredNotification.tickerText = title; mTetheredNotification.setLatestEventInfo(mContext, title, message, pi); - notificationManager.notify(mTetheredNotification.icon, mTetheredNotification); + notificationManager.notifyAsUser(null, mTetheredNotification.icon, + mTetheredNotification, UserHandle.ALL); } private void clearTetheredNotification() { NotificationManager notificationManager = (NotificationManager)mContext.getSystemService(Context.NOTIFICATION_SERVICE); if (notificationManager != null && mTetheredNotification != null) { - notificationManager.cancel(mTetheredNotification.icon); + notificationManager.cancelAsUser(null, mTetheredNotification.icon, + UserHandle.ALL); mTetheredNotification = null; } } diff --git a/services/java/com/android/server/connectivity/Vpn.java b/services/java/com/android/server/connectivity/Vpn.java index b3cbb84..03ff21f 100644 --- a/services/java/com/android/server/connectivity/Vpn.java +++ b/services/java/com/android/server/connectivity/Vpn.java @@ -50,6 +50,7 @@ import android.os.Process; import android.os.RemoteException; import android.os.SystemClock; import android.os.SystemService; +import android.os.UserHandle; import android.security.Credentials; import android.security.KeyStore; import android.util.Log; @@ -421,7 +422,7 @@ public class Vpn extends BaseNetworkStateTracker { .setDefaults(0) .setOngoing(true) .build(); - nm.notify(R.drawable.vpn_connected, notification); + nm.notifyAsUser(null, R.drawable.vpn_connected, notification, UserHandle.ALL); } } @@ -433,7 +434,7 @@ public class Vpn extends BaseNetworkStateTracker { mContext.getSystemService(Context.NOTIFICATION_SERVICE); if (nm != null) { - nm.cancel(R.drawable.vpn_connected); + nm.cancelAsUser(null, R.drawable.vpn_connected, UserHandle.ALL); } } diff --git a/services/java/com/android/server/display/WifiDisplayController.java b/services/java/com/android/server/display/WifiDisplayController.java index 58f0445..d533c94 100644 --- a/services/java/com/android/server/display/WifiDisplayController.java +++ b/services/java/com/android/server/display/WifiDisplayController.java @@ -73,7 +73,7 @@ final class WifiDisplayController implements DumpUtils.Dump { private static final int DEFAULT_CONTROL_PORT = 7236; private static final int MAX_THROUGHPUT = 50; - private static final int CONNECTION_TIMEOUT_SECONDS = 30; + private static final int CONNECTION_TIMEOUT_SECONDS = 60; private static final int RTSP_TIMEOUT_SECONDS = 15; private static final int DISCOVER_PEERS_MAX_RETRIES = 10; diff --git a/services/java/com/android/server/input/InputManagerService.java b/services/java/com/android/server/input/InputManagerService.java index 3709314..948c0e0 100644 --- a/services/java/com/android/server/input/InputManagerService.java +++ b/services/java/com/android/server/input/InputManagerService.java @@ -58,6 +58,7 @@ import android.os.Message; import android.os.MessageQueue; import android.os.Process; import android.os.RemoteException; +import android.os.UserHandle; import android.provider.Settings; import android.provider.Settings.SettingNotFoundException; import android.util.Log; @@ -660,7 +661,8 @@ public class InputManagerService extends IInputManager.Stub intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED | Intent.FLAG_ACTIVITY_CLEAR_TOP); - mKeyboardLayoutIntent = PendingIntent.getActivity(mContext, 0, intent, 0); + mKeyboardLayoutIntent = PendingIntent.getActivityAsUser(mContext, 0, + intent, 0, null, UserHandle.CURRENT); } Resources r = mContext.getResources(); @@ -673,8 +675,9 @@ public class InputManagerService extends IInputManager.Stub .setSmallIcon(R.drawable.ic_settings_language) .setPriority(Notification.PRIORITY_LOW) .build(); - mNotificationManager.notify(R.string.select_keyboard_layout_notification_title, - notification); + mNotificationManager.notifyAsUser(null, + R.string.select_keyboard_layout_notification_title, + notification, UserHandle.ALL); mKeyboardLayoutNotificationShown = true; } } @@ -683,7 +686,9 @@ public class InputManagerService extends IInputManager.Stub private void hideMissingKeyboardLayoutNotification() { if (mKeyboardLayoutNotificationShown) { mKeyboardLayoutNotificationShown = false; - mNotificationManager.cancel(R.string.select_keyboard_layout_notification_title); + mNotificationManager.cancelAsUser(null, + R.string.select_keyboard_layout_notification_title, + UserHandle.ALL); } } diff --git a/services/java/com/android/server/pm/PackageManagerService.java b/services/java/com/android/server/pm/PackageManagerService.java index 4b4febd..4800e7db 100644 --- a/services/java/com/android/server/pm/PackageManagerService.java +++ b/services/java/com/android/server/pm/PackageManagerService.java @@ -413,7 +413,6 @@ public class PackageManagerService extends IPackageManager.Stub { // package uri's from external media onto secure containers // or internal storage. private IMediaContainerService mContainerService = null; - private int mContainerServiceUserId; static final int SEND_PENDING_BROADCAST = 1; static final int MCS_BOUND = 3; @@ -482,15 +481,8 @@ public class PackageManagerService extends IPackageManager.Stub { " DefaultContainerService"); Intent service = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT); Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); - mContainerServiceUserId = 0; - if (mPendingInstalls.size() > 0) { - mContainerServiceUserId = mPendingInstalls.get(0).getUser().getIdentifier(); - if (mContainerServiceUserId == UserHandle.USER_ALL) { - mContainerServiceUserId = 0; - } - } if (mContext.bindService(service, mDefContainerConn, - Context.BIND_AUTO_CREATE, mContainerServiceUserId)) { + Context.BIND_AUTO_CREATE, UserHandle.USER_OWNER)) { Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); mBound = true; return true; @@ -567,15 +559,6 @@ public class PackageManagerService extends IPackageManager.Stub { } else if (mPendingInstalls.size() > 0) { HandlerParams params = mPendingInstalls.get(0); if (params != null) { - // Check if we're connected to the correct service, if it's an install - // request. - final int installFor = params.getUser().getIdentifier(); - if (installFor != mContainerServiceUserId - && (installFor == UserHandle.USER_ALL - && mContainerServiceUserId != 0)) { - mHandler.sendEmptyMessage(MCS_RECONNECT); - return; - } if (params.startCopy()) { // We are done... look for more work or to // go idle. @@ -693,20 +676,23 @@ public class PackageManagerService extends IPackageManager.Stub { } case START_CLEANING_PACKAGE: { Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); - PackageCleanItem item = new PackageCleanItem((String)msg.obj, - msg.arg2 != 0); + final String packageName = (String)msg.obj; + final int userId = msg.arg1; + final boolean andCode = msg.arg2 != 0; synchronized (mPackages) { - if (msg.arg1 == UserHandle.USER_ALL) { + if (userId == UserHandle.USER_ALL) { int[] users = sUserManager.getUserIds(); for (int user : users) { - mSettings.addPackageToCleanLPw(user, item); + mSettings.addPackageToCleanLPw( + new PackageCleanItem(user, packageName, andCode)); } } else { - mSettings.addPackageToCleanLPw(msg.arg1, item); + mSettings.addPackageToCleanLPw( + new PackageCleanItem(userId, packageName, andCode)); } } Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); - startCleaningPackages(-1); + startCleaningPackages(); } break; case POST_INSTALL: { if (DEBUG_INSTALL) Log.v(TAG, "Handling post-install for " + msg.arg1); @@ -4193,10 +4179,14 @@ public class PackageManagerService extends IPackageManager.Stub { // Add the new setting to mPackages mPackages.put(pkg.applicationInfo.packageName, pkg); // Make sure we don't accidentally delete its data. - for (int i=0; i<mSettings.mPackagesToBeCleaned.size(); i++) { - mSettings.mPackagesToBeCleaned.valueAt(i).remove(pkgName); + final Iterator<PackageCleanItem> iter = mSettings.mPackagesToBeCleaned.iterator(); + while (iter.hasNext()) { + PackageCleanItem item = iter.next(); + if (pkgName.equals(item.packageName)) { + iter.remove(); + } } - + // Take care of first install / last update times. if (currentTime != 0) { if (pkgSetting.firstInstallTime == 0) { @@ -5443,7 +5433,6 @@ public class PackageManagerService extends IPackageManager.Stub { public PackageCleanItem nextPackageToClean(PackageCleanItem lastPackage) { // writer - final int userId = UserHandle.getCallingUserId(); synchronized (mPackages) { if (!isExternalMediaAvailable()) { // If the external storage is no longer mounted at this point, @@ -5451,23 +5440,13 @@ public class PackageManagerService extends IPackageManager.Stub { // packages files and can not delete any more. Bail. return null; } - ArrayList<PackageCleanItem> pkgs = mSettings.mPackagesToBeCleaned.get(userId); - if (pkgs != null) { - if (lastPackage != null) { - pkgs.remove(lastPackage); - } - if (pkgs.size() > 0) { - return pkgs.get(0); - } + final ArrayList<PackageCleanItem> pkgs = mSettings.mPackagesToBeCleaned; + if (lastPackage != null) { + pkgs.remove(lastPackage); + } + if (pkgs.size() > 0) { + return pkgs.get(0); } - mSettings.mPackagesToBeCleaned.remove(userId); - } - // Move on to the next user to clean. - long ident = Binder.clearCallingIdentity(); - try { - startCleaningPackages(userId); - } finally { - Binder.restoreCallingIdentity(ident); } return null; } @@ -5483,34 +5462,22 @@ public class PackageManagerService extends IPackageManager.Stub { userId, andCode ? 1 : 0, packageName)); } - void startCleaningPackages(int lastUser) { + void startCleaningPackages() { // reader - int nextUser = -1; synchronized (mPackages) { if (!isExternalMediaAvailable()) { return; } - final int N = mSettings.mPackagesToBeCleaned.size(); - if (N <= 0) { + if (mSettings.mPackagesToBeCleaned.isEmpty()) { return; } - for (int i=0; i<N; i++) { - int user = mSettings.mPackagesToBeCleaned.keyAt(i); - if (user > lastUser) { - nextUser = user; - break; - } - } - if (nextUser < 0) { - nextUser = mSettings.mPackagesToBeCleaned.keyAt(0); - } } Intent intent = new Intent(PackageManager.ACTION_CLEAN_EXTERNAL_STORAGE); intent.setComponent(DEFAULT_CONTAINER_COMPONENT); IActivityManager am = ActivityManagerNative.getDefault(); if (am != null) { try { - am.startService(null, intent, null, nextUser); + am.startService(null, intent, null, UserHandle.USER_OWNER); } catch (RemoteException e) { } } @@ -8399,10 +8366,11 @@ public class PackageManagerService extends IPackageManager.Stub { } else { users = new int[] { userId }; } - for (int curUser : users) { - ClearStorageConnection conn = new ClearStorageConnection(); - if (mContext.bindService(containerIntent, conn, Context.BIND_AUTO_CREATE, curUser)) { - try { + final ClearStorageConnection conn = new ClearStorageConnection(); + if (mContext.bindService( + containerIntent, conn, Context.BIND_AUTO_CREATE, UserHandle.USER_OWNER)) { + try { + for (int curUser : users) { long timeout = SystemClock.uptimeMillis() + 5000; synchronized (conn) { long now = SystemClock.uptimeMillis(); @@ -8438,9 +8406,9 @@ public class PackageManagerService extends IPackageManager.Stub { } catch (RemoteException e) { } } - } finally { - mContext.unbindService(conn); } + } finally { + mContext.unbindService(conn); } } } @@ -9596,7 +9564,7 @@ public class PackageManagerService extends IPackageManager.Stub { if (DEBUG_SD_INSTALL) Log.i(TAG, "Loading packages"); loadMediaPackages(processCids, uidArr, removeCids); - startCleaningPackages(-1); + startCleaningPackages(); } else { if (DEBUG_SD_INSTALL) Log.i(TAG, "Unloading packages"); diff --git a/services/java/com/android/server/pm/Settings.java b/services/java/com/android/server/pm/Settings.java index 23e54678..2fb853a 100644 --- a/services/java/com/android/server/pm/Settings.java +++ b/services/java/com/android/server/pm/Settings.java @@ -159,8 +159,7 @@ final class Settings { // Packages that have been uninstalled and still need their external // storage data deleted. - final SparseArray<ArrayList<PackageCleanItem>> mPackagesToBeCleaned - = new SparseArray<ArrayList<PackageCleanItem>>(); + final ArrayList<PackageCleanItem> mPackagesToBeCleaned = new ArrayList<PackageCleanItem>(); // Packages that have been renamed since they were first installed. // Keys are the new names of the packages, values are the original @@ -1257,18 +1256,13 @@ final class Settings { } if (mPackagesToBeCleaned.size() > 0) { - for (int i=0; i<mPackagesToBeCleaned.size(); i++) { - final int userId = mPackagesToBeCleaned.keyAt(i); - final String userStr = Integer.toString(userId); - final ArrayList<PackageCleanItem> pkgs = mPackagesToBeCleaned.valueAt(i); - for (int j=0; j<pkgs.size(); j++) { - serializer.startTag(null, "cleaning-package"); - PackageCleanItem item = pkgs.get(j); - serializer.attribute(null, ATTR_NAME, item.packageName); - serializer.attribute(null, ATTR_CODE, item.andCode ? "true" : "false"); - serializer.attribute(null, ATTR_USER, userStr); - serializer.endTag(null, "cleaning-package"); - } + for (PackageCleanItem item : mPackagesToBeCleaned) { + final String userStr = Integer.toString(item.userId); + serializer.startTag(null, "cleaning-package"); + serializer.attribute(null, ATTR_NAME, item.packageName); + serializer.attribute(null, ATTR_CODE, item.andCode ? "true" : "false"); + serializer.attribute(null, ATTR_USER, userStr); + serializer.endTag(null, "cleaning-package"); } } @@ -1524,14 +1518,9 @@ final class Settings { return ret; } - void addPackageToCleanLPw(int userId, PackageCleanItem pkg) { - ArrayList<PackageCleanItem> pkgs = mPackagesToBeCleaned.get(userId); - if (pkgs == null) { - pkgs = new ArrayList<PackageCleanItem>(); - mPackagesToBeCleaned.put(userId, pkgs); - } - if (!pkgs.contains(pkg)) { - pkgs.add(pkg); + void addPackageToCleanLPw(PackageCleanItem pkg) { + if (!mPackagesToBeCleaned.contains(pkg)) { + mPackagesToBeCleaned.add(pkg); } } @@ -1615,18 +1604,18 @@ final class Settings { String userStr = parser.getAttributeValue(null, ATTR_USER); String codeStr = parser.getAttributeValue(null, ATTR_CODE); if (name != null) { - int user = 0; + int userId = 0; boolean andCode = true; try { if (userStr != null) { - user = Integer.parseInt(userStr); + userId = Integer.parseInt(userStr); } } catch (NumberFormatException e) { } if (codeStr != null) { andCode = Boolean.parseBoolean(codeStr); } - addPackageToCleanLPw(user, new PackageCleanItem(name, andCode)); + addPackageToCleanLPw(new PackageCleanItem(userId, name, andCode)); } } else if (tagName.equals("renamed-package")) { String nname = parser.getAttributeValue(null, "new"); diff --git a/services/java/com/android/server/usb/UsbDeviceManager.java b/services/java/com/android/server/usb/UsbDeviceManager.java index 392d5e7..8f13501 100644 --- a/services/java/com/android/server/usb/UsbDeviceManager.java +++ b/services/java/com/android/server/usb/UsbDeviceManager.java @@ -667,7 +667,8 @@ public class UsbDeviceManager { if (id != mUsbNotificationId) { // clear notification if title needs changing if (mUsbNotificationId != 0) { - mNotificationManager.cancel(mUsbNotificationId); + mNotificationManager.cancelAsUser(null, mUsbNotificationId, + UserHandle.ALL); mUsbNotificationId = 0; } if (id != 0) { @@ -688,10 +689,11 @@ public class UsbDeviceManager { Intent intent = Intent.makeRestartActivityTask( new ComponentName("com.android.settings", "com.android.settings.UsbSettings")); - PendingIntent pi = PendingIntent.getActivity(mContext, 0, - intent, 0); + PendingIntent pi = PendingIntent.getActivityAsUser(mContext, 0, + intent, 0, null, UserHandle.CURRENT); notification.setLatestEventInfo(mContext, title, message, pi); - mNotificationManager.notify(id, notification); + mNotificationManager.notifyAsUser(null, id, notification, + UserHandle.ALL); mUsbNotificationId = id; } } @@ -722,15 +724,16 @@ public class UsbDeviceManager { Intent intent = Intent.makeRestartActivityTask( new ComponentName("com.android.settings", "com.android.settings.DevelopmentSettings")); - PendingIntent pi = PendingIntent.getActivity(mContext, 0, - intent, 0); + PendingIntent pi = PendingIntent.getActivityAsUser(mContext, 0, + intent, 0, null, UserHandle.CURRENT); notification.setLatestEventInfo(mContext, title, message, pi); mAdbNotificationShown = true; - mNotificationManager.notify(id, notification); + mNotificationManager.notifyAsUser(null, id, notification, + UserHandle.ALL); } } else if (mAdbNotificationShown) { mAdbNotificationShown = false; - mNotificationManager.cancel(id); + mNotificationManager.cancelAsUser(null, id, UserHandle.ALL); } } diff --git a/tests/RenderScriptTests/ImageProcessing/res/drawable-nodpi/img1600x1067b.jpg b/tests/RenderScriptTests/ImageProcessing/res/drawable-nodpi/img1600x1067b.jpg Binary files differnew file mode 100644 index 0000000..aed0781 --- /dev/null +++ b/tests/RenderScriptTests/ImageProcessing/res/drawable-nodpi/img1600x1067b.jpg diff --git a/tests/RenderScriptTests/ImageProcessing/res/drawable-nodpi/img640x427.jpg b/tests/RenderScriptTests/ImageProcessing/res/drawable-nodpi/img640x427.jpg Binary files differdeleted file mode 100644 index 5bce392..0000000 --- a/tests/RenderScriptTests/ImageProcessing/res/drawable-nodpi/img640x427.jpg +++ /dev/null diff --git a/tools/aidl/aidl.cpp b/tools/aidl/aidl.cpp index 8dbbf50..0728246 100644 --- a/tools/aidl/aidl.cpp +++ b/tools/aidl/aidl.cpp @@ -590,7 +590,8 @@ exactly_one_interface(const char* filename, const document_item_type* items, con } const document_item_type* next = items->next; - if (items->next != NULL) { + // Allow parcelables to skip the "one-only" rule. + if (items->next != NULL && next->item_type != USER_DATA_TYPE) { int lineno = -1; if (next->item_type == INTERFACE_TYPE_BINDER) { lineno = ((interface_type*)next)->interface_token.lineno; @@ -598,9 +599,6 @@ exactly_one_interface(const char* filename, const document_item_type* items, con else if (next->item_type == INTERFACE_TYPE_RPC) { lineno = ((interface_type*)next)->interface_token.lineno; } - else if (next->item_type == USER_DATA_TYPE) { - lineno = ((user_data_type*)next)->keyword_token.lineno; - } fprintf(stderr, "%s:%d aidl can only handle one interface per file\n", filename, lineno); return 1; |