diff options
author | android-build-team Robot <android-build-team-robot@google.com> | 2019-12-18 06:25:18 +0000 |
---|---|---|
committer | android-build-team Robot <android-build-team-robot@google.com> | 2019-12-18 06:25:18 +0000 |
commit | b7ac35af035970a29423a017bfeba7cd5ebf200b (patch) | |
tree | 186682a44275fedbc109a2a7b5259823f3ea8476 | |
parent | f00b6679d1533e80535e0c00377a8caae406faf4 (diff) | |
parent | 9d06d85670788e309d05163edc2ccec0a39855bd (diff) | |
download | base-b7ac35af035970a29423a017bfeba7cd5ebf200b.tar.gz |
Merge cherrypicks of [9944759, 9944760, 9944761, 9943995, 9944763, 9942371, 9942372, 9942373, 9942374, 9944689, 9944690, 9944779, 9944766, 9944767, 9944483, 9944413, 9944801, 9944802, 9944803] into qt-qpr1-d-release
Change-Id: I03060eafab992368343bf27f4264d1a40783e8bb
5 files changed, 99 insertions, 36 deletions
diff --git a/media/java/android/media/ExifInterface.java b/media/java/android/media/ExifInterface.java index 5645ba5d7dac..6c723b3a7006 100644 --- a/media/java/android/media/ExifInterface.java +++ b/media/java/android/media/ExifInterface.java @@ -1345,7 +1345,9 @@ public class ExifInterface { private ByteOrder mExifByteOrder = ByteOrder.BIG_ENDIAN; @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private boolean mHasThumbnail; - // The following values used for indicating a thumbnail position. + private boolean mHasThumbnailStrips; + private boolean mAreThumbnailStripsConsecutive; + // Used to indicate the position of the thumbnail (includes offset to EXIF data segment). private int mThumbnailOffset; private int mThumbnailLength; private byte[] mThumbnailBytes; @@ -2043,10 +2045,12 @@ public class ExifInterface { /** * Returns the offset and length of thumbnail inside the image file, or - * {@code null} if there is no thumbnail. + * {@code null} if either there is no thumbnail or the thumbnail bytes are stored + * non-consecutively. * * @return two-element array, the offset in the first value, and length in - * the second, or {@code null} if no thumbnail was found. + * the second, or {@code null} if no thumbnail was found or the thumbnail strips are + * not placed consecutively. * @throws IllegalStateException if {@link #saveAttributes()} has been * called since the underlying file was initially parsed, since * that means offsets may have changed. @@ -2058,10 +2062,12 @@ public class ExifInterface { } if (mHasThumbnail) { + if (mHasThumbnailStrips && !mAreThumbnailStripsConsecutive) { + return null; + } return new long[] { mThumbnailOffset, mThumbnailLength }; - } else { - return null; } + return null; } /** @@ -2536,10 +2542,9 @@ public class ExifInterface { final byte[] value = Arrays.copyOfRange(bytes, IDENTIFIER_EXIF_APP1.length, bytes.length); - readExifSegment(value, imageType); - // Save offset values for createJpegThumbnailBitmap() function mExifOffset = (int) offset; + readExifSegment(value, imageType); } else if (ArrayUtils.startsWith(bytes, IDENTIFIER_XMP_APP1)) { // See XMP Specification Part 3: Storage in Files, 1.1.3 JPEG, Table 6 final long offset = start + IDENTIFIER_XMP_APP1.length; @@ -2843,6 +2848,8 @@ public class ExifInterface { if (in.read(bytes) != length) { throw new IOException("Can't read exif"); } + // Save offset values for handling thumbnail and attribute offsets. + mExifOffset = offset; readExifSegment(bytes, IFD_TYPE_PRIMARY); } @@ -2988,7 +2995,7 @@ public class ExifInterface { // Write EXIF APP1 segment dataOutputStream.writeByte(MARKER); dataOutputStream.writeByte(MARKER_APP1); - writeExifSegment(dataOutputStream, 6); + writeExifSegment(dataOutputStream); byte[] bytes = new byte[4096]; @@ -3319,7 +3326,7 @@ public class ExifInterface { continue; } - final int bytesOffset = dataInputStream.peek(); + final int bytesOffset = dataInputStream.peek() + mExifOffset; final byte[] bytes = new byte[(int) byteCount]; dataInputStream.readFully(bytes); ExifAttribute attribute = new ExifAttribute(dataFormat, numberOfComponents, @@ -3451,31 +3458,28 @@ public class ExifInterface { // The following code limits the size of thumbnail size not to overflow EXIF data area. thumbnailLength = Math.min(thumbnailLength, in.getLength() - thumbnailOffset); - if (mMimeType == IMAGE_TYPE_JPEG || mMimeType == IMAGE_TYPE_RAF - || mMimeType == IMAGE_TYPE_RW2) { - thumbnailOffset += mExifOffset; - } else if (mMimeType == IMAGE_TYPE_ORF) { + if (mMimeType == IMAGE_TYPE_ORF) { // Update offset value since RAF files have IFD data preceding MakerNote data. thumbnailOffset += mOrfMakerNoteOffset; } - if (DEBUG) { - Log.d(TAG, "Setting thumbnail attributes with offset: " + thumbnailOffset - + ", length: " + thumbnailLength); - } if (thumbnailOffset > 0 && thumbnailLength > 0) { mHasThumbnail = true; - mThumbnailOffset = thumbnailOffset; + mThumbnailOffset = thumbnailOffset + mExifOffset; mThumbnailLength = thumbnailLength; mThumbnailCompression = DATA_JPEG; if (mFilename == null && mAssetInputStream == null && mSeekableFileDescriptor == null) { // Save the thumbnail in memory if the input doesn't support reading again. - byte[] thumbnailBytes = new byte[thumbnailLength]; - in.seek(thumbnailOffset); + byte[] thumbnailBytes = new byte[mThumbnailLength]; + in.seek(mThumbnailOffset); in.readFully(thumbnailBytes); mThumbnailBytes = thumbnailBytes; } + if (DEBUG) { + Log.d(TAG, "Setting thumbnail attributes with offset: " + thumbnailOffset + + ", length: " + thumbnailLength); + } } } } @@ -3494,12 +3498,16 @@ public class ExifInterface { long[] stripByteCounts = convertToLongArray(stripByteCountsAttribute.getValue(mExifByteOrder)); - if (stripOffsets == null) { - Log.w(TAG, "stripOffsets should not be null."); + if (stripOffsets == null || stripOffsets.length == 0) { + Log.w(TAG, "stripOffsets should not be null or have zero length."); return; } - if (stripByteCounts == null) { - Log.w(TAG, "stripByteCounts should not be null."); + if (stripByteCounts == null || stripByteCounts.length == 0) { + Log.w(TAG, "stripByteCounts should not be null or have zero length."); + return; + } + if (stripOffsets.length != stripByteCounts.length) { + Log.w(TAG, "stripOffsets and stripByteCounts should have same length."); return; } @@ -3509,10 +3517,18 @@ public class ExifInterface { int bytesRead = 0; int bytesAdded = 0; + mHasThumbnail = mHasThumbnailStrips = mAreThumbnailStripsConsecutive = true; for (int i = 0; i < stripOffsets.length; i++) { int stripOffset = (int) stripOffsets[i]; int stripByteCount = (int) stripByteCounts[i]; + // Check if strips are consecutive + // TODO: Add test for non-consecutive thumbnail image + if (i < stripOffsets.length - 1 + && stripOffset + stripByteCount != stripOffsets[i + 1]) { + mAreThumbnailStripsConsecutive = false; + } + // Skip to offset int skipBytes = stripOffset - bytesRead; if (skipBytes < 0) { @@ -3531,10 +3547,13 @@ public class ExifInterface { stripBytes.length); bytesAdded += stripBytes.length; } - - mHasThumbnail = true; mThumbnailBytes = totalStripBytes; - mThumbnailLength = totalStripBytes.length; + + if (mAreThumbnailStripsConsecutive) { + // Need to add mExifOffset, which is the offset to the EXIF data segment + mThumbnailOffset = (int) stripOffsets[0] + mExifOffset; + mThumbnailLength = totalStripBytes.length; + } } } @@ -3691,8 +3710,7 @@ public class ExifInterface { } // Writes an Exif segment into the given output stream. - private int writeExifSegment(ByteOrderedDataOutputStream dataOutputStream, - int exifOffsetFromBeginning) throws IOException { + private int writeExifSegment(ByteOrderedDataOutputStream dataOutputStream) throws IOException { // The following variables are for calculating each IFD tag group size in bytes. int[] ifdOffsets = new int[EXIF_TAGS.length]; int[] ifdDataSizes = new int[EXIF_TAGS.length]; @@ -3751,6 +3769,8 @@ public class ExifInterface { } // Calculate IFD offsets. + // 8 bytes are for TIFF headers: 2 bytes (byte order) + 2 bytes (identifier) + 4 bytes + // (offset of IFDs) int position = 8; for (int ifdType = 0; ifdType < EXIF_TAGS.length; ++ifdType) { if (!mAttributes[ifdType].isEmpty()) { @@ -3762,7 +3782,8 @@ public class ExifInterface { int thumbnailOffset = position; mAttributes[IFD_TYPE_THUMBNAIL].put(JPEG_INTERCHANGE_FORMAT_TAG.name, ExifAttribute.createULong(thumbnailOffset, mExifByteOrder)); - mThumbnailOffset = exifOffsetFromBeginning + thumbnailOffset; + // Need to add mExifOffset, which is the offset to the EXIF data segment + mThumbnailOffset = thumbnailOffset + mExifOffset; position += mThumbnailLength; } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java index a37367e4bb25..da0f83da5a71 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java @@ -89,7 +89,6 @@ public class NotificationEntryManager implements private NotificationRowBinder mNotificationRowBinder; private NotificationPresenter mPresenter; - private NotificationListenerService.RankingMap mLatestRankingMap; @VisibleForTesting protected NotificationData mNotificationData; @@ -168,8 +167,7 @@ public class NotificationEntryManager implements /** Adds a {@link NotificationLifetimeExtender}. */ public void addNotificationLifetimeExtender(NotificationLifetimeExtender extender) { mNotificationLifetimeExtenders.add(extender); - extender.setCallback(key -> removeNotification(key, mLatestRankingMap, - UNDEFINED_DISMISS_REASON)); + extender.setCallback(key -> removeNotification(key, null, UNDEFINED_DISMISS_REASON)); } public NotificationData getNotificationData() { @@ -307,7 +305,6 @@ public class NotificationEntryManager implements if (!forceRemove && !entryDismissed) { for (NotificationLifetimeExtender extender : mNotificationLifetimeExtenders) { if (extender.shouldExtendLifetime(entry)) { - mLatestRankingMap = ranking; extendLifetime(entry, extender); lifetimeExtended = true; break; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationData.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationData.java index 00092929fd49..4ad7487091e4 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationData.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationData.java @@ -201,6 +201,9 @@ public class NotificationData { removed = mEntries.remove(key); } if (removed == null) return null; + // NEM may pass us a null ranking map if removing a lifetime-extended notification, + // so use the most recent ranking + if (ranking == null) ranking = mRankingMap; mGroupManager.onEntryRemoved(removed); updateRankingAndSort(ranking); return removed; diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java index 4c33bec71a14..b844362e69ed 100644 --- a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java +++ b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java @@ -48,6 +48,7 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.UserIdInt; import android.content.Context; +import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManager.PermissionWhitelistFlags; import android.content.pm.PackageManagerInternal; @@ -2601,7 +2602,7 @@ public class PermissionManagerService { // Make sure all dynamic permissions have been assigned to a package, // and make sure there are no dangling permissions. - flags = updatePermissions(changingPkgName, changingPkg, flags); + flags = updatePermissions(changingPkgName, changingPkg, flags, callback); synchronized (mLock) { if (mBackgroundPermissions == null) { @@ -2651,7 +2652,8 @@ public class PermissionManagerService { Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); } - private int updatePermissions(String packageName, PackageParser.Package pkg, int flags) { + private int updatePermissions(String packageName, PackageParser.Package pkg, int flags, + @Nullable PermissionCallback callback) { Set<BasePermission> needsUpdate = null; synchronized (mLock) { final Iterator<BasePermission> it = mSettings.mPermissions.values().iterator(); @@ -2665,6 +2667,44 @@ public class PermissionManagerService { && (pkg == null || !hasPermission(pkg, bp.getName()))) { Slog.i(TAG, "Removing old permission tree: " + bp.getName() + " from package " + bp.getSourcePackageName()); + if (bp.isRuntime()) { + final int[] userIds = mUserManagerInt.getUserIds(); + final int numUserIds = userIds.length; + for (int userIdNum = 0; userIdNum < numUserIds; userIdNum++) { + final int userId = userIds[userIdNum]; + + mPackageManagerInt.forEachPackage((Package p) -> { + final String pName = p.packageName; + final ApplicationInfo appInfo = + mPackageManagerInt.getApplicationInfo(pName, 0, + Process.SYSTEM_UID, UserHandle.USER_SYSTEM); + if (appInfo != null + && appInfo.targetSdkVersion < Build.VERSION_CODES.M) { + return; + } + + final String permissionName = bp.getName(); + if (checkPermission(permissionName, pName, Process.SYSTEM_UID, + userId) == PackageManager.PERMISSION_GRANTED) { + try { + revokeRuntimePermission( + permissionName, + pName, + false, + userId, + callback); + } catch (IllegalArgumentException e) { + Slog.e(TAG, + "Failed to revoke " + + permissionName + + " from " + + pName, + e); + } + } + }); + } + } flags |= UPDATE_PERMISSIONS_ALL; it.remove(); } diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java index 99a9db316c63..d4a462822ff3 100644 --- a/services/core/java/com/android/server/wm/DisplayPolicy.java +++ b/services/core/java/com/android/server/wm/DisplayPolicy.java @@ -865,6 +865,8 @@ public class DisplayPolicy { if (canToastShowWhenLocked(callingPid)) { attrs.flags |= WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED; } + // Toasts can't be clickable + attrs.flags |= WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; break; } |