diff options
13 files changed, 242 insertions, 115 deletions
diff --git a/core/java/android/app/LoadedApk.java b/core/java/android/app/LoadedApk.java index 1f3dfa729a92..152f45e35287 100644 --- a/core/java/android/app/LoadedApk.java +++ b/core/java/android/app/LoadedApk.java @@ -543,12 +543,7 @@ public final class LoadedApk { // It is NOT ok to call this function from the system_server (for any of the packages it // loads code from) so we explicitly disallow it there. if (needToSetupJitProfiles && !ActivityThread.isSystem()) { - // Temporarily disable logging of disk reads/writes on the Looper thread - // as this is early and necessary. Write is only needed to create the - // profile file if it's not already there. - StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites(); setupJitProfileSupport(); - StrictMode.setThreadPolicy(oldPolicy); } } @@ -572,6 +567,15 @@ public final class LoadedApk { if (!SystemProperties.getBoolean("dalvik.vm.usejitprofiles", false)) { return; } + // Only set up profile support if the loaded apk has the same uid as the + // current process. + // Currently, we do not support profiling across different apps. + // (e.g. application's uid might be different when the code is + // loaded by another app via createApplicationContext) + if (mApplicationInfo.uid != Process.myUid()) { + return; + } + final List<String> codePaths = new ArrayList<>(); if ((mApplicationInfo.flags & ApplicationInfo.FLAG_HAS_CODE) != 0) { codePaths.add(mApplicationInfo.sourceDir); @@ -587,55 +591,11 @@ public final class LoadedApk { } final File profileFile = getPrimaryProfileFile(mPackageName); - if (profileFile.exists()) { - if (!profileFile.canRead() || !profileFile.canWrite()) { - // The apk might be loaded in a context where we don't have permissions - // to track the profile (e.g. when loaded by another app via - // createApplicationContext) - return; - } - } else { - // Profile does not exist. Create it. - FileDescriptor fd = null; - try { - final int permissions = 0600; // read-write for user. - fd = Os.open(profileFile.getAbsolutePath(), OsConstants.O_CREAT, permissions); - Os.fchmod(fd, permissions); - Os.fchown(fd, mApplicationInfo.uid, mApplicationInfo.uid); - } catch (ErrnoException e) { - if (e.errno == OsConstants.EACCES) { - // It can happen that the profile file does not exist but the apk is loaded in a - // context where we don't have permissions (e.g. when loaded by another app via - // createApplicationContext) - return; - } - Log.v(TAG, "Unable to create jit profile file " - + profileFile + ": " + e.getMessage()); - try { - Os.unlink(profileFile.getAbsolutePath()); - } catch (ErrnoException unlinkErr) { - if (unlinkErr.errno != OsConstants.ENOENT) { - Log.v(TAG, "Unable to unlink jit profile file " - + profileFile + ": " + unlinkErr.getMessage()); - } - } - return; - } finally { - IoUtils.closeQuietly(fd); - } - } - final File foreignDexProfilesFile = Environment.getDataProfilesDeForeignDexDirectory(UserHandle.myUserId()); - String foreignDexProfilesPath = null; - if (!foreignDexProfilesFile.exists()) { - Log.v(TAG, "ForeignDexProfilesPath does not exists:" + - foreignDexProfilesFile.getPath()); - } else { - foreignDexProfilesPath = foreignDexProfilesFile.getAbsolutePath(); - } - VMRuntime.registerAppInfo(profileFile.getAbsolutePath(), mApplicationInfo.dataDir, - codePaths.toArray(new String[codePaths.size()]), foreignDexProfilesPath); + + VMRuntime.registerAppInfo(profileFile.getPath(), mApplicationInfo.dataDir, + codePaths.toArray(new String[codePaths.size()]), foreignDexProfilesFile.getPath()); } /** diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index e408cca4e330..8fb49b18b7cf 100755 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -8981,6 +8981,14 @@ public final class Settings { * @hide */ public static final String ENABLE_CELLULAR_ON_BOOT = "enable_cellular_on_boot"; + + /** + * The maximum allowed notification enqueue rate in Hertz. + * + * Should be a float, and includes both posts and updates. + * @hide + */ + public static final String MAX_NOTIFICATION_ENQUEUE_RATE = "max_notification_enqueue_rate"; } /** diff --git a/core/java/com/android/internal/util/FastPrintWriter.java b/core/java/com/android/internal/util/FastPrintWriter.java index c74fea05b6d6..e46e6b026fd9 100644 --- a/core/java/com/android/internal/util/FastPrintWriter.java +++ b/core/java/com/android/internal/util/FastPrintWriter.java @@ -1,5 +1,6 @@ package com.android.internal.util; +import android.util.Log; import android.util.Printer; import java.io.IOException; @@ -328,11 +329,13 @@ public class FastPrintWriter extends PrintWriter { } private void flushBytesLocked() throws IOException { - int position; - if ((position = mBytes.position()) > 0) { - mBytes.flip(); - mOutputStream.write(mBytes.array(), 0, position); - mBytes.clear(); + if (!mIoError) { + int position; + if ((position = mBytes.position()) > 0) { + mBytes.flip(); + mOutputStream.write(mBytes.array(), 0, position); + mBytes.clear(); + } } } @@ -352,11 +355,15 @@ public class FastPrintWriter extends PrintWriter { } break; } - flushBytesLocked(); - mOutputStream.flush(); + if (!mIoError) { + flushBytesLocked(); + mOutputStream.flush(); + } } else if (mWriter != null) { - mWriter.write(mText, 0, mPos); - mWriter.flush(); + if (!mIoError) { + mWriter.write(mText, 0, mPos); + mWriter.flush(); + } } else { int nonEolOff = 0; final int sepLen = mSeparator.length(); @@ -385,12 +392,15 @@ public class FastPrintWriter extends PrintWriter { synchronized (lock) { try { flushLocked(); - if (mOutputStream != null) { - mOutputStream.flush(); - } else if (mWriter != null) { - mWriter.flush(); + if (!mIoError) { + if (mOutputStream != null) { + mOutputStream.flush(); + } else if (mWriter != null) { + mWriter.flush(); + } } } catch (IOException e) { + Log.w("FastPrintWriter", "Write failure", e); setError(); } } @@ -407,6 +417,7 @@ public class FastPrintWriter extends PrintWriter { mWriter.close(); } } catch (IOException e) { + Log.w("FastPrintWriter", "Write failure", e); setError(); } } @@ -425,6 +436,8 @@ public class FastPrintWriter extends PrintWriter { try { appendLocked(charArray, 0, charArray.length); } catch (IOException e) { + Log.w("FastPrintWriter", "Write failure", e); + setError(); } } } @@ -442,6 +455,8 @@ public class FastPrintWriter extends PrintWriter { try { appendLocked(ch); } catch (IOException e) { + Log.w("FastPrintWriter", "Write failure", e); + setError(); } } } @@ -465,6 +480,7 @@ public class FastPrintWriter extends PrintWriter { try { appendLocked(str, 0, str.length()); } catch (IOException e) { + Log.w("FastPrintWriter", "Write failure", e); setError(); } } @@ -500,6 +516,7 @@ public class FastPrintWriter extends PrintWriter { flushLocked(); } } catch (IOException e) { + Log.w("FastPrintWriter", "Write failure", e); setError(); } } @@ -564,6 +581,8 @@ public class FastPrintWriter extends PrintWriter { try { appendLocked(buf, offset, count); } catch (IOException e) { + Log.w("FastPrintWriter", "Write failure", e); + setError(); } } } @@ -584,6 +603,8 @@ public class FastPrintWriter extends PrintWriter { try { appendLocked((char) oneChar); } catch (IOException e) { + Log.w("FastPrintWriter", "Write failure", e); + setError(); } } } @@ -600,6 +621,8 @@ public class FastPrintWriter extends PrintWriter { try { appendLocked(str, 0, str.length()); } catch (IOException e) { + Log.w("FastPrintWriter", "Write failure", e); + setError(); } } } @@ -624,6 +647,8 @@ public class FastPrintWriter extends PrintWriter { try { appendLocked(str, offset, count); } catch (IOException e) { + Log.w("FastPrintWriter", "Write failure", e); + setError(); } } } diff --git a/media/java/android/media/MediaCodecInfo.java b/media/java/android/media/MediaCodecInfo.java index 70029a3dad10..45d0cc025a16 100644 --- a/media/java/android/media/MediaCodecInfo.java +++ b/media/java/android/media/MediaCodecInfo.java @@ -651,6 +651,27 @@ public final class MediaCodecInfo { continue; } } + + // MPEG4 levels are not completely ordered: + // Level1 support only implies Level0 (and not Level0b) support + if (mMime.equalsIgnoreCase(MediaFormat.MIMETYPE_VIDEO_MPEG4)) { + if (pl.level != level && pl.level == CodecProfileLevel.MPEG4Level1 + && level > CodecProfileLevel.MPEG4Level0) { + continue; + } + } + + // HEVC levels incorporate both tiers and levels. Verify tier support. + if (mMime.equalsIgnoreCase(MediaFormat.MIMETYPE_VIDEO_HEVC)) { + boolean supportsHighTier = + (pl.level & CodecProfileLevel.HEVCHighTierLevels) != 0; + boolean checkingHighTier = (level & CodecProfileLevel.HEVCHighTierLevels) != 0; + // high tier levels are only supported by other high tier levels + if (checkingHighTier && !supportsHighTier) { + continue; + } + } + if (pl.level >= level) { // if we recognize the listed profile/level, we must also recognize the // profile/level arguments. @@ -1132,6 +1153,8 @@ public final class MediaCodecInfo { private int mHeightAlignment; private int mSmallerDimensionUpperLimit; + private boolean mAllowMbOverride; // allow XML to override calculated limits + /** * Returns the range of supported bitrates in bits/second. */ @@ -1696,7 +1719,7 @@ public final class MediaCodecInfo { Long.MAX_VALUE, blockSize.getWidth(), blockSize.getHeight(), alignment.getWidth(), alignment.getHeight()); - if ((mParent.mError & ERROR_UNSUPPORTED) != 0) { + if ((mParent.mError & ERROR_UNSUPPORTED) != 0 || mAllowMbOverride) { // codec supports profiles that we don't know. // Use supplied values clipped to platform limits if (widths != null) { @@ -1728,7 +1751,12 @@ public final class MediaCodecInfo { mFrameRateRange = FRAME_RATE_RANGE.intersect(frameRates); } if (bitRates != null) { - mBitrateRange = BITRATE_RANGE.intersect(bitRates); + // only allow bitrate override if unsupported profiles were encountered + if ((mParent.mError & ERROR_UNSUPPORTED) != 0) { + mBitrateRange = BITRATE_RANGE.intersect(bitRates); + } else { + mBitrateRange = mBitrateRange.intersect(bitRates); + } } } else { // no unsupported profile/levels, so restrict values to known limits @@ -1883,6 +1911,19 @@ public final class MediaCodecInfo { int maxBlocks, long maxBlocksPerSecond, int blockWidth, int blockHeight, int widthAlignment, int heightAlignment) { + applyMacroBlockLimits( + 1 /* minHorizontalBlocks */, 1 /* minVerticalBlocks */, + maxHorizontalBlocks, maxVerticalBlocks, + maxBlocks, maxBlocksPerSecond, + blockWidth, blockHeight, widthAlignment, heightAlignment); + } + + private void applyMacroBlockLimits( + int minHorizontalBlocks, int minVerticalBlocks, + int maxHorizontalBlocks, int maxVerticalBlocks, + int maxBlocks, long maxBlocksPerSecond, + int blockWidth, int blockHeight, + int widthAlignment, int heightAlignment) { applyAlignment(widthAlignment, heightAlignment); applyBlockLimits( blockWidth, blockHeight, Range.create(1, maxBlocks), @@ -1892,10 +1933,12 @@ public final class MediaCodecInfo { new Rational(maxHorizontalBlocks, 1))); mHorizontalBlockRange = mHorizontalBlockRange.intersect( - 1, maxHorizontalBlocks / (mBlockWidth / blockWidth)); + Utils.divUp(minHorizontalBlocks, (mBlockWidth / blockWidth)), + maxHorizontalBlocks / (mBlockWidth / blockWidth)); mVerticalBlockRange = mVerticalBlockRange.intersect( - 1, maxVerticalBlocks / (mBlockHeight / blockHeight)); + Utils.divUp(minVerticalBlocks, (mBlockHeight / blockHeight)), + maxVerticalBlocks / (mBlockHeight / blockHeight)); } private void applyLevelLimits() { @@ -2005,7 +2048,7 @@ public final class MediaCodecInfo { case CodecProfileLevel.MPEG2ProfileSimple: switch (profileLevel.level) { case CodecProfileLevel.MPEG2LevelML: - FR = 30; W = 45; H = 36; MBPS = 48600; FS = 1620; BR = 15000; break; + FR = 30; W = 45; H = 36; MBPS = 40500; FS = 1620; BR = 15000; break; default: Log.w(TAG, "Unrecognized profile/level " + profileLevel.profile + "/" @@ -2018,7 +2061,7 @@ public final class MediaCodecInfo { case CodecProfileLevel.MPEG2LevelLL: FR = 30; W = 22; H = 18; MBPS = 11880; FS = 396; BR = 4000; break; case CodecProfileLevel.MPEG2LevelML: - FR = 30; W = 45; H = 36; MBPS = 48600; FS = 1620; BR = 15000; break; + FR = 30; W = 45; H = 36; MBPS = 40500; FS = 1620; BR = 15000; break; case CodecProfileLevel.MPEG2LevelH14: FR = 60; W = 90; H = 68; MBPS = 183600; FS = 6120; BR = 60000; break; case CodecProfileLevel.MPEG2LevelHL: @@ -2068,16 +2111,19 @@ public final class MediaCodecInfo { maxBps = 64000; for (CodecProfileLevel profileLevel: profileLevels) { int MBPS = 0, FS = 0, BR = 0, FR = 0, W = 0, H = 0; + boolean strict = false; // true: W, H and FR are individual max limits boolean supported = true; switch (profileLevel.profile) { case CodecProfileLevel.MPEG4ProfileSimple: switch (profileLevel.level) { case CodecProfileLevel.MPEG4Level0: + strict = true; FR = 15; W = 11; H = 9; MBPS = 1485; FS = 99; BR = 64; break; case CodecProfileLevel.MPEG4Level1: FR = 30; W = 11; H = 9; MBPS = 1485; FS = 99; BR = 64; break; case CodecProfileLevel.MPEG4Level0b: - FR = 30; W = 11; H = 9; MBPS = 1485; FS = 99; BR = 128; break; + strict = true; + FR = 15; W = 11; H = 9; MBPS = 1485; FS = 99; BR = 128; break; case CodecProfileLevel.MPEG4Level2: FR = 30; W = 22; H = 18; MBPS = 5940; FS = 396; BR = 128; break; case CodecProfileLevel.MPEG4Level3: @@ -2125,11 +2171,16 @@ public final class MediaCodecInfo { case CodecProfileLevel.MPEG4ProfileCore: // 1-2 case CodecProfileLevel.MPEG4ProfileAdvancedCore: // 1-4 case CodecProfileLevel.MPEG4ProfileSimpleScalable: // 0-2 - case CodecProfileLevel.MPEG4ProfileAdvancedScalable: // 1-3 case CodecProfileLevel.MPEG4ProfileHybrid: // 1-2 + + // Studio profiles are not supported by our codecs. + + // Only profiles that can decode simple object types are considered. + // The following profiles are not able to. case CodecProfileLevel.MPEG4ProfileBasicAnimated: // 1-2 case CodecProfileLevel.MPEG4ProfileScalableTexture: // 1 case CodecProfileLevel.MPEG4ProfileSimpleFace: // 1-2 + case CodecProfileLevel.MPEG4ProfileAdvancedScalable: // 1-3 case CodecProfileLevel.MPEG4ProfileSimpleFBA: // 1-2 Log.i(TAG, "Unsupported profile " + profileLevel.profile + " for " + mime); @@ -2147,9 +2198,17 @@ public final class MediaCodecInfo { maxBlocksPerSecond = Math.max(MBPS, maxBlocksPerSecond); maxBlocks = Math.max(FS, maxBlocks); maxBps = Math.max(BR * 1000, maxBps); - maxWidth = Math.max(W, maxWidth); - maxHeight = Math.max(H, maxHeight); - maxRate = Math.max(FR, maxRate); + if (strict) { + maxWidth = Math.max(W, maxWidth); + maxHeight = Math.max(H, maxHeight); + maxRate = Math.max(FR, maxRate); + } else { + // assuming max 60 fps frame rate and 1:2 aspect ratio + int maxDim = (int)Math.sqrt(FS * 2); + maxWidth = Math.max(maxDim, maxWidth); + maxHeight = Math.max(maxDim, maxHeight); + maxRate = Math.max(Math.max(FR, 60), maxRate); + } } applyMacroBlockLimits(maxWidth, maxHeight, maxBlocks, maxBlocksPerSecond, @@ -2158,34 +2217,47 @@ public final class MediaCodecInfo { mFrameRateRange = mFrameRateRange.intersect(12, maxRate); } else if (mime.equalsIgnoreCase(MediaFormat.MIMETYPE_VIDEO_H263)) { int maxWidth = 11, maxHeight = 9, maxRate = 15; + int minWidth = maxWidth, minHeight = maxHeight; + int minAlignment = 16; maxBlocks = 99; maxBlocksPerSecond = 1485; maxBps = 64000; for (CodecProfileLevel profileLevel: profileLevels) { - int MBPS = 0, BR = 0, FR = 0, W = 0, H = 0; + int MBPS = 0, BR = 0, FR = 0, W = 0, H = 0, minW = minWidth, minH = minHeight; + boolean strict = false; // true: support only sQCIF, QCIF (maybe CIF) switch (profileLevel.level) { case CodecProfileLevel.H263Level10: + strict = true; // only supports sQCIF & QCIF FR = 15; W = 11; H = 9; BR = 1; MBPS = W * H * FR; break; case CodecProfileLevel.H263Level20: - // only supports CIF, 0..QCIF - FR = 30; W = 22; H = 18; BR = 2; MBPS = W * H * FR; break; + strict = true; // only supports sQCIF, QCIF & CIF + FR = 30; W = 22; H = 18; BR = 2; MBPS = W * H * 15; break; case CodecProfileLevel.H263Level30: - // only supports CIF, 0..QCIF + strict = true; // only supports sQCIF, QCIF & CIF FR = 30; W = 22; H = 18; BR = 6; MBPS = W * H * FR; break; case CodecProfileLevel.H263Level40: - // only supports CIF, 0..QCIF + strict = true; // only supports sQCIF, QCIF & CIF FR = 30; W = 22; H = 18; BR = 32; MBPS = W * H * FR; break; case CodecProfileLevel.H263Level45: // only implies level 10 support - FR = 30; W = 11; H = 9; BR = 2; MBPS = W * H * FR; break; + strict = profileLevel.profile == CodecProfileLevel.H263ProfileBaseline + || profileLevel.profile == + CodecProfileLevel.H263ProfileBackwardCompatible; + if (!strict) { + minW = 1; minH = 1; minAlignment = 4; + } + FR = 15; W = 11; H = 9; BR = 2; MBPS = W * H * FR; break; case CodecProfileLevel.H263Level50: // only supports 50fps for H > 15 + minW = 1; minH = 1; minAlignment = 4; FR = 60; W = 22; H = 18; BR = 64; MBPS = W * H * 50; break; case CodecProfileLevel.H263Level60: // only supports 50fps for H > 15 + minW = 1; minH = 1; minAlignment = 4; FR = 60; W = 45; H = 18; BR = 128; MBPS = W * H * 50; break; case CodecProfileLevel.H263Level70: // only supports 50fps for H > 30 + minW = 1; minH = 1; minAlignment = 4; FR = 60; W = 45; H = 36; BR = 256; MBPS = W * H * 50; break; default: Log.w(TAG, "Unrecognized profile/level " + profileLevel.profile @@ -2208,6 +2280,18 @@ public final class MediaCodecInfo { + profileLevel.profile + " for " + mime); errors |= ERROR_UNRECOGNIZED; } + if (strict) { + // Strict levels define sub-QCIF min size and enumerated sizes. We cannot + // express support for "only sQCIF & QCIF (& CIF)" using VideoCapabilities + // but we can express "only QCIF (& CIF)", so set minimume size at QCIF. + // minW = 8; minH = 6; + minW = 11; minH = 9; + } else { + // any support for non-strict levels (including unrecognized profiles or + // levels) allow custom frame size support beyond supported limits + // (other than bitrate) + mAllowMbOverride = true; + } errors &= ~ERROR_NONE_SUPPORTED; maxBlocksPerSecond = Math.max(MBPS, maxBlocksPerSecond); maxBlocks = Math.max(W * H, maxBlocks); @@ -2215,11 +2299,21 @@ public final class MediaCodecInfo { maxWidth = Math.max(W, maxWidth); maxHeight = Math.max(H, maxHeight); maxRate = Math.max(FR, maxRate); + minWidth = Math.min(minW, minWidth); + minHeight = Math.min(minH, minHeight); } - applyMacroBlockLimits(maxWidth, maxHeight, + // unless we encountered custom frame size support, limit size to QCIF and CIF + // using aspect ratio. + if (!mAllowMbOverride) { + mBlockAspectRatioRange = + Range.create(new Rational(11, 9), new Rational(11, 9)); + } + applyMacroBlockLimits( + minWidth, minHeight, + maxWidth, maxHeight, maxBlocks, maxBlocksPerSecond, 16 /* blockWidth */, 16 /* blockHeight */, - 1 /* widthAlignment */, 1 /* heightAlignment */); + minAlignment /* widthAlignment */, minAlignment /* heightAlignment */); mFrameRateRange = Range.create(1, maxRate); } else if (mime.equalsIgnoreCase(MediaFormat.MIMETYPE_VIDEO_VP8)) { maxBlocks = Integer.MAX_VALUE; @@ -2307,6 +2401,8 @@ public final class MediaCodecInfo { case CodecProfileLevel.VP9Profile1: case CodecProfileLevel.VP9Profile2: case CodecProfileLevel.VP9Profile3: + case CodecProfileLevel.VP9Profile2HDR: + case CodecProfileLevel.VP9Profile3HDR: break; default: Log.w(TAG, "Unrecognized profile " @@ -2331,7 +2427,8 @@ public final class MediaCodecInfo { blockSize, blockSize, 1 /* widthAlignment */, 1 /* heightAlignment */); } else if (mime.equalsIgnoreCase(MediaFormat.MIMETYPE_VIDEO_HEVC)) { - maxBlocks = 36864; + // CTBs are at least 8x8 so use 8x8 block size + maxBlocks = 36864 >> 6; // 192x192 pixels == 576 8x8 blocks maxBlocksPerSecond = maxBlocks * 15; maxBps = 128000; for (CodecProfileLevel profileLevel: profileLevels) { @@ -2339,6 +2436,10 @@ public final class MediaCodecInfo { int FS = 0; int BR = 0; switch (profileLevel.level) { + /* The HEVC spec talks only in a very convoluted manner about the + existence of levels 1-3.1 for High tier, which could also be + understood as 'decoders and encoders should treat these levels + as if they were Main tier', so we do that. */ case CodecProfileLevel.HEVCMainTierLevel1: case CodecProfileLevel.HEVCHighTierLevel1: FR = 15; FS = 36864; BR = 128; break; @@ -2409,6 +2510,7 @@ public final class MediaCodecInfo { else DPB = 6; */ + FS >>= 6; // convert pixels to blocks errors &= ~ERROR_NONE_SUPPORTED; maxBlocksPerSecond = Math.max((int)(FR * FS), maxBlocksPerSecond); maxBlocks = Math.max(FS, maxBlocks); @@ -2416,11 +2518,6 @@ public final class MediaCodecInfo { } int maxLengthInBlocks = (int)(Math.sqrt(maxBlocks * 8)); - // CTBs are at least 8x8 - maxBlocks = Utils.divUp(maxBlocks, 8 * 8); - maxBlocksPerSecond = Utils.divUp(maxBlocksPerSecond, 8 * 8); - maxLengthInBlocks = Utils.divUp(maxLengthInBlocks, 8); - applyMacroBlockLimits( maxLengthInBlocks, maxLengthInBlocks, maxBlocks, maxBlocksPerSecond, @@ -2834,6 +2931,12 @@ public final class MediaCodecInfo { public static final int HEVCMainTierLevel62 = 0x1000000; public static final int HEVCHighTierLevel62 = 0x2000000; + private static final int HEVCHighTierLevels = + HEVCHighTierLevel1 | HEVCHighTierLevel2 | HEVCHighTierLevel21 | HEVCHighTierLevel3 | + HEVCHighTierLevel31 | HEVCHighTierLevel4 | HEVCHighTierLevel41 | HEVCHighTierLevel5 | + HEVCHighTierLevel51 | HEVCHighTierLevel52 | HEVCHighTierLevel6 | HEVCHighTierLevel61 | + HEVCHighTierLevel62; + // from OMX_VIDEO_DOLBYVISIONPROFILETYPE public static final int DolbyVisionProfileDvavPer = 0x1; public static final int DolbyVisionProfileDvavPen = 0x2; diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardPinBasedInputView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardPinBasedInputView.java index c8719f3f88e3..8d6e07e619ff 100644 --- a/packages/Keyguard/src/com/android/keyguard/KeyguardPinBasedInputView.java +++ b/packages/Keyguard/src/com/android/keyguard/KeyguardPinBasedInputView.java @@ -239,8 +239,7 @@ public abstract class KeyguardPinBasedInputView extends KeyguardAbsKeyInputView @Override public boolean onKey(View v, int keyCode, KeyEvent event) { if (event.getAction() == KeyEvent.ACTION_DOWN) { - onKeyDown(keyCode, event); - return true; + return onKeyDown(keyCode, event); } return false; } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java index 760f4328e4e3..aedc7df0ebc3 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java @@ -1097,7 +1097,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView { mIsSystemExpanded = expand; notifyHeightChanged(false /* needsAnimation */); logExpansionEvent(false, wasExpanded); - if (mChildrenContainer != null) { + if (mIsSummaryWithChildren) { mChildrenContainer.updateGroupOverflow(); } } @@ -1166,13 +1166,14 @@ public class ExpandableNotificationRow extends ActivatableNotificationView { mChildrenContainer.recreateNotificationHeader(mExpandClickListener, mEntry.notification); } + getShowingLayout().updateBackgroundColor(false /* animate */); mPrivateLayout.updateExpandButtons(isExpandable()); updateChildrenHeaderAppearance(); updateChildrenVisibility(); } public void updateChildrenHeaderAppearance() { - if (mChildrenContainer != null) { + if (mIsSummaryWithChildren) { mChildrenContainer.updateChildrenHeaderAppearance(); } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationCustomViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationCustomViewWrapper.java index 61df44acbc50..85e87ddc84df 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationCustomViewWrapper.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationCustomViewWrapper.java @@ -127,7 +127,8 @@ public class NotificationCustomViewWrapper extends NotificationViewWrapper { @Override public int getCustomBackgroundColor() { - return mBackgroundColor; + // Parent notifications should always use the normal background color + return mRow.isSummaryWithChildren() ? 0 : mBackgroundColor; } @Override diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java index 29b4db174375..68e5d0b5bdd3 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java @@ -369,13 +369,15 @@ public class QSTileHost implements QSTile.Host, Tunable { } public void addTile(String spec) { - if (mTileSpecs.contains(spec)) { + final String setting = Settings.Secure.getStringForUser(mContext.getContentResolver(), + TILES_SETTING, ActivityManager.getCurrentUser()); + final List<String> tileSpecs = loadTileSpecs(mContext, setting); + if (tileSpecs.contains(spec)) { return; } - ArrayList<String> specs = new ArrayList<>(mTileSpecs); - specs.add(spec); + tileSpecs.add(spec); Settings.Secure.putStringForUser(mContext.getContentResolver(), TILES_SETTING, - TextUtils.join(",", specs), ActivityManager.getCurrentUser()); + TextUtils.join(",", tileSpecs), ActivityManager.getCurrentUser()); } public void addTile(ComponentName tile) { diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialog.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialog.java index f2cd885d68ce..c6992aad068e 100644 --- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialog.java +++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialog.java @@ -106,14 +106,14 @@ public class VolumeDialog implements TunerService.Tunable { private ViewGroup mDialogContentView; private ImageButton mExpandButton; private final List<VolumeRow> mRows = new ArrayList<>(); - private final SpTexts mSpTexts; + private SpTexts mSpTexts; private final SparseBooleanArray mDynamic = new SparseBooleanArray(); private final KeyguardManager mKeyguard; private final AudioManager mAudioManager; private final AccessibilityManager mAccessibilityMgr; private int mExpandButtonAnimationDuration; private ZenFooter mZenFooter; - private final LayoutTransition mLayoutTransition; + private LayoutTransition mLayoutTransition; private final Object mSafetyWarningLock = new Object(); private final Accessibility mAccessibility = new Accessibility(); private final ColorStateList mActiveSliderTint; @@ -149,14 +149,11 @@ public class VolumeDialog implements TunerService.Tunable { mCallback = callback; mWindowType = windowType; mZenModeController = zenModeController; - mSpTexts = new SpTexts(mContext); mKeyguard = (KeyguardManager) context.getSystemService(Context.KEYGUARD_SERVICE); mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE); mAccessibilityMgr = (AccessibilityManager) mContext.getSystemService(Context.ACCESSIBILITY_SERVICE); mActiveSliderTint = loadColorStateList(R.color.system_accent_color); mInactiveSliderTint = loadColorStateList(R.color.volume_slider_inactive); - mLayoutTransition = new LayoutTransition(); - mLayoutTransition.setDuration(new ValueAnimator().getDuration() / 2); initDialog(); @@ -173,6 +170,9 @@ public class VolumeDialog implements TunerService.Tunable { private void initDialog() { mDialog = new CustomDialog(mContext); + mSpTexts = new SpTexts(mContext); + mLayoutTransition = new LayoutTransition(); + mLayoutTransition.setDuration(new ValueAnimator().getDuration() / 2); mHovering = false; mShowing = false; final Window window = mDialog.getWindow(); diff --git a/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java b/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java index a67299e95327..0c712be8b12a 100644 --- a/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java +++ b/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java @@ -501,9 +501,17 @@ public class ZenModePanel extends LinearLayout { if (mCountdownConditionSupported) { Condition nextAlarmCondition = getTimeUntilNextAlarmCondition(); if (nextAlarmCondition != null) { + mZenRadioGroup.getChildAt( + COUNTDOWN_ALARM_CONDITION_INDEX).setVisibility(View.VISIBLE); + mZenRadioGroupContent.getChildAt( + COUNTDOWN_ALARM_CONDITION_INDEX).setVisibility(View.VISIBLE); bind(nextAlarmCondition, mZenRadioGroupContent.getChildAt(COUNTDOWN_ALARM_CONDITION_INDEX), COUNTDOWN_ALARM_CONDITION_INDEX); + } else { + mZenRadioGroup.getChildAt(COUNTDOWN_ALARM_CONDITION_INDEX).setVisibility(View.GONE); + mZenRadioGroupContent.getChildAt( + COUNTDOWN_ALARM_CONDITION_INDEX).setVisibility(View.GONE); } } // ensure something is selected diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java index a8b1a4a2cd05..0af0c7356fa3 100644 --- a/services/core/java/com/android/server/notification/NotificationManagerService.java +++ b/services/core/java/com/android/server/notification/NotificationManagerService.java @@ -181,7 +181,7 @@ public class NotificationManagerService extends SystemService { = SystemProperties.getBoolean("debug.child_notifs", true); static final int MAX_PACKAGE_NOTIFICATIONS = 50; - static final float MAX_PACKAGE_ENQUEUE_RATE = 50f; + static final float DEFAULT_MAX_NOTIFICATION_ENQUEUE_RATE = 50f; // message codes static final int MESSAGE_TIMEOUT = 2; @@ -305,6 +305,7 @@ public class NotificationManagerService extends SystemService { private static final int MY_PID = Process.myPid(); private RankingHandler mRankingHandler; private long mLastOverRateLogTime; + private float mMaxPackageEnqueueRate = DEFAULT_MAX_NOTIFICATION_ENQUEUE_RATE; private static class Archive { final int mBufferSize; @@ -817,6 +818,8 @@ public class NotificationManagerService extends SystemService { private final class SettingsObserver extends ContentObserver { private final Uri NOTIFICATION_LIGHT_PULSE_URI = Settings.System.getUriFor(Settings.System.NOTIFICATION_LIGHT_PULSE); + private final Uri NOTIFICATION_RATE_LIMIT_URI + = Settings.Global.getUriFor(Settings.Global.MAX_NOTIFICATION_ENQUEUE_RATE); SettingsObserver(Handler handler) { super(handler); @@ -826,6 +829,8 @@ public class NotificationManagerService extends SystemService { ContentResolver resolver = getContext().getContentResolver(); resolver.registerContentObserver(NOTIFICATION_LIGHT_PULSE_URI, false, this, UserHandle.USER_ALL); + resolver.registerContentObserver(NOTIFICATION_RATE_LIMIT_URI, + false, this, UserHandle.USER_ALL); update(null); } @@ -843,6 +848,10 @@ public class NotificationManagerService extends SystemService { updateNotificationPulse(); } } + if (uri == null || NOTIFICATION_RATE_LIMIT_URI.equals(uri)) { + mMaxPackageEnqueueRate = Settings.Global.getFloat(resolver, + Settings.Global.MAX_NOTIFICATION_ENQUEUE_RATE, mMaxPackageEnqueueRate); + } } } @@ -899,6 +908,10 @@ public class NotificationManagerService extends SystemService { public void onStart() { Resources resources = getContext().getResources(); + mMaxPackageEnqueueRate = Settings.Global.getFloat(getContext().getContentResolver(), + Settings.Global.MAX_NOTIFICATION_ENQUEUE_RATE, + DEFAULT_MAX_NOTIFICATION_ENQUEUE_RATE); + mAm = ActivityManagerNative.getDefault(); mAppOps = (AppOpsManager) getContext().getSystemService(Context.APP_OPS_SERVICE); mVibrator = (Vibrator) getContext().getSystemService(Context.VIBRATOR_SERVICE); @@ -2369,6 +2382,7 @@ public class NotificationManagerService extends SystemService { pw.println(" mDisableNotificationEffects=" + mDisableNotificationEffects); pw.println(" mCallState=" + callStateToString(mCallState)); pw.println(" mSystemReady=" + mSystemReady); + pw.println(" mMaxPackageEnqueueRate=" + mMaxPackageEnqueueRate); } pw.println(" mArchive=" + mArchive.toString()); Iterator<StatusBarNotification> iter = mArchive.descendingIterator(); @@ -2512,7 +2526,7 @@ public class NotificationManagerService extends SystemService { if (!isSystemNotification && !isNotificationFromListener) { synchronized (mNotificationList) { final float appEnqueueRate = mUsageStats.getAppEnqueueRate(pkg); - if (appEnqueueRate > MAX_PACKAGE_ENQUEUE_RATE) { + if (appEnqueueRate > mMaxPackageEnqueueRate) { mUsageStats.registerOverRateQuota(pkg); final long now = SystemClock.elapsedRealtime(); if ((now - mLastOverRateLogTime) > MIN_PACKAGE_OVERRATE_LOG_INTERVAL) { diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java index 9d8ba127c834..b9167905612d 100644 --- a/services/core/java/com/android/server/pm/UserManagerService.java +++ b/services/core/java/com/android/server/pm/UserManagerService.java @@ -1009,9 +1009,13 @@ public class UserManagerService extends IUserManager.Stub { // in getUserRestrictionSource on who set local policies. mGlobalRestrictionOwnerUserId = userId; } else { - // When profile owner sets restrictions it passes null global bundle and we reset - // global restriction owner userId. - mGlobalRestrictionOwnerUserId = UserHandle.USER_NULL; + if (mGlobalRestrictionOwnerUserId == userId) { + // When profile owner sets restrictions it passes null global bundle and we + // reset global restriction owner userId. + // This means this user used to have DO, but now the DO is gone and the user + // instead has PO. + mGlobalRestrictionOwnerUserId = UserHandle.USER_NULL; + } } { // Update local. diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java index eed4351b9287..476a559eaea3 100644 --- a/services/java/com/android/server/SystemServer.java +++ b/services/java/com/android/server/SystemServer.java @@ -701,13 +701,15 @@ public final class SystemServer { // as appropriate. mSystemServiceManager.startService(UiModeManagerService.class); - Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "UpdatePackagesIfNeeded"); - try { - mPackageManagerService.updatePackagesIfNeeded(); - } catch (Throwable e) { - reportWtf("update packages", e); + if (!mOnlyCore) { + Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "UpdatePackagesIfNeeded"); + try { + mPackageManagerService.updatePackagesIfNeeded(); + } catch (Throwable e) { + reportWtf("update packages", e); + } + Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); } - Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "PerformFstrimIfNeeded"); try { |