diff options
Diffstat (limited to 'core/java')
20 files changed, 395 insertions, 148 deletions
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; |