Merge "Null check while removing suspensions" into rvc-dev
diff --git a/apex/media/framework/java/android/media/MediaParser.java b/apex/media/framework/java/android/media/MediaParser.java
index d0692e4..070b13b 100644
--- a/apex/media/framework/java/android/media/MediaParser.java
+++ b/apex/media/framework/java/android/media/MediaParser.java
@@ -402,9 +402,9 @@
          *     onSampleDataFound(int, MediaParser.InputReader)} for the specified track, since the
          *     last byte belonging to the sample whose metadata is being passed.
          * @param cryptoInfo Encryption data required to decrypt the sample. May be null for
-         *     unencrypted samples. MediaParser may reuse {@link CryptoInfo} instances to avoid
-         *     allocations, so implementations of this method must not write to or keep reference to
-         *     the fields of this parameter.
+         *     unencrypted samples. Implementors should treat any output {@link CryptoInfo}
+         *     instances as immutable. MediaParser will not modify any output {@code cryptoInfos}
+         *     and implementors should not modify them either.
          */
         void onSampleCompleted(
                 int trackIndex,
@@ -1409,23 +1409,28 @@
     private class TrackOutputAdapter implements TrackOutput {
 
         private final int mTrackIndex;
-        private final CryptoInfo mCryptoInfo;
+
+        private CryptoInfo mLastOutputCryptoInfo;
+        private CryptoInfo.Pattern mLastOutputEncryptionPattern;
+        private CryptoData mLastReceivedCryptoData;
 
         @EncryptionDataReadState private int mEncryptionDataReadState;
         private int mEncryptionDataSizeToSubtractFromSampleDataSize;
         private int mEncryptionVectorSize;
+        private byte[] mScratchIvSpace;
+        private int mSubsampleEncryptionDataSize;
+        private int[] mScratchSubsampleEncryptedBytesCount;
+        private int[] mScratchSubsampleClearBytesCount;
         private boolean mHasSubsampleEncryptionData;
-        private CryptoInfo.Pattern mEncryptionPattern;
         private int mSkippedSupplementalDataBytes;
 
         private TrackOutputAdapter(int trackIndex) {
             mTrackIndex = trackIndex;
-            mCryptoInfo = new CryptoInfo();
-            mCryptoInfo.iv = new byte[16]; // Size documented in CryptoInfo.
-            mCryptoInfo.numBytesOfClearData = new int[0];
-            mCryptoInfo.numBytesOfEncryptedData = new int[0];
+            mScratchIvSpace = new byte[16]; // Size documented in CryptoInfo.
+            mScratchSubsampleEncryptedBytesCount = new int[32];
+            mScratchSubsampleClearBytesCount = new int[32];
             mEncryptionDataReadState = STATE_READING_SIGNAL_BYTE;
-            mEncryptionPattern =
+            mLastOutputEncryptionPattern =
                     new CryptoInfo.Pattern(/* blocksToEncrypt= */ 0, /* blocksToSkip= */ 0);
         }
 
@@ -1466,35 +1471,39 @@
                             mEncryptionDataReadState = STATE_READING_INIT_VECTOR;
                             break;
                         case STATE_READING_INIT_VECTOR:
-                            Arrays.fill(mCryptoInfo.iv, (byte) 0); // Ensure 0-padding.
-                            data.readBytes(mCryptoInfo.iv, /* offset= */ 0, mEncryptionVectorSize);
+                            Arrays.fill(mScratchIvSpace, (byte) 0); // Ensure 0-padding.
+                            data.readBytes(mScratchIvSpace, /* offset= */ 0, mEncryptionVectorSize);
                             length -= mEncryptionVectorSize;
                             if (mHasSubsampleEncryptionData) {
                                 mEncryptionDataReadState = STATE_READING_SUBSAMPLE_ENCRYPTION_SIZE;
                             } else {
-                                mCryptoInfo.numSubSamples = 0;
+                                mSubsampleEncryptionDataSize = 0;
                                 mEncryptionDataReadState = STATE_READING_SIGNAL_BYTE;
                             }
                             break;
                         case STATE_READING_SUBSAMPLE_ENCRYPTION_SIZE:
-                            int numSubSamples = data.readUnsignedShort();
-                            mCryptoInfo.numSubSamples = numSubSamples;
-                            if (mCryptoInfo.numBytesOfClearData.length < numSubSamples) {
-                                mCryptoInfo.numBytesOfClearData = new int[numSubSamples];
-                                mCryptoInfo.numBytesOfEncryptedData = new int[numSubSamples];
+                            mSubsampleEncryptionDataSize = data.readUnsignedShort();
+                            if (mScratchSubsampleClearBytesCount.length
+                                    < mSubsampleEncryptionDataSize) {
+                                mScratchSubsampleClearBytesCount =
+                                        new int[mSubsampleEncryptionDataSize];
+                                mScratchSubsampleEncryptedBytesCount =
+                                        new int[mSubsampleEncryptionDataSize];
                             }
                             length -= 2;
                             mEncryptionDataSizeToSubtractFromSampleDataSize +=
-                                    2 + numSubSamples * BYTES_PER_SUBSAMPLE_ENCRYPTION_ENTRY;
+                                    2
+                                            + mSubsampleEncryptionDataSize
+                                                    * BYTES_PER_SUBSAMPLE_ENCRYPTION_ENTRY;
                             mEncryptionDataReadState = STATE_READING_SUBSAMPLE_ENCRYPTION_DATA;
                             break;
                         case STATE_READING_SUBSAMPLE_ENCRYPTION_DATA:
-                            for (int i = 0; i < mCryptoInfo.numSubSamples; i++) {
-                                mCryptoInfo.numBytesOfClearData[i] = data.readUnsignedShort();
-                                mCryptoInfo.numBytesOfEncryptedData[i] = data.readInt();
+                            for (int i = 0; i < mSubsampleEncryptionDataSize; i++) {
+                                mScratchSubsampleClearBytesCount[i] = data.readUnsignedShort();
+                                mScratchSubsampleEncryptedBytesCount[i] = data.readInt();
                             }
                             length -=
-                                    mCryptoInfo.numSubSamples
+                                    mSubsampleEncryptionDataSize
                                             * BYTES_PER_SUBSAMPLE_ENCRYPTION_ENTRY;
                             mEncryptionDataReadState = STATE_READING_SIGNAL_BYTE;
                             if (length != 0) {
@@ -1536,24 +1545,71 @@
             if (cryptoData == null) {
                 // The sample is not encrypted.
                 return null;
+            } else if (mInBandCryptoInfo) {
+                if (cryptoData != mLastReceivedCryptoData) {
+                    mLastOutputCryptoInfo =
+                            createNewCryptoInfoAndPopulateWithCryptoData(cryptoData);
+                }
+            } else /* We must populate the full CryptoInfo. */ {
+                // CryptoInfo.pattern is not accessible to the user, so the user needs to feed
+                // this CryptoInfo directly to MediaCodec. We need to create a new CryptoInfo per
+                // sample because of per-sample initialization vector changes.
+                CryptoInfo newCryptoInfo = createNewCryptoInfoAndPopulateWithCryptoData(cryptoData);
+                newCryptoInfo.iv = Arrays.copyOf(mScratchIvSpace, mScratchIvSpace.length);
+                boolean canReuseSubsampleInfo =
+                        mLastOutputCryptoInfo != null
+                                && mLastOutputCryptoInfo.numSubSamples
+                                        == mSubsampleEncryptionDataSize;
+                for (int i = 0; i < mSubsampleEncryptionDataSize && canReuseSubsampleInfo; i++) {
+                    canReuseSubsampleInfo =
+                            mLastOutputCryptoInfo.numBytesOfClearData[i]
+                                            == mScratchSubsampleClearBytesCount[i]
+                                    && mLastOutputCryptoInfo.numBytesOfEncryptedData[i]
+                                            == mScratchSubsampleEncryptedBytesCount[i];
+                }
+                newCryptoInfo.numSubSamples = mSubsampleEncryptionDataSize;
+                if (canReuseSubsampleInfo) {
+                    newCryptoInfo.numBytesOfClearData = mLastOutputCryptoInfo.numBytesOfClearData;
+                    newCryptoInfo.numBytesOfEncryptedData =
+                            mLastOutputCryptoInfo.numBytesOfEncryptedData;
+                } else {
+                    newCryptoInfo.numBytesOfClearData =
+                            Arrays.copyOf(
+                                    mScratchSubsampleClearBytesCount, mSubsampleEncryptionDataSize);
+                    newCryptoInfo.numBytesOfEncryptedData =
+                            Arrays.copyOf(
+                                    mScratchSubsampleEncryptedBytesCount,
+                                    mSubsampleEncryptionDataSize);
+                }
+                mLastOutputCryptoInfo = newCryptoInfo;
             }
-            mCryptoInfo.key = cryptoData.encryptionKey;
-            // ExoPlayer modes match MediaCodec modes.
-            mCryptoInfo.mode = cryptoData.cryptoMode;
-            if (cryptoData.clearBlocks != 0) {
-                // Content is pattern-encrypted.
-                mCryptoInfo.setPattern(mEncryptionPattern);
-                mEncryptionPattern.set(cryptoData.encryptedBlocks, cryptoData.clearBlocks);
-            } else {
-                mCryptoInfo.setPattern(null);
+            mLastReceivedCryptoData = cryptoData;
+            return mLastOutputCryptoInfo;
+        }
+
+        private CryptoInfo createNewCryptoInfoAndPopulateWithCryptoData(CryptoData cryptoData) {
+            CryptoInfo cryptoInfo = new CryptoInfo();
+            cryptoInfo.key = cryptoData.encryptionKey;
+            cryptoInfo.mode = cryptoData.cryptoMode;
+            if (cryptoData.clearBlocks != mLastOutputEncryptionPattern.getSkipBlocks()
+                    || cryptoData.encryptedBlocks
+                            != mLastOutputEncryptionPattern.getEncryptBlocks()) {
+                mLastOutputEncryptionPattern =
+                        new CryptoInfo.Pattern(cryptoData.encryptedBlocks, cryptoData.clearBlocks);
             }
-            return mCryptoInfo;
+            cryptoInfo.setPattern(mLastOutputEncryptionPattern);
+            return cryptoInfo;
         }
 
         private void outputSampleData(ParsableByteArray data, int length) {
             mScratchParsableByteArrayAdapter.resetWithByteArray(data, length);
             try {
-                mOutputConsumer.onSampleDataFound(mTrackIndex, mScratchParsableByteArrayAdapter);
+                // Read all bytes from data. ExoPlayer extractors expect all sample data to be
+                // consumed by TrackOutput implementations when passing a ParsableByteArray.
+                while (mScratchParsableByteArrayAdapter.getLength() > 0) {
+                    mOutputConsumer.onSampleDataFound(
+                            mTrackIndex, mScratchParsableByteArrayAdapter);
+                }
             } catch (IOException e) {
                 // Unexpected.
                 throw new RuntimeException(e);
diff --git a/apex/statsd/framework/java/android/app/StatsManager.java b/apex/statsd/framework/java/android/app/StatsManager.java
index d2c6c09..a7d2057 100644
--- a/apex/statsd/framework/java/android/app/StatsManager.java
+++ b/apex/statsd/framework/java/android/app/StatsManager.java
@@ -561,7 +561,15 @@
                     try {
                         resultReceiver.pullFinished(atomTag, success, parcels);
                     } catch (RemoteException e) {
-                        Log.w(TAG, "StatsPullResultReceiver failed for tag " + mAtomId);
+                        Log.w(TAG, "StatsPullResultReceiver failed for tag " + mAtomId
+                                + " due to TransactionTooLarge. Calling pullFinish with no data");
+                        StatsEventParcel[] emptyData = new StatsEventParcel[0];
+                        try {
+                            resultReceiver.pullFinished(atomTag, /*success=*/false, emptyData);
+                        } catch (RemoteException nestedException) {
+                            Log.w(TAG, "StatsPullResultReceiver failed for tag " + mAtomId
+                                    + " with empty payload");
+                        }
                     }
                 });
             } finally {
diff --git a/cmds/statsd/src/condition/CombinationConditionTracker.cpp b/cmds/statsd/src/condition/CombinationConditionTracker.cpp
index c829ccd..e9875ba 100644
--- a/cmds/statsd/src/condition/CombinationConditionTracker.cpp
+++ b/cmds/statsd/src/condition/CombinationConditionTracker.cpp
@@ -37,7 +37,8 @@
 bool CombinationConditionTracker::init(const vector<Predicate>& allConditionConfig,
                                        const vector<sp<ConditionTracker>>& allConditionTrackers,
                                        const unordered_map<int64_t, int>& conditionIdIndexMap,
-                                       vector<bool>& stack) {
+                                       vector<bool>& stack,
+                                       vector<ConditionState>& initialConditionCache) {
     VLOG("Combination predicate init() %lld", (long long)mConditionId);
     if (mInitialized) {
         return true;
@@ -73,9 +74,9 @@
             return false;
         }
 
-
-        bool initChildSucceeded = childTracker->init(allConditionConfig, allConditionTrackers,
-                                                     conditionIdIndexMap, stack);
+        bool initChildSucceeded =
+                childTracker->init(allConditionConfig, allConditionTrackers, conditionIdIndexMap,
+                                   stack, initialConditionCache);
 
         if (!initChildSucceeded) {
             ALOGW("Child initialization failed %lld ", (long long)child);
@@ -95,6 +96,11 @@
                              childTracker->getLogTrackerIndex().end());
     }
 
+    mUnSlicedPartCondition = evaluateCombinationCondition(mUnSlicedChildren, mLogicalOperation,
+                                                          initialConditionCache);
+    initialConditionCache[mIndex] =
+            evaluateCombinationCondition(mChildren, mLogicalOperation, initialConditionCache);
+
     // unmark this node in the recursion stack.
     stack[mIndex] = false;
 
diff --git a/cmds/statsd/src/condition/CombinationConditionTracker.h b/cmds/statsd/src/condition/CombinationConditionTracker.h
index e3d8601..39ff0ab 100644
--- a/cmds/statsd/src/condition/CombinationConditionTracker.h
+++ b/cmds/statsd/src/condition/CombinationConditionTracker.h
@@ -32,8 +32,8 @@
 
     bool init(const std::vector<Predicate>& allConditionConfig,
               const std::vector<sp<ConditionTracker>>& allConditionTrackers,
-              const std::unordered_map<int64_t, int>& conditionIdIndexMap,
-              std::vector<bool>& stack) override;
+              const std::unordered_map<int64_t, int>& conditionIdIndexMap, std::vector<bool>& stack,
+              std::vector<ConditionState>& initialConditionCache) override;
 
     void evaluateCondition(const LogEvent& event,
                            const std::vector<MatchingState>& eventMatcherValues,
diff --git a/cmds/statsd/src/condition/ConditionTracker.h b/cmds/statsd/src/condition/ConditionTracker.h
index f9a2c34..62736c8 100644
--- a/cmds/statsd/src/condition/ConditionTracker.h
+++ b/cmds/statsd/src/condition/ConditionTracker.h
@@ -51,10 +51,12 @@
     //                       need to call init() on children conditions)
     // conditionIdIndexMap: the mapping from condition id to its index.
     // stack: a bit map to keep track which nodes have been visited on the stack in the recursion.
+    // initialConditionCache: tracks initial conditions of all ConditionTrackers.
     virtual bool init(const std::vector<Predicate>& allConditionConfig,
                       const std::vector<sp<ConditionTracker>>& allConditionTrackers,
                       const std::unordered_map<int64_t, int>& conditionIdIndexMap,
-                      std::vector<bool>& stack) = 0;
+                      std::vector<bool>& stack,
+                      std::vector<ConditionState>& initialConditionCache) = 0;
 
     // evaluate current condition given the new event.
     // event: the new log event
diff --git a/cmds/statsd/src/condition/SimpleConditionTracker.cpp b/cmds/statsd/src/condition/SimpleConditionTracker.cpp
index f23ec50..efb4d49 100644
--- a/cmds/statsd/src/condition/SimpleConditionTracker.cpp
+++ b/cmds/statsd/src/condition/SimpleConditionTracker.cpp
@@ -95,9 +95,11 @@
 bool SimpleConditionTracker::init(const vector<Predicate>& allConditionConfig,
                                   const vector<sp<ConditionTracker>>& allConditionTrackers,
                                   const unordered_map<int64_t, int>& conditionIdIndexMap,
-                                  vector<bool>& stack) {
+                                  vector<bool>& stack,
+                                  vector<ConditionState>& initialConditionCache) {
     // SimpleConditionTracker does not have dependency on other conditions, thus we just return
     // if the initialization was successful.
+    initialConditionCache[mIndex] = mInitialValue;
     return mInitialized;
 }
 
diff --git a/cmds/statsd/src/condition/SimpleConditionTracker.h b/cmds/statsd/src/condition/SimpleConditionTracker.h
index 5c5cc56..ea7f87b 100644
--- a/cmds/statsd/src/condition/SimpleConditionTracker.h
+++ b/cmds/statsd/src/condition/SimpleConditionTracker.h
@@ -37,8 +37,8 @@
 
     bool init(const std::vector<Predicate>& allConditionConfig,
               const std::vector<sp<ConditionTracker>>& allConditionTrackers,
-              const std::unordered_map<int64_t, int>& conditionIdIndexMap,
-              std::vector<bool>& stack) override;
+              const std::unordered_map<int64_t, int>& conditionIdIndexMap, std::vector<bool>& stack,
+              std::vector<ConditionState>& initialConditionCache) override;
 
     void evaluateCondition(const LogEvent& event,
                            const std::vector<MatchingState>& eventMatcherValues,
diff --git a/cmds/statsd/src/metrics/CountMetricProducer.cpp b/cmds/statsd/src/metrics/CountMetricProducer.cpp
index d865c21..5739612 100644
--- a/cmds/statsd/src/metrics/CountMetricProducer.cpp
+++ b/cmds/statsd/src/metrics/CountMetricProducer.cpp
@@ -68,14 +68,14 @@
 
 CountMetricProducer::CountMetricProducer(
         const ConfigKey& key, const CountMetric& metric, const int conditionIndex,
-        const sp<ConditionWizard>& wizard, const int64_t timeBaseNs, const int64_t startTimeNs,
-
+        const vector<ConditionState>& initialConditionCache, const sp<ConditionWizard>& wizard,
+        const int64_t timeBaseNs, const int64_t startTimeNs,
         const unordered_map<int, shared_ptr<Activation>>& eventActivationMap,
         const unordered_map<int, vector<shared_ptr<Activation>>>& eventDeactivationMap,
         const vector<int>& slicedStateAtoms,
         const unordered_map<int, unordered_map<int, int64_t>>& stateGroupMap)
-    : MetricProducer(metric.id(), key, timeBaseNs, conditionIndex, wizard, eventActivationMap,
-                     eventDeactivationMap, slicedStateAtoms, stateGroupMap) {
+    : MetricProducer(metric.id(), key, timeBaseNs, conditionIndex, initialConditionCache, wizard,
+                     eventActivationMap, eventDeactivationMap, slicedStateAtoms, stateGroupMap) {
     if (metric.has_bucket()) {
         mBucketSizeNs =
                 TimeUnitToBucketSizeInMillisGuardrailed(key.GetUid(), metric.bucket()) * 1000000;
diff --git a/cmds/statsd/src/metrics/CountMetricProducer.h b/cmds/statsd/src/metrics/CountMetricProducer.h
index 26b3d3c..f05fb06 100644
--- a/cmds/statsd/src/metrics/CountMetricProducer.h
+++ b/cmds/statsd/src/metrics/CountMetricProducer.h
@@ -43,7 +43,8 @@
 public:
     CountMetricProducer(
             const ConfigKey& key, const CountMetric& countMetric, const int conditionIndex,
-            const sp<ConditionWizard>& wizard, const int64_t timeBaseNs, const int64_t startTimeNs,
+            const vector<ConditionState>& initialConditionCache, const sp<ConditionWizard>& wizard,
+            const int64_t timeBaseNs, const int64_t startTimeNs,
             const std::unordered_map<int, std::shared_ptr<Activation>>& eventActivationMap = {},
             const std::unordered_map<int, std::vector<std::shared_ptr<Activation>>>&
                     eventDeactivationMap = {},
diff --git a/cmds/statsd/src/metrics/DurationMetricProducer.cpp b/cmds/statsd/src/metrics/DurationMetricProducer.cpp
index 6633659..e9b0438 100644
--- a/cmds/statsd/src/metrics/DurationMetricProducer.cpp
+++ b/cmds/statsd/src/metrics/DurationMetricProducer.cpp
@@ -64,15 +64,16 @@
 
 DurationMetricProducer::DurationMetricProducer(
         const ConfigKey& key, const DurationMetric& metric, const int conditionIndex,
-        const size_t startIndex, const size_t stopIndex, const size_t stopAllIndex,
-        const bool nesting, const sp<ConditionWizard>& wizard,
-        const FieldMatcher& internalDimensions, const int64_t timeBaseNs, const int64_t startTimeNs,
+        const vector<ConditionState>& initialConditionCache, const size_t startIndex,
+        const size_t stopIndex, const size_t stopAllIndex, const bool nesting,
+        const sp<ConditionWizard>& wizard, const FieldMatcher& internalDimensions,
+        const int64_t timeBaseNs, const int64_t startTimeNs,
         const unordered_map<int, shared_ptr<Activation>>& eventActivationMap,
         const unordered_map<int, vector<shared_ptr<Activation>>>& eventDeactivationMap,
         const vector<int>& slicedStateAtoms,
         const unordered_map<int, unordered_map<int, int64_t>>& stateGroupMap)
-    : MetricProducer(metric.id(), key, timeBaseNs, conditionIndex, wizard, eventActivationMap,
-                     eventDeactivationMap, slicedStateAtoms, stateGroupMap),
+    : MetricProducer(metric.id(), key, timeBaseNs, conditionIndex, initialConditionCache, wizard,
+                     eventActivationMap, eventDeactivationMap, slicedStateAtoms, stateGroupMap),
       mAggregationType(metric.aggregation_type()),
       mStartIndex(startIndex),
       mStopIndex(stopIndex),
diff --git a/cmds/statsd/src/metrics/DurationMetricProducer.h b/cmds/statsd/src/metrics/DurationMetricProducer.h
index 53f0f28..bfe1010 100644
--- a/cmds/statsd/src/metrics/DurationMetricProducer.h
+++ b/cmds/statsd/src/metrics/DurationMetricProducer.h
@@ -40,10 +40,10 @@
 public:
     DurationMetricProducer(
             const ConfigKey& key, const DurationMetric& durationMetric, const int conditionIndex,
-            const size_t startIndex, const size_t stopIndex, const size_t stopAllIndex,
-            const bool nesting, const sp<ConditionWizard>& wizard,
-            const FieldMatcher& internalDimensions, const int64_t timeBaseNs,
-            const int64_t startTimeNs,
+            const vector<ConditionState>& initialConditionCache, const size_t startIndex,
+            const size_t stopIndex, const size_t stopAllIndex, const bool nesting,
+            const sp<ConditionWizard>& wizard, const FieldMatcher& internalDimensions,
+            const int64_t timeBaseNs, const int64_t startTimeNs,
             const unordered_map<int, shared_ptr<Activation>>& eventActivationMap = {},
             const unordered_map<int, vector<shared_ptr<Activation>>>& eventDeactivationMap = {},
             const vector<int>& slicedStateAtoms = {},
diff --git a/cmds/statsd/src/metrics/EventMetricProducer.cpp b/cmds/statsd/src/metrics/EventMetricProducer.cpp
index d68f64a..dc0036a 100644
--- a/cmds/statsd/src/metrics/EventMetricProducer.cpp
+++ b/cmds/statsd/src/metrics/EventMetricProducer.cpp
@@ -54,13 +54,14 @@
 
 EventMetricProducer::EventMetricProducer(
         const ConfigKey& key, const EventMetric& metric, const int conditionIndex,
-        const sp<ConditionWizard>& wizard, const int64_t startTimeNs,
+        const vector<ConditionState>& initialConditionCache, const sp<ConditionWizard>& wizard,
+        const int64_t startTimeNs,
         const unordered_map<int, shared_ptr<Activation>>& eventActivationMap,
         const unordered_map<int, vector<shared_ptr<Activation>>>& eventDeactivationMap,
         const vector<int>& slicedStateAtoms,
         const unordered_map<int, unordered_map<int, int64_t>>& stateGroupMap)
-    : MetricProducer(metric.id(), key, startTimeNs, conditionIndex, wizard, eventActivationMap,
-                     eventDeactivationMap, slicedStateAtoms, stateGroupMap) {
+    : MetricProducer(metric.id(), key, startTimeNs, conditionIndex, initialConditionCache, wizard,
+                     eventActivationMap, eventDeactivationMap, slicedStateAtoms, stateGroupMap) {
     if (metric.links().size() > 0) {
         for (const auto& link : metric.links()) {
             Metric2Condition mc;
diff --git a/cmds/statsd/src/metrics/EventMetricProducer.h b/cmds/statsd/src/metrics/EventMetricProducer.h
index e8f2119..bfb2de3 100644
--- a/cmds/statsd/src/metrics/EventMetricProducer.h
+++ b/cmds/statsd/src/metrics/EventMetricProducer.h
@@ -35,7 +35,8 @@
 public:
     EventMetricProducer(
             const ConfigKey& key, const EventMetric& eventMetric, const int conditionIndex,
-            const sp<ConditionWizard>& wizard, const int64_t startTimeNs,
+            const vector<ConditionState>& initialConditionCache, const sp<ConditionWizard>& wizard,
+            const int64_t startTimeNs,
             const std::unordered_map<int, std::shared_ptr<Activation>>& eventActivationMap = {},
             const std::unordered_map<int, std::vector<std::shared_ptr<Activation>>>&
                     eventDeactivationMap = {},
diff --git a/cmds/statsd/src/metrics/GaugeMetricProducer.cpp b/cmds/statsd/src/metrics/GaugeMetricProducer.cpp
index 1d4d0b3..020f4b6 100644
--- a/cmds/statsd/src/metrics/GaugeMetricProducer.cpp
+++ b/cmds/statsd/src/metrics/GaugeMetricProducer.cpp
@@ -70,14 +70,15 @@
 
 GaugeMetricProducer::GaugeMetricProducer(
         const ConfigKey& key, const GaugeMetric& metric, const int conditionIndex,
-        const sp<ConditionWizard>& wizard, const int whatMatcherIndex,
-        const sp<EventMatcherWizard>& matcherWizard, const int pullTagId, const int triggerAtomId,
-        const int atomId, const int64_t timeBaseNs, const int64_t startTimeNs,
-        const sp<StatsPullerManager>& pullerManager,
+        const vector<ConditionState>& initialConditionCache, const sp<ConditionWizard>& wizard,
+        const int whatMatcherIndex, const sp<EventMatcherWizard>& matcherWizard,
+        const int pullTagId, const int triggerAtomId, const int atomId, const int64_t timeBaseNs,
+        const int64_t startTimeNs, const sp<StatsPullerManager>& pullerManager,
         const unordered_map<int, shared_ptr<Activation>>& eventActivationMap,
         const unordered_map<int, vector<shared_ptr<Activation>>>& eventDeactivationMap)
-    : MetricProducer(metric.id(), key, timeBaseNs, conditionIndex, wizard, eventActivationMap,
-                     eventDeactivationMap, /*slicedStateAtoms=*/{}, /*stateGroupMap=*/{}),
+    : MetricProducer(metric.id(), key, timeBaseNs, conditionIndex, initialConditionCache, wizard,
+                     eventActivationMap, eventDeactivationMap, /*slicedStateAtoms=*/{},
+                     /*stateGroupMap=*/{}),
       mWhatMatcherIndex(whatMatcherIndex),
       mEventMatcherWizard(matcherWizard),
       mPullerManager(pullerManager),
diff --git a/cmds/statsd/src/metrics/GaugeMetricProducer.h b/cmds/statsd/src/metrics/GaugeMetricProducer.h
index 2eb584b..2fc772b 100644
--- a/cmds/statsd/src/metrics/GaugeMetricProducer.h
+++ b/cmds/statsd/src/metrics/GaugeMetricProducer.h
@@ -58,6 +58,7 @@
 public:
     GaugeMetricProducer(
             const ConfigKey& key, const GaugeMetric& gaugeMetric, const int conditionIndex,
+            const vector<ConditionState>& initialConditionCache,
             const sp<ConditionWizard>& conditionWizard, const int whatMatcherIndex,
             const sp<EventMatcherWizard>& matcherWizard, const int pullTagId,
             const int triggerAtomId, const int atomId, const int64_t timeBaseNs,
diff --git a/cmds/statsd/src/metrics/MetricProducer.cpp b/cmds/statsd/src/metrics/MetricProducer.cpp
index bb4f03e..cdd20cd 100644
--- a/cmds/statsd/src/metrics/MetricProducer.cpp
+++ b/cmds/statsd/src/metrics/MetricProducer.cpp
@@ -45,7 +45,8 @@
 
 MetricProducer::MetricProducer(
         const int64_t& metricId, const ConfigKey& key, const int64_t timeBaseNs,
-        const int conditionIndex, const sp<ConditionWizard>& wizard,
+        const int conditionIndex, const vector<ConditionState>& initialConditionCache,
+        const sp<ConditionWizard>& wizard,
         const std::unordered_map<int, std::shared_ptr<Activation>>& eventActivationMap,
         const std::unordered_map<int, std::vector<std::shared_ptr<Activation>>>&
                 eventDeactivationMap,
@@ -56,7 +57,7 @@
       mTimeBaseNs(timeBaseNs),
       mCurrentBucketStartTimeNs(timeBaseNs),
       mCurrentBucketNum(0),
-      mCondition(initialCondition(conditionIndex)),
+      mCondition(initialCondition(conditionIndex, initialConditionCache)),
       mConditionTrackerIndex(conditionIndex),
       mConditionSliced(false),
       mWizard(wizard),
diff --git a/cmds/statsd/src/metrics/MetricProducer.h b/cmds/statsd/src/metrics/MetricProducer.h
index 9d37608..be4cd67 100644
--- a/cmds/statsd/src/metrics/MetricProducer.h
+++ b/cmds/statsd/src/metrics/MetricProducer.h
@@ -129,7 +129,8 @@
 class MetricProducer : public virtual android::RefBase, public virtual StateListener {
 public:
     MetricProducer(const int64_t& metricId, const ConfigKey& key, const int64_t timeBaseNs,
-                   const int conditionIndex, const sp<ConditionWizard>& wizard,
+                   const int conditionIndex, const vector<ConditionState>& initialConditionCache,
+                   const sp<ConditionWizard>& wizard,
                    const std::unordered_map<int, std::shared_ptr<Activation>>& eventActivationMap,
                    const std::unordered_map<int, std::vector<std::shared_ptr<Activation>>>&
                            eventDeactivationMap,
@@ -138,8 +139,9 @@
 
     virtual ~MetricProducer(){};
 
-    ConditionState initialCondition(const int conditionIndex) const {
-        return conditionIndex >= 0 ? ConditionState::kUnknown : ConditionState::kTrue;
+    ConditionState initialCondition(const int conditionIndex,
+                                    const vector<ConditionState>& initialConditionCache) const {
+        return conditionIndex >= 0 ? initialConditionCache[conditionIndex] : ConditionState::kTrue;
     }
 
     /**
@@ -496,6 +498,8 @@
     FRIEND_TEST(ValueMetricE2eTest, TestInitWithSlicedState_WithDimensions);
     FRIEND_TEST(ValueMetricE2eTest, TestInitWithSlicedState_WithIncorrectDimensions);
     FRIEND_TEST(ValueMetricE2eTest, TestInitialConditionChanges);
+
+    FRIEND_TEST(MetricsManagerTest, TestInitialConditions);
 };
 
 }  // namespace statsd
diff --git a/cmds/statsd/src/metrics/ValueMetricProducer.cpp b/cmds/statsd/src/metrics/ValueMetricProducer.cpp
index 71df710..c0d1174 100644
--- a/cmds/statsd/src/metrics/ValueMetricProducer.cpp
+++ b/cmds/statsd/src/metrics/ValueMetricProducer.cpp
@@ -78,6 +78,7 @@
 // ValueMetric has a minimum bucket size of 10min so that we don't pull too frequently
 ValueMetricProducer::ValueMetricProducer(
         const ConfigKey& key, const ValueMetric& metric, const int conditionIndex,
+        const vector<ConditionState>& initialConditionCache,
         const sp<ConditionWizard>& conditionWizard, const int whatMatcherIndex,
         const sp<EventMatcherWizard>& matcherWizard, const int pullTagId, const int64_t timeBaseNs,
         const int64_t startTimeNs, const sp<StatsPullerManager>& pullerManager,
@@ -85,8 +86,9 @@
         const unordered_map<int, vector<shared_ptr<Activation>>>& eventDeactivationMap,
         const vector<int>& slicedStateAtoms,
         const unordered_map<int, unordered_map<int, int64_t>>& stateGroupMap)
-    : MetricProducer(metric.id(), key, timeBaseNs, conditionIndex, conditionWizard,
-                     eventActivationMap, eventDeactivationMap, slicedStateAtoms, stateGroupMap),
+    : MetricProducer(metric.id(), key, timeBaseNs, conditionIndex, initialConditionCache,
+                     conditionWizard, eventActivationMap, eventDeactivationMap, slicedStateAtoms,
+                     stateGroupMap),
       mWhatMatcherIndex(whatMatcherIndex),
       mEventMatcherWizard(matcherWizard),
       mPullerManager(pullerManager),
diff --git a/cmds/statsd/src/metrics/ValueMetricProducer.h b/cmds/statsd/src/metrics/ValueMetricProducer.h
index aaf7df5..3de5b99 100644
--- a/cmds/statsd/src/metrics/ValueMetricProducer.h
+++ b/cmds/statsd/src/metrics/ValueMetricProducer.h
@@ -52,6 +52,7 @@
 public:
     ValueMetricProducer(
             const ConfigKey& key, const ValueMetric& valueMetric, const int conditionIndex,
+            const vector<ConditionState>& initialConditionCache,
             const sp<ConditionWizard>& conditionWizard, const int whatMatcherIndex,
             const sp<EventMatcherWizard>& matcherWizard, const int pullTagId,
             const int64_t timeBaseNs, const int64_t startTimeNs,
diff --git a/cmds/statsd/src/metrics/metrics_manager_util.cpp b/cmds/statsd/src/metrics/metrics_manager_util.cpp
index 210d382..8917c36 100644
--- a/cmds/statsd/src/metrics/metrics_manager_util.cpp
+++ b/cmds/statsd/src/metrics/metrics_manager_util.cpp
@@ -285,11 +285,14 @@
                     const unordered_map<int64_t, int>& logTrackerMap,
                     unordered_map<int64_t, int>& conditionTrackerMap,
                     vector<sp<ConditionTracker>>& allConditionTrackers,
-                    unordered_map<int, std::vector<int>>& trackerToConditionMap) {
+                    unordered_map<int, std::vector<int>>& trackerToConditionMap,
+                    vector<ConditionState>& initialConditionCache) {
     vector<Predicate> conditionConfigs;
     const int conditionTrackerCount = config.predicate_size();
     conditionConfigs.reserve(conditionTrackerCount);
     allConditionTrackers.reserve(conditionTrackerCount);
+    initialConditionCache.reserve(conditionTrackerCount);
+    std::fill(initialConditionCache.begin(), initialConditionCache.end(), ConditionState::kUnknown);
 
     for (int i = 0; i < conditionTrackerCount; i++) {
         const Predicate& condition = config.predicate(i);
@@ -321,7 +324,7 @@
     for (size_t i = 0; i < allConditionTrackers.size(); i++) {
         auto& conditionTracker = allConditionTrackers[i];
         if (!conditionTracker->init(conditionConfigs, allConditionTrackers, conditionTrackerMap,
-                                    stackTracker)) {
+                                    stackTracker, initialConditionCache)) {
             return false;
         }
         for (const int trackerIndex : conditionTracker->getLogTrackerIndex()) {
@@ -351,14 +354,14 @@
 }
 
 bool initMetrics(const ConfigKey& key, const StatsdConfig& config, const int64_t timeBaseTimeNs,
-                 const int64_t currentTimeNs,
-                 const sp<StatsPullerManager>& pullerManager,
+                 const int64_t currentTimeNs, const sp<StatsPullerManager>& pullerManager,
                  const unordered_map<int64_t, int>& logTrackerMap,
                  const unordered_map<int64_t, int>& conditionTrackerMap,
                  const vector<sp<LogMatchingTracker>>& allAtomMatchers,
                  const unordered_map<int64_t, int>& stateAtomIdMap,
                  const unordered_map<int64_t, unordered_map<int, int64_t>>& allStateGroupMaps,
                  vector<sp<ConditionTracker>>& allConditionTrackers,
+                 const vector<ConditionState>& initialConditionCache,
                  vector<sp<MetricProducer>>& allMetricProducers,
                  unordered_map<int, vector<int>>& conditionToMetricMap,
                  unordered_map<int, vector<int>>& trackerToMetricMap,
@@ -441,9 +444,10 @@
                 eventDeactivationMap);
         if (!success) return false;
 
-        sp<MetricProducer> countProducer = new CountMetricProducer(
-                key, metric, conditionIndex, wizard, timeBaseTimeNs, currentTimeNs,
-                eventActivationMap, eventDeactivationMap, slicedStateAtoms, stateGroupMap);
+        sp<MetricProducer> countProducer =
+                new CountMetricProducer(key, metric, conditionIndex, initialConditionCache, wizard,
+                                        timeBaseTimeNs, currentTimeNs, eventActivationMap,
+                                        eventDeactivationMap, slicedStateAtoms, stateGroupMap);
         allMetricProducers.push_back(countProducer);
     }
 
@@ -547,10 +551,10 @@
         if (!success) return false;
 
         sp<MetricProducer> durationMetric = new DurationMetricProducer(
-                key, metric, conditionIndex, trackerIndices[0], trackerIndices[1],
-                trackerIndices[2], nesting, wizard, internalDimensions, timeBaseTimeNs,
-                currentTimeNs, eventActivationMap, eventDeactivationMap, slicedStateAtoms,
-                stateGroupMap);
+                key, metric, conditionIndex, initialConditionCache, trackerIndices[0],
+                trackerIndices[1], trackerIndices[2], nesting, wizard, internalDimensions,
+                timeBaseTimeNs, currentTimeNs, eventActivationMap, eventDeactivationMap,
+                slicedStateAtoms, stateGroupMap);
 
         allMetricProducers.push_back(durationMetric);
     }
@@ -593,9 +597,9 @@
                 eventDeactivationMap);
         if (!success) return false;
 
-        sp<MetricProducer> eventMetric = new EventMetricProducer(
-                key, metric, conditionIndex, wizard, timeBaseTimeNs, eventActivationMap,
-                eventDeactivationMap);
+        sp<MetricProducer> eventMetric =
+                new EventMetricProducer(key, metric, conditionIndex, initialConditionCache, wizard,
+                                        timeBaseTimeNs, eventActivationMap, eventDeactivationMap);
 
         allMetricProducers.push_back(eventMetric);
     }
@@ -683,9 +687,9 @@
         if (!success) return false;
 
         sp<MetricProducer> valueProducer = new ValueMetricProducer(
-                key, metric, conditionIndex, wizard, trackerIndex, matcherWizard, pullTagId,
-                timeBaseTimeNs, currentTimeNs, pullerManager, eventActivationMap,
-                eventDeactivationMap, slicedStateAtoms, stateGroupMap);
+                key, metric, conditionIndex, initialConditionCache, wizard, trackerIndex,
+                matcherWizard, pullTagId, timeBaseTimeNs, currentTimeNs, pullerManager,
+                eventActivationMap, eventDeactivationMap, slicedStateAtoms, stateGroupMap);
         allMetricProducers.push_back(valueProducer);
     }
 
@@ -778,9 +782,9 @@
         if (!success) return false;
 
         sp<MetricProducer> gaugeProducer = new GaugeMetricProducer(
-                key, metric, conditionIndex, wizard, trackerIndex, matcherWizard, pullTagId,
-                triggerAtomId, atomTagId, timeBaseTimeNs, currentTimeNs, pullerManager,
-                eventActivationMap, eventDeactivationMap);
+                key, metric, conditionIndex, initialConditionCache, wizard, trackerIndex,
+                matcherWizard, pullTagId, triggerAtomId, atomTagId, timeBaseTimeNs, currentTimeNs,
+                pullerManager, eventActivationMap, eventDeactivationMap);
         allMetricProducers.push_back(gaugeProducer);
     }
     for (int i = 0; i < config.no_report_metric_size(); ++i) {
@@ -930,6 +934,7 @@
                       std::set<int64_t>& noReportMetricIds) {
     unordered_map<int64_t, int> logTrackerMap;
     unordered_map<int64_t, int> conditionTrackerMap;
+    vector<ConditionState> initialConditionCache;
     unordered_map<int64_t, int> metricProducerMap;
     unordered_map<int64_t, int> stateAtomIdMap;
     unordered_map<int64_t, unordered_map<int, int64_t>> allStateGroupMaps;
@@ -941,7 +946,7 @@
     VLOG("initLogMatchingTrackers succeed...");
 
     if (!initConditions(key, config, logTrackerMap, conditionTrackerMap, allConditionTrackers,
-                        trackerToConditionMap)) {
+                        trackerToConditionMap, initialConditionCache)) {
         ALOGE("initConditionTrackers failed");
         return false;
     }
@@ -952,10 +957,10 @@
     }
     if (!initMetrics(key, config, timeBaseNs, currentTimeNs, pullerManager, logTrackerMap,
                      conditionTrackerMap, allAtomMatchers, stateAtomIdMap, allStateGroupMaps,
-                     allConditionTrackers, allMetricProducers,
-                     conditionToMetricMap, trackerToMetricMap, metricProducerMap,
-                     noReportMetricIds, activationAtomTrackerToMetricMap,
-                     deactivationAtomTrackerToMetricMap, metricsWithActivation)) {
+                     allConditionTrackers, initialConditionCache, allMetricProducers,
+                     conditionToMetricMap, trackerToMetricMap, metricProducerMap, noReportMetricIds,
+                     activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap,
+                     metricsWithActivation)) {
         ALOGE("initMetricProducers failed");
         return false;
     }
diff --git a/cmds/statsd/src/metrics/metrics_manager_util.h b/cmds/statsd/src/metrics/metrics_manager_util.h
index 6af7a9a..96b5c26 100644
--- a/cmds/statsd/src/metrics/metrics_manager_util.h
+++ b/cmds/statsd/src/metrics/metrics_manager_util.h
@@ -60,12 +60,14 @@
 // [allConditionTrackers]: stores the sp to all the ConditionTrackers
 // [trackerToConditionMap]: contain the mapping from index of
 //                        log tracker to condition trackers that use the log tracker
+// [initialConditionCache]: stores the initial conditions for each ConditionTracker
 bool initConditions(const ConfigKey& key, const StatsdConfig& config,
                     const std::unordered_map<int64_t, int>& logTrackerMap,
                     std::unordered_map<int64_t, int>& conditionTrackerMap,
                     std::vector<sp<ConditionTracker>>& allConditionTrackers,
                     std::unordered_map<int, std::vector<int>>& trackerToConditionMap,
-                    std::unordered_map<int, std::vector<MetricConditionLink>>& eventConditionLinks);
+                    std::unordered_map<int, std::vector<MetricConditionLink>>& eventConditionLinks,
+                    std::vector<ConditionState>& initialConditionCache);
 
 // Initialize State maps using State protos in the config. These maps will
 // eventually be passed to MetricProducers to initialize their state info.
@@ -103,6 +105,7 @@
         const unordered_map<int64_t, int>& stateAtomIdMap,
         const unordered_map<int64_t, unordered_map<int, int64_t>>& allStateGroupMaps,
         vector<sp<ConditionTracker>>& allConditionTrackers,
+        const std::vector<ConditionState>& initialConditionCache,
         std::vector<sp<MetricProducer>>& allMetricProducers,
         std::unordered_map<int, std::vector<int>>& conditionToMetricMap,
         std::unordered_map<int, std::vector<int>>& trackerToMetricMap,
diff --git a/cmds/statsd/tests/MetricsManager_test.cpp b/cmds/statsd/tests/MetricsManager_test.cpp
index b3b095b..6259757 100644
--- a/cmds/statsd/tests/MetricsManager_test.cpp
+++ b/cmds/statsd/tests/MetricsManager_test.cpp
@@ -276,11 +276,157 @@
     return config;
 }
 
+StatsdConfig buildConfigWithDifferentPredicates() {
+    StatsdConfig config;
+    config.set_id(12345);
+
+    auto pulledAtomMatcher =
+            CreateSimpleAtomMatcher("SUBSYSTEM_SLEEP", util::SUBSYSTEM_SLEEP_STATE);
+    *config.add_atom_matcher() = pulledAtomMatcher;
+    auto screenOnAtomMatcher = CreateScreenTurnedOnAtomMatcher();
+    *config.add_atom_matcher() = screenOnAtomMatcher;
+    auto screenOffAtomMatcher = CreateScreenTurnedOffAtomMatcher();
+    *config.add_atom_matcher() = screenOffAtomMatcher;
+    auto batteryNoneAtomMatcher = CreateBatteryStateNoneMatcher();
+    *config.add_atom_matcher() = batteryNoneAtomMatcher;
+    auto batteryUsbAtomMatcher = CreateBatteryStateUsbMatcher();
+    *config.add_atom_matcher() = batteryUsbAtomMatcher;
+
+    // Simple condition with InitialValue set to default (unknown).
+    auto screenOnUnknownPredicate = CreateScreenIsOnPredicate();
+    *config.add_predicate() = screenOnUnknownPredicate;
+
+    // Simple condition with InitialValue set to false.
+    auto screenOnFalsePredicate = config.add_predicate();
+    screenOnFalsePredicate->set_id(StringToId("ScreenIsOnInitialFalse"));
+    SimplePredicate* simpleScreenOnFalsePredicate =
+            screenOnFalsePredicate->mutable_simple_predicate();
+    simpleScreenOnFalsePredicate->set_start(screenOnAtomMatcher.id());
+    simpleScreenOnFalsePredicate->set_stop(screenOffAtomMatcher.id());
+    simpleScreenOnFalsePredicate->set_initial_value(SimplePredicate_InitialValue_FALSE);
+
+    // Simple condition with InitialValue set to false.
+    auto onBatteryFalsePredicate = config.add_predicate();
+    onBatteryFalsePredicate->set_id(StringToId("OnBatteryInitialFalse"));
+    SimplePredicate* simpleOnBatteryFalsePredicate =
+            onBatteryFalsePredicate->mutable_simple_predicate();
+    simpleOnBatteryFalsePredicate->set_start(batteryNoneAtomMatcher.id());
+    simpleOnBatteryFalsePredicate->set_stop(batteryUsbAtomMatcher.id());
+    simpleOnBatteryFalsePredicate->set_initial_value(SimplePredicate_InitialValue_FALSE);
+
+    // Combination condition with both simple condition InitialValues set to false.
+    auto screenOnFalseOnBatteryFalsePredicate = config.add_predicate();
+    screenOnFalseOnBatteryFalsePredicate->set_id(StringToId("ScreenOnFalseOnBatteryFalse"));
+    screenOnFalseOnBatteryFalsePredicate->mutable_combination()->set_operation(
+            LogicalOperation::AND);
+    addPredicateToPredicateCombination(*screenOnFalsePredicate,
+                                       screenOnFalseOnBatteryFalsePredicate);
+    addPredicateToPredicateCombination(*onBatteryFalsePredicate,
+                                       screenOnFalseOnBatteryFalsePredicate);
+
+    // Combination condition with one simple condition InitialValue set to unknown and one set to
+    // false.
+    auto screenOnUnknownOnBatteryFalsePredicate = config.add_predicate();
+    screenOnUnknownOnBatteryFalsePredicate->set_id(StringToId("ScreenOnUnknowneOnBatteryFalse"));
+    screenOnUnknownOnBatteryFalsePredicate->mutable_combination()->set_operation(
+            LogicalOperation::AND);
+    addPredicateToPredicateCombination(screenOnUnknownPredicate,
+                                       screenOnUnknownOnBatteryFalsePredicate);
+    addPredicateToPredicateCombination(*onBatteryFalsePredicate,
+                                       screenOnUnknownOnBatteryFalsePredicate);
+
+    // Simple condition metric with initial value false.
+    ValueMetric* metric1 = config.add_value_metric();
+    metric1->set_id(StringToId("ValueSubsystemSleepWhileScreenOnInitialFalse"));
+    metric1->set_what(pulledAtomMatcher.id());
+    *metric1->mutable_value_field() =
+            CreateDimensions(util::SUBSYSTEM_SLEEP_STATE, {4 /* time sleeping field */});
+    metric1->set_bucket(FIVE_MINUTES);
+    metric1->set_condition(screenOnFalsePredicate->id());
+
+    // Simple condition metric with initial value unknown.
+    ValueMetric* metric2 = config.add_value_metric();
+    metric2->set_id(StringToId("ValueSubsystemSleepWhileScreenOnInitialUnknown"));
+    metric2->set_what(pulledAtomMatcher.id());
+    *metric2->mutable_value_field() =
+            CreateDimensions(util::SUBSYSTEM_SLEEP_STATE, {4 /* time sleeping field */});
+    metric2->set_bucket(FIVE_MINUTES);
+    metric2->set_condition(screenOnUnknownPredicate.id());
+
+    // Combination condition metric with initial values false and false.
+    ValueMetric* metric3 = config.add_value_metric();
+    metric3->set_id(StringToId("ValueSubsystemSleepWhileScreenOnFalseDeviceUnpluggedFalse"));
+    metric3->set_what(pulledAtomMatcher.id());
+    *metric3->mutable_value_field() =
+            CreateDimensions(util::SUBSYSTEM_SLEEP_STATE, {4 /* time sleeping field */});
+    metric3->set_bucket(FIVE_MINUTES);
+    metric3->set_condition(screenOnFalseOnBatteryFalsePredicate->id());
+
+    // Combination condition metric with initial values unknown and false.
+    ValueMetric* metric4 = config.add_value_metric();
+    metric4->set_id(StringToId("ValueSubsystemSleepWhileScreenOnUnknownDeviceUnpluggedFalse"));
+    metric4->set_what(pulledAtomMatcher.id());
+    *metric4->mutable_value_field() =
+            CreateDimensions(util::SUBSYSTEM_SLEEP_STATE, {4 /* time sleeping field */});
+    metric4->set_bucket(FIVE_MINUTES);
+    metric4->set_condition(screenOnUnknownOnBatteryFalsePredicate->id());
+
+    return config;
+}
+
 bool isSubset(const set<int32_t>& set1, const set<int32_t>& set2) {
     return std::includes(set2.begin(), set2.end(), set1.begin(), set1.end());
 }
 }  // anonymous namespace
 
+TEST(MetricsManagerTest, TestInitialConditions) {
+    UidMap uidMap;
+    sp<StatsPullerManager> pullerManager = new StatsPullerManager();
+    sp<AlarmMonitor> anomalyAlarmMonitor;
+    sp<AlarmMonitor> periodicAlarmMonitor;
+    StatsdConfig config = buildConfigWithDifferentPredicates();
+    set<int> allTagIds;
+    vector<sp<LogMatchingTracker>> allAtomMatchers;
+    vector<sp<ConditionTracker>> allConditionTrackers;
+    vector<sp<MetricProducer>> allMetricProducers;
+    std::vector<sp<AnomalyTracker>> allAnomalyTrackers;
+    std::vector<sp<AlarmTracker>> allAlarmTrackers;
+    unordered_map<int, std::vector<int>> conditionToMetricMap;
+    unordered_map<int, std::vector<int>> trackerToMetricMap;
+    unordered_map<int, std::vector<int>> trackerToConditionMap;
+    unordered_map<int, std::vector<int>> activationAtomTrackerToMetricMap;
+    unordered_map<int, std::vector<int>> deactivationAtomTrackerToMetricMap;
+    unordered_map<int64_t, int> alertTrackerMap;
+    vector<int> metricsWithActivation;
+    std::set<int64_t> noReportMetricIds;
+
+    EXPECT_TRUE(initStatsdConfig(
+            kConfigKey, config, uidMap, pullerManager, anomalyAlarmMonitor, periodicAlarmMonitor,
+            timeBaseSec, timeBaseSec, allTagIds, allAtomMatchers, allConditionTrackers,
+            allMetricProducers, allAnomalyTrackers, allAlarmTrackers, conditionToMetricMap,
+            trackerToMetricMap, trackerToConditionMap, activationAtomTrackerToMetricMap,
+            deactivationAtomTrackerToMetricMap, alertTrackerMap, metricsWithActivation,
+            noReportMetricIds));
+    ASSERT_EQ(4u, allMetricProducers.size());
+    ASSERT_EQ(5u, allConditionTrackers.size());
+
+    ConditionKey queryKey;
+    vector<ConditionState> conditionCache(5, ConditionState::kNotEvaluated);
+
+    allConditionTrackers[3]->isConditionMet(queryKey, allConditionTrackers, false, conditionCache);
+    allConditionTrackers[4]->isConditionMet(queryKey, allConditionTrackers, false, conditionCache);
+    EXPECT_EQ(ConditionState::kUnknown, conditionCache[0]);
+    EXPECT_EQ(ConditionState::kFalse, conditionCache[1]);
+    EXPECT_EQ(ConditionState::kFalse, conditionCache[2]);
+    EXPECT_EQ(ConditionState::kFalse, conditionCache[3]);
+    EXPECT_EQ(ConditionState::kUnknown, conditionCache[4]);
+
+    EXPECT_EQ(ConditionState::kFalse, allMetricProducers[0]->mCondition);
+    EXPECT_EQ(ConditionState::kUnknown, allMetricProducers[1]->mCondition);
+    EXPECT_EQ(ConditionState::kFalse, allMetricProducers[2]->mCondition);
+    EXPECT_EQ(ConditionState::kUnknown, allMetricProducers[3]->mCondition);
+}
+
 TEST(MetricsManagerTest, TestGoodConfig) {
     UidMap uidMap;
     sp<StatsPullerManager> pullerManager = new StatsPullerManager();
diff --git a/cmds/statsd/tests/condition/CombinationConditionTracker_test.cpp b/cmds/statsd/tests/condition/CombinationConditionTracker_test.cpp
index 6529d65..1d501fd 100644
--- a/cmds/statsd/tests/condition/CombinationConditionTracker_test.cpp
+++ b/cmds/statsd/tests/condition/CombinationConditionTracker_test.cpp
@@ -24,6 +24,7 @@
 using std::vector;
 
 #ifdef __ANDROID__
+
 TEST(ConditionTrackerTest, TestUnknownCondition) {
     LogicalOperation operation = LogicalOperation::AND;
 
diff --git a/cmds/statsd/tests/condition/SimpleConditionTracker_test.cpp b/cmds/statsd/tests/condition/SimpleConditionTracker_test.cpp
index 86e24fb..07b5311b 100644
--- a/cmds/statsd/tests/condition/SimpleConditionTracker_test.cpp
+++ b/cmds/statsd/tests/condition/SimpleConditionTracker_test.cpp
@@ -112,6 +112,114 @@
     return outputKeyMap;
 }
 
+TEST(SimpleConditionTrackerTest, TestNonSlicedInitialValueFalse) {
+    SimplePredicate simplePredicate;
+    simplePredicate.set_start(StringToId("SCREEN_TURNED_ON"));
+    simplePredicate.set_stop(StringToId("SCREEN_TURNED_OFF"));
+    simplePredicate.set_count_nesting(false);
+    simplePredicate.set_initial_value(SimplePredicate_InitialValue_FALSE);
+
+    unordered_map<int64_t, int> trackerNameIndexMap;
+    trackerNameIndexMap[StringToId("SCREEN_TURNED_ON")] = 0;
+    trackerNameIndexMap[StringToId("SCREEN_TURNED_OFF")] = 1;
+
+    SimpleConditionTracker conditionTracker(kConfigKey, StringToId("SCREEN_IS_ON"),
+                                            0 /*tracker index*/, simplePredicate,
+                                            trackerNameIndexMap);
+
+    ConditionKey queryKey;
+    vector<sp<ConditionTracker>> allPredicates;
+    vector<ConditionState> conditionCache(1, ConditionState::kNotEvaluated);
+
+    // Check that initial condition is false.
+    conditionTracker.isConditionMet(queryKey, allPredicates, false, conditionCache);
+    EXPECT_EQ(ConditionState::kFalse, conditionCache[0]);
+
+    vector<MatchingState> matcherState;
+    vector<bool> changedCache(1, false);
+
+    // Matched stop event.
+    // Check that condition is still false.
+    unique_ptr<LogEvent> screenOffEvent =
+            CreateScreenStateChangedEvent(/*timestamp=*/50, android::view::DISPLAY_STATE_OFF);
+    matcherState.clear();
+    matcherState.push_back(MatchingState::kNotMatched);  // On matcher not matched
+    matcherState.push_back(MatchingState::kMatched);     // Off matcher matched
+    conditionCache[0] = ConditionState::kNotEvaluated;
+    conditionTracker.evaluateCondition(*screenOffEvent, matcherState, allPredicates, conditionCache,
+                                       changedCache);
+    EXPECT_EQ(ConditionState::kFalse, conditionCache[0]);
+    EXPECT_FALSE(changedCache[0]);
+
+    // Matched start event.
+    // Check that condition has changed to true.
+    unique_ptr<LogEvent> screenOnEvent =
+            CreateScreenStateChangedEvent(/*timestamp=*/100, android::view::DISPLAY_STATE_ON);
+    matcherState.clear();
+    matcherState.push_back(MatchingState::kMatched);     // On matcher matched
+    matcherState.push_back(MatchingState::kNotMatched);  // Off matcher not matched
+    conditionCache[0] = ConditionState::kNotEvaluated;
+    changedCache[0] = false;
+    conditionTracker.evaluateCondition(*screenOnEvent, matcherState, allPredicates, conditionCache,
+                                       changedCache);
+    EXPECT_EQ(ConditionState::kTrue, conditionCache[0]);
+    EXPECT_TRUE(changedCache[0]);
+}
+
+TEST(SimpleConditionTrackerTest, TestNonSlicedInitialValueUnknown) {
+    SimplePredicate simplePredicate;
+    simplePredicate.set_start(StringToId("SCREEN_TURNED_ON"));
+    simplePredicate.set_stop(StringToId("SCREEN_TURNED_OFF"));
+    simplePredicate.set_count_nesting(false);
+    simplePredicate.set_initial_value(SimplePredicate_InitialValue_UNKNOWN);
+
+    unordered_map<int64_t, int> trackerNameIndexMap;
+    trackerNameIndexMap[StringToId("SCREEN_TURNED_ON")] = 0;
+    trackerNameIndexMap[StringToId("SCREEN_TURNED_OFF")] = 1;
+
+    SimpleConditionTracker conditionTracker(kConfigKey, StringToId("SCREEN_IS_ON"),
+                                            0 /*tracker index*/, simplePredicate,
+                                            trackerNameIndexMap);
+
+    ConditionKey queryKey;
+    vector<sp<ConditionTracker>> allPredicates;
+    vector<ConditionState> conditionCache(1, ConditionState::kNotEvaluated);
+
+    // Check that initial condition is unknown.
+    conditionTracker.isConditionMet(queryKey, allPredicates, false, conditionCache);
+    EXPECT_EQ(ConditionState::kUnknown, conditionCache[0]);
+
+    vector<MatchingState> matcherState;
+    vector<bool> changedCache(1, false);
+
+    // Matched stop event.
+    // Check that condition is changed to false.
+    unique_ptr<LogEvent> screenOffEvent =
+            CreateScreenStateChangedEvent(/*timestamp=*/50, android::view::DISPLAY_STATE_OFF);
+    matcherState.clear();
+    matcherState.push_back(MatchingState::kNotMatched);  // On matcher not matched
+    matcherState.push_back(MatchingState::kMatched);     // Off matcher matched
+    conditionCache[0] = ConditionState::kNotEvaluated;
+    conditionTracker.evaluateCondition(*screenOffEvent, matcherState, allPredicates, conditionCache,
+                                       changedCache);
+    EXPECT_EQ(ConditionState::kFalse, conditionCache[0]);
+    EXPECT_TRUE(changedCache[0]);
+
+    // Matched start event.
+    // Check that condition has changed to true.
+    unique_ptr<LogEvent> screenOnEvent =
+            CreateScreenStateChangedEvent(/*timestamp=*/100, android::view::DISPLAY_STATE_ON);
+    matcherState.clear();
+    matcherState.push_back(MatchingState::kMatched);     // On matcher matched
+    matcherState.push_back(MatchingState::kNotMatched);  // Off matcher not matched
+    conditionCache[0] = ConditionState::kNotEvaluated;
+    changedCache[0] = false;
+    conditionTracker.evaluateCondition(*screenOnEvent, matcherState, allPredicates, conditionCache,
+                                       changedCache);
+    EXPECT_EQ(ConditionState::kTrue, conditionCache[0]);
+    EXPECT_TRUE(changedCache[0]);
+}
+
 TEST(SimpleConditionTrackerTest, TestNonSlicedCondition) {
     SimplePredicate simplePredicate;
     simplePredicate.set_start(StringToId("SCREEN_TURNED_ON"));
diff --git a/cmds/statsd/tests/metrics/CountMetricProducer_test.cpp b/cmds/statsd/tests/metrics/CountMetricProducer_test.cpp
index 74ecaac..bb8e7bf 100644
--- a/cmds/statsd/tests/metrics/CountMetricProducer_test.cpp
+++ b/cmds/statsd/tests/metrics/CountMetricProducer_test.cpp
@@ -74,8 +74,8 @@
     metric.set_bucket(ONE_MINUTE);
     sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
 
-    CountMetricProducer countProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, wizard, 5,
-                                      600 * NS_PER_SEC + NS_PER_SEC / 2);
+    CountMetricProducer countProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, {},
+                                      wizard, 5, 600 * NS_PER_SEC + NS_PER_SEC / 2);
     EXPECT_EQ(600500000000, countProducer.mCurrentBucketStartTimeNs);
     EXPECT_EQ(10, countProducer.mCurrentBucketNum);
     EXPECT_EQ(660000000005, countProducer.getCurrentBucketEndTimeNs());
@@ -94,8 +94,8 @@
 
     sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
 
-    CountMetricProducer countProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, wizard,
-                                      bucketStartTimeNs, bucketStartTimeNs);
+    CountMetricProducer countProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, {},
+                                      wizard, bucketStartTimeNs, bucketStartTimeNs);
 
     // 2 events in bucket 1.
     LogEvent event1(/*uid=*/0, /*pid=*/0);
@@ -157,8 +157,8 @@
 
     sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
 
-    CountMetricProducer countProducer(kConfigKey, metric, 1, wizard, bucketStartTimeNs,
-                                      bucketStartTimeNs);
+    CountMetricProducer countProducer(kConfigKey, metric, 0, {ConditionState::kUnknown}, wizard,
+                                      bucketStartTimeNs, bucketStartTimeNs);
 
     countProducer.onConditionChanged(true, bucketStartTimeNs);
 
@@ -220,12 +220,14 @@
             getMockedDimensionKey(conditionTagId, 2, "222")};
 
     sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
+
     EXPECT_CALL(*wizard, query(_, key1, _)).WillOnce(Return(ConditionState::kFalse));
 
     EXPECT_CALL(*wizard, query(_, key2, _)).WillOnce(Return(ConditionState::kTrue));
 
-    CountMetricProducer countProducer(kConfigKey, metric, 1 /*condition tracker index*/, wizard,
-                                      bucketStartTimeNs, bucketStartTimeNs);
+    CountMetricProducer countProducer(kConfigKey, metric, 0 /*condition tracker index*/,
+                                      {ConditionState::kUnknown}, wizard, bucketStartTimeNs,
+                                      bucketStartTimeNs);
 
     countProducer.onMatchedLogEvent(1 /*log matcher index*/, event1);
     countProducer.flushIfNeededLocked(bucketStartTimeNs + 1);
@@ -261,7 +263,8 @@
     alert.set_trigger_if_sum_gt(2);
 
     sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-    CountMetricProducer countProducer(kConfigKey, metric, -1 /* no condition */, wizard,
+
+    CountMetricProducer countProducer(kConfigKey, metric, -1 /* no condition */, {}, wizard,
                                       bucketStartTimeNs, bucketStartTimeNs);
 
     sp<AnomalyTracker> anomalyTracker = countProducer.addAnomalyTracker(alert, alarmMonitor);
@@ -327,7 +330,8 @@
     metric.set_bucket(ONE_MINUTE);
 
     sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-    CountMetricProducer countProducer(kConfigKey, metric, -1 /* no condition */, wizard,
+
+    CountMetricProducer countProducer(kConfigKey, metric, -1 /* no condition */, {}, wizard,
                                       bucketStartTimeNs, bucketStartTimeNs);
 
     // Bucket is flushed yet.
@@ -391,8 +395,9 @@
     metric.set_bucket(ONE_MINUTE);
 
     sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-    CountMetricProducer countProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, wizard,
-                                      bucketStartTimeNs, bucketStartTimeNs);
+
+    CountMetricProducer countProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, {},
+                                      wizard, bucketStartTimeNs, bucketStartTimeNs);
 
     sp<AnomalyTracker> anomalyTracker = countProducer.addAnomalyTracker(alert, alarmMonitor);
 
@@ -453,8 +458,8 @@
     int64_t oneDayNs = 24 * 60 * 60 * 1e9;
     int64_t fiveWeeksNs = 5 * 7 * oneDayNs;
 
-    CountMetricProducer countProducer(
-            kConfigKey, metric, -1 /* meaning no condition */, wizard, oneDayNs, fiveWeeksNs);
+    CountMetricProducer countProducer(kConfigKey, metric, -1 /* meaning no condition */, {}, wizard,
+                                      oneDayNs, fiveWeeksNs);
 
     int64_t fiveWeeksOneDayNs = fiveWeeksNs + oneDayNs;
 
diff --git a/cmds/statsd/tests/metrics/DurationMetricProducer_test.cpp b/cmds/statsd/tests/metrics/DurationMetricProducer_test.cpp
index ddda71d..05cfa37b 100644
--- a/cmds/statsd/tests/metrics/DurationMetricProducer_test.cpp
+++ b/cmds/statsd/tests/metrics/DurationMetricProducer_test.cpp
@@ -70,9 +70,11 @@
     metric.set_aggregation_type(DurationMetric_AggregationType_SUM);
 
     FieldMatcher dimensions;
-    DurationMetricProducer durationProducer(
-            kConfigKey, metric, -1 /*no condition*/, 1 /* start index */, 2 /* stop index */,
-            3 /* stop_all index */, false /*nesting*/, wizard, dimensions, 5, 600 * NS_PER_SEC + NS_PER_SEC/2);
+
+    DurationMetricProducer durationProducer(kConfigKey, metric, -1 /*no condition*/, {},
+                                            1 /* start index */, 2 /* stop index */,
+                                            3 /* stop_all index */, false /*nesting*/, wizard,
+                                            dimensions, 5, 600 * NS_PER_SEC + NS_PER_SEC / 2);
 
     EXPECT_EQ(600500000000, durationProducer.mCurrentBucketStartTimeNs);
     EXPECT_EQ(10, durationProducer.mCurrentBucketNum);
@@ -96,7 +98,8 @@
     makeLogEvent(&event2, bucketStartTimeNs + bucketSizeNs + 2, tagId);
 
     FieldMatcher dimensions;
-    DurationMetricProducer durationProducer(kConfigKey, metric, -1 /*no condition*/,
+
+    DurationMetricProducer durationProducer(kConfigKey, metric, -1 /*no condition*/, {},
                                             1 /* start index */, 2 /* stop index */,
                                             3 /* stop_all index */, false /*nesting*/, wizard,
                                             dimensions, bucketStartTimeNs, bucketStartTimeNs);
@@ -138,10 +141,11 @@
     makeLogEvent(&event4, bucketStartTimeNs + bucketSizeNs + 3, tagId);
 
     FieldMatcher dimensions;
-    DurationMetricProducer durationProducer(kConfigKey, metric, 0 /* condition index */,
-                                            1 /* start index */, 2 /* stop index */,
-                                            3 /* stop_all index */, false /*nesting*/, wizard,
-                                            dimensions, bucketStartTimeNs, bucketStartTimeNs);
+
+    DurationMetricProducer durationProducer(
+            kConfigKey, metric, 0 /* condition index */, {ConditionState::kUnknown},
+            1 /* start index */, 2 /* stop index */, 3 /* stop_all index */, false /*nesting*/,
+            wizard, dimensions, bucketStartTimeNs, bucketStartTimeNs);
     durationProducer.mCondition = ConditionState::kFalse;
 
     EXPECT_FALSE(durationProducer.mCondition);
@@ -187,10 +191,11 @@
     makeLogEvent(&event4, bucketStartTimeNs + bucketSizeNs + 3, tagId);
 
     FieldMatcher dimensions;
-    DurationMetricProducer durationProducer(kConfigKey, metric, 0 /* condition index */,
-                                            1 /* start index */, 2 /* stop index */,
-                                            3 /* stop_all index */, false /*nesting*/, wizard,
-                                            dimensions, bucketStartTimeNs, bucketStartTimeNs);
+
+    DurationMetricProducer durationProducer(
+            kConfigKey, metric, 0 /* condition index */, {ConditionState::kUnknown},
+            1 /* start index */, 2 /* stop index */, 3 /* stop_all index */, false /*nesting*/,
+            wizard, dimensions, bucketStartTimeNs, bucketStartTimeNs);
 
     EXPECT_EQ(ConditionState::kUnknown, durationProducer.mCondition);
     EXPECT_FALSE(durationProducer.isConditionSliced());
@@ -232,7 +237,8 @@
     metric.set_aggregation_type(DurationMetric_AggregationType_SUM);
     sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
     FieldMatcher dimensions;
-    DurationMetricProducer durationProducer(kConfigKey, metric, -1 /* no condition */,
+
+    DurationMetricProducer durationProducer(kConfigKey, metric, -1 /* no condition */, {},
                                             1 /* start index */, 2 /* stop index */,
                                             3 /* stop_all index */, false /*nesting*/, wizard,
                                             dimensions, bucketStartTimeNs, bucketStartTimeNs);
@@ -294,7 +300,8 @@
     metric.set_aggregation_type(DurationMetric_AggregationType_SUM);
     sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
     FieldMatcher dimensions;
-    DurationMetricProducer durationProducer(kConfigKey, metric, -1 /* no condition */,
+
+    DurationMetricProducer durationProducer(kConfigKey, metric, -1 /* no condition */, {},
                                             1 /* start index */, 2 /* stop index */,
                                             3 /* stop_all index */, false /*nesting*/, wizard,
                                             dimensions, bucketStartTimeNs, bucketStartTimeNs);
@@ -357,7 +364,8 @@
 
     sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
     FieldMatcher dimensions;
-    DurationMetricProducer durationProducer(kConfigKey, metric, -1 /* no condition */,
+
+    DurationMetricProducer durationProducer(kConfigKey, metric, -1 /* no condition */, {},
                                             1 /* start index */, 2 /* stop index */,
                                             3 /* stop_all index */, false /*nesting*/, wizard,
                                             dimensions, bucketStartTimeNs, bucketStartTimeNs);
@@ -402,7 +410,8 @@
 
     sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
     FieldMatcher dimensions;
-    DurationMetricProducer durationProducer(kConfigKey, metric, -1 /* no condition */,
+
+    DurationMetricProducer durationProducer(kConfigKey, metric, -1 /* no condition */, {},
                                             1 /* start index */, 2 /* stop index */,
                                             3 /* stop_all index */, false /*nesting*/, wizard,
                                             dimensions, bucketStartTimeNs, bucketStartTimeNs);
@@ -455,7 +464,8 @@
 
     sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
     FieldMatcher dimensions;
-    DurationMetricProducer durationProducer(kConfigKey, metric, -1 /* no condition */,
+
+    DurationMetricProducer durationProducer(kConfigKey, metric, -1 /* no condition */, {},
                                             1 /* start index */, 2 /* stop index */,
                                             3 /* stop_all index */, false /*nesting*/, wizard,
                                             dimensions, bucketStartTimeNs, bucketStartTimeNs);
diff --git a/cmds/statsd/tests/metrics/EventMetricProducer_test.cpp b/cmds/statsd/tests/metrics/EventMetricProducer_test.cpp
index 5bae364..dfbb9da 100644
--- a/cmds/statsd/tests/metrics/EventMetricProducer_test.cpp
+++ b/cmds/statsd/tests/metrics/EventMetricProducer_test.cpp
@@ -65,8 +65,8 @@
 
     sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
 
-    EventMetricProducer eventProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, wizard,
-                                      bucketStartTimeNs);
+    EventMetricProducer eventProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, {},
+                                      wizard, bucketStartTimeNs);
 
     eventProducer.onMatchedLogEvent(1 /*matcher index*/, event1);
     eventProducer.onMatchedLogEvent(1 /*matcher index*/, event2);
@@ -101,7 +101,8 @@
 
     sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
 
-    EventMetricProducer eventProducer(kConfigKey, metric, 1, wizard, bucketStartTimeNs);
+    EventMetricProducer eventProducer(kConfigKey, metric, 0 /*condition index*/,
+                                      {ConditionState::kUnknown}, wizard, bucketStartTimeNs);
 
     eventProducer.onConditionChanged(true /*condition*/, bucketStartTimeNs);
     eventProducer.onMatchedLogEvent(1 /*matcher index*/, event1);
@@ -155,7 +156,8 @@
     // Condition is true for second event.
     EXPECT_CALL(*wizard, query(_, key2, _)).WillOnce(Return(ConditionState::kTrue));
 
-    EventMetricProducer eventProducer(kConfigKey, metric, 1, wizard, bucketStartTimeNs);
+    EventMetricProducer eventProducer(kConfigKey, metric, 0 /*condition index*/,
+                                      {ConditionState::kUnknown}, wizard, bucketStartTimeNs);
 
     eventProducer.onMatchedLogEvent(1 /*matcher index*/, event1);
     eventProducer.onMatchedLogEvent(1 /*matcher index*/, event2);
diff --git a/cmds/statsd/tests/metrics/GaugeMetricProducer_test.cpp b/cmds/statsd/tests/metrics/GaugeMetricProducer_test.cpp
index cc5f459..5997bed 100644
--- a/cmds/statsd/tests/metrics/GaugeMetricProducer_test.cpp
+++ b/cmds/statsd/tests/metrics/GaugeMetricProducer_test.cpp
@@ -104,10 +104,9 @@
 
     // statsd started long ago.
     // The metric starts in the middle of the bucket
-    GaugeMetricProducer gaugeProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, wizard,
-                                      logEventMatcherIndex, eventMatcherWizard,
-                                      -1, -1, tagId, 5, 600 * NS_PER_SEC + NS_PER_SEC / 2,
-                                      pullerManager);
+    GaugeMetricProducer gaugeProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, {},
+                                      wizard, logEventMatcherIndex, eventMatcherWizard, -1, -1,
+                                      tagId, 5, 600 * NS_PER_SEC + NS_PER_SEC / 2, pullerManager);
     gaugeProducer.prepareFirstBucket();
 
     EXPECT_EQ(600500000000, gaugeProducer.mCurrentBucketStartTimeNs);
@@ -147,9 +146,9 @@
                 return true;
             }));
 
-    GaugeMetricProducer gaugeProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, wizard,
-                                      logEventMatcherIndex, eventMatcherWizard, tagId, -1, tagId,
-                                      bucketStartTimeNs, bucketStartTimeNs, pullerManager);
+    GaugeMetricProducer gaugeProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, {},
+                                      wizard, logEventMatcherIndex, eventMatcherWizard, tagId, -1,
+                                      tagId, bucketStartTimeNs, bucketStartTimeNs, pullerManager);
     gaugeProducer.prepareFirstBucket();
 
     vector<shared_ptr<LogEvent>> allData;
@@ -225,8 +224,8 @@
             new EventMatcherWizard({new SimpleLogMatchingTracker(
                     atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
 
-    GaugeMetricProducer gaugeProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, wizard,
-                                      logEventMatcherIndex, eventMatcherWizard,
+    GaugeMetricProducer gaugeProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, {},
+                                      wizard, logEventMatcherIndex, eventMatcherWizard,
                                       -1 /* -1 means no pulling */, -1, tagId, bucketStartTimeNs,
                                       bucketStartTimeNs, pullerManager);
     gaugeProducer.prepareFirstBucket();
@@ -308,7 +307,6 @@
     sp<EventMatcherWizard> eventMatcherWizard =
             new EventMatcherWizard({new SimpleLogMatchingTracker(
                     atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
-
     sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
     EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, kConfigKey, _, _, _)).WillOnce(Return());
     EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, kConfigKey, _)).WillOnce(Return());
@@ -322,9 +320,9 @@
                 return true;
             }));
 
-    GaugeMetricProducer gaugeProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, wizard,
-                                      logEventMatcherIndex, eventMatcherWizard, tagId, -1, tagId,
-                                      bucketStartTimeNs, bucketStartTimeNs, pullerManager);
+    GaugeMetricProducer gaugeProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, {},
+                                      wizard, logEventMatcherIndex, eventMatcherWizard, tagId, -1,
+                                      tagId, bucketStartTimeNs, bucketStartTimeNs, pullerManager);
     gaugeProducer.prepareFirstBucket();
 
     vector<shared_ptr<LogEvent>> allData;
@@ -393,9 +391,9 @@
     EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs, _, _))
             .WillOnce(Return(false));
 
-    GaugeMetricProducer gaugeProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, wizard,
-                                      logEventMatcherIndex, eventMatcherWizard, tagId, -1, tagId,
-                                      bucketStartTimeNs, bucketStartTimeNs, pullerManager);
+    GaugeMetricProducer gaugeProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, {},
+                                      wizard, logEventMatcherIndex, eventMatcherWizard, tagId, -1,
+                                      tagId, bucketStartTimeNs, bucketStartTimeNs, pullerManager);
     gaugeProducer.prepareFirstBucket();
 
     vector<shared_ptr<LogEvent>> allData;
@@ -450,7 +448,8 @@
                 return true;
             }));
 
-    GaugeMetricProducer gaugeProducer(kConfigKey, metric, 1, wizard, logEventMatcherIndex,
+    GaugeMetricProducer gaugeProducer(kConfigKey, metric, 0 /*condition index*/,
+                                      {ConditionState::kUnknown}, wizard, logEventMatcherIndex,
                                       eventMatcherWizard, tagId, -1, tagId, bucketStartTimeNs,
                                       bucketStartTimeNs, pullerManager);
     gaugeProducer.prepareFirstBucket();
@@ -536,7 +535,8 @@
                 return true;
             }));
 
-    GaugeMetricProducer gaugeProducer(kConfigKey, metric, 1, wizard, logEventMatcherIndex,
+    GaugeMetricProducer gaugeProducer(kConfigKey, metric, 0 /*condition index*/,
+                                      {ConditionState::kUnknown}, wizard, logEventMatcherIndex,
                                       eventMatcherWizard, tagId, -1, tagId, bucketStartTimeNs,
                                       bucketStartTimeNs, pullerManager);
     gaugeProducer.prepareFirstBucket();
@@ -584,9 +584,9 @@
             new EventMatcherWizard({new SimpleLogMatchingTracker(
                     atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
 
-    GaugeMetricProducer gaugeProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, wizard,
-                                      logEventMatcherIndex, eventMatcherWizard, tagId, -1, tagId,
-                                      bucketStartTimeNs, bucketStartTimeNs, pullerManager);
+    GaugeMetricProducer gaugeProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, {},
+                                      wizard, logEventMatcherIndex, eventMatcherWizard, tagId, -1,
+                                      tagId, bucketStartTimeNs, bucketStartTimeNs, pullerManager);
     gaugeProducer.prepareFirstBucket();
 
     Alert alert;
@@ -683,9 +683,10 @@
             .WillOnce(Return(true));
 
     int triggerId = 5;
-    GaugeMetricProducer gaugeProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, wizard,
-                                      logEventMatcherIndex, eventMatcherWizard, tagId, triggerId,
-                                      tagId, bucketStartTimeNs, bucketStartTimeNs, pullerManager);
+    GaugeMetricProducer gaugeProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, {},
+                                      wizard, logEventMatcherIndex, eventMatcherWizard, tagId,
+                                      triggerId, tagId, bucketStartTimeNs, bucketStartTimeNs,
+                                      pullerManager);
     gaugeProducer.prepareFirstBucket();
 
     ASSERT_EQ(0UL, gaugeProducer.mCurrentSlicedBucket->size());
@@ -761,9 +762,10 @@
             .WillOnce(Return(true));
 
     int triggerId = 5;
-    GaugeMetricProducer gaugeProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, wizard,
-                                      logEventMatcherIndex, eventMatcherWizard, tagId, triggerId,
-                                      tagId, bucketStartTimeNs, bucketStartTimeNs, pullerManager);
+    GaugeMetricProducer gaugeProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, {},
+                                      wizard, logEventMatcherIndex, eventMatcherWizard, tagId,
+                                      triggerId, tagId, bucketStartTimeNs, bucketStartTimeNs,
+                                      pullerManager);
     gaugeProducer.prepareFirstBucket();
 
     LogEvent triggerEvent(/*uid=*/0, /*pid=*/0);
@@ -823,9 +825,10 @@
             }));
 
     int triggerId = 5;
-    GaugeMetricProducer gaugeProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, wizard,
-                                      logEventMatcherIndex, eventMatcherWizard, tagId, triggerId,
-                                      tagId, bucketStartTimeNs, bucketStartTimeNs, pullerManager);
+    GaugeMetricProducer gaugeProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, {},
+                                      wizard, logEventMatcherIndex, eventMatcherWizard, tagId,
+                                      triggerId, tagId, bucketStartTimeNs, bucketStartTimeNs,
+                                      pullerManager);
     gaugeProducer.prepareFirstBucket();
 
     LogEvent triggerEvent(/*uid=*/0, /*pid=*/0);
diff --git a/cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp b/cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp
index 52eb740..1bcc35d 100644
--- a/cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp
+++ b/cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp
@@ -111,15 +111,17 @@
         EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, kConfigKey, _))
                 .WillRepeatedly(Return());
 
-        sp<ValueMetricProducer> valueProducer = new ValueMetricProducer(
-                kConfigKey, metric, -1 /*-1 meaning no condition*/, wizard, logEventMatcherIndex,
-                eventMatcherWizard, tagId, bucketStartTimeNs, bucketStartTimeNs, pullerManager);
+        sp<ValueMetricProducer> valueProducer =
+                new ValueMetricProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, {},
+                                        wizard, logEventMatcherIndex, eventMatcherWizard, tagId,
+                                        bucketStartTimeNs, bucketStartTimeNs, pullerManager);
         valueProducer->prepareFirstBucket();
         return valueProducer;
     }
 
     static sp<ValueMetricProducer> createValueProducerWithCondition(
-            sp<MockStatsPullerManager>& pullerManager, ValueMetric& metric) {
+            sp<MockStatsPullerManager>& pullerManager, ValueMetric& metric,
+            ConditionState conditionAfterFirstBucketPrepared) {
         UidMap uidMap;
         SimpleAtomMatcher atomMatcher;
         atomMatcher.set_atom_id(tagId);
@@ -133,31 +135,11 @@
                 .WillRepeatedly(Return());
 
         sp<ValueMetricProducer> valueProducer = new ValueMetricProducer(
-                kConfigKey, metric, 1, wizard, logEventMatcherIndex, eventMatcherWizard, tagId,
-                bucketStartTimeNs, bucketStartTimeNs, pullerManager);
+                kConfigKey, metric, 0 /*condition index*/, {ConditionState::kUnknown}, wizard,
+                logEventMatcherIndex, eventMatcherWizard, tagId, bucketStartTimeNs,
+                bucketStartTimeNs, pullerManager);
         valueProducer->prepareFirstBucket();
-        valueProducer->mCondition = ConditionState::kFalse;
-        return valueProducer;
-    }
-
-    static sp<ValueMetricProducer> createValueProducerWithNoInitialCondition(
-            sp<MockStatsPullerManager>& pullerManager, ValueMetric& metric) {
-        UidMap uidMap;
-        SimpleAtomMatcher atomMatcher;
-        atomMatcher.set_atom_id(tagId);
-        sp<EventMatcherWizard> eventMatcherWizard =
-                new EventMatcherWizard({new SimpleLogMatchingTracker(
-                        atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
-        sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-        EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, kConfigKey, _, _, _))
-                .WillOnce(Return());
-        EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, kConfigKey, _))
-                .WillRepeatedly(Return());
-
-        sp<ValueMetricProducer> valueProducer = new ValueMetricProducer(
-                kConfigKey, metric, 1, wizard, logEventMatcherIndex, eventMatcherWizard, tagId,
-                bucketStartTimeNs, bucketStartTimeNs, pullerManager);
-        valueProducer->prepareFirstBucket();
+        valueProducer->mCondition = conditionAfterFirstBucketPrepared;
         return valueProducer;
     }
 
@@ -176,8 +158,9 @@
                 .WillOnce(Return());
         EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, kConfigKey, _))
                 .WillRepeatedly(Return());
+
         sp<ValueMetricProducer> valueProducer = new ValueMetricProducer(
-                kConfigKey, metric, -1 /* no condition */, wizard, logEventMatcherIndex,
+                kConfigKey, metric, -1 /* no condition */, {}, wizard, logEventMatcherIndex,
                 eventMatcherWizard, tagId, bucketStartTimeNs, bucketStartTimeNs, pullerManager, {},
                 {}, slicedStateAtoms, stateGroupMap);
         valueProducer->prepareFirstBucket();
@@ -232,9 +215,9 @@
 
     // statsd started long ago.
     // The metric starts in the middle of the bucket
-    ValueMetricProducer valueProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, wizard,
-                                      logEventMatcherIndex, eventMatcherWizard, -1, startTimeBase,
-                                      22, pullerManager);
+    ValueMetricProducer valueProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, {},
+                                      wizard, logEventMatcherIndex, eventMatcherWizard, -1,
+                                      startTimeBase, 22, pullerManager);
     valueProducer.prepareFirstBucket();
 
     EXPECT_EQ(startTimeBase, valueProducer.calcPreviousBucketEndTime(60 * NS_PER_SEC + 10));
@@ -262,8 +245,8 @@
 
     // statsd started long ago.
     // The metric starts in the middle of the bucket
-    ValueMetricProducer valueProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, wizard,
-                                      logEventMatcherIndex, eventMatcherWizard, -1, 5,
+    ValueMetricProducer valueProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, {},
+                                      wizard, logEventMatcherIndex, eventMatcherWizard, -1, 5,
                                       600 * NS_PER_SEC + NS_PER_SEC / 2, pullerManager);
     valueProducer.prepareFirstBucket();
 
@@ -427,7 +410,7 @@
             }));
 
     sp<ValueMetricProducer> valueProducer = new ValueMetricProducer(
-            kConfigKey, metric, -1 /*-1 meaning no condition*/, wizard, logEventMatcherIndex,
+            kConfigKey, metric, -1 /*-1 meaning no condition*/, {}, wizard, logEventMatcherIndex,
             eventMatcherWizard, tagId, bucketStartTimeNs, bucketStartTimeNs, pullerManager);
     valueProducer->prepareFirstBucket();
 
@@ -629,7 +612,8 @@
             }));
 
     sp<ValueMetricProducer> valueProducer =
-            ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric);
+            ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric,
+                                                                            ConditionState::kFalse);
 
     valueProducer->onConditionChanged(true, bucketStartTimeNs + 8);
 
@@ -689,7 +673,8 @@
                     atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
     sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
     sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-    ValueMetricProducer valueProducer(kConfigKey, metric, -1, wizard, logEventMatcherIndex,
+
+    ValueMetricProducer valueProducer(kConfigKey, metric, -1, {}, wizard, logEventMatcherIndex,
                                       eventMatcherWizard, -1, bucketStartTimeNs, bucketStartTimeNs,
                                       pullerManager);
     valueProducer.prepareFirstBucket();
@@ -762,7 +747,8 @@
                 data->push_back(CreateRepeatedValueLogEvent(tagId, partialBucketSplitTimeNs, 120));
                 return true;
             }));
-    ValueMetricProducer valueProducer(kConfigKey, metric, -1, wizard, logEventMatcherIndex,
+
+    ValueMetricProducer valueProducer(kConfigKey, metric, -1, {}, wizard, logEventMatcherIndex,
                                       eventMatcherWizard, tagId, bucketStartTimeNs,
                                       bucketStartTimeNs, pullerManager);
     valueProducer.prepareFirstBucket();
@@ -813,7 +799,8 @@
     EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, kConfigKey, _)).WillOnce(Return());
     EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs, _, _))
             .WillOnce(Return(true));
-    ValueMetricProducer valueProducer(kConfigKey, metric, -1, wizard, logEventMatcherIndex,
+
+    ValueMetricProducer valueProducer(kConfigKey, metric, -1, {}, wizard, logEventMatcherIndex,
                                       eventMatcherWizard, tagId, bucketStartTimeNs,
                                       bucketStartTimeNs, pullerManager);
     valueProducer.prepareFirstBucket();
@@ -851,7 +838,8 @@
                 return true;
             }));
     sp<ValueMetricProducer> valueProducer =
-            ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric);
+            ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric,
+                                                                            ConditionState::kFalse);
 
     valueProducer->onConditionChanged(true, bucketStartTimeNs + 1);
 
@@ -875,6 +863,7 @@
                                     {bucketStartTimeNs}, {partialBucketSplitTimeNs});
     EXPECT_FALSE(valueProducer->mCondition);
 }
+
 TEST(ValueMetricProducerTest, TestPushedEventsWithoutCondition) {
     ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
 
@@ -887,7 +876,7 @@
     sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
     sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
 
-    ValueMetricProducer valueProducer(kConfigKey, metric, -1, wizard, logEventMatcherIndex,
+    ValueMetricProducer valueProducer(kConfigKey, metric, -1, {}, wizard, logEventMatcherIndex,
                                       eventMatcherWizard, -1, bucketStartTimeNs, bucketStartTimeNs,
                                       pullerManager);
     valueProducer.prepareFirstBucket();
@@ -931,9 +920,9 @@
     sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
     sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
 
-    ValueMetricProducer valueProducer(kConfigKey, metric, 1, wizard, logEventMatcherIndex,
-                                      eventMatcherWizard, -1, bucketStartTimeNs, bucketStartTimeNs,
-                                      pullerManager);
+    ValueMetricProducer valueProducer(kConfigKey, metric, 0, {ConditionState::kUnknown}, wizard,
+                                      logEventMatcherIndex, eventMatcherWizard, -1,
+                                      bucketStartTimeNs, bucketStartTimeNs, pullerManager);
     valueProducer.prepareFirstBucket();
     valueProducer.mCondition = ConditionState::kFalse;
 
@@ -1001,9 +990,11 @@
                     atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
     sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
     sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-    ValueMetricProducer valueProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, wizard,
-                                      logEventMatcherIndex, eventMatcherWizard, -1 /*not pulled*/,
-                                      bucketStartTimeNs, bucketStartTimeNs, pullerManager);
+
+    ValueMetricProducer valueProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, {},
+                                      wizard, logEventMatcherIndex, eventMatcherWizard,
+                                      -1 /*not pulled*/, bucketStartTimeNs, bucketStartTimeNs,
+                                      pullerManager);
     valueProducer.prepareFirstBucket();
 
     sp<AnomalyTracker> anomalyTracker = valueProducer.addAnomalyTracker(alert, alarmMonitor);
@@ -1158,7 +1149,8 @@
                 return true;
             }));
     sp<ValueMetricProducer> valueProducer =
-            ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric);
+            ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric,
+                                                                            ConditionState::kFalse);
 
     valueProducer->onConditionChanged(true, bucketStartTimeNs + 8);
 
@@ -1229,7 +1221,8 @@
             }));
 
     sp<ValueMetricProducer> valueProducer =
-            ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric);
+            ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric,
+                                                                            ConditionState::kFalse);
 
     valueProducer->onConditionChanged(true, bucketStartTimeNs + 8);
 
@@ -1300,7 +1293,7 @@
     sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
     sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
 
-    ValueMetricProducer valueProducer(kConfigKey, metric, -1, wizard, logEventMatcherIndex,
+    ValueMetricProducer valueProducer(kConfigKey, metric, -1, {}, wizard, logEventMatcherIndex,
                                       eventMatcherWizard, -1, bucketStartTimeNs, bucketStartTimeNs,
                                       pullerManager);
     valueProducer.prepareFirstBucket();
@@ -1344,7 +1337,7 @@
     sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
     sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
 
-    ValueMetricProducer valueProducer(kConfigKey, metric, -1, wizard, logEventMatcherIndex,
+    ValueMetricProducer valueProducer(kConfigKey, metric, -1, {}, wizard, logEventMatcherIndex,
                                       eventMatcherWizard, -1, bucketStartTimeNs, bucketStartTimeNs,
                                       pullerManager);
     valueProducer.prepareFirstBucket();
@@ -1387,7 +1380,7 @@
     sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
     sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
 
-    ValueMetricProducer valueProducer(kConfigKey, metric, -1, wizard, logEventMatcherIndex,
+    ValueMetricProducer valueProducer(kConfigKey, metric, -1, {}, wizard, logEventMatcherIndex,
                                       eventMatcherWizard, -1, bucketStartTimeNs, bucketStartTimeNs,
                                       pullerManager);
     valueProducer.prepareFirstBucket();
@@ -1435,7 +1428,7 @@
     sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
     sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
 
-    ValueMetricProducer valueProducer(kConfigKey, metric, -1, wizard, logEventMatcherIndex,
+    ValueMetricProducer valueProducer(kConfigKey, metric, -1, {}, wizard, logEventMatcherIndex,
                                       eventMatcherWizard, -1, bucketStartTimeNs, bucketStartTimeNs,
                                       pullerManager);
     valueProducer.prepareFirstBucket();
@@ -1479,7 +1472,7 @@
     sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
     sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
 
-    ValueMetricProducer valueProducer(kConfigKey, metric, -1, wizard, logEventMatcherIndex,
+    ValueMetricProducer valueProducer(kConfigKey, metric, -1, {}, wizard, logEventMatcherIndex,
                                       eventMatcherWizard, -1, bucketStartTimeNs, bucketStartTimeNs,
                                       pullerManager);
     valueProducer.prepareFirstBucket();
@@ -1551,7 +1544,7 @@
     sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
     sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
 
-    ValueMetricProducer valueProducer(kConfigKey, metric, -1, wizard, logEventMatcherIndex,
+    ValueMetricProducer valueProducer(kConfigKey, metric, -1, {}, wizard, logEventMatcherIndex,
                                       eventMatcherWizard, -1, bucketStartTimeNs, bucketStartTimeNs,
                                       pullerManager);
     valueProducer.prepareFirstBucket();
@@ -1944,7 +1937,8 @@
             }));
 
     sp<ValueMetricProducer> valueProducer =
-            ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric);
+            ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric,
+                                                                            ConditionState::kFalse);
 
     valueProducer->onConditionChanged(true, bucketStartTimeNs + 8);
     // has one slice
@@ -1979,7 +1973,8 @@
             .WillOnce(Return(false));
 
     sp<ValueMetricProducer> valueProducer =
-            ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric);
+            ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric,
+                                                                            ConditionState::kFalse);
 
     valueProducer->onConditionChanged(true, bucketStartTimeNs + 8);
 
@@ -2023,7 +2018,8 @@
             }));
 
     sp<ValueMetricProducer> valueProducer =
-            ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric);
+            ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric,
+                                                                            ConditionState::kFalse);
 
     // Don't directly set mCondition; the real code never does that. Go through regular code path
     // to avoid unexpected behaviors.
@@ -2057,9 +2053,8 @@
             }));
 
     sp<ValueMetricProducer> valueProducer =
-            ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric);
-
-    valueProducer->mCondition = ConditionState::kFalse;
+            ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric,
+                                                                            ConditionState::kFalse);
 
     // Max delay is set to 0 so pull will exceed max delay.
     valueProducer->onConditionChanged(true, bucketStartTimeNs + 1);
@@ -2080,9 +2075,9 @@
     EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, kConfigKey, _, _, _)).WillOnce(Return());
     EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, kConfigKey, _)).WillRepeatedly(Return());
 
-    ValueMetricProducer valueProducer(kConfigKey, metric, 1, wizard, logEventMatcherIndex,
-                                      eventMatcherWizard, tagId, bucket2StartTimeNs,
-                                      bucket2StartTimeNs, pullerManager);
+    ValueMetricProducer valueProducer(kConfigKey, metric, 0, {ConditionState::kUnknown}, wizard,
+                                      logEventMatcherIndex, eventMatcherWizard, tagId,
+                                      bucket2StartTimeNs, bucket2StartTimeNs, pullerManager);
     valueProducer.prepareFirstBucket();
     valueProducer.mCondition = ConditionState::kFalse;
 
@@ -2105,9 +2100,8 @@
             }));
 
     sp<ValueMetricProducer> valueProducer =
-            ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric);
-
-    valueProducer->mCondition = ConditionState::kFalse;
+            ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric,
+                                                                            ConditionState::kFalse);
     valueProducer->mHasGlobalBase = false;
 
     valueProducer->onConditionChanged(true, bucketStartTimeNs + 1);
@@ -2142,9 +2136,8 @@
             }));
 
     sp<ValueMetricProducer> valueProducer =
-            ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric);
-
-    valueProducer->mCondition = ConditionState::kTrue;
+            ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric,
+                                                                            ConditionState::kTrue);
 
     // Bucket start.
     vector<shared_ptr<LogEvent>> allData;
@@ -2218,8 +2211,8 @@
             }));
 
     sp<ValueMetricProducer> valueProducer =
-            ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric);
-    valueProducer->mCondition = ConditionState::kFalse;
+            ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric,
+                                                                            ConditionState::kFalse);
 
     valueProducer->onConditionChanged(true, bucketStartTimeNs + 2);
     EXPECT_EQ(true, valueProducer->mCurrentBucketIsSkipped);
@@ -2283,9 +2276,8 @@
             }));
 
     sp<ValueMetricProducer> valueProducer =
-            ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric);
-
-    valueProducer->mCondition = ConditionState::kTrue;
+            ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric,
+                                                                            ConditionState::kTrue);
 
     // Bucket start.
     vector<shared_ptr<LogEvent>> allData;
@@ -2363,9 +2355,8 @@
             }));
 
     sp<ValueMetricProducer> valueProducer =
-            ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric);
-
-    valueProducer->mCondition = ConditionState::kTrue;
+            ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric,
+                                                                            ConditionState::kTrue);
 
     // Bucket start.
     vector<shared_ptr<LogEvent>> allData;
@@ -2468,7 +2459,8 @@
             }));
 
     sp<ValueMetricProducer> valueProducer =
-            ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric);
+            ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric,
+                                                                            ConditionState::kFalse);
 
     valueProducer->onConditionChanged(true, bucketStartTimeNs + 10);
     ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
@@ -2518,7 +2510,8 @@
             }));
 
     sp<ValueMetricProducer> valueProducer =
-            ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric);
+            ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric,
+                                                                            ConditionState::kFalse);
 
     valueProducer->onConditionChanged(true, bucketStartTimeNs + 10);
     valueProducer->onConditionChanged(false, bucketStartTimeNs + 11);
@@ -2566,7 +2559,8 @@
             }));
 
     sp<ValueMetricProducer> valueProducer =
-            ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric);
+            ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric,
+                                                                            ConditionState::kFalse);
 
     valueProducer->onConditionChanged(true, bucketStartTimeNs + 10);
     ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
@@ -2673,8 +2667,8 @@
             }));
 
     sp<ValueMetricProducer> valueProducer =
-            ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric);
-    valueProducer->mCondition = ConditionState::kUnknown;
+            ValueMetricProducerTestHelper::createValueProducerWithCondition(
+                    pullerManager, metric, ConditionState::kUnknown);
 
     valueProducer->onConditionChanged(false, bucketStartTimeNs);
     ASSERT_EQ(0UL, valueProducer->mCurrentSlicedBucket.size());
@@ -2814,7 +2808,8 @@
             }));
 
     sp<ValueMetricProducer> valueProducer =
-            ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric);
+            ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric,
+                                                                            ConditionState::kFalse);
 
     valueProducer->onConditionChanged(true, bucketStartTimeNs + 8);
     valueProducer->onConditionChanged(false, bucketStartTimeNs + 10);
@@ -2866,7 +2861,8 @@
             }));
 
     sp<ValueMetricProducer> valueProducer =
-            ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric);
+            ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric,
+                                                                            ConditionState::kFalse);
     valueProducer->onConditionChanged(true, bucket2StartTimeNs + 10);
 
     vector<shared_ptr<LogEvent>> allData;
@@ -2911,7 +2907,7 @@
                 return true;
             }));
 
-    ValueMetricProducer valueProducer(kConfigKey, metric, -1, wizard, logEventMatcherIndex,
+    ValueMetricProducer valueProducer(kConfigKey, metric, -1, {}, wizard, logEventMatcherIndex,
                                       eventMatcherWizard, tagId, bucketStartTimeNs,
                                       bucketStartTimeNs, pullerManager);
     valueProducer.prepareFirstBucket();
@@ -2949,7 +2945,7 @@
                 return true;
             }));
 
-    ValueMetricProducer valueProducer(kConfigKey, metric, -1, wizard, logEventMatcherIndex,
+    ValueMetricProducer valueProducer(kConfigKey, metric, -1, {}, wizard, logEventMatcherIndex,
                                       eventMatcherWizard, tagId, bucketStartTimeNs,
                                       bucketStartTimeNs, pullerManager);
     valueProducer.prepareFirstBucket();
@@ -3002,7 +2998,7 @@
                 return true;
             }));
 
-    ValueMetricProducer valueProducer(kConfigKey, metric, -1, wizard, logEventMatcherIndex,
+    ValueMetricProducer valueProducer(kConfigKey, metric, -1, {}, wizard, logEventMatcherIndex,
                                       eventMatcherWizard, tagId, bucketStartTimeNs,
                                       bucketStartTimeNs, pullerManager);
     valueProducer.prepareFirstBucket();
@@ -3058,8 +3054,8 @@
                 return true;
             }));
     sp<ValueMetricProducer> valueProducer =
-            ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric);
-    valueProducer->mCondition = ConditionState::kFalse;
+            ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric,
+                                                                            ConditionState::kFalse);
 
     valueProducer->onConditionChanged(true, bucketStartTimeNs + 8);
     valueProducer->onConditionChanged(false, bucketStartTimeNs + 50);
@@ -3099,8 +3095,8 @@
                 return true;
             }));
     sp<ValueMetricProducer> valueProducer =
-            ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric);
-    valueProducer->mCondition = ConditionState::kFalse;
+            ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric,
+                                                                            ConditionState::kFalse);
 
     valueProducer->onConditionChanged(true, bucketStartTimeNs + 8);
 
@@ -3124,8 +3120,8 @@
 
     sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
     sp<ValueMetricProducer> valueProducer =
-            ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric);
-    valueProducer->mCondition = ConditionState::kFalse;
+            ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric,
+                                                                            ConditionState::kFalse);
 
     // Now the alarm is delivered. Condition is off though.
     vector<shared_ptr<LogEvent>> allData;
@@ -3152,8 +3148,8 @@
             }))
             .WillOnce(Return(false));
     sp<ValueMetricProducer> valueProducer =
-            ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric);
-    valueProducer->mCondition = ConditionState::kFalse;
+            ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric,
+                                                                            ConditionState::kFalse);
 
     valueProducer->onConditionChanged(true, bucketStartTimeNs + 8);
     valueProducer->onConditionChanged(false, bucketStartTimeNs + 50);
@@ -3191,7 +3187,8 @@
             }));
 
     sp<ValueMetricProducer> valueProducer =
-            ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric);
+            ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric,
+                                                                            ConditionState::kFalse);
 
     // Condition change event.
     valueProducer->onConditionChanged(true, bucketStartTimeNs + 20);
@@ -3236,7 +3233,8 @@
             }));
 
     sp<ValueMetricProducer> valueProducer =
-            ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric);
+            ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric,
+                                                                            ConditionState::kFalse);
 
     // Condition change event.
     valueProducer->onConditionChanged(true, bucketStartTimeNs + 50);
@@ -3298,7 +3296,8 @@
             }));
 
     sp<ValueMetricProducer> valueProducer =
-            ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric);
+            ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric,
+                                                                            ConditionState::kFalse);
 
     // Condition change event.
     valueProducer->onConditionChanged(true, bucketStartTimeNs + 50);
@@ -3363,8 +3362,8 @@
             }));
 
     sp<ValueMetricProducer> valueProducer =
-            ValueMetricProducerTestHelper::createValueProducerWithNoInitialCondition(pullerManager,
-                                                                                     metric);
+            ValueMetricProducerTestHelper::createValueProducerWithCondition(
+                    pullerManager, metric, ConditionState::kUnknown);
 
     // Condition change event.
     valueProducer->onConditionChanged(true, bucketStartTimeNs + 50);
@@ -3413,7 +3412,8 @@
             .WillOnce(Return(false));
 
     sp<ValueMetricProducer> valueProducer =
-            ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric);
+            ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric,
+                                                                            ConditionState::kFalse);
 
     // Condition change event.
     valueProducer->onConditionChanged(true, bucketStartTimeNs + 50);
@@ -3468,7 +3468,8 @@
             }));
 
     sp<ValueMetricProducer> valueProducer =
-            ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric);
+            ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric,
+                                                                            ConditionState::kFalse);
 
     // Condition change event.
     valueProducer->onConditionChanged(true, bucketStartTimeNs + 10);
@@ -3542,7 +3543,8 @@
             }));
 
     sp<ValueMetricProducer> valueProducer =
-            ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric);
+            ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric,
+                                                                            ConditionState::kFalse);
 
     // Condition change event.
     valueProducer->onConditionChanged(true, bucketStartTimeNs + 10);
@@ -3579,7 +3581,8 @@
     sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
 
     sp<ValueMetricProducer> valueProducer =
-            ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric);
+            ValueMetricProducerTestHelper::createValueProducerWithCondition(
+                    pullerManager, metric, ConditionState::kUnknown);
 
     // Check dump report.
     ProtoOutputStream output;
@@ -3632,7 +3635,8 @@
             }));
 
     sp<ValueMetricProducer> valueProducer =
-            ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric);
+            ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric,
+                                                                            ConditionState::kFalse);
 
     // Condition changed event
     int64_t conditionChangeTimeNs = bucketStartTimeNs + 10;
@@ -3687,8 +3691,8 @@
             }));
 
     sp<ValueMetricProducer> valueProducer =
-            ValueMetricProducerTestHelper::createValueProducerWithNoInitialCondition(pullerManager,
-                                                                                     metric);
+            ValueMetricProducerTestHelper::createValueProducerWithCondition(
+                    pullerManager, metric, ConditionState::kUnknown);
 
     // Condition change event.
     valueProducer->onConditionChanged(true, bucketStartTimeNs + 10);
@@ -3756,8 +3760,8 @@
             }));
 
     sp<ValueMetricProducer> valueProducer =
-            ValueMetricProducerTestHelper::createValueProducerWithNoInitialCondition(pullerManager,
-                                                                                     metric);
+            ValueMetricProducerTestHelper::createValueProducerWithCondition(
+                    pullerManager, metric, ConditionState::kUnknown);
 
     // First condition change event causes guardrail to be reached.
     valueProducer->onConditionChanged(true, bucketStartTimeNs + 10);
diff --git a/core/java/android/content/pm/ActivityInfo.java b/core/java/android/content/pm/ActivityInfo.java
index b1f8869..bd02210 100644
--- a/core/java/android/content/pm/ActivityInfo.java
+++ b/core/java/android/content/pm/ActivityInfo.java
@@ -245,6 +245,13 @@
     public float minAspectRatio;
 
     /**
+     * Indicates that the activity works well with size changes like display changing size.
+     *
+     * @hide
+     */
+    public boolean supportsSizeChanges;
+
+    /**
      * Name of the VrListenerService component to run for this activity.
      * @see android.R.attr#enableVrMode
      * @hide
@@ -1013,6 +1020,7 @@
         colorMode = orig.colorMode;
         maxAspectRatio = orig.maxAspectRatio;
         minAspectRatio = orig.minAspectRatio;
+        supportsSizeChanges = orig.supportsSizeChanges;
     }
 
     /**
@@ -1188,6 +1196,9 @@
         if (minAspectRatio != 0) {
             pw.println(prefix + "minAspectRatio=" + minAspectRatio);
         }
+        if (supportsSizeChanges) {
+            pw.println(prefix + "supportsSizeChanges=true");
+        }
         super.dumpBack(pw, prefix, dumpFlags);
     }
 
@@ -1232,6 +1243,7 @@
         dest.writeInt(colorMode);
         dest.writeFloat(maxAspectRatio);
         dest.writeFloat(minAspectRatio);
+        dest.writeBoolean(supportsSizeChanges);
     }
 
     /**
@@ -1350,6 +1362,7 @@
         colorMode = source.readInt();
         maxAspectRatio = source.readFloat();
         minAspectRatio = source.readFloat();
+        supportsSizeChanges = source.readBoolean();
     }
 
     /**
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index 0d8618f..c8dd4d9 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -207,6 +207,7 @@
     public static final String TAG_USES_SPLIT = "uses-split";
 
     public static final String METADATA_MAX_ASPECT_RATIO = "android.max_aspect";
+    public static final String METADATA_SUPPORTS_SIZE_CHANGES = "android.supports_size_changes";
     public static final String METADATA_ACTIVITY_WINDOW_LAYOUT_AFFINITY =
             "android.activity_window_layout_affinity";
 
@@ -3897,6 +3898,7 @@
         // every activity info has had a chance to set it from its attributes.
         setMaxAspectRatio(owner);
         setMinAspectRatio(owner);
+        setSupportsSizeChanges(owner);
 
         if (hasDomainURLs(owner)) {
             owner.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_HAS_DOMAIN_URLS;
@@ -4694,6 +4696,18 @@
         }
     }
 
+    private void setSupportsSizeChanges(Package owner) {
+        final boolean supportsSizeChanges = owner.mAppMetaData != null
+                && owner.mAppMetaData.getBoolean(METADATA_SUPPORTS_SIZE_CHANGES, false);
+
+        for (Activity activity : owner.activities) {
+            if (supportsSizeChanges || (activity.metaData != null
+                    && activity.metaData.getBoolean(METADATA_SUPPORTS_SIZE_CHANGES, false))) {
+                activity.info.supportsSizeChanges = true;
+            }
+        }
+    }
+
     /**
      * @param configChanges The bit mask of configChanges fetched from AndroidManifest.xml.
      * @param recreateOnConfigChanges The bit mask recreateOnConfigChanges fetched from
@@ -4863,6 +4877,7 @@
         info.resizeMode = target.info.resizeMode;
         info.maxAspectRatio = target.info.maxAspectRatio;
         info.minAspectRatio = target.info.minAspectRatio;
+        info.supportsSizeChanges = target.info.supportsSizeChanges;
         info.requestedVrComponent = target.info.requestedVrComponent;
 
         info.directBootAware = target.info.directBootAware;
diff --git a/core/java/android/content/pm/parsing/PackageInfoWithoutStateUtils.java b/core/java/android/content/pm/parsing/PackageInfoWithoutStateUtils.java
index 216b3bb..e450748 100644
--- a/core/java/android/content/pm/parsing/PackageInfoWithoutStateUtils.java
+++ b/core/java/android/content/pm/parsing/PackageInfoWithoutStateUtils.java
@@ -445,6 +445,7 @@
         ai.maxAspectRatio = maxAspectRatio != null ? maxAspectRatio : 0f;
         Float minAspectRatio = a.getMinAspectRatio();
         ai.minAspectRatio = minAspectRatio != null ? minAspectRatio : 0f;
+        ai.supportsSizeChanges = a.getSupportsSizeChanges();
         ai.requestedVrComponent = a.getRequestedVrComponent();
         ai.rotationAnimation = a.getRotationAnimation();
         ai.colorMode = a.getColorMode();
diff --git a/core/java/android/content/pm/parsing/ParsingPackageUtils.java b/core/java/android/content/pm/parsing/ParsingPackageUtils.java
index 5a79475..3171078 100644
--- a/core/java/android/content/pm/parsing/ParsingPackageUtils.java
+++ b/core/java/android/content/pm/parsing/ParsingPackageUtils.java
@@ -1912,6 +1912,7 @@
         // every activity info has had a chance to set it from its attributes.
         setMaxAspectRatio(pkg);
         setMinAspectRatio(pkg);
+        setSupportsSizeChanges(pkg);
 
         pkg.setHasDomainUrls(hasDomainURLs(pkg));
 
@@ -2366,6 +2367,23 @@
         }
     }
 
+    private void setSupportsSizeChanges(ParsingPackage pkg) {
+        final Bundle appMetaData = pkg.getMetaData();
+        final boolean supportsSizeChanges = appMetaData != null
+                && appMetaData.getBoolean(PackageParser.METADATA_SUPPORTS_SIZE_CHANGES, false);
+
+        List<ParsedActivity> activities = pkg.getActivities();
+        int activitiesSize = activities.size();
+        for (int index = 0; index < activitiesSize; index++) {
+            ParsedActivity activity = activities.get(index);
+            if (supportsSizeChanges || (activity.getMetaData() != null
+                    && activity.getMetaData().getBoolean(
+                            PackageParser.METADATA_SUPPORTS_SIZE_CHANGES, false))) {
+                activity.setSupportsSizeChanges(true);
+            }
+        }
+    }
+
     private static ParseResult<ParsingPackage> parseOverlay(ParseInput input, ParsingPackage pkg,
             Resources res, XmlResourceParser parser) {
         TypedArray sa = res.obtainAttributes(parser, R.styleable.AndroidManifestResourceOverlay);
diff --git a/core/java/android/content/pm/parsing/component/ParsedActivity.java b/core/java/android/content/pm/parsing/component/ParsedActivity.java
index 4c93d09..1915028 100644
--- a/core/java/android/content/pm/parsing/component/ParsedActivity.java
+++ b/core/java/android/content/pm/parsing/component/ParsedActivity.java
@@ -73,6 +73,8 @@
     @Nullable
     private Float minAspectRatio;
 
+    private boolean supportsSizeChanges;
+
     @Nullable
     String requestedVrComponent;
     int rotationAnimation = -1;
@@ -101,6 +103,7 @@
         this.resizeMode = other.resizeMode;
         this.maxAspectRatio = other.maxAspectRatio;
         this.minAspectRatio = other.minAspectRatio;
+        this.supportsSizeChanges = other.supportsSizeChanges;
         this.requestedVrComponent = other.requestedVrComponent;
         this.rotationAnimation = other.rotationAnimation;
         this.colorMode = other.colorMode;
@@ -165,6 +168,7 @@
         alias.resizeMode = target.resizeMode;
         alias.maxAspectRatio = target.maxAspectRatio;
         alias.minAspectRatio = target.minAspectRatio;
+        alias.supportsSizeChanges = target.supportsSizeChanges;
         alias.requestedVrComponent = target.requestedVrComponent;
         alias.directBootAware = target.directBootAware;
         alias.setProcessName(target.getProcessName());
@@ -217,6 +221,11 @@
         return this;
     }
 
+    public ParsedActivity setSupportsSizeChanges(boolean supportsSizeChanges) {
+        this.supportsSizeChanges = supportsSizeChanges;
+        return this;
+    }
+
     public ParsedActivity setFlags(int flags) {
         this.flags = flags;
         return this;
@@ -279,6 +288,7 @@
         dest.writeInt(this.resizeMode);
         dest.writeValue(this.maxAspectRatio);
         dest.writeValue(this.minAspectRatio);
+        dest.writeBoolean(this.supportsSizeChanges);
         dest.writeString(this.requestedVrComponent);
         dest.writeInt(this.rotationAnimation);
         dest.writeInt(this.colorMode);
@@ -315,6 +325,7 @@
         this.resizeMode = in.readInt();
         this.maxAspectRatio = (Float) in.readValue(Float.class.getClassLoader());
         this.minAspectRatio = (Float) in.readValue(Float.class.getClassLoader());
+        this.supportsSizeChanges = in.readBoolean();
         this.requestedVrComponent = in.readString();
         this.rotationAnimation = in.readInt();
         this.colorMode = in.readInt();
@@ -414,6 +425,10 @@
         return minAspectRatio;
     }
 
+    public boolean getSupportsSizeChanges() {
+        return supportsSizeChanges;
+    }
+
     @Nullable
     public String getRequestedVrComponent() {
         return requestedVrComponent;
diff --git a/core/java/android/hardware/biometrics/IBiometricAuthenticator.aidl b/core/java/android/hardware/biometrics/IBiometricAuthenticator.aidl
index b4ebed7..c1dd20d 100644
--- a/core/java/android/hardware/biometrics/IBiometricAuthenticator.aidl
+++ b/core/java/android/hardware/biometrics/IBiometricAuthenticator.aidl
@@ -57,5 +57,5 @@
     void setActiveUser(int uid);
 
     // Gets the authenticator ID representing the current set of enrolled templates
-    long getAuthenticatorId();
+    long getAuthenticatorId(int callingUserId);
 }
diff --git a/core/java/android/hardware/biometrics/IBiometricService.aidl b/core/java/android/hardware/biometrics/IBiometricService.aidl
index 10295db..07f88c2 100644
--- a/core/java/android/hardware/biometrics/IBiometricService.aidl
+++ b/core/java/android/hardware/biometrics/IBiometricService.aidl
@@ -65,5 +65,5 @@
     // Get a list of AuthenticatorIDs for authenticators which have enrolled templates and meet
     // the requirements for integrating with Keystore. The AuthenticatorID are known in Keystore
     // land as SIDs, and are used during key generation.
-    long[] getAuthenticatorIds();
+    long[] getAuthenticatorIds(int callingUserId);
 }
diff --git a/core/java/android/hardware/face/IFaceService.aidl b/core/java/android/hardware/face/IFaceService.aidl
index 03937e0..e2ab529 100644
--- a/core/java/android/hardware/face/IFaceService.aidl
+++ b/core/java/android/hardware/face/IFaceService.aidl
@@ -85,7 +85,7 @@
     // long getHardwareDevice(int i);
 
     // Gets the authenticator ID for face
-    long getAuthenticatorId();
+    long getAuthenticatorId(int callingUserId);
 
     // Reset the lockout when user authenticates with strong auth (e.g. PIN, pattern or password)
     void resetLockout(in byte [] token);
diff --git a/core/java/android/hardware/fingerprint/IFingerprintService.aidl b/core/java/android/hardware/fingerprint/IFingerprintService.aidl
index 2507c84..c5c3755 100644
--- a/core/java/android/hardware/fingerprint/IFingerprintService.aidl
+++ b/core/java/android/hardware/fingerprint/IFingerprintService.aidl
@@ -89,7 +89,7 @@
     // long getHardwareDevice(int i);
 
     // Gets the authenticator ID for fingerprint
-    long getAuthenticatorId();
+    long getAuthenticatorId(int callingUserId);
 
     // Reset the timeout when user authenticates with strong auth (e.g. PIN, pattern or password)
     void resetTimeout(in byte [] cryptoToken);
diff --git a/core/java/android/os/storage/StorageManager.java b/core/java/android/os/storage/StorageManager.java
index 66b8cab..4ca48cb 100644
--- a/core/java/android/os/storage/StorageManager.java
+++ b/core/java/android/os/storage/StorageManager.java
@@ -56,6 +56,7 @@
 import android.content.pm.PackageManager;
 import android.content.res.ObbInfo;
 import android.content.res.ObbScanner;
+import android.database.Cursor;
 import android.net.Uri;
 import android.os.Binder;
 import android.os.Environment;
@@ -1201,7 +1202,19 @@
      * {@link MediaStore} item.
      */
     public @NonNull StorageVolume getStorageVolume(@NonNull Uri uri) {
-        final String volumeName = MediaStore.getVolumeName(uri);
+        String volumeName = MediaStore.getVolumeName(uri);
+
+        // When Uri is pointing at a synthetic volume, we're willing to query to
+        // resolve the actual volume name
+        if (Objects.equals(volumeName, MediaStore.VOLUME_EXTERNAL)) {
+            try (Cursor c = mContext.getContentResolver().query(uri,
+                    new String[] { MediaStore.MediaColumns.VOLUME_NAME }, null, null)) {
+                if (c.moveToFirst()) {
+                    volumeName = c.getString(0);
+                }
+            }
+        }
+
         switch (volumeName) {
             case MediaStore.VOLUME_EXTERNAL_PRIMARY:
                 return getPrimaryStorageVolume();
diff --git a/core/java/android/view/Surface.java b/core/java/android/view/Surface.java
index d12ca73..4e07a5f 100644
--- a/core/java/android/view/Surface.java
+++ b/core/java/android/view/Surface.java
@@ -195,7 +195,10 @@
 
     // From native_window.h. Keep these in sync.
     /**
-     * There are no inherent restrictions on the frame rate of this surface.
+     * There are no inherent restrictions on the frame rate of this surface. When the
+     * system selects a frame rate other than what the app requested, the app will be able
+     * to run at the system frame rate without requiring pull down. This value should be
+     * used when displaying game content, UIs, and anything that isn't video.
      */
     public static final int FRAME_RATE_COMPATIBILITY_DEFAULT = 0;
 
@@ -205,7 +208,7 @@
      * other than what the app requested, the app will need to do pull down or use some
      * other technique to adapt to the system's frame rate. The user experience is likely
      * to be worse (e.g. more frame stuttering) than it would be if the system had chosen
-     * the app's requested frame rate.
+     * the app's requested frame rate. This value should be used for video content.
      */
     public static final int FRAME_RATE_COMPATIBILITY_FIXED_SOURCE = 1;
 
diff --git a/core/java/com/android/internal/app/ChooserListAdapter.java b/core/java/com/android/internal/app/ChooserListAdapter.java
index a87f847..f4fb993 100644
--- a/core/java/com/android/internal/app/ChooserListAdapter.java
+++ b/core/java/com/android/internal/app/ChooserListAdapter.java
@@ -80,6 +80,7 @@
     private static final int MAX_SUGGESTED_APP_TARGETS = 4;
     private static final int MAX_CHOOSER_TARGETS_PER_APP = 2;
     private static final int MAX_SERVICE_TARGET_APP = 8;
+    private static final int DEFAULT_DIRECT_SHARE_RANKING_SCORE = 1000;
 
     static final int MAX_SERVICE_TARGETS = 8;
 
@@ -564,11 +565,13 @@
         }
         Map<String, Integer> scores = mChooserTargetScores.get(componentName);
         Collections.sort(mParkingDirectShareTargets.get(componentName).first, (o1, o2) -> {
-            // The score has been normalized between 0 and 2, the default is 1.
+            // The score has been normalized between 0 and 2000, the default is 1000.
             int score1 = scores.getOrDefault(
-                    ChooserUtil.md5(o1.getChooserTarget().getTitle().toString()), 1);
+                    ChooserUtil.md5(o1.getChooserTarget().getTitle().toString()),
+                    DEFAULT_DIRECT_SHARE_RANKING_SCORE);
             int score2 = scores.getOrDefault(
-                    ChooserUtil.md5(o2.getChooserTarget().getTitle().toString()), 1);
+                    ChooserUtil.md5(o2.getChooserTarget().getTitle().toString()),
+                    DEFAULT_DIRECT_SHARE_RANKING_SCORE);
             return score2 - score1;
         });
     }
diff --git a/media/java/android/media/ThumbnailUtils.java b/media/java/android/media/ThumbnailUtils.java
index 1f7b5ad..fbf38dc 100644
--- a/media/java/android/media/ThumbnailUtils.java
+++ b/media/java/android/media/ThumbnailUtils.java
@@ -34,6 +34,7 @@
 import android.graphics.ImageDecoder.Source;
 import android.graphics.Matrix;
 import android.graphics.Rect;
+import android.media.MediaMetadataRetriever.BitmapParams;
 import android.net.Uri;
 import android.os.Build;
 import android.os.CancellationSignal;
@@ -365,6 +366,9 @@
                 return ImageDecoder.decodeBitmap(ImageDecoder.createSource(raw), resizer);
             }
 
+            final BitmapParams params = new BitmapParams();
+            params.setPreferredConfig(Bitmap.Config.ARGB_8888);
+
             final int width = Integer.parseInt(mmr.extractMetadata(METADATA_KEY_VIDEO_WIDTH));
             final int height = Integer.parseInt(mmr.extractMetadata(METADATA_KEY_VIDEO_HEIGHT));
             // Fall back to middle of video
@@ -376,11 +380,11 @@
             // return a frame without up-scaling it
             if (size.getWidth() > width && size.getHeight() > height) {
                 return Objects.requireNonNull(
-                        mmr.getFrameAtTime(thumbnailTimeUs, OPTION_CLOSEST_SYNC));
+                        mmr.getFrameAtTime(thumbnailTimeUs, OPTION_CLOSEST_SYNC, params));
             } else {
                 return Objects.requireNonNull(
                         mmr.getScaledFrameAtTime(thumbnailTimeUs, OPTION_CLOSEST_SYNC,
-                        size.getWidth(), size.getHeight()));
+                        size.getWidth(), size.getHeight(), params));
             }
         } catch (RuntimeException e) {
             throw new IOException("Failed to create thumbnail", e);
diff --git a/media/jni/soundpool/SoundDecoder.cpp b/media/jni/soundpool/SoundDecoder.cpp
index 6614fdb..5ed10b0 100644
--- a/media/jni/soundpool/SoundDecoder.cpp
+++ b/media/jni/soundpool/SoundDecoder.cpp
@@ -107,7 +107,8 @@
     }
     // Launch threads as needed.  The "as needed" is weakly consistent as we release mLock.
     if (pendingSounds > mThreadPool->getActiveThreadCount()) {
-        const int32_t id __unused = mThreadPool->launch([this](int32_t id) { run(id); });
+        const int32_t id = mThreadPool->launch([this](int32_t id) { run(id); });
+        (void)id; // avoid clang warning -Wunused-variable -Wused-but-marked-unused
         ALOGV_IF(id != 0, "%s: launched thread %d", __func__, id);
     }
 }
diff --git a/media/jni/soundpool/Stream.cpp b/media/jni/soundpool/Stream.cpp
index a6d9758..e7042d0 100644
--- a/media/jni/soundpool/Stream.cpp
+++ b/media/jni/soundpool/Stream.cpp
@@ -203,7 +203,7 @@
 void Stream::stop_l()
 {
     if (mState != IDLE) {
-        ALOGV("%s: track streamID: %d", __func__, (int)mStreamID);
+        ALOGV("%s: track(%p) streamID: %d", __func__, mAudioTrack.get(), (int)mStreamID);
         if (mAudioTrack != nullptr) {
             mAudioTrack->stop();
         }
@@ -232,7 +232,7 @@
     LOG_ALWAYS_FATAL_IF(pairStream == nullptr, "No pair stream!");
     sp<AudioTrack> releaseTracks[2];
     {
-        ALOGV("%s: track streamID: %d", __func__, (int)mStreamID);
+        ALOGV("%s: track streamID: %d", __func__, (int)getStreamID());
         // TODO: Do we really want to force a simultaneous synchronization between
         // the stream and its pair?
 
@@ -390,10 +390,10 @@
 
 void Stream::callback(int event, void* info, int toggle, int tries)
 {
-    ALOGV("%s streamID %d", __func__, (int)mStreamID);
     int32_t activeStreamIDToRestart = 0;
     {
         std::unique_lock lock(mLock);
+        ALOGV("%s track(%p) streamID %d", __func__, mAudioTrack.get(), (int)mStreamID);
 
         if (mAudioTrack == nullptr) {
             // The AudioTrack is either with this stream or its pair.
@@ -403,6 +403,7 @@
             // logic here.
             if (tries < 3) {
                 lock.unlock();
+                ALOGV("%s streamID %d going to pair stream", __func__, (int)mStreamID);
                 getPairStream()->callback(event, info, toggle, tries + 1);
             } else {
                 ALOGW("%s streamID %d cannot find track", __func__, (int)mStreamID);
@@ -449,8 +450,9 @@
 
 void Stream::dump() const
 {
+    // TODO: consider std::try_lock() - ok for now for ALOGV.
     ALOGV("mPairStream=%p, mState=%d, mStreamID=%d, mSoundID=%d, mPriority=%d, mLoop=%d",
-            getPairStream(), mState, (int)mStreamID, mSoundID, mPriority, mLoop);
+            getPairStream(), mState, (int)getStreamID(), getSoundID(), mPriority, mLoop);
 }
 
 } // namespace android::soundpool
diff --git a/media/jni/soundpool/Stream.h b/media/jni/soundpool/Stream.h
index fd92921..d4e5c9f 100644
--- a/media/jni/soundpool/Stream.h
+++ b/media/jni/soundpool/Stream.h
@@ -88,7 +88,7 @@
     void resume(int32_t streamID);
     void autoResume();
     void mute(bool muting);
-    void dump() const;
+    void dump() const NO_THREAD_SAFETY_ANALYSIS; // disable for ALOGV (see func for details).
 
     // returns the pair stream if successful, nullptr otherwise
     Stream* playPairStream();
diff --git a/media/jni/soundpool/StreamManager.cpp b/media/jni/soundpool/StreamManager.cpp
index 9ff4254..5b6494d 100644
--- a/media/jni/soundpool/StreamManager.cpp
+++ b/media/jni/soundpool/StreamManager.cpp
@@ -249,7 +249,8 @@
     } // lock
 
     if (launchThread) {
-        const int32_t id __unused = mThreadPool->launch([this](int32_t id) { run(id); });
+        const int32_t id = mThreadPool->launch([this](int32_t id) { run(id); });
+        (void)id; // avoid clang warning -Wunused-variable -Wused-but-marked-unused
         ALOGV_IF(id != 0, "%s: launched thread %d", __func__, id);
     }
     ALOGV("%s: returning %d", __func__, streamID);
@@ -277,7 +278,8 @@
         sanityCheckQueue_l();
     }
     if (restart) {
-        const int32_t id __unused = mThreadPool->launch([this](int32_t id) { run(id); });
+        const int32_t id = mThreadPool->launch([this](int32_t id) { run(id); });
+        (void)id; // avoid clang warning -Wunused-variable -Wused-but-marked-unused
         ALOGV_IF(id != 0, "%s: launched thread %d", __func__, id);
     }
 }
diff --git a/packages/SettingsLib/RestrictedLockUtils/res/values-da/strings.xml b/packages/SettingsLib/RestrictedLockUtils/res/values-da/strings.xml
index 3a0bc2d..7f10edf 100644
--- a/packages/SettingsLib/RestrictedLockUtils/res/values-da/strings.xml
+++ b/packages/SettingsLib/RestrictedLockUtils/res/values-da/strings.xml
@@ -18,5 +18,5 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="enabled_by_admin" msgid="6630472777476410137">"Aktiveret af administratoren"</string>
-    <string name="disabled_by_admin" msgid="4023569940620832713">"Deaktiveret af administratoren"</string>
+    <string name="disabled_by_admin" msgid="4023569940620832713">"Deaktiveret af administrator"</string>
 </resources>
diff --git a/packages/SettingsLib/RestrictedLockUtils/res/values-eu/strings.xml b/packages/SettingsLib/RestrictedLockUtils/res/values-eu/strings.xml
index aaf607f..2a88124 100644
--- a/packages/SettingsLib/RestrictedLockUtils/res/values-eu/strings.xml
+++ b/packages/SettingsLib/RestrictedLockUtils/res/values-eu/strings.xml
@@ -18,5 +18,5 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="enabled_by_admin" msgid="6630472777476410137">"Administratzaileak gaitu egin du"</string>
-    <string name="disabled_by_admin" msgid="4023569940620832713">"Administratzaileak desgaitu egin du"</string>
+    <string name="disabled_by_admin" msgid="4023569940620832713">"Administratzaileak desgaitu du"</string>
 </resources>
diff --git a/packages/SettingsLib/SearchWidget/res/values-hr/strings.xml b/packages/SettingsLib/SearchWidget/res/values-hr/strings.xml
index 9d83396..34cb8e0 100644
--- a/packages/SettingsLib/SearchWidget/res/values-hr/strings.xml
+++ b/packages/SettingsLib/SearchWidget/res/values-hr/strings.xml
@@ -17,5 +17,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="search_menu" msgid="1914043873178389845">"Pretraži postavke"</string>
+    <string name="search_menu" msgid="1914043873178389845">"Pretražite postavke"</string>
 </resources>
diff --git a/packages/SettingsLib/SearchWidget/res/values-is/strings.xml b/packages/SettingsLib/SearchWidget/res/values-is/strings.xml
index 7ab103b..3378c84 100644
--- a/packages/SettingsLib/SearchWidget/res/values-is/strings.xml
+++ b/packages/SettingsLib/SearchWidget/res/values-is/strings.xml
@@ -17,5 +17,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="search_menu" msgid="1914043873178389845">"Leitarstillingar"</string>
+    <string name="search_menu" msgid="1914043873178389845">"Leita í stillingum"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-vi/strings.xml b/packages/SettingsLib/res/values-vi/strings.xml
index 380cd8e..b501c65 100644
--- a/packages/SettingsLib/res/values-vi/strings.xml
+++ b/packages/SettingsLib/res/values-vi/strings.xml
@@ -196,7 +196,7 @@
     <string name="choose_profile" msgid="343803890897657450">"Chọn hồ sơ"</string>
     <string name="category_personal" msgid="6236798763159385225">"Cá nhân"</string>
     <string name="category_work" msgid="4014193632325996115">"Cơ quan"</string>
-    <string name="development_settings_title" msgid="140296922921597393">"Tùy chọn nhà phát triển"</string>
+    <string name="development_settings_title" msgid="140296922921597393">"Tùy chọn cho nhà phát triển"</string>
     <string name="development_settings_enable" msgid="4285094651288242183">"Bật tùy chọn nhà phát triển"</string>
     <string name="development_settings_summary" msgid="8718917813868735095">"Đặt tùy chọn cho phát triển ứng dụng"</string>
     <string name="development_settings_not_available" msgid="355070198089140951">"Tùy chọn dành cho nhà phát triển không khả dụng cho người dùng này"</string>
diff --git a/packages/SettingsProvider/res/values-fa/strings.xml b/packages/SettingsProvider/res/values-fa/strings.xml
index cc0b557..946e2c0 100644
--- a/packages/SettingsProvider/res/values-fa/strings.xml
+++ b/packages/SettingsProvider/res/values-fa/strings.xml
@@ -19,7 +19,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_label" msgid="4567566098528588863">"تنظیم محل ذخیره"</string>
+    <string name="app_label" msgid="4567566098528588863">"تنظیم محل فضای ذخیره‌سازی"</string>
     <string name="wifi_softap_config_change" msgid="5688373762357941645">"تنظیمات نقطه اتصال تغییر کرده است"</string>
     <string name="wifi_softap_config_change_summary" msgid="8946397286141531087">"برای مشاهده جزئیات ضربه بزنید"</string>
 </resources>
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java
index 028c304..75b680d 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java
@@ -80,6 +80,7 @@
         sBroadcastOnRestore.add(Settings.Secure.UI_NIGHT_MODE);
         sBroadcastOnRestore.add(Settings.Secure.DARK_THEME_CUSTOM_START_TIME);
         sBroadcastOnRestore.add(Settings.Secure.DARK_THEME_CUSTOM_END_TIME);
+        sBroadcastOnRestore.add(Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_NAVBAR_ENABLED);
     }
 
     private interface SettingsLookup {
diff --git a/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsHelperRestoreTest.java b/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsHelperRestoreTest.java
index 54f8688..197788e 100644
--- a/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsHelperRestoreTest.java
+++ b/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsHelperRestoreTest.java
@@ -31,6 +31,7 @@
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.Mockito;
 
 /**
  * Tests for {@link SettingsHelper#restoreValue(Context, ContentResolver, ContentValues, Uri,
@@ -89,7 +90,7 @@
         float restoreSettingValue = defaultSettingValue + 0.5f;
 
         mSettingsHelper.restoreValue(
-                mContext,
+                Mockito.mock(Context.class),
                 mContentResolver,
                 new ContentValues(2),
                 Settings.Secure.getUriFor(settingName),
@@ -132,7 +133,7 @@
         Settings.Secure.putInt(mContentResolver, settingName, configuredSettingValue);
 
         mSettingsHelper.restoreValue(
-                mContext,
+                Mockito.mock(Context.class),
                 mContentResolver,
                 new ContentValues(2),
                 Settings.Secure.getUriFor(settingName),
@@ -154,7 +155,7 @@
 
         int restoreSettingValue = 1;
         mSettingsHelper.restoreValue(
-                mContext,
+                Mockito.mock(Context.class),
                 mContentResolver,
                 new ContentValues(2),
                 Settings.Secure.getUriFor(settingName),
diff --git a/packages/SystemUI/res/drawable/ic_device_air_freshener.xml b/packages/SystemUI/res/drawable/ic_device_air_freshener.xml
new file mode 100644
index 0000000..5050223
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_device_air_freshener.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2020 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
+  -->
+<selector
+    xmlns:android="http://schemas.android.com/apk/res/android">
+  <item
+      android:id="@+id/off"
+      android:state_enabled="false"
+      android:drawable="@drawable/ic_device_air_freshener_off" />
+  <item
+      android:id="@+id/on"
+      android:state_enabled="true"
+      android:drawable="@drawable/ic_device_air_freshener_on" />
+</selector>
diff --git a/packages/SystemUI/res/drawable/ic_device_air_purifier.xml b/packages/SystemUI/res/drawable/ic_device_air_purifier.xml
new file mode 100644
index 0000000..7de46bf
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_device_air_purifier.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2020 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
+  -->
+<selector
+    xmlns:android="http://schemas.android.com/apk/res/android">
+  <item
+      android:id="@+id/off"
+      android:state_enabled="false"
+      android:drawable="@drawable/ic_device_air_purifier_off" />
+  <item
+      android:id="@+id/on"
+      android:state_enabled="true"
+      android:drawable="@drawable/ic_device_air_purifier_on" />
+</selector>
diff --git a/packages/SystemUI/res/drawable/ic_device_blinds.xml b/packages/SystemUI/res/drawable/ic_device_blinds.xml
new file mode 100644
index 0000000..104da7e
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_device_blinds.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2020 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
+  -->
+<animated-selector
+    xmlns:android="http://schemas.android.com/apk/res/android">
+  <item
+      android:id="@+id/off"
+      android:state_enabled="false"
+      android:drawable="@drawable/ic_device_blinds_off" />
+  <item
+      android:id="@+id/on"
+      android:state_enabled="true"
+      android:drawable="@drawable/ic_device_blinds_on" />
+  <transition
+      android:fromId="@id/off"
+      android:toId="@id/on"
+      android:drawable="@drawable/ic_device_blinds_on_anim" />
+  <transition
+      android:fromId="@id/on"
+      android:toId="@id/off"
+      android:drawable="@drawable/ic_device_blinds_off_anim" />
+</animated-selector>
diff --git a/packages/SystemUI/res/drawable/ic_device_blinds_off_anim.xml b/packages/SystemUI/res/drawable/ic_device_blinds_off_anim.xml
new file mode 100644
index 0000000..1eaccf5
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_device_blinds_off_anim.xml
@@ -0,0 +1,140 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2020 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
+  -->
+<animated-vector
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:aapt="http://schemas.android.com/aapt">
+  <aapt:attr name="android:drawable">
+    <vector android:height="24dp" android:width="24dp" android:viewportHeight="24" android:viewportWidth="24">
+      <group android:name="_R_G">
+        <group android:name="_R_G_L_2_G_N_2_T_0" android:translateX="12" android:translateY="12">
+          <group android:name="_R_G_L_2_G_T_1" android:translateX="0" android:translateY="-3.032">
+            <group android:name="_R_G_L_2_G" android:translateY="3.032">
+              <group android:name="_R_G_L_2_C_0_G">
+                <clip-path android:name="_R_G_L_2_C_0" android:pathData=" M10.68 -9.87 C10.68,-9.87 -10.19,-9.87 -10.19,-9.87 C-10.19,-9.87 -10.19,7.92 -10.19,7.92 C-10.19,7.92 10.68,7.92 10.68,7.92 C10.68,7.92 10.68,-9.87 10.68,-9.87c "/>
+                <group android:name="_R_G_L_2_C_0_G_G">
+                  <path android:name="_R_G_L_2_G_G_0_D_0_P_0" android:fillColor="#000000" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M-6 -1 C-6,-1 -6,-6.47 -6,-6.47 C-6,-6.47 6,-6.47 6,-6.47 C6,-6.47 6,-1 6,-1 C6,-1 1,-1 1,-1 C1,-1 1,1.28 1,1.28 C1.38,1.5 1.68,1.84 1.85,2.24 C2.02,2.65 2.05,3.1 1.93,3.53 C1.82,3.95 1.57,4.33 1.22,4.6 C0.87,4.86 0.44,5.01 0,5.01 C-0.44,5.01 -0.87,4.86 -1.22,4.6 C-1.57,4.33 -1.82,3.95 -1.93,3.53 C-2.05,3.1 -2.02,2.65 -1.85,2.24 C-1.68,1.84 -1.38,1.5 -1,1.28 C-1,1.28 -1,-1 -1,-1 C-1,-1 -6,-1 -6,-1c "/>
+                </group>
+              </group>
+            </group>
+          </group>
+        </group>
+        <group android:name="_R_G_L_1_G_N_2_T_0" android:translateX="12" android:translateY="12">
+          <group android:name="_R_G_L_1_G">
+            <path android:name="_R_G_L_1_G_D_0_P_0" android:fillColor="#000000" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M-6 -5.97 C-6,-5.97 -6,6 -6,6 C-6,6 6,6 6,6 C6,6 6,-5.97 6,-5.97 C6,-5.97 -6,-5.97 -6,-5.97c  M8 -8 C8,-8 8,6 8,6 C8,6 10,6 10,6 C10,6 10,8 10,8 C10,8 -10,8 -10,8 C-10,8 -10,6 -10,6 C-10,6 -8,6 -8,6 C-8,6 -8,-8 -8,-8 C-8,-8 8,-8 8,-8c "/>
+          </group>
+        </group>
+        <group android:name="_R_G_L_0_G_N_2_T_0" android:translateX="12" android:translateY="12" android:scaleY="0">
+          <group android:name="_R_G_L_0_G_T_1" android:translateX="0" android:translateY="-13.407">
+            <group android:name="_R_G_L_0_G" android:translateY="3.032">
+              <group android:name="_R_G_L_0_C_0_G">
+                <clip-path android:name="_R_G_L_0_C_0" android:pathData=" M10.68 2.46 C10.68,2.46 -10.19,2.46 -10.19,2.46 C-10.19,2.46 -10.19,20.26 -10.19,20.26 C-10.19,20.26 10.68,20.26 10.68,20.26 C10.68,20.26 10.68,2.46 10.68,2.46c "/>
+                <group android:name="_R_G_L_0_C_0_G_G">
+                  <path android:name="_R_G_L_0_G_G_0_D_0_P_0" android:fillColor="#000000" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M-6 -1 C-6,-1 -6,-3.03 -6,-3.03 C-6,-3.03 6,-3.03 6,-3.03 C6,-3.03 6,-1 6,-1 C6,-1 1,-1 1,-1 C1,-1 1,-0.47 1,-0.47 C1.38,-0.25 1.68,0.09 1.85,0.49 C2.02,0.9 2.05,1.35 1.93,1.78 C1.82,2.2 1.57,2.58 1.22,2.85 C0.87,3.11 0.44,3.26 0,3.26 C-0.44,3.26 -0.87,3.11 -1.22,2.85 C-1.57,2.58 -1.82,2.2 -1.93,1.78 C-2.05,1.35 -2.02,0.9 -1.85,0.49 C-1.68,0.09 -1.38,-0.25 -1,-0.47 C-1,-0.47 -1,-1 -1,-1 C-1,-1 -6,-1 -6,-1c "/>
+                </group>
+              </group>
+            </group>
+          </group>
+        </group>
+      </group>
+      <group android:name="time_group"/>
+    </vector>
+  </aapt:attr>
+  <target android:name="_R_G_L_2_C_0">
+    <aapt:attr name="android:animation">
+      <set android:ordering="together">
+        <objectAnimator android:propertyName="pathData" android:duration="317" android:startOffset="0" android:valueFrom="M10.68 -9.87 C10.68,-9.87 -10.19,-9.87 -10.19,-9.87 C-10.19,-9.87 -10.19,7.92 -10.19,7.92 C-10.19,7.92 10.68,7.92 10.68,7.92 C10.68,7.92 10.68,-9.87 10.68,-9.87c " android:valueTo="M10.68 -19.87 C10.68,-19.87 -10.19,-19.87 -10.19,-19.87 C-10.19,-19.87 -10.19,-6.87 -10.19,-6.87 C-10.19,-6.87 10.68,-6.87 10.68,-6.87 C10.68,-6.87 10.68,-19.87 10.68,-19.87c " android:valueType="pathType">
+          <aapt:attr name="android:interpolator">
+            <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0"/>
+          </aapt:attr>
+        </objectAnimator>
+      </set>
+    </aapt:attr>
+  </target>
+  <target android:name="_R_G_L_2_G_T_1">
+    <aapt:attr name="android:animation">
+      <set android:ordering="together">
+        <objectAnimator android:propertyName="translateXY" android:duration="317" android:startOffset="0" android:propertyXName="translateX" android:propertyYName="translateY" android:pathData="M 0,-3.032C 0,-3.516 0,10.093 0,10.093">
+          <aapt:attr name="android:interpolator">
+            <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0"/>
+          </aapt:attr>
+        </objectAnimator>
+      </set>
+    </aapt:attr>
+  </target>
+  <target android:name="_R_G_L_0_C_0">
+    <aapt:attr name="android:animation">
+      <set android:ordering="together">
+        <objectAnimator android:propertyName="pathData" android:duration="67" android:startOffset="0" android:valueFrom="M10.68 2.46 C10.68,2.46 -10.19,2.46 -10.19,2.46 C-10.19,2.46 -10.19,20.26 -10.19,20.26 C-10.19,20.26 10.68,20.26 10.68,20.26 C10.68,20.26 10.68,2.46 10.68,2.46c " android:valueTo="M10.68 2.46 C10.68,2.46 -10.19,2.46 -10.19,2.46 C-10.19,2.46 -10.19,20.26 -10.19,20.26 C-10.19,20.26 10.68,20.26 10.68,20.26 C10.68,20.26 10.68,2.46 10.68,2.46c " android:valueType="pathType">
+          <aapt:attr name="android:interpolator">
+            <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0"/>
+          </aapt:attr>
+        </objectAnimator>
+        <objectAnimator android:propertyName="pathData" android:duration="433" android:startOffset="67" android:valueFrom="M10.68 2.46 C10.68,2.46 -10.19,2.46 -10.19,2.46 C-10.19,2.46 -10.19,20.26 -10.19,20.26 C-10.19,20.26 10.68,20.26 10.68,20.26 C10.68,20.26 10.68,2.46 10.68,2.46c " android:valueTo="M10.68 -7.87 C10.68,-7.87 -10.19,-7.87 -10.19,-7.87 C-10.19,-7.87 -10.19,9.92 -10.19,9.92 C-10.19,9.92 10.68,9.92 10.68,9.92 C10.68,9.92 10.68,-7.87 10.68,-7.87c " android:valueType="pathType">
+          <aapt:attr name="android:interpolator">
+            <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0"/>
+          </aapt:attr>
+        </objectAnimator>
+      </set>
+    </aapt:attr>
+  </target>
+  <target android:name="_R_G_L_0_G_G_0_D_0_P_0">
+    <aapt:attr name="android:animation">
+      <set android:ordering="together">
+        <objectAnimator android:propertyName="pathData" android:duration="67" android:startOffset="0" android:valueFrom="M-6 -1 C-6,-1 -6,-3.03 -6,-3.03 C-6,-3.03 6,-3.03 6,-3.03 C6,-3.03 6,-1 6,-1 C6,-1 1,-1 1,-1 C1,-1 1,-0.47 1,-0.47 C1.38,-0.25 1.68,0.09 1.85,0.49 C2.02,0.9 2.05,1.35 1.93,1.78 C1.82,2.2 1.57,2.58 1.22,2.85 C0.87,3.11 0.44,3.26 0,3.26 C-0.44,3.26 -0.87,3.11 -1.22,2.85 C-1.57,2.58 -1.82,2.2 -1.93,1.78 C-2.05,1.35 -2.02,0.9 -1.85,0.49 C-1.68,0.09 -1.38,-0.25 -1,-0.47 C-1,-0.47 -1,-1 -1,-1 C-1,-1 -6,-1 -6,-1c " android:valueTo="M-6 -1 C-6,-1 -6,-3.03 -6,-3.03 C-6,-3.03 6,-3.03 6,-3.03 C6,-3.03 6,-1 6,-1 C6,-1 1,-1 1,-1 C1,-1 1,-0.47 1,-0.47 C1.38,-0.25 1.68,0.09 1.85,0.49 C2.02,0.9 2.05,1.35 1.93,1.78 C1.82,2.2 1.57,2.58 1.22,2.85 C0.87,3.11 0.44,3.26 0,3.26 C-0.44,3.26 -0.87,3.11 -1.22,2.85 C-1.57,2.58 -1.82,2.2 -1.93,1.78 C-2.05,1.35 -2.02,0.9 -1.85,0.49 C-1.68,0.09 -1.38,-0.25 -1,-0.47 C-1,-0.47 -1,-1 -1,-1 C-1,-1 -6,-1 -6,-1c " android:valueType="pathType">
+          <aapt:attr name="android:interpolator">
+            <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0"/>
+          </aapt:attr>
+        </objectAnimator>
+        <objectAnimator android:propertyName="pathData" android:duration="433" android:startOffset="67" android:valueFrom="M-6 -1 C-6,-1 -6,-3.03 -6,-3.03 C-6,-3.03 6,-3.03 6,-3.03 C6,-3.03 6,-1 6,-1 C6,-1 1,-1 1,-1 C1,-1 1,-0.47 1,-0.47 C1.38,-0.25 1.68,0.09 1.85,0.49 C2.02,0.9 2.05,1.35 1.93,1.78 C1.82,2.2 1.57,2.58 1.22,2.85 C0.87,3.11 0.44,3.26 0,3.26 C-0.44,3.26 -0.87,3.11 -1.22,2.85 C-1.57,2.58 -1.82,2.2 -1.93,1.78 C-2.05,1.35 -2.02,0.9 -1.85,0.49 C-1.68,0.09 -1.38,-0.25 -1,-0.47 C-1,-0.47 -1,-1 -1,-1 C-1,-1 -6,-1 -6,-1c " android:valueTo="M-6 -1 C-6,-1 -6,-3.03 -6,-3.03 C-6,-3.03 6,-3.03 6,-3.03 C6,-3.03 6,-1 6,-1 C6,-1 1,-1 1,-1 C1,-1 1,1.28 1,1.28 C1.38,1.5 1.68,1.84 1.85,2.24 C2.02,2.65 2.05,3.1 1.93,3.53 C1.82,3.95 1.57,4.33 1.22,4.6 C0.87,4.86 0.44,5.01 0,5.01 C-0.44,5.01 -0.87,4.86 -1.22,4.6 C-1.57,4.33 -1.82,3.95 -1.93,3.53 C-2.05,3.1 -2.02,2.65 -1.85,2.24 C-1.68,1.84 -1.38,1.5 -1,1.28 C-1,1.28 -1,-1 -1,-1 C-1,-1 -6,-1 -6,-1c " android:valueType="pathType">
+          <aapt:attr name="android:interpolator">
+            <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0"/>
+          </aapt:attr>
+        </objectAnimator>
+      </set>
+    </aapt:attr>
+  </target>
+  <target android:name="_R_G_L_0_G_T_1">
+    <aapt:attr name="android:animation">
+      <set android:ordering="together">
+        <objectAnimator android:propertyName="translateXY" android:duration="67" android:startOffset="0" android:propertyXName="translateX" android:propertyYName="translateY" android:pathData="M 0,-13.407C 0,-13.407 0,-12.568 0,-13.407">
+          <aapt:attr name="android:interpolator">
+            <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0"/>
+          </aapt:attr>
+        </objectAnimator>
+        <objectAnimator android:propertyName="translateXY" android:duration="433" android:startOffset="67" android:propertyXName="translateX" android:propertyYName="translateY" android:pathData="M 0,-13.407C 0,-13.407 0,-2.193 0,-3.032">
+          <aapt:attr name="android:interpolator">
+            <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0"/>
+          </aapt:attr>
+        </objectAnimator>
+      </set>
+    </aapt:attr>
+  </target>
+  <target android:name="_R_G_L_0_G_N_2_T_0">
+    <aapt:attr name="android:animation">
+      <set android:ordering="together">
+        <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="67" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+      </set>
+    </aapt:attr>
+  </target>
+  <target android:name="time_group">
+    <aapt:attr name="android:animation">
+      <set android:ordering="together">
+        <objectAnimator android:propertyName="translateX" android:duration="750" android:startOffset="0" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+      </set>
+    </aapt:attr>
+  </target>
+</animated-vector>
diff --git a/packages/SystemUI/res/drawable/ic_device_blinds_on_anim.xml b/packages/SystemUI/res/drawable/ic_device_blinds_on_anim.xml
new file mode 100644
index 0000000..de87f81
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_device_blinds_on_anim.xml
@@ -0,0 +1,141 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2020 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
+  -->
+<animated-vector
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:aapt="http://schemas.android.com/aapt">
+  <aapt:attr name="android:drawable">
+    <vector android:height="24dp" android:width="24dp" android:viewportHeight="24" android:viewportWidth="24">
+      <group android:name="_R_G">
+        <group android:name="_R_G_L_2_G_N_1_T_0" android:translateX="12" android:translateY="12">
+          <group android:name="_R_G_L_2_G_T_1" android:translateX="0" android:translateY="-3.032">
+            <group android:name="_R_G_L_2_G" android:translateY="3.032">
+              <group android:name="_R_G_L_2_C_0_G">
+                <clip-path android:name="_R_G_L_2_C_0" android:pathData=" M10.68 -9.87 C10.68,-9.87 -10.19,-9.87 -10.19,-9.87 C-10.19,-9.87 -10.19,7.92 -10.19,7.92 C-10.19,7.92 10.68,7.92 10.68,7.92 C10.68,7.92 10.68,-9.87 10.68,-9.87c "/>
+                <group android:name="_R_G_L_2_C_0_G_G">
+                  <path android:name="_R_G_L_2_G_G_0_D_0_P_0" android:fillColor="#000000" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M-6 -1 C-6,-1 -6,-3.03 -6,-3.03 C-6,-3.03 6,-3.03 6,-3.03 C6,-3.03 6,-1 6,-1 C6,-1 1,-1 1,-1 C1,-1 1,1.28 1,1.28 C1.38,1.5 1.68,1.84 1.85,2.24 C2.02,2.65 2.05,3.1 1.93,3.53 C1.82,3.95 1.57,4.33 1.22,4.6 C0.87,4.86 0.44,5.01 0,5.01 C-0.44,5.01 -0.87,4.86 -1.22,4.6 C-1.57,4.33 -1.82,3.95 -1.93,3.53 C-2.05,3.1 -2.02,2.65 -1.85,2.24 C-1.68,1.84 -1.38,1.5 -1,1.28 C-1,1.28 -1,-1 -1,-1 C-1,-1 -6,-1 -6,-1c "/>
+                </group>
+              </group>
+            </group>
+          </group>
+        </group>
+        <group android:name="_R_G_L_1_G_N_1_T_0" android:translateX="12" android:translateY="12">
+          <group android:name="_R_G_L_1_G">
+            <path android:name="_R_G_L_1_G_D_0_P_0" android:fillColor="#000000" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M-6 -5.97 C-6,-5.97 -6,6 -6,6 C-6,6 6,6 6,6 C6,6 6,-5.97 6,-5.97 C6,-5.97 -6,-5.97 -6,-5.97c  M8 -8 C8,-8 8,6 8,6 C8,6 10,6 10,6 C10,6 10,8 10,8 C10,8 -10,8 -10,8 C-10,8 -10,6 -10,6 C-10,6 -8,6 -8,6 C-8,6 -8,-8 -8,-8 C-8,-8 8,-8 8,-8c "/>
+          </group>
+        </group>
+        <group android:name="_R_G_L_0_G_N_1_T_0" android:translateX="12" android:translateY="12" android:scaleY="0">
+          <group android:name="_R_G_L_0_G_T_1" android:translateX="0" android:translateY="-8.064">
+            <group android:name="_R_G_L_0_G" android:translateY="3.032">
+              <group android:name="_R_G_L_0_C_0_G">
+                <clip-path android:name="_R_G_L_0_C_0" android:pathData=" M7.78 -2 C7.78,-2 -7.75,-2 -7.75,-2 C-7.75,-2 -7.75,12.15 -7.75,12.15 C-7.75,12.15 7.78,12.15 7.78,12.15 C7.78,12.15 7.78,-2 7.78,-2c "/>
+                <group android:name="_R_G_L_0_C_0_G_G">
+                  <path android:name="_R_G_L_0_G_G_0_D_0_P_0" android:fillColor="#000000" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M-6 -5.37 C-6,-5.37 -6,-6.88 -6,-6.88 C-6,-6.88 6,-6.88 6,-6.88 C6,-6.88 6,-5.37 6,-5.37 C6,-5.37 1,-5.37 1,-5.37 C1,-5.37 1,-5.34 1,-5.34 C1.38,-5.12 1.68,-4.78 1.85,-4.37 C2.02,-3.97 2.05,-3.52 1.93,-3.09 C1.82,-2.67 1.57,-2.29 1.22,-2.02 C0.87,-1.75 0.44,-1.61 0,-1.61 C-0.44,-1.61 -0.87,-1.75 -1.22,-2.02 C-1.57,-2.29 -1.82,-2.67 -1.93,-3.09 C-2.05,-3.52 -2.02,-3.97 -1.85,-4.37 C-1.68,-4.78 -1.38,-5.12 -1,-5.34 C-1,-5.34 -1,-5.37 -1,-5.37 C-1,-5.37 -6,-5.37 -6,-5.37c "/>
+                </group>
+              </group>
+            </group>
+          </group>
+        </group>
+      </group>
+      <group android:name="time_group"/>
+    </vector>
+  </aapt:attr>
+  <target android:name="_R_G_L_2_C_0">
+    <aapt:attr name="android:animation">
+      <set android:ordering="together">
+        <objectAnimator android:propertyName="pathData" android:duration="317" android:startOffset="0" android:valueFrom="M10.68 -9.87 C10.68,-9.87 -10.19,-9.87 -10.19,-9.87 C-10.19,-9.87 -10.19,7.92 -10.19,7.92 C-10.19,7.92 10.68,7.92 10.68,7.92 C10.68,7.92 10.68,-9.87 10.68,-9.87c " android:valueTo="M10.68 -19.87 C10.68,-19.87 -10.19,-19.87 -10.19,-19.87 C-10.19,-19.87 -10.19,-2.08 -10.19,-2.08 C-10.19,-2.08 10.68,-2.08 10.68,-2.08 C10.68,-2.08 10.68,-19.87 10.68,-19.87c " android:valueType="pathType">
+          <aapt:attr name="android:interpolator">
+            <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0"/>
+          </aapt:attr>
+        </objectAnimator>
+      </set>
+    </aapt:attr>
+  </target>
+  <target android:name="_R_G_L_2_G_T_1">
+    <aapt:attr name="android:animation">
+      <set android:ordering="together">
+        <objectAnimator android:propertyName="translateXY" android:duration="317" android:startOffset="0" android:propertyXName="translateX" android:propertyYName="translateY" android:pathData="M 0,-3.032C 0,-3.516 0,6.968 0,6.968">
+          <aapt:attr name="android:interpolator">
+            <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0"/>
+          </aapt:attr>
+        </objectAnimator>
+      </set>
+    </aapt:attr>
+  </target>
+  <target android:name="_R_G_L_0_C_0">
+    <aapt:attr name="android:animation">
+      <set android:ordering="together">
+        <objectAnimator android:propertyName="pathData" android:duration="67" android:startOffset="0" android:valueFrom="M7.78 -2 C7.78,-2 -7.75,-2 -7.75,-2 C-7.75,-2 -7.75,12.15 -7.75,12.15 C-7.75,12.15 7.78,12.15 7.78,12.15 C7.78,12.15 7.78,-2 7.78,-2c " android:valueTo="M7.78 -2 C7.78,-2 -7.75,-2 -7.75,-2 C-7.75,-2 -7.75,12.15 -7.75,12.15 C-7.75,12.15 7.78,12.15 7.78,12.15 C7.78,12.15 7.78,-2 7.78,-2c " android:valueType="pathType">
+          <aapt:attr name="android:interpolator">
+            <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0"/>
+          </aapt:attr>
+        </objectAnimator>
+        <objectAnimator android:propertyName="pathData" android:duration="433" android:startOffset="67" android:valueFrom="M7.78 -2 C7.78,-2 -7.75,-2 -7.75,-2 C-7.75,-2 -7.75,12.15 -7.75,12.15 C-7.75,12.15 7.78,12.15 7.78,12.15 C7.78,12.15 7.78,-2 7.78,-2c " android:valueTo="M7.78 -7 C7.78,-7 -7.75,-7 -7.75,-7 C-7.75,-7 -7.75,7.15 -7.75,7.15 C-7.75,7.15 7.78,7.15 7.78,7.15 C7.78,7.15 7.78,-7 7.78,-7c " android:valueType="pathType">
+          <aapt:attr name="android:interpolator">
+            <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0"/>
+          </aapt:attr>
+        </objectAnimator>
+      </set>
+    </aapt:attr>
+  </target>
+  <target android:name="_R_G_L_0_G_G_0_D_0_P_0">
+    <aapt:attr name="android:animation">
+      <set android:ordering="together">
+        <objectAnimator android:propertyName="pathData" android:duration="67" android:startOffset="0" android:valueFrom="M-6 -5.37 C-6,-5.37 -6,-6.88 -6,-6.88 C-6,-6.88 6,-6.88 6,-6.88 C6,-6.88 6,-5.37 6,-5.37 C6,-5.37 1,-5.37 1,-5.37 C1,-5.37 1,-5.34 1,-5.34 C1.38,-5.12 1.68,-4.78 1.85,-4.37 C2.02,-3.97 2.05,-3.52 1.93,-3.09 C1.82,-2.67 1.57,-2.29 1.22,-2.02 C0.87,-1.75 0.44,-1.61 0,-1.61 C-0.44,-1.61 -0.87,-1.75 -1.22,-2.02 C-1.57,-2.29 -1.82,-2.67 -1.93,-3.09 C-2.05,-3.52 -2.02,-3.97 -1.85,-4.37 C-1.68,-4.78 -1.38,-5.12 -1,-5.34 C-1,-5.34 -1,-5.37 -1,-5.37 C-1,-5.37 -6,-5.37 -6,-5.37c " android:valueTo="M-6 -5.37 C-6,-5.37 -6,-6.88 -6,-6.88 C-6,-6.88 6,-6.88 6,-6.88 C6,-6.88 6,-5.37 6,-5.37 C6,-5.37 1,-5.37 1,-5.37 C1,-5.37 1,-5.34 1,-5.34 C1.38,-5.12 1.68,-4.78 1.85,-4.37 C2.02,-3.97 2.05,-3.52 1.93,-3.09 C1.82,-2.67 1.57,-2.29 1.22,-2.02 C0.87,-1.75 0.44,-1.61 0,-1.61 C-0.44,-1.61 -0.87,-1.75 -1.22,-2.02 C-1.57,-2.29 -1.82,-2.67 -1.93,-3.09 C-2.05,-3.52 -2.02,-3.97 -1.85,-4.37 C-1.68,-4.78 -1.38,-5.12 -1,-5.34 C-1,-5.34 -1,-5.37 -1,-5.37 C-1,-5.37 -6,-5.37 -6,-5.37c " android:valueType="pathType">
+          <aapt:attr name="android:interpolator">
+            <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0"/>
+          </aapt:attr>
+        </objectAnimator>
+        <objectAnimator android:propertyName="pathData" android:duration="433" android:startOffset="67" android:valueFrom="M-6 -5.37 C-6,-5.37 -6,-6.88 -6,-6.88 C-6,-6.88 6,-6.88 6,-6.88 C6,-6.88 6,-5.37 6,-5.37 C6,-5.37 1,-5.37 1,-5.37 C1,-5.37 1,-5.34 1,-5.34 C1.38,-5.12 1.68,-4.78 1.85,-4.37 C2.02,-3.97 2.05,-3.52 1.93,-3.09 C1.82,-2.67 1.57,-2.29 1.22,-2.02 C0.87,-1.75 0.44,-1.61 0,-1.61 C-0.44,-1.61 -0.87,-1.75 -1.22,-2.02 C-1.57,-2.29 -1.82,-2.67 -1.93,-3.09 C-2.05,-3.52 -2.02,-3.97 -1.85,-4.37 C-1.68,-4.78 -1.38,-5.12 -1,-5.34 C-1,-5.34 -1,-5.37 -1,-5.37 C-1,-5.37 -6,-5.37 -6,-5.37c " android:valueTo="M-6 -1 C-6,-1 -6,-6.5 -6,-6.5 C-6,-6.5 6,-6.5 6,-6.5 C6,-6.5 6,-1 6,-1 C6,-1 1,-1 1,-1 C1,-1 1,1.28 1,1.28 C1.38,1.5 1.68,1.84 1.85,2.24 C2.02,2.65 2.05,3.1 1.93,3.53 C1.82,3.95 1.57,4.33 1.22,4.6 C0.87,4.86 0.44,5.01 0,5.01 C-0.44,5.01 -0.87,4.86 -1.22,4.6 C-1.57,4.33 -1.82,3.95 -1.93,3.53 C-2.05,3.1 -2.02,2.65 -1.85,2.24 C-1.68,1.84 -1.38,1.5 -1,1.28 C-1,1.28 -1,-1 -1,-1 C-1,-1 -6,-1 -6,-1c " android:valueType="pathType">
+          <aapt:attr name="android:interpolator">
+            <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0"/>
+          </aapt:attr>
+        </objectAnimator>
+      </set>
+    </aapt:attr>
+  </target>
+  <target android:name="_R_G_L_0_G_T_1">
+    <aapt:attr name="android:animation">
+
+      <set android:ordering="together">
+        <objectAnimator android:propertyName="translateXY" android:duration="67" android:startOffset="0" android:propertyXName="translateX" android:propertyYName="translateY" android:pathData="M 0,-8.064C 0,-8.064 0,-8.903 0,-8.064">
+          <aapt:attr name="android:interpolator">
+            <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0"/>
+          </aapt:attr>
+        </objectAnimator>
+        <objectAnimator android:propertyName="translateXY" android:duration="433" android:startOffset="67" android:propertyXName="translateX" android:propertyYName="translateY" android:pathData="M 0,-8.064C 0,-8.064 0,-3.871 0,-3.032">
+          <aapt:attr name="android:interpolator">
+            <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0"/>
+          </aapt:attr>
+        </objectAnimator>
+      </set>
+    </aapt:attr>
+  </target>
+  <target android:name="_R_G_L_0_G_N_1_T_0">
+    <aapt:attr name="android:animation">
+      <set android:ordering="together">
+        <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="67" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+      </set>
+    </aapt:attr>
+  </target>
+  <target android:name="time_group">
+    <aapt:attr name="android:animation">
+      <set android:ordering="together">
+        <objectAnimator android:propertyName="translateX" android:duration="750" android:startOffset="0" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+      </set>
+    </aapt:attr>
+  </target>
+</animated-vector>
diff --git a/packages/SystemUI/res/drawable/ic_device_camera.xml b/packages/SystemUI/res/drawable/ic_device_camera.xml
new file mode 100644
index 0000000..a76142a
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_device_camera.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2020 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
+  -->
+<animated-selector
+    xmlns:android="http://schemas.android.com/apk/res/android">
+  <item
+      android:id="@+id/off"
+      android:state_enabled="false"
+      android:drawable="@drawable/ic_device_camera_off" />
+  <item
+      android:id="@+id/on"
+      android:state_enabled="true"
+      android:drawable="@drawable/ic_device_camera_on" />
+  <transition
+      android:fromId="@id/off"
+      android:toId="@id/on"
+      android:drawable="@drawable/ic_device_camera_on_anim" />
+  <transition
+      android:fromId="@id/on"
+      android:toId="@id/off"
+      android:drawable="@drawable/ic_device_camera_off_anim" />
+</animated-selector>
diff --git a/packages/SystemUI/res/drawable/ic_device_camera_off_anim.xml b/packages/SystemUI/res/drawable/ic_device_camera_off_anim.xml
new file mode 100644
index 0000000..32d1a0e
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_device_camera_off_anim.xml
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2020 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
+  -->
+<animated-vector
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:aapt="http://schemas.android.com/aapt">
+  <aapt:attr name="android:drawable">
+    <vector android:height="24dp" android:width="24dp" android:viewportHeight="24" android:viewportWidth="24">
+      <group android:name="_R_G">
+        <group android:name="_R_G_L_1_G_N_1_T_0" android:translateX="12" android:translateY="12">
+          <group android:name="_R_G_L_1_G">
+            <path android:name="_R_G_L_1_G_D_0_P_0" android:fillColor="#000000" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M4 6 C4,6 4,-2.31 4,-2.31 C4,-2.31 4,-6 4,-6 C4,-6 -8,-6 -8,-6 C-8,-6 -8,6 -8,6 C-8,6 4,6 4,6c  M6 -6 C6,-6 6,-1.52 6,-1.52 C6,-1.52 10,-5.5 10,-5.5 C10,-5.5 10,5.5 10,5.5 C10,5.5 6,1.52 6,1.52 C6,1.52 6,6 6,6 C6,6.53 5.79,7.04 5.41,7.41 C5.04,7.79 4.53,8 4,8 C4,8 -8,8 -8,8 C-8.53,8 -9.04,7.79 -9.41,7.41 C-9.79,7.04 -10,6.53 -10,6 C-10,6 -10,-6 -10,-6 C-10,-6.53 -9.79,-7.04 -9.41,-7.41 C-9.04,-7.79 -8.53,-8 -8,-8 C-8,-8 4,-8 4,-8 C4.53,-8 5.04,-7.79 5.41,-7.41 C5.79,-7.04 6,-6.53 6,-6c "/>
+          </group>
+        </group>
+        <group android:name="_R_G_L_0_G" android:translateX="12" android:translateY="12">
+          <group android:name="_R_G_L_0_C_0_G">
+            <clip-path android:name="_R_G_L_0_C_0" android:pathData=" M-2.25 -12.33 C-8.89,-12.33 -14.27,-6.95 -14.27,-0.31 C-14.27,6.32 -8.89,11.71 -2.25,11.71 C4.39,11.71 9.77,6.32 9.77,-0.31 C9.77,-6.95 4.39,-12.33 -2.25,-12.33c "/>
+            <group android:name="_R_G_L_0_C_0_G_G">
+              <path android:name="_R_G_L_0_G_G_0_D_0_P_0" android:fillColor="#000000" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M6 -6 C6,-6 6,-1.52 6,-1.52 C6,-1.52 10,-5.5 10,-5.5 C10,-5.5 10,5.5 10,5.5 C10,5.5 6,1.52 6,1.52 C6,1.52 6,6 6,6 C6,6.53 5.79,7.04 5.41,7.41 C5.04,7.79 4.53,8 4,8 C4,8 -8,8 -8,8 C-8.53,8 -9.04,7.79 -9.41,7.41 C-9.79,7.04 -10,6.53 -10,6 C-10,6 -10,-6 -10,-6 C-10,-6.53 -9.79,-7.04 -9.41,-7.41 C-9.04,-7.79 -8.53,-8 -8,-8 C-8,-8 4,-8 4,-8 C4.53,-8 5.04,-7.79 5.41,-7.41 C5.79,-7.04 6,-6.53 6,-6c "/>
+            </group>
+          </group>
+        </group>
+      </group>
+      <group android:name="time_group"/>
+    </vector>
+  </aapt:attr>
+  <target android:name="_R_G_L_0_C_0">
+    <aapt:attr name="android:animation">
+      <set android:ordering="together">
+        <objectAnimator android:propertyName="pathData" android:duration="500" android:startOffset="0" android:valueFrom="M-2.25 -12.33 C-8.89,-12.33 -14.27,-6.95 -14.27,-0.31 C-14.27,6.32 -8.89,11.71 -2.25,11.71 C4.39,11.71 9.77,6.32 9.77,-0.31 C9.77,-6.95 4.39,-12.33 -2.25,-12.33c " android:valueTo="M-1.84 0.09 C-1.84,0.09 -1.84,0.09 -1.84,0.09 C-1.84,0.09 -1.84,0.09 -1.84,0.09 C-1.84,0.09 -1.84,0.09 -1.84,0.09 C-1.84,0.09 -1.84,0.09 -1.84,0.09c " android:valueType="pathType">
+          <aapt:attr name="android:interpolator">
+            <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0"/>
+          </aapt:attr>
+        </objectAnimator>
+      </set>
+    </aapt:attr>
+  </target>
+  <target android:name="time_group">
+    <aapt:attr name="android:animation">
+      <set android:ordering="together">
+        <objectAnimator android:propertyName="translateX" android:duration="750" android:startOffset="0" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+      </set>
+    </aapt:attr>
+  </target>
+</animated-vector>
diff --git a/packages/SystemUI/res/drawable/ic_device_camera_on_anim.xml b/packages/SystemUI/res/drawable/ic_device_camera_on_anim.xml
new file mode 100644
index 0000000..1a1a3ff
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_device_camera_on_anim.xml
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2020 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
+  -->
+<animated-vector
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:aapt="http://schemas.android.com/aapt">
+  <aapt:attr name="android:drawable">
+    <vector android:height="24dp" android:width="24dp" android:viewportHeight="24" android:viewportWidth="24">
+      <group android:name="_R_G">
+        <group android:name="_R_G_L_1_G_N_1_T_0" android:translateX="12" android:translateY="12">
+          <group android:name="_R_G_L_1_G">
+            <path android:name="_R_G_L_1_G_D_0_P_0" android:fillColor="#000000" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M4 6 C4,6 4,-2.31 4,-2.31 C4,-2.31 4,-6 4,-6 C4,-6 -8,-6 -8,-6 C-8,-6 -8,6 -8,6 C-8,6 4,6 4,6c  M6 -6 C6,-6 6,-1.52 6,-1.52 C6,-1.52 10,-5.5 10,-5.5 C10,-5.5 10,5.5 10,5.5 C10,5.5 6,1.52 6,1.52 C6,1.52 6,6 6,6 C6,6.53 5.79,7.04 5.41,7.41 C5.04,7.79 4.53,8 4,8 C4,8 -8,8 -8,8 C-8.53,8 -9.04,7.79 -9.41,7.41 C-9.79,7.04 -10,6.53 -10,6 C-10,6 -10,-6 -10,-6 C-10,-6.53 -9.79,-7.04 -9.41,-7.41 C-9.04,-7.79 -8.53,-8 -8,-8 C-8,-8 4,-8 4,-8 C4.53,-8 5.04,-7.79 5.41,-7.41 C5.79,-7.04 6,-6.53 6,-6c "/>
+          </group>
+        </group>
+        <group android:name="_R_G_L_0_G_N_1_T_0" android:translateX="12" android:translateY="12">
+          <group android:name="_R_G_L_0_G">
+            <group android:name="_R_G_L_0_C_0_G">
+              <clip-path android:name="_R_G_L_0_C_0" android:pathData=" M-1.84 0.09 C-1.84,0.09 -1.84,0.09 -1.84,0.09 C-1.84,0.09 -1.84,0.09 -1.84,0.09 C-1.84,0.09 -1.84,0.09 -1.84,0.09 C-1.84,0.09 -1.84,0.09 -1.84,0.09c "/>
+              <group android:name="_R_G_L_0_C_0_G_G">
+                <path android:name="_R_G_L_0_G_G_0_D_0_P_0" android:fillColor="#000000" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M6 -6 C6,-6 6,-1.52 6,-1.52 C6,-1.52 10,-5.5 10,-5.5 C10,-5.5 10,5.5 10,5.5 C10,5.5 6,1.52 6,1.52 C6,1.52 6,6 6,6 C6,6.53 5.79,7.04 5.41,7.41 C5.04,7.79 4.53,8 4,8 C4,8 -8,8 -8,8 C-8.53,8 -9.04,7.79 -9.41,7.41 C-9.79,7.04 -10,6.53 -10,6 C-10,6 -10,-6 -10,-6 C-10,-6.53 -9.79,-7.04 -9.41,-7.41 C-9.04,-7.79 -8.53,-8 -8,-8 C-8,-8 4,-8 4,-8 C4.53,-8 5.04,-7.79 5.41,-7.41 C5.79,-7.04 6,-6.53 6,-6c "/>
+              </group>
+            </group>
+          </group>
+        </group>
+      </group>
+      <group android:name="time_group"/>
+    </vector>
+  </aapt:attr>
+  <target android:name="_R_G_L_0_C_0">
+    <aapt:attr name="android:animation">
+      <set android:ordering="together">
+        <objectAnimator android:propertyName="pathData" android:duration="500" android:startOffset="0" android:valueFrom="M-1.84 0.09 C-1.84,0.09 -1.84,0.09 -1.84,0.09 C-1.84,0.09 -1.84,0.09 -1.84,0.09 C-1.84,0.09 -1.84,0.09 -1.84,0.09 C-1.84,0.09 -1.84,0.09 -1.84,0.09c " android:valueTo="M-2.25 -12.33 C-8.89,-12.33 -14.27,-6.95 -14.27,-0.31 C-14.27,6.32 -8.89,11.71 -2.25,11.71 C4.39,11.71 9.77,6.32 9.77,-0.31 C9.77,-6.95 4.39,-12.33 -2.25,-12.33c " android:valueType="pathType">
+          <aapt:attr name="android:interpolator">
+            <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0"/>
+          </aapt:attr>
+        </objectAnimator>
+      </set>
+    </aapt:attr>
+  </target>
+  <target android:name="time_group">
+    <aapt:attr name="android:animation">
+      <set android:ordering="together">
+        <objectAnimator android:propertyName="translateX" android:duration="750" android:startOffset="0" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+      </set>
+    </aapt:attr>
+  </target>
+</animated-vector>
diff --git a/packages/SystemUI/res/drawable/ic_device_cooking.xml b/packages/SystemUI/res/drawable/ic_device_cooking.xml
new file mode 100644
index 0000000..e3922e2
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_device_cooking.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2020 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
+  -->
+<selector
+    xmlns:android="http://schemas.android.com/apk/res/android">
+  <item
+      android:id="@+id/off"
+      android:state_enabled="false"
+      android:drawable="@drawable/ic_device_cooking_off" />
+  <item
+      android:id="@+id/on"
+      android:state_enabled="true"
+      android:drawable="@drawable/ic_device_cooking_on" />
+</selector>
diff --git a/packages/SystemUI/res/drawable/ic_device_dishwasher.xml b/packages/SystemUI/res/drawable/ic_device_dishwasher.xml
new file mode 100644
index 0000000..cc7f7f9
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_device_dishwasher.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2020 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
+  -->
+<selector
+    xmlns:android="http://schemas.android.com/apk/res/android">
+  <item
+      android:id="@+id/off"
+      android:state_enabled="false"
+      android:drawable="@drawable/ic_device_dishwasher_off" />
+  <item
+      android:id="@+id/on"
+      android:state_enabled="true"
+      android:drawable="@drawable/ic_device_dishwasher_on" />
+</selector>
diff --git a/packages/SystemUI/res/drawable/ic_device_display.xml b/packages/SystemUI/res/drawable/ic_device_display.xml
new file mode 100644
index 0000000..9a2ee29
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_device_display.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2020 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
+  -->
+<selector
+    xmlns:android="http://schemas.android.com/apk/res/android">
+  <item
+      android:id="@+id/off"
+      android:state_enabled="false"
+      android:drawable="@drawable/ic_device_display_off" />
+  <item
+      android:id="@+id/on"
+      android:state_enabled="true"
+      android:drawable="@drawable/ic_device_display_on" />
+</selector>
diff --git a/packages/SystemUI/res/drawable/ic_device_door.xml b/packages/SystemUI/res/drawable/ic_device_door.xml
new file mode 100644
index 0000000..367f97f
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_device_door.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2020 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
+  -->
+<selector
+    xmlns:android="http://schemas.android.com/apk/res/android">
+  <item
+      android:id="@+id/off"
+      android:state_enabled="false"
+      android:drawable="@drawable/ic_device_door_off" />
+  <item
+      android:id="@+id/on"
+      android:state_enabled="true"
+      android:drawable="@drawable/ic_device_door_on" />
+</selector>
diff --git a/packages/SystemUI/res/drawable/ic_device_doorbell.xml b/packages/SystemUI/res/drawable/ic_device_doorbell.xml
new file mode 100644
index 0000000..6f96a1b
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_device_doorbell.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2020 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
+  -->
+<selector
+    xmlns:android="http://schemas.android.com/apk/res/android">
+  <item
+      android:id="@+id/off"
+      android:state_enabled="false"
+      android:drawable="@drawable/ic_device_doorbell_off" />
+  <item
+      android:id="@+id/on"
+      android:state_enabled="true"
+      android:drawable="@drawable/ic_device_doorbell_on" />
+</selector>
diff --git a/packages/SystemUI/res/drawable/ic_device_drawer.xml b/packages/SystemUI/res/drawable/ic_device_drawer.xml
new file mode 100644
index 0000000..0f86f90
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_device_drawer.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2020 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
+  -->
+<selector
+    xmlns:android="http://schemas.android.com/apk/res/android">
+  <item
+      android:id="@+id/off"
+      android:state_enabled="false"
+      android:drawable="@drawable/ic_device_drawer_off" />
+  <item
+      android:id="@+id/on"
+      android:state_enabled="true"
+      android:drawable="@drawable/ic_device_drawer_on" />
+</selector>
diff --git a/packages/SystemUI/res/drawable/ic_device_fan.xml b/packages/SystemUI/res/drawable/ic_device_fan.xml
new file mode 100644
index 0000000..34dc712
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_device_fan.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2020 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
+  -->
+<animated-selector
+    xmlns:android="http://schemas.android.com/apk/res/android">
+  <item
+      android:id="@+id/off"
+      android:state_enabled="false"
+      android:drawable="@drawable/ic_device_fan_off" />
+  <item
+      android:id="@+id/on"
+      android:state_enabled="true"
+      android:drawable="@drawable/ic_device_fan_on" />
+  <transition
+      android:fromId="@id/off"
+      android:toId="@id/on"
+      android:drawable="@drawable/ic_device_fan_on_anim" />
+  <transition
+      android:fromId="@id/on"
+      android:toId="@id/off"
+      android:drawable="@drawable/ic_device_fan_off_anim" />
+</animated-selector>
diff --git a/packages/SystemUI/res/drawable/ic_device_fan_off_anim.xml b/packages/SystemUI/res/drawable/ic_device_fan_off_anim.xml
new file mode 100644
index 0000000..189d85a
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_device_fan_off_anim.xml
@@ -0,0 +1,91 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2020 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
+  -->
+<animated-vector
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:aapt="http://schemas.android.com/aapt">
+  <aapt:attr name="android:drawable">
+    <vector android:height="24dp" android:width="24dp" android:viewportHeight="24" android:viewportWidth="24">
+      <group android:name="_R_G">
+        <group android:name="_R_G_L_1_G_N_2_N_1_T_0" android:translateX="12" android:translateY="12">
+          <group android:name="_R_G_L_1_G_N_2_T_0" android:rotation="180">
+            <group android:name="_R_G_L_1_G" android:rotation="360">
+              <path android:name="_R_G_L_1_G_D_0_P_0" android:fillColor="#000000" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M5.4 0.25 C5.99,0.64 6.5,1.14 6.89,1.73 C6.89,1.73 6.89,1.73 6.89,1.73 C6.96,1.84 7.07,1.93 7.19,1.97 C7.31,2.02 7.45,2.03 7.57,1.99 C7.7,1.95 7.81,1.87 7.89,1.76 C7.97,1.66 8,1.53 8,1.39 C8.07,0.81 7.99,0.22 7.78,-0.33 C7.57,-0.88 7.23,-1.37 6.78,-1.76 C6.54,-1.91 6.27,-1.99 5.99,-2 C5.71,-2.01 5.42,-1.95 5.17,-1.82 C5.17,-1.82 3.29,-1.14 3.29,-1.14 C3.36,-0.94 3.42,-0.73 3.45,-0.52 C4.14,-0.4 4.81,-0.14 5.4,0.25c  M0.33 7.78 C0.88,7.57 1.37,7.22 1.76,6.78 C1.76,6.78 1.76,6.78 1.76,6.78 C1.9,6.54 1.99,6.27 2,5.99 C2.01,5.71 1.95,5.42 1.82,5.17 C1.82,5.17 1.14,3.29 1.14,3.29 C0.94,3.36 0.73,3.42 0.52,3.45 C0.4,4.14 0.13,4.81 -0.25,5.4 C-0.64,5.99 -1.14,6.5 -1.73,6.89 C-1.84,6.96 -1.93,7.07 -1.97,7.19 C-2.02,7.31 -2.02,7.45 -1.99,7.57 C-1.95,7.7 -1.87,7.81 -1.76,7.89 C-1.66,7.97 -1.53,8 -1.39,8 C-0.81,8.07 -0.22,7.99 0.33,7.78c  M-5.99 2 C-5.7,2.01 -5.42,1.95 -5.17,1.82 C-5.17,1.82 -3.29,1.14 -3.29,1.14 C-3.36,0.94 -3.42,0.73 -3.45,0.52 C-4.14,0.4 -4.81,0.14 -5.4,-0.25 C-5.99,-0.64 -6.5,-1.14 -6.89,-1.73 C-6.96,-1.84 -7.06,-1.93 -7.19,-1.97 C-7.31,-2.02 -7.45,-2.02 -7.57,-1.99 C-7.7,-1.95 -7.81,-1.87 -7.89,-1.76 C-7.96,-1.66 -8,-1.53 -8,-1.39 C-8.07,-0.81 -7.99,-0.22 -7.78,0.33 C-7.57,0.88 -7.23,1.37 -6.78,1.75 C-6.54,1.9 -6.27,1.99 -5.99,2c  M-0.33 -7.78 C-0.88,-7.57 -1.37,-7.23 -1.75,-6.78 C-1.9,-6.54 -1.99,-6.27 -2,-5.99 C-2.01,-5.7 -1.95,-5.42 -1.82,-5.17 C-1.82,-5.17 -1.14,-3.29 -1.14,-3.29 C-0.94,-3.36 -0.73,-3.41 -0.52,-3.45 C-0.4,-4.14 -0.13,-4.81 0.25,-5.4 C0.64,-5.99 1.14,-6.5 1.73,-6.89 C1.84,-6.96 1.93,-7.06 1.97,-7.19 C2.02,-7.31 2.03,-7.45 1.99,-7.57 C1.95,-7.7 1.87,-7.81 1.76,-7.89 C1.66,-7.96 1.53,-8 1.39,-8 C0.81,-8.07 0.22,-7.99 -0.33,-7.78c  M-0.83 1.25 C-0.59,1.41 -0.3,1.5 0,1.5 C0.4,1.5 0.78,1.34 1.06,1.06 C1.34,0.78 1.5,0.4 1.5,0 C1.5,-0.3 1.41,-0.59 1.25,-0.83 C1.08,-1.08 0.85,-1.27 0.57,-1.39 C0.3,-1.5 0,-1.53 -0.29,-1.47 C-0.58,-1.41 -0.85,-1.27 -1.06,-1.06 C-1.27,-0.85 -1.41,-0.58 -1.47,-0.29 C-1.53,0 -1.5,0.3 -1.39,0.57 C-1.27,0.85 -1.08,1.08 -0.83,1.25c  M2.06 -2.82 C2.06,-2.82 4.35,-3.64 4.35,-3.64 C6.99,-4.84 10,-3 10,1.39 C10,1.96 9.83,2.5 9.49,2.95 C9.16,3.41 8.69,3.74 8.15,3.9 C7.62,4.06 7.04,4.05 6.51,3.86 C5.99,3.67 5.54,3.31 5.23,2.84 C4.75,2.13 4.01,1.64 3.16,1.48 C3.07,1.68 2.95,1.87 2.82,2.06 C2.82,2.06 3.64,4.35 3.64,4.35 C4.84,6.99 3.01,10 -1.39,10 C-1.95,10 -2.5,9.83 -2.95,9.49 C-3.41,9.16 -3.74,8.69 -3.9,8.15 C-4.06,7.62 -4.05,7.04 -3.86,6.51 C-3.67,5.99 -3.31,5.54 -2.84,5.23 C-2.13,4.75 -1.64,4.01 -1.47,3.16 C-1.68,3.07 -1.87,2.95 -2.06,2.82 C-2.06,2.82 -4.34,3.64 -4.34,3.64 C-6.99,4.84 -10,3.01 -10,-1.39 C-10,-1.95 -9.83,-2.5 -9.49,-2.95 C-9.16,-3.41 -8.69,-3.74 -8.15,-3.9 C-7.62,-4.06 -7.04,-4.05 -6.51,-3.86 C-5.99,-3.66 -5.53,-3.31 -5.23,-2.84 C-4.75,-2.13 -4,-1.64 -3.16,-1.47 C-3.07,-1.68 -2.95,-1.87 -2.82,-2.06 C-2.82,-2.06 -3.64,-4.34 -3.64,-4.34 C-4.84,-6.99 -3.01,-10 1.39,-10 C1.96,-10 2.5,-9.83 2.95,-9.49 C3.41,-9.16 3.74,-8.69 3.9,-8.15 C4.06,-7.62 4.05,-7.04 3.86,-6.51 C3.67,-5.99 3.31,-5.53 2.84,-5.23 C2.13,-4.75 1.64,-4 1.47,-3.16 C1.68,-3.07 1.87,-2.95 2.06,-2.82c "/>
+            </group>
+          </group>
+        </group>
+        <group android:name="_R_G_L_0_G_N_1_T_0" android:translateX="12" android:translateY="12">
+          <group android:name="_R_G_L_0_G" android:rotation="180">
+            <group android:name="_R_G_L_0_C_0_G">
+              <clip-path android:name="_R_G_L_0_C_0" android:pathData=" M0.25 -12 C-6.37,-12.14 -11.86,-6.88 -12,-0.25 C-12.14,6.37 -6.88,11.86 -0.25,12 C6.37,12.14 11.86,6.88 12,0.25 C12.14,-6.37 6.88,-11.86 0.25,-12c "/>
+              <group android:name="_R_G_L_0_C_0_G_G">
+                <path android:name="_R_G_L_0_G_G_0_D_0_P_0" android:fillColor="#000000" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M-0.83 1.25 C-0.59,1.41 -0.3,1.5 0,1.5 C0.4,1.5 0.78,1.34 1.06,1.06 C1.34,0.78 1.5,0.4 1.5,0 C1.5,-0.3 1.41,-0.59 1.25,-0.83 C1.08,-1.08 0.85,-1.27 0.57,-1.39 C0.3,-1.5 0,-1.53 -0.29,-1.47 C-0.58,-1.41 -0.85,-1.27 -1.06,-1.06 C-1.27,-0.85 -1.41,-0.58 -1.47,-0.29 C-1.53,0 -1.5,0.3 -1.39,0.57 C-1.27,0.85 -1.08,1.08 -0.83,1.25c  M2.06 -2.82 C2.06,-2.82 4.35,-3.64 4.35,-3.64 C6.99,-4.84 10,-3 10,1.39 C10,1.96 9.83,2.5 9.49,2.95 C9.16,3.41 8.69,3.74 8.15,3.9 C7.62,4.06 7.04,4.05 6.51,3.86 C5.99,3.67 5.54,3.31 5.23,2.84 C4.75,2.13 4.01,1.64 3.16,1.48 C3.07,1.68 2.95,1.87 2.82,2.06 C2.82,2.06 3.64,4.35 3.64,4.35 C4.84,6.99 3.01,10 -1.39,10 C-1.95,10 -2.5,9.83 -2.95,9.49 C-3.41,9.16 -3.74,8.69 -3.9,8.15 C-4.06,7.62 -4.05,7.04 -3.86,6.51 C-3.67,5.99 -3.31,5.54 -2.84,5.23 C-2.13,4.75 -1.64,4.01 -1.47,3.16 C-1.68,3.07 -1.87,2.95 -2.06,2.82 C-2.06,2.82 -4.34,3.64 -4.34,3.64 C-6.99,4.84 -10,3.01 -10,-1.39 C-10,-1.95 -9.83,-2.5 -9.49,-2.95 C-9.16,-3.41 -8.69,-3.74 -8.15,-3.9 C-7.62,-4.06 -7.04,-4.05 -6.51,-3.86 C-5.99,-3.66 -5.53,-3.31 -5.23,-2.84 C-4.75,-2.13 -4,-1.64 -3.16,-1.47 C-3.07,-1.68 -2.95,-1.87 -2.82,-2.06 C-2.82,-2.06 -3.64,-4.34 -3.64,-4.34 C-4.84,-6.99 -3.01,-10 1.39,-10 C1.96,-10 2.5,-9.83 2.95,-9.49 C3.41,-9.16 3.74,-8.69 3.9,-8.15 C4.06,-7.62 4.05,-7.04 3.86,-6.51 C3.67,-5.99 3.31,-5.53 2.84,-5.23 C2.13,-4.75 1.64,-4 1.47,-3.16 C1.68,-3.07 1.87,-2.95 2.06,-2.82c "/>
+              </group>
+            </group>
+          </group>
+        </group>
+      </group>
+      <group android:name="time_group"/>
+    </vector>
+  </aapt:attr>
+  <target android:name="_R_G_L_1_G_N_2_T_0">
+    <aapt:attr name="android:animation">
+      <set android:ordering="together">
+        <objectAnimator android:propertyName="rotation" android:duration="500" android:startOffset="0" android:valueFrom="180" android:valueTo="360" android:valueType="floatType">
+          <aapt:attr name="android:interpolator">
+            <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0"/>
+          </aapt:attr>
+        </objectAnimator>
+      </set>
+    </aapt:attr>
+  </target>
+  <target android:name="_R_G_L_0_C_0">
+    <aapt:attr name="android:animation">
+      <set android:ordering="together">
+        <objectAnimator android:propertyName="pathData" android:duration="500" android:startOffset="0" android:valueFrom="M0.25 -12 C-6.37,-12.14 -11.86,-6.88 -12,-0.25 C-12.14,6.37 -6.88,11.86 -0.25,12 C6.37,12.14 11.86,6.88 12,0.25 C12.14,-6.37 6.88,-11.86 0.25,-12c " android:valueTo="M0.03 -1.6 C-0.85,-1.62 -1.58,-0.92 -1.6,-0.03 C-1.62,0.85 -0.92,1.58 -0.03,1.6 C0.85,1.62 1.58,0.92 1.6,0.03 C1.62,-0.85 0.92,-1.58 0.03,-1.6c " android:valueType="pathType">
+          <aapt:attr name="android:interpolator">
+            <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0"/>
+          </aapt:attr>
+        </objectAnimator>
+      </set>
+    </aapt:attr>
+  </target>
+  <target android:name="_R_G_L_0_G">
+    <aapt:attr name="android:animation">
+      <set android:ordering="together">
+        <objectAnimator android:propertyName="rotation" android:duration="500" android:startOffset="0" android:valueFrom="180" android:valueTo="360" android:valueType="floatType">
+          <aapt:attr name="android:interpolator">
+            <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0"/>
+          </aapt:attr>
+        </objectAnimator>
+      </set>
+    </aapt:attr>
+  </target>
+  <target android:name="_R_G_L_0_G_N_1_T_0">
+    <aapt:attr name="android:animation">
+      <set android:ordering="together">
+        <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="500" android:valueFrom="1" android:valueTo="0" android:valueType="floatType"/>
+      </set>
+    </aapt:attr>
+  </target>
+  <target android:name="time_group">
+    <aapt:attr name="android:animation">
+      <set android:ordering="together">
+        <objectAnimator android:propertyName="translateX" android:duration="767" android:startOffset="0" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+      </set>
+    </aapt:attr>
+  </target>
+</animated-vector>
diff --git a/packages/SystemUI/res/drawable/ic_device_fan_on_anim.xml b/packages/SystemUI/res/drawable/ic_device_fan_on_anim.xml
new file mode 100644
index 0000000..5987b07
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_device_fan_on_anim.xml
@@ -0,0 +1,80 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2020 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
+  -->
+<animated-vector
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:aapt="http://schemas.android.com/aapt">
+  <aapt:attr name="android:drawable">
+    <vector android:height="24dp" android:width="24dp" android:viewportHeight="24" android:viewportWidth="24">
+      <group android:name="_R_G">
+        <group android:name="_R_G_L_1_G_N_1_T_0" android:translateX="12" android:translateY="12" android:rotation="180">
+          <group android:name="_R_G_L_1_G" android:rotation="360">
+            <path android:name="_R_G_L_1_G_D_0_P_0" android:fillColor="#000000" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M5.4 0.25 C5.99,0.64 6.5,1.14 6.89,1.73 C6.89,1.73 6.89,1.73 6.89,1.73 C6.96,1.84 7.07,1.93 7.19,1.97 C7.31,2.02 7.45,2.03 7.57,1.99 C7.7,1.95 7.81,1.87 7.89,1.76 C7.97,1.66 8,1.53 8,1.39 C8.07,0.81 7.99,0.22 7.78,-0.33 C7.57,-0.88 7.23,-1.37 6.78,-1.76 C6.54,-1.91 6.27,-1.99 5.99,-2 C5.71,-2.01 5.42,-1.95 5.17,-1.82 C5.17,-1.82 3.29,-1.14 3.29,-1.14 C3.36,-0.94 3.42,-0.73 3.45,-0.52 C4.14,-0.4 4.81,-0.14 5.4,0.25c  M0.33 7.78 C0.88,7.57 1.37,7.22 1.76,6.78 C1.76,6.78 1.76,6.78 1.76,6.78 C1.9,6.54 1.99,6.27 2,5.99 C2.01,5.71 1.95,5.42 1.82,5.17 C1.82,5.17 1.14,3.29 1.14,3.29 C0.94,3.36 0.73,3.42 0.52,3.45 C0.4,4.14 0.13,4.81 -0.25,5.4 C-0.64,5.99 -1.14,6.5 -1.73,6.89 C-1.84,6.96 -1.93,7.07 -1.97,7.19 C-2.02,7.31 -2.02,7.45 -1.99,7.57 C-1.95,7.7 -1.87,7.81 -1.76,7.89 C-1.66,7.97 -1.53,8 -1.39,8 C-0.81,8.07 -0.22,7.99 0.33,7.78c  M-5.99 2 C-5.7,2.01 -5.42,1.95 -5.17,1.82 C-5.17,1.82 -3.29,1.14 -3.29,1.14 C-3.36,0.94 -3.42,0.73 -3.45,0.52 C-4.14,0.4 -4.81,0.14 -5.4,-0.25 C-5.99,-0.64 -6.5,-1.14 -6.89,-1.73 C-6.96,-1.84 -7.06,-1.93 -7.19,-1.97 C-7.31,-2.02 -7.45,-2.02 -7.57,-1.99 C-7.7,-1.95 -7.81,-1.87 -7.89,-1.76 C-7.96,-1.66 -8,-1.53 -8,-1.39 C-8.07,-0.81 -7.99,-0.22 -7.78,0.33 C-7.57,0.88 -7.23,1.37 -6.78,1.75 C-6.54,1.9 -6.27,1.99 -5.99,2c  M-0.33 -7.78 C-0.88,-7.57 -1.37,-7.23 -1.75,-6.78 C-1.9,-6.54 -1.99,-6.27 -2,-5.99 C-2.01,-5.7 -1.95,-5.42 -1.82,-5.17 C-1.82,-5.17 -1.14,-3.29 -1.14,-3.29 C-0.94,-3.36 -0.73,-3.41 -0.52,-3.45 C-0.4,-4.14 -0.13,-4.81 0.25,-5.4 C0.64,-5.99 1.14,-6.5 1.73,-6.89 C1.84,-6.96 1.93,-7.06 1.97,-7.19 C2.02,-7.31 2.03,-7.45 1.99,-7.57 C1.95,-7.7 1.87,-7.81 1.76,-7.89 C1.66,-7.96 1.53,-8 1.39,-8 C0.81,-8.07 0.22,-7.99 -0.33,-7.78c  M-0.83 1.25 C-0.59,1.41 -0.3,1.5 0,1.5 C0.4,1.5 0.78,1.34 1.06,1.06 C1.34,0.78 1.5,0.4 1.5,0 C1.5,-0.3 1.41,-0.59 1.25,-0.83 C1.08,-1.08 0.85,-1.27 0.57,-1.39 C0.3,-1.5 0,-1.53 -0.29,-1.47 C-0.58,-1.41 -0.85,-1.27 -1.06,-1.06 C-1.27,-0.85 -1.41,-0.58 -1.47,-0.29 C-1.53,0 -1.5,0.3 -1.39,0.57 C-1.27,0.85 -1.08,1.08 -0.83,1.25c  M2.06 -2.82 C2.06,-2.82 4.35,-3.64 4.35,-3.64 C6.99,-4.84 10,-3 10,1.39 C10,1.96 9.83,2.5 9.49,2.95 C9.16,3.41 8.69,3.74 8.15,3.9 C7.62,4.06 7.04,4.05 6.51,3.86 C5.99,3.67 5.54,3.31 5.23,2.84 C4.75,2.13 4.01,1.64 3.16,1.48 C3.07,1.68 2.95,1.87 2.82,2.06 C2.82,2.06 3.64,4.35 3.64,4.35 C4.84,6.99 3.01,10 -1.39,10 C-1.95,10 -2.5,9.83 -2.95,9.49 C-3.41,9.16 -3.74,8.69 -3.9,8.15 C-4.06,7.62 -4.05,7.04 -3.86,6.51 C-3.67,5.99 -3.31,5.54 -2.84,5.23 C-2.13,4.75 -1.64,4.01 -1.47,3.16 C-1.68,3.07 -1.87,2.95 -2.06,2.82 C-2.06,2.82 -4.34,3.64 -4.34,3.64 C-6.99,4.84 -10,3.01 -10,-1.39 C-10,-1.95 -9.83,-2.5 -9.49,-2.95 C-9.16,-3.41 -8.69,-3.74 -8.15,-3.9 C-7.62,-4.06 -7.04,-4.05 -6.51,-3.86 C-5.99,-3.66 -5.53,-3.31 -5.23,-2.84 C-4.75,-2.13 -4,-1.64 -3.16,-1.47 C-3.07,-1.68 -2.95,-1.87 -2.82,-2.06 C-2.82,-2.06 -3.64,-4.34 -3.64,-4.34 C-4.84,-6.99 -3.01,-10 1.39,-10 C1.96,-10 2.5,-9.83 2.95,-9.49 C3.41,-9.16 3.74,-8.69 3.9,-8.15 C4.06,-7.62 4.05,-7.04 3.86,-6.51 C3.67,-5.99 3.31,-5.53 2.84,-5.23 C2.13,-4.75 1.64,-4 1.47,-3.16 C1.68,-3.07 1.87,-2.95 2.06,-2.82c "/>
+          </group>
+        </group>
+        <group android:name="_R_G_L_0_G" android:translateX="12" android:translateY="12" android:rotation="180">
+          <group android:name="_R_G_L_0_C_0_G">
+            <clip-path android:name="_R_G_L_0_C_0" android:pathData=" M0.03 -1.6 C-0.85,-1.62 -1.58,-0.92 -1.6,-0.03 C-1.62,0.85 -0.92,1.58 -0.03,1.6 C0.85,1.62 1.58,0.92 1.6,0.03 C1.62,-0.85 0.92,-1.58 0.03,-1.6c "/>
+            <group android:name="_R_G_L_0_C_0_G_G">
+              <path android:name="_R_G_L_0_G_G_0_D_0_P_0" android:fillColor="#000000" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M-0.83 1.25 C-0.59,1.41 -0.3,1.5 0,1.5 C0.4,1.5 0.78,1.34 1.06,1.06 C1.34,0.78 1.5,0.4 1.5,0 C1.5,-0.3 1.41,-0.59 1.25,-0.83 C1.08,-1.08 0.85,-1.27 0.57,-1.39 C0.3,-1.5 0,-1.53 -0.29,-1.47 C-0.58,-1.41 -0.85,-1.27 -1.06,-1.06 C-1.27,-0.85 -1.41,-0.58 -1.47,-0.29 C-1.53,0 -1.5,0.3 -1.39,0.57 C-1.27,0.85 -1.08,1.08 -0.83,1.25c  M2.06 -2.82 C2.06,-2.82 4.35,-3.64 4.35,-3.64 C6.99,-4.84 10,-3 10,1.39 C10,1.96 9.83,2.5 9.49,2.95 C9.16,3.41 8.69,3.74 8.15,3.9 C7.62,4.06 7.04,4.05 6.51,3.86 C5.99,3.67 5.54,3.31 5.23,2.84 C4.75,2.13 4.01,1.64 3.16,1.48 C3.07,1.68 2.95,1.87 2.82,2.06 C2.82,2.06 3.64,4.35 3.64,4.35 C4.84,6.99 3.01,10 -1.39,10 C-1.95,10 -2.5,9.83 -2.95,9.49 C-3.41,9.16 -3.74,8.69 -3.9,8.15 C-4.06,7.62 -4.05,7.04 -3.86,6.51 C-3.67,5.99 -3.31,5.54 -2.84,5.23 C-2.13,4.75 -1.64,4.01 -1.47,3.16 C-1.68,3.07 -1.87,2.95 -2.06,2.82 C-2.06,2.82 -4.34,3.64 -4.34,3.64 C-6.99,4.84 -10,3.01 -10,-1.39 C-10,-1.95 -9.83,-2.5 -9.49,-2.95 C-9.16,-3.41 -8.69,-3.74 -8.15,-3.9 C-7.62,-4.06 -7.04,-4.05 -6.51,-3.86 C-5.99,-3.66 -5.53,-3.31 -5.23,-2.84 C-4.75,-2.13 -4,-1.64 -3.16,-1.47 C-3.07,-1.68 -2.95,-1.87 -2.82,-2.06 C-2.82,-2.06 -3.64,-4.34 -3.64,-4.34 C-4.84,-6.99 -3.01,-10 1.39,-10 C1.96,-10 2.5,-9.83 2.95,-9.49 C3.41,-9.16 3.74,-8.69 3.9,-8.15 C4.06,-7.62 4.05,-7.04 3.86,-6.51 C3.67,-5.99 3.31,-5.53 2.84,-5.23 C2.13,-4.75 1.64,-4 1.47,-3.16 C1.68,-3.07 1.87,-2.95 2.06,-2.82c "/>
+            </group>
+          </group>
+        </group>
+      </group>
+      <group android:name="time_group"/>
+    </vector>
+  </aapt:attr>
+  <target android:name="_R_G_L_1_G_N_1_T_0">
+    <aapt:attr name="android:animation">
+      <set android:ordering="together">
+        <objectAnimator android:propertyName="rotation" android:duration="500" android:startOffset="0" android:valueFrom="180" android:valueTo="360" android:valueType="floatType">
+          <aapt:attr name="android:interpolator">
+            <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0"/>
+          </aapt:attr>
+        </objectAnimator>
+      </set>
+    </aapt:attr>
+  </target>
+  <target android:name="_R_G_L_0_C_0">
+    <aapt:attr name="android:animation">
+      <set android:ordering="together">
+        <objectAnimator android:propertyName="pathData" android:duration="500" android:startOffset="0" android:valueFrom="M0.03 -1.6 C-0.85,-1.62 -1.58,-0.92 -1.6,-0.03 C-1.62,0.85 -0.92,1.58 -0.03,1.6 C0.85,1.62 1.58,0.92 1.6,0.03 C1.62,-0.85 0.92,-1.58 0.03,-1.6c " android:valueTo="M0.25 -12 C-6.37,-12.14 -11.86,-6.88 -12,-0.25 C-12.14,6.37 -6.88,11.86 -0.25,12 C6.37,12.14 11.86,6.88 12,0.25 C12.14,-6.37 6.88,-11.86 0.25,-12c " android:valueType="pathType">
+          <aapt:attr name="android:interpolator">
+            <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0"/>
+          </aapt:attr>
+        </objectAnimator>
+      </set>
+    </aapt:attr>
+  </target>
+  <target android:name="_R_G_L_0_G">
+    <aapt:attr name="android:animation">
+      <set android:ordering="together">
+        <objectAnimator android:propertyName="rotation" android:duration="500" android:startOffset="0" android:valueFrom="180" android:valueTo="360" android:valueType="floatType">
+          <aapt:attr name="android:interpolator">
+            <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0"/>
+          </aapt:attr>
+        </objectAnimator>
+      </set>
+    </aapt:attr>
+  </target>
+  <target android:name="time_group">
+    <aapt:attr name="android:animation">
+      <set android:ordering="together">
+        <objectAnimator android:propertyName="translateX" android:duration="750" android:startOffset="0" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+      </set>
+    </aapt:attr>
+  </target>
+</animated-vector>
diff --git a/packages/SystemUI/res/drawable/ic_device_garage.xml b/packages/SystemUI/res/drawable/ic_device_garage.xml
new file mode 100644
index 0000000..9a31f33
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_device_garage.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2020 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
+  -->
+<animated-selector
+    xmlns:android="http://schemas.android.com/apk/res/android">
+  <item
+      android:id="@+id/off"
+      android:state_enabled="false"
+      android:drawable="@drawable/ic_device_garage_off" />
+  <item
+      android:id="@+id/on"
+      android:state_enabled="true"
+      android:drawable="@drawable/ic_device_garage_on" />
+  <transition
+      android:fromId="@id/off"
+      android:toId="@id/on"
+      android:drawable="@drawable/ic_device_garage_on_anim" />
+  <transition
+      android:fromId="@id/on"
+      android:toId="@id/off"
+      android:drawable="@drawable/ic_device_garage_off_anim" />
+</animated-selector>
diff --git a/packages/SystemUI/res/drawable/ic_device_garage_off_anim.xml b/packages/SystemUI/res/drawable/ic_device_garage_off_anim.xml
new file mode 100644
index 0000000..1a5bd28
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_device_garage_off_anim.xml
@@ -0,0 +1,290 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2020 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
+  -->
+<animated-vector
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:aapt="http://schemas.android.com/aapt">
+  <aapt:attr name="android:drawable">
+    <vector android:height="24dp" android:width="24dp" android:viewportHeight="24" android:viewportWidth="24">
+      <group android:name="_R_G">
+        <group android:name="_R_G_L_6_G_N_1_T_0" android:translateX="12" android:translateY="12" android:scaleY="0">
+          <group android:name="_R_G_L_6_G">
+            <path android:name="_R_G_L_6_G_D_0_P_0" android:fillColor="#000000" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M0 -9 C0,-9 8,-3 8,-3 C8,-3 8,9 8,9 C8,9 6,9 6,9 C6,9 6,-2 6,-2 C6,-2 0,-6.5 0,-6.5 C0,-6.5 -6,-2 -6,-2 C-6,-2 -6,9 -6,9 C-6,9 -8,9 -8,9 C-8,9 -8,-3 -8,-3 C-8,-3 0,-9 0,-9c "/>
+          </group>
+        </group>
+        <group android:name="_R_G_L_5_G_N_1_T_0" android:translateX="12" android:translateY="12" android:scaleY="0">
+          <group android:name="_R_G_L_5_G" android:translateX="0" android:translateY="4">
+            <group android:name="_R_G_L_5_C_0_G">
+              <clip-path android:name="_R_G_L_5_C_0" android:pathData=" M5.14 -5.06 C5.14,-5.06 -5.12,-5.06 -5.12,-5.06 C-5.12,-5.06 -5.12,4.88 -5.12,4.88 C-5.12,4.88 5.14,4.88 5.14,4.88 C5.14,4.88 5.14,-5.06 5.14,-5.06c "/>
+              <group android:name="_R_G_L_5_C_0_G_G">
+                <path android:name="_R_G_L_5_G_G_0_D_0_P_0" android:fillColor="#000000" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M-3 1 C-3,1 -3,3 -3,3 C-3,3 3,3 3,3 C3,3 3,1 3,1 C3,1 -3,1 -3,1c  M3 -1 C3,-1 3,-3 3,-3 C3,-3 -3,-3 -3,-3 C-3,-3 -3,-1 -3,-1 C-3,-1 3,-1 3,-1c  M-5 5 C-5,5 -5,-5 -5,-5 C-5,-5 5,-5 5,-5 C5,-5 5,5 5,5 C5,5 -5,5 -5,5c "/>
+              </group>
+            </group>
+          </group>
+        </group>
+        <group android:name="_R_G_L_4_G_N_7_N_1_T_0" android:translateX="12" android:translateY="12" android:scaleY="0">
+          <group android:name="_R_G_L_4_G_N_7_T_0" android:translateX="0" android:translateY="4">
+            <group android:name="_R_G_L_4_G" android:translateY="-8.125">
+              <group android:name="_R_G_L_4_C_0_G">
+                <clip-path android:name="_R_G_L_4_C_0" android:pathData=" M5.14 3.19 C5.14,3.19 -5.12,3.19 -5.12,3.19 C-5.12,3.19 -5.12,13.13 -5.12,13.13 C-5.12,13.13 5.14,13.13 5.14,13.13 C5.14,13.13 5.14,3.19 5.14,3.19c "/>
+                <group android:name="_R_G_L_4_C_0_G_G">
+                  <path android:name="_R_G_L_4_G_G_0_D_0_P_0" android:fillColor="#000000" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M-3 1 C-3,1 -3,3 -3,3 C-3,3 3,3 3,3 C3,3 3,1 3,1 C3,1 -3,1 -3,1c  M3.35 -1.34 C3.35,-1.34 0.75,-1.44 0.75,-1.44 C0.75,-1.44 -0.62,-1.44 -0.62,-1.44 C-0.62,-1.44 -2.65,-1.34 -2.65,-1.34 C-2.65,-1.34 3.35,-1.34 3.35,-1.34c  M-5 5 C-5,5 -5,-5 -5,-5 C-5,-5 5,-5 5,-5 C5,-5 5,5 5,5 C5,5 -5,5 -5,5c "/>
+                </group>
+              </group>
+            </group>
+          </group>
+        </group>
+        <group android:name="_R_G_L_3_G_N_7_N_1_T_0" android:translateX="12" android:translateY="12">
+          <group android:name="_R_G_L_3_G_N_7_T_0" android:translateX="0" android:translateY="4">
+            <group android:name="_R_G_L_3_G" android:translateX="0" android:translateY="-2">
+              <group android:name="_R_G_L_3_C_0_G">
+                <clip-path android:name="_R_G_L_3_C_0" android:pathData=" M4.96 -2.77 C4.96,-2.77 -4.87,-2.77 -4.87,-2.77 C-4.87,-2.77 -4.87,7.15 -4.87,7.15 C-4.87,7.15 4.96,7.15 4.96,7.15 C4.96,7.15 4.96,-2.77 4.96,-2.77c "/>
+                <group android:name="_R_G_L_3_C_0_G_G">
+                  <path android:name="_R_G_L_3_G_G_0_D_0_P_0" android:fillColor="#000000" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M-3 -1 C-3,-1 3,-1 3,-1 C3,-1 3,1 3,1 C3,1 -3,1 -3,1 C-3,1 -3,-1 -3,-1c "/>
+                </group>
+              </group>
+            </group>
+          </group>
+        </group>
+        <group android:name="_R_G_L_2_G_N_7_N_1_T_0" android:translateX="12" android:translateY="12">
+          <group android:name="_R_G_L_2_G_N_7_T_0" android:translateX="0" android:translateY="4">
+            <group android:name="_R_G_L_2_G" android:translateX="0" android:translateY="2">
+              <group android:name="_R_G_L_2_C_0_G">
+                <clip-path android:name="_R_G_L_2_C_0" android:pathData=" M4.96 -6.95 C4.96,-6.95 -4.87,-6.95 -4.87,-6.95 C-4.87,-6.95 -4.87,2.97 -4.87,2.97 C-4.87,2.97 4.96,2.97 4.96,2.97 C4.96,2.97 4.96,-6.95 4.96,-6.95c "/>
+                <group android:name="_R_G_L_2_C_0_G_G">
+                  <path android:name="_R_G_L_2_G_G_0_D_0_P_0" android:fillColor="#000000" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M-3 -1 C-3,-1 3,-1 3,-1 C3,-1 3,1 3,1 C3,1 -3,1 -3,1 C-3,1 -3,-1 -3,-1c "/>
+                </group>
+              </group>
+            </group>
+          </group>
+        </group>
+        <group android:name="_R_G_L_1_G_N_7_N_1_T_0" android:translateX="12" android:translateY="12">
+          <group android:name="_R_G_L_1_G_N_7_T_0" android:translateX="0" android:translateY="4">
+            <group android:name="_R_G_L_1_G" android:translateY="-6.062">
+              <path android:name="_R_G_L_1_G_D_0_P_0" android:fillColor="#000000" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M-0.75 -0.22 C-0.75,-0.22 1,-0.25 1,-0.25 C1,-0.25 3,1 3,1 C3,1 -3,1 -3,1 C-3,1 -0.75,-0.22 -0.75,-0.22c "/>
+            </group>
+          </group>
+        </group>
+        <group android:name="_R_G_L_0_G_N_1_T_0" android:translateX="12" android:translateY="12">
+          <group android:name="_R_G_L_0_G">
+            <path android:name="_R_G_L_0_G_D_0_P_0" android:fillColor="#000000" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M-8 -3 C-8,-3 0,-9 0,-9 C0,-9 8,-3 8,-3 C8,-3 8,9 8,9 C8,9 5,9 5,9 C5,9 5,-1 5,-1 C5,-1 -5,-1 -5,-1 C-5,-1 -5,9 -5,9 C-5,9 -8,9 -8,9 C-8,9 -8,-3 -8,-3c "/>
+          </group>
+        </group>
+      </group>
+      <group android:name="time_group"/>
+    </vector>
+  </aapt:attr>
+  <target android:name="_R_G_L_6_G_N_1_T_0">
+    <aapt:attr name="android:animation">
+      <set android:ordering="together">
+        <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="267" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+      </set>
+    </aapt:attr>
+  </target>
+  <target android:name="_R_G_L_5_C_0">
+    <aapt:attr name="android:animation">
+      <set android:ordering="together">
+        <objectAnimator android:propertyName="pathData" android:duration="517" android:startOffset="0" android:valueFrom="M5.14 -5.06 C5.14,-5.06 -5.12,-5.06 -5.12,-5.06 C-5.12,-5.06 -5.12,4.88 -5.12,4.88 C-5.12,4.88 5.14,4.88 5.14,4.88 C5.14,4.88 5.14,-5.06 5.14,-5.06c " android:valueTo="M5.14 -12.94 C5.14,-12.94 -5.12,-12.94 -5.12,-12.94 C-5.12,-12.94 -5.12,-3 -5.12,-3 C-5.12,-3 5.14,-3 5.14,-3 C5.14,-3 5.14,-12.94 5.14,-12.94c " android:valueType="pathType">
+          <aapt:attr name="android:interpolator">
+            <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0"/>
+          </aapt:attr>
+        </objectAnimator>
+      </set>
+    </aapt:attr>
+  </target>
+  <target android:name="_R_G_L_5_G">
+    <aapt:attr name="android:animation">
+      <set android:ordering="together">
+        <objectAnimator android:propertyName="translateXY" android:duration="517" android:startOffset="0" android:propertyXName="translateX" android:propertyYName="translateY" android:pathData="M 0,4C 0,4.281 0,10.998999999999999 0,12.062">
+          <aapt:attr name="android:interpolator">
+            <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0"/>
+          </aapt:attr>
+        </objectAnimator>
+      </set>
+    </aapt:attr>
+  </target>
+  <target android:name="_R_G_L_5_G_N_1_T_0">
+    <aapt:attr name="android:animation">
+      <set android:ordering="together">
+        <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="267" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+      </set>
+    </aapt:attr>
+  </target>
+  <target android:name="_R_G_L_4_C_0">
+    <aapt:attr name="android:animation">
+      <set android:ordering="together">
+        <objectAnimator android:propertyName="pathData" android:duration="517" android:startOffset="0" android:valueFrom="M5.14 3.19 C5.14,3.19 -5.12,3.19 -5.12,3.19 C-5.12,3.19 -5.12,13.13 -5.12,13.13 C-5.12,13.13 5.14,13.13 5.14,13.13 C5.14,13.13 5.14,3.19 5.14,3.19c " android:valueTo="M5.14 -4.94 C5.14,-4.94 -5.12,-4.94 -5.12,-4.94 C-5.12,-4.94 -5.12,5 -5.12,5 C-5.12,5 5.14,5 5.14,5 C5.14,5 5.14,-4.94 5.14,-4.94c " android:valueType="pathType">
+          <aapt:attr name="android:interpolator">
+            <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0"/>
+          </aapt:attr>
+        </objectAnimator>
+      </set>
+    </aapt:attr>
+  </target>
+  <target android:name="_R_G_L_4_G_G_0_D_0_P_0">
+    <aapt:attr name="android:animation">
+      <set android:ordering="together">
+        <objectAnimator android:propertyName="pathData" android:duration="517" android:startOffset="0" android:valueFrom=" M-3 1 C-3,1 -3,3 -3,3 C-3,3 3,3 3,3 C3,3 3,1 3,1 C3,1 -3,1 -3,1c M3.35 -1.34 C3.35,-1.34 0.75,-1.44 0.75,-1.44 C0.75,-1.44 -0.62,-1.44 -0.62,-1.44 C-0.62,-1.44 -2.65,-1.34 -2.65,-1.34 C-2.65,-1.34 3.35,-1.34 3.35,-1.34c  M-5 5 C-5,5 -5,-5 -5,-5 C-5,-5 5,-5 5,-5 C5,-5 5,5 5,5 C5,5 -5,5 -5,5c " android:valueTo=" M-3 1 C-3,1 -3,3 -3,3 C-3,3 3,3 3,3 C3,3 3,1 3,1 C3,1 -3,1 -3,1c M3 -1 C3,-1 3,-3 3,-3 C3,-3 -3,-3 -3,-3 C-3,-3 -3,-1 -3,-1 C-3,-1 3,-1 3,-1c  M-5 5 C-5,5 -5,-5 -5,-5 C-5,-5 5,-5 5,-5 C5,-5 5,5 5,5 C5,5 -5,5 -5,5c " android:valueType="pathType">
+          <aapt:attr name="android:interpolator">
+            <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0"/>
+          </aapt:attr>
+        </objectAnimator>
+      </set>
+    </aapt:attr>
+  </target>
+  <target android:name="_R_G_L_4_G_N_7_T_0">
+    <aapt:attr name="android:animation">
+      <set android:ordering="together">
+        <objectAnimator android:propertyName="translateXY" android:duration="517" android:startOffset="0" android:propertyXName="translateX" android:propertyYName="translateY" android:pathData="M 0,4C 0,4.281 0,10.998999999999999 0,12.062">
+          <aapt:attr name="android:interpolator">
+            <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0"/>
+          </aapt:attr>
+        </objectAnimator>
+      </set>
+    </aapt:attr>
+  </target>
+  <target android:name="_R_G_L_4_G_N_7_N_1_T_0">
+    <aapt:attr name="android:animation">
+      <set android:ordering="together">
+        <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="267" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+      </set>
+    </aapt:attr>
+  </target>
+  <target android:name="_R_G_L_3_C_0">
+    <aapt:attr name="android:animation">
+      <set android:ordering="together">
+        <objectAnimator android:propertyName="pathData" android:duration="517" android:startOffset="0" android:valueFrom="M4.96 -2.77 C4.96,-2.77 -4.87,-2.77 -4.87,-2.77 C-4.87,-2.77 -4.87,7.15 -4.87,7.15 C-4.87,7.15 4.96,7.15 4.96,7.15 C4.96,7.15 4.96,-2.77 4.96,-2.77c " android:valueTo="M4.96 -7.02 C4.96,-7.02 -4.87,-7.02 -4.87,-7.02 C-4.87,-7.02 -4.87,2.9 -4.87,2.9 C-4.87,2.9 4.96,2.9 4.96,2.9 C4.96,2.9 4.96,-7.02 4.96,-7.02c " android:valueType="pathType">
+          <aapt:attr name="android:interpolator">
+            <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0"/>
+          </aapt:attr>
+        </objectAnimator>
+      </set>
+    </aapt:attr>
+  </target>
+  <target android:name="_R_G_L_3_G">
+    <aapt:attr name="android:animation">
+      <set android:ordering="together">
+        <objectAnimator android:propertyName="translateXY" android:duration="517" android:startOffset="0" android:propertyXName="translateX" android:propertyYName="translateY" android:pathData="M 0,-2C 0,-1.844 0,-1.218 0,-1.062">
+          <aapt:attr name="android:interpolator">
+            <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0"/>
+          </aapt:attr>
+        </objectAnimator>
+      </set>
+    </aapt:attr>
+  </target>
+  <target android:name="_R_G_L_3_G_N_7_T_0">
+    <aapt:attr name="android:animation">
+      <set android:ordering="together">
+        <objectAnimator android:propertyName="translateXY" android:duration="517" android:startOffset="0" android:propertyXName="translateX" android:propertyYName="translateY" android:pathData="M 0,4C 0,4.281 0,10.998999999999999 0,12.062">
+          <aapt:attr name="android:interpolator">
+            <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0"/>
+          </aapt:attr>
+        </objectAnimator>
+      </set>
+    </aapt:attr>
+  </target>
+  <target android:name="_R_G_L_3_G_N_7_N_1_T_0">
+    <aapt:attr name="android:animation">
+      <set android:ordering="together">
+        <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="267" android:valueFrom="1" android:valueTo="0" android:valueType="floatType"/>
+      </set>
+    </aapt:attr>
+  </target>
+  <target android:name="_R_G_L_2_C_0">
+    <aapt:attr name="android:animation">
+      <set android:ordering="together">
+        <objectAnimator android:propertyName="pathData" android:duration="517" android:startOffset="0" android:valueFrom="M4.96 -6.95 C4.96,-6.95 -4.87,-6.95 -4.87,-6.95 C-4.87,-6.95 -4.87,2.97 -4.87,2.97 C-4.87,2.97 4.96,2.97 4.96,2.97 C4.96,2.97 4.96,-6.95 4.96,-6.95c " android:valueTo="M4.96 -16.33 C4.96,-16.33 -4.87,-16.33 -4.87,-16.33 C-4.87,-16.33 -4.87,-6.41 -4.87,-6.41 C-4.87,-6.41 4.96,-6.41 4.96,-6.41 C4.96,-6.41 4.96,-16.33 4.96,-16.33c " android:valueType="pathType">
+          <aapt:attr name="android:interpolator">
+            <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0"/>
+          </aapt:attr>
+        </objectAnimator>
+      </set>
+    </aapt:attr>
+  </target>
+  <target android:name="_R_G_L_2_G">
+    <aapt:attr name="android:animation">
+      <set android:ordering="together">
+        <objectAnimator android:propertyName="translateXY" android:duration="517" android:startOffset="0" android:propertyXName="translateX" android:propertyYName="translateY" android:pathData="M 0,2C 0,2.208 0,3.042 0,3.25">
+          <aapt:attr name="android:interpolator">
+            <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0"/>
+          </aapt:attr>
+        </objectAnimator>
+      </set>
+    </aapt:attr>
+  </target>
+  <target android:name="_R_G_L_2_G_N_7_T_0">
+    <aapt:attr name="android:animation">
+      <set android:ordering="together">
+        <objectAnimator android:propertyName="translateXY" android:duration="517" android:startOffset="0" android:propertyXName="translateX" android:propertyYName="translateY" android:pathData="M 0,4C 0,4.281 0,10.998999999999999 0,12.062">
+          <aapt:attr name="android:interpolator">
+            <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0"/>
+          </aapt:attr>
+        </objectAnimator>
+      </set>
+    </aapt:attr>
+  </target>
+  <target android:name="_R_G_L_2_G_N_7_N_1_T_0">
+    <aapt:attr name="android:animation">
+      <set android:ordering="together">
+        <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="267" android:valueFrom="1" android:valueTo="0" android:valueType="floatType"/>
+      </set>
+    </aapt:attr>
+  </target>
+  <target android:name="_R_G_L_1_G_D_0_P_0">
+    <aapt:attr name="android:animation">
+      <set android:ordering="together">
+        <objectAnimator android:propertyName="pathData" android:duration="317" android:startOffset="0" android:valueFrom="M-0.75 -0.22 C-0.75,-0.22 1,-0.25 1,-0.25 C1,-0.25 3,1 3,1 C3,1 -3,1 -3,1 C-3,1 -0.75,-0.22 -0.75,-0.22c " android:valueTo="M-3 -1 C-3,-1 3,-1 3,-1 C3,-1 3,1 3,1 C3,1 -3,1 -3,1 C-3,1 -3,-1 -3,-1c " android:valueType="pathType">
+          <aapt:attr name="android:interpolator">
+            <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0"/>
+          </aapt:attr>
+        </objectAnimator>
+      </set>
+    </aapt:attr>
+  </target>
+  <target android:name="_R_G_L_1_G_N_7_T_0">
+    <aapt:attr name="android:animation">
+      <set android:ordering="together">
+        <objectAnimator android:propertyName="translateXY" android:duration="517" android:startOffset="0" android:propertyXName="translateX" android:propertyYName="translateY" android:pathData="M 0,4C 0,4.281 0,10.998999999999999 0,12.062">
+          <aapt:attr name="android:interpolator">
+            <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0"/>
+          </aapt:attr>
+        </objectAnimator>
+      </set>
+    </aapt:attr>
+  </target>
+  <target android:name="_R_G_L_1_G_N_7_N_1_T_0">
+    <aapt:attr name="android:animation">
+
+      <set android:ordering="together">
+        <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="267" android:valueFrom="1" android:valueTo="0" android:valueType="floatType"/>
+      </set>
+    </aapt:attr>
+  </target>
+  <target android:name="_R_G_L_0_G_N_1_T_0">
+    <aapt:attr name="android:animation">
+      <set android:ordering="together">
+        <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="267" android:valueFrom="1" android:valueTo="0" android:valueType="floatType"/>
+      </set>
+    </aapt:attr>
+  </target>
+  <target android:name="time_group">
+    <aapt:attr name="android:animation">
+      <set android:ordering="together">
+        <objectAnimator android:propertyName="translateX" android:duration="750" android:startOffset="0" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+      </set>
+    </aapt:attr>
+  </target>
+</animated-vector>
diff --git a/packages/SystemUI/res/drawable/ic_device_garage_on_anim.xml b/packages/SystemUI/res/drawable/ic_device_garage_on_anim.xml
new file mode 100644
index 0000000..a1999e0
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_device_garage_on_anim.xml
@@ -0,0 +1,295 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2020 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
+  -->
+<animated-vector
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:aapt="http://schemas.android.com/aapt">
+  <aapt:attr name="android:drawable">
+    <vector android:height="24dp" android:width="24dp" android:viewportHeight="24" android:viewportWidth="24">
+      <group android:name="_R_G">
+        <group android:name="_R_G_L_6_G_N_1_T_0" android:translateX="12" android:translateY="12">
+          <group android:name="_R_G_L_6_G">
+            <path android:name="_R_G_L_6_G_D_0_P_0" android:fillColor="#000000" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M0 -9 C0,-9 8,-3 8,-3 C8,-3 8,9 8,9 C8,9 6,9 6,9 C6,9 6,-2 6,-2 C6,-2 0,-6.5 0,-6.5 C0,-6.5 -6,-2 -6,-2 C-6,-2 -6,9 -6,9 C-6,9 -8,9 -8,9 C-8,9 -8,-3 -8,-3 C-8,-3 0,-9 0,-9c "/>
+          </group>
+        </group>
+        <group android:name="_R_G_L_5_G_N_1_T_0" android:translateX="12" android:translateY="12">
+          <group android:name="_R_G_L_5_G" android:translateX="0" android:translateY="12.062">
+            <group android:name="_R_G_L_5_C_0_G">
+              <clip-path android:name="_R_G_L_5_C_0" android:pathData=" M5.14 -12.94 C5.14,-12.94 -5.12,-12.94 -5.12,-12.94 C-5.12,-12.94 -5.12,-3 -5.12,-3 C-5.12,-3 5.14,-3 5.14,-3 C5.14,-3 5.14,-12.94 5.14,-12.94c "/>
+              <group android:name="_R_G_L_5_C_0_G_G">
+                <path android:name="_R_G_L_5_G_G_0_D_0_P_0" android:fillColor="#000000" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M-3 1 C-3,1 -3,3 -3,3 C-3,3 3,3 3,3 C3,3 3,1 3,1 C3,1 -3,1 -3,1c  M3 -1 C3,-1 3,-3 3,-3 C3,-3 -3,-3 -3,-3 C-3,-3 -3,-1 -3,-1 C-3,-1 3,-1 3,-1c  M-5 5 C-5,5 -5,-5 -5,-5 C-5,-5 5,-5 5,-5 C5,-5 5,5 5,5 C5,5 -5,5 -5,5c "/>
+              </group>
+            </group>
+          </group>
+        </group>
+        <group android:name="_R_G_L_4_G_N_7_N_1_T_0" android:translateX="12" android:translateY="12">
+          <group android:name="_R_G_L_4_G_N_7_T_0" android:translateX="0" android:translateY="12.062">
+            <group android:name="_R_G_L_4_G" android:translateY="-8.125">
+              <group android:name="_R_G_L_4_C_0_G">
+                <clip-path android:name="_R_G_L_4_C_0" android:pathData=" M5.14 -4.94 C5.14,-4.94 -5.12,-4.94 -5.12,-4.94 C-5.12,-4.94 -5.12,5 -5.12,5 C-5.12,5 5.14,5 5.14,5 C5.14,5 5.14,-4.94 5.14,-4.94c "/>
+                <group android:name="_R_G_L_4_C_0_G_G">
+                  <path android:name="_R_G_L_4_G_G_0_D_0_P_0" android:fillColor="#000000" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M-3 1 C-3,1 -3,3 -3,3 C-3,3 3,3 3,3 C3,3 3,1 3,1 C3,1 -3,1 -3,1c  M3 -1 C3,-1 3,-3 3,-3 C3,-3 -3,-3 -3,-3 C-3,-3 -3,-1 -3,-1 C-3,-1 3,-1 3,-1c  M-5 5 C-5,5 -5,-5 -5,-5 C-5,-5 5,-5 5,-5 C5,-5 5,5 5,5 C5,5 -5,5 -5,5c "/>
+                </group>
+              </group>
+            </group>
+          </group>
+        </group>
+        <group android:name="_R_G_L_3_G_N_7_N_1_T_0" android:translateX="12" android:translateY="12" android:scaleY="0">
+          <group android:name="_R_G_L_3_G_N_7_T_0" android:translateX="0" android:translateY="12.062">
+            <group android:name="_R_G_L_3_G" android:translateX="0" android:translateY="-1.062">
+              <group android:name="_R_G_L_3_C_0_G">
+                <clip-path android:name="_R_G_L_3_C_0" android:pathData=" M4.96 -7.02 C4.96,-7.02 -4.87,-7.02 -4.87,-7.02 C-4.87,-7.02 -4.87,2.9 -4.87,2.9 C-4.87,2.9 4.96,2.9 4.96,2.9 C4.96,2.9 4.96,-7.02 4.96,-7.02c "/>
+                <group android:name="_R_G_L_3_C_0_G_G">
+                  <path android:name="_R_G_L_3_G_G_0_D_0_P_0" android:fillColor="#000000" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M-3 -1 C-3,-1 3,-1 3,-1 C3,-1 3,1 3,1 C3,1 -3,1 -3,1 C-3,1 -3,-1 -3,-1c "/>
+                </group>
+              </group>
+            </group>
+          </group>
+        </group>
+        <group android:name="_R_G_L_2_G_N_7_N_1_T_0" android:translateX="12" android:translateY="12" android:scaleY="0">
+          <group android:name="_R_G_L_2_G_N_7_T_0" android:translateX="0" android:translateY="12.062">
+            <group android:name="_R_G_L_2_G" android:translateX="0" android:translateY="3.25">
+              <group android:name="_R_G_L_2_C_0_G">
+                <clip-path android:name="_R_G_L_2_C_0" android:pathData=" M4.96 -16.33 C4.96,-16.33 -4.87,-16.33 -4.87,-16.33 C-4.87,-16.33 -4.87,-6.41 -4.87,-6.41 C-4.87,-6.41 4.96,-6.41 4.96,-6.41 C4.96,-6.41 4.96,-16.33 4.96,-16.33c "/>
+                <group android:name="_R_G_L_2_C_0_G_G">
+                  <path android:name="_R_G_L_2_G_G_0_D_0_P_0" android:fillColor="#000000" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M-3 -1 C-3,-1 3,-1 3,-1 C3,-1 3,1 3,1 C3,1 -3,1 -3,1 C-3,1 -3,-1 -3,-1c "/>
+                </group>
+              </group>
+            </group>
+          </group>
+        </group>
+        <group android:name="_R_G_L_1_G_N_7_N_1_T_0" android:translateX="12" android:translateY="12" android:scaleY="0">
+          <group android:name="_R_G_L_1_G_N_7_T_0" android:translateX="0" android:translateY="12.062">
+            <group android:name="_R_G_L_1_G" android:translateY="-6.062">
+              <path android:name="_R_G_L_1_G_D_0_P_0" android:fillColor="#000000" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M-3 -1 C-3,-1 3,-1 3,-1 C3,-1 3,1 3,1 C3,1 -3,1 -3,1 C-3,1 -3,-1 -3,-1c "/>
+            </group>
+          </group>
+        </group>
+        <group android:name="_R_G_L_0_G_N_1_T_0" android:translateX="12" android:translateY="12" android:scaleY="0">
+          <group android:name="_R_G_L_0_G">
+            <path android:name="_R_G_L_0_G_D_0_P_0" android:fillColor="#000000" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M-8 -3 C-8,-3 0,-9 0,-9 C0,-9 8,-3 8,-3 C8,-3 8,9 8,9 C8,9 5,9 5,9 C5,9 5,-1 5,-1 C5,-1 -5,-1 -5,-1 C-5,-1 -5,9 -5,9 C-5,9 -8,9 -8,9 C-8,9 -8,-3 -8,-3c "/>
+          </group>
+        </group>
+      </group>
+      <group android:name="time_group"/>
+    </vector>
+  </aapt:attr>
+  <target android:name="_R_G_L_6_G_N_1_T_0">
+
+    <aapt:attr name="android:animation">
+      <set android:ordering="together">
+        <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="250" android:valueFrom="1" android:valueTo="0" android:valueType="floatType"/>
+      </set>
+    </aapt:attr>
+  </target>
+  <target android:name="_R_G_L_5_C_0">
+    <aapt:attr name="android:animation">
+      <set android:ordering="together">
+        <objectAnimator android:propertyName="pathData" android:duration="517" android:startOffset="0" android:valueFrom="M5.14 -12.94 C5.14,-12.94 -5.12,-12.94 -5.12,-12.94 C-5.12,-12.94 -5.12,-3 -5.12,-3 C-5.12,-3 5.14,-3 5.14,-3 C5.14,-3 5.14,-12.94 5.14,-12.94c " android:valueTo="M5.14 -5.06 C5.14,-5.06 -5.12,-5.06 -5.12,-5.06 C-5.12,-5.06 -5.12,4.88 -5.12,4.88 C-5.12,4.88 5.14,4.88 5.14,4.88 C5.14,4.88 5.14,-5.06 5.14,-5.06c " android:valueType="pathType">
+          <aapt:attr name="android:interpolator">
+            <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0"/>
+          </aapt:attr>
+        </objectAnimator>
+      </set>
+    </aapt:attr>
+  </target>
+  <target android:name="_R_G_L_5_G">
+    <aapt:attr name="android:animation">
+      <set android:ordering="together">
+        <objectAnimator android:propertyName="translateXY" android:duration="517" android:startOffset="0" android:propertyXName="translateX" android:propertyYName="translateY" android:pathData="M 0,12.062C 0,10.998999999999999 0,4.281 0,4">
+          <aapt:attr name="android:interpolator">
+            <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0"/>
+          </aapt:attr>
+        </objectAnimator>
+      </set>
+    </aapt:attr>
+  </target>
+  <target android:name="_R_G_L_5_G_N_1_T_0">
+    <aapt:attr name="android:animation">
+      <set android:ordering="together">
+        <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="250" android:valueFrom="1" android:valueTo="0" android:valueType="floatType"/>
+      </set>
+    </aapt:attr>
+  </target>
+  <target android:name="_R_G_L_4_C_0">
+    <aapt:attr name="android:animation">
+      <set android:ordering="together">
+        <objectAnimator android:propertyName="pathData" android:duration="517" android:startOffset="0" android:valueFrom="M5.14 -4.94 C5.14,-4.94 -5.12,-4.94 -5.12,-4.94 C-5.12,-4.94 -5.12,5 -5.12,5 C-5.12,5 5.14,5 5.14,5 C5.14,5 5.14,-4.94 5.14,-4.94c " android:valueTo="M5.14 3.19 C5.14,3.19 -5.12,3.19 -5.12,3.19 C-5.12,3.19 -5.12,13.13 -5.12,13.13 C-5.12,13.13 5.14,13.13 5.14,13.13 C5.14,13.13 5.14,3.19 5.14,3.19c " android:valueType="pathType">
+          <aapt:attr name="android:interpolator">
+            <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0"/>
+          </aapt:attr>
+        </objectAnimator>
+      </set>
+    </aapt:attr>
+  </target>
+  <target android:name="_R_G_L_4_G_G_0_D_0_P_0">
+    <aapt:attr name="android:animation">
+      <set android:ordering="together">
+        <objectAnimator android:propertyName="pathData" android:duration="517" android:startOffset="0" android:valueFrom=" M-3 1 C-3,1 -3,3 -3,3 C-3,3 3,3 3,3 C3,3 3,1 3,1 C3,1 -3,1 -3,1c M3 -1 C3,-1 3,-3 3,-3 C3,-3 -3,-3 -3,-3 C-3,-3 -3,-1 -3,-1 C-3,-1 3,-1 3,-1c  M-5 5 C-5,5 -5,-5 -5,-5 C-5,-5 5,-5 5,-5 C5,-5 5,5 5,5 C5,5 -5,5 -5,5c " android:valueTo=" M-3 1 C-3,1 -3,3 -3,3 C-3,3 3,3 3,3 C3,3 3,1 3,1 C3,1 -3,1 -3,1c M3.35 -1.34 C3.35,-1.34 0.75,-1.44 0.75,-1.44 C0.75,-1.44 -0.62,-1.44 -0.62,-1.44 C-0.62,-1.44 -2.65,-1.34 -2.65,-1.34 C-2.65,-1.34 3.35,-1.34 3.35,-1.34c  M-5 5 C-5,5 -5,-5 -5,-5 C-5,-5 5,-5 5,-5 C5,-5 5,5 5,5 C5,5 -5,5 -5,5c " android:valueType="pathType">
+          <aapt:attr name="android:interpolator">
+            <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0"/>
+          </aapt:attr>
+        </objectAnimator>
+      </set>
+    </aapt:attr>
+  </target>
+  <target android:name="_R_G_L_4_G_N_7_T_0">
+    <aapt:attr name="android:animation">
+      <set android:ordering="together">
+        <objectAnimator android:propertyName="translateXY" android:duration="517" android:startOffset="0" android:propertyXName="translateX" android:propertyYName="translateY" android:pathData="M 0,12.062C 0,10.998999999999999 0,4.281 0,4">
+          <aapt:attr name="android:interpolator">
+            <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0"/>
+          </aapt:attr>
+        </objectAnimator>
+      </set>
+    </aapt:attr>
+  </target>
+  <target android:name="_R_G_L_4_G_N_7_N_1_T_0">
+    <aapt:attr name="android:animation">
+      <set android:ordering="together">
+        <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="250" android:valueFrom="1" android:valueTo="0" android:valueType="floatType"/>
+      </set>
+    </aapt:attr>
+  </target>
+  <target android:name="_R_G_L_3_C_0">
+    <aapt:attr name="android:animation">
+      <set android:ordering="together">
+        <objectAnimator android:propertyName="pathData" android:duration="517" android:startOffset="0" android:valueFrom="M4.96 -7.02 C4.96,-7.02 -4.87,-7.02 -4.87,-7.02 C-4.87,-7.02 -4.87,2.9 -4.87,2.9 C-4.87,2.9 4.96,2.9 4.96,2.9 C4.96,2.9 4.96,-7.02 4.96,-7.02c " android:valueTo="M4.96 -2.77 C4.96,-2.77 -4.87,-2.77 -4.87,-2.77 C-4.87,-2.77 -4.87,7.15 -4.87,7.15 C-4.87,7.15 4.96,7.15 4.96,7.15 C4.96,7.15 4.96,-2.77 4.96,-2.77c " android:valueType="pathType">
+          <aapt:attr name="android:interpolator">
+            <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0"/>
+          </aapt:attr>
+        </objectAnimator>
+      </set>
+    </aapt:attr>
+  </target>
+  <target android:name="_R_G_L_3_G">
+    <aapt:attr name="android:animation">
+      <set android:ordering="together">
+        <objectAnimator android:propertyName="translateXY" android:duration="517" android:startOffset="0" android:propertyXName="translateX" android:propertyYName="translateY" android:pathData="M 0,-1.062C 0,-1.218 0,-1.844 0,-2">
+          <aapt:attr name="android:interpolator">
+            <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0"/>
+          </aapt:attr>
+        </objectAnimator>
+      </set>
+    </aapt:attr>
+  </target>
+  <target android:name="_R_G_L_3_G_N_7_T_0">
+    <aapt:attr name="android:animation">
+      <set android:ordering="together">
+        <objectAnimator android:propertyName="translateXY" android:duration="517" android:startOffset="0" android:propertyXName="translateX" android:propertyYName="translateY" android:pathData="M 0,12.062C 0,10.998999999999999 0,4.281 0,4">
+          <aapt:attr name="android:interpolator">
+            <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0"/>
+          </aapt:attr>
+        </objectAnimator>
+      </set>
+    </aapt:attr>
+  </target>
+  <target android:name="_R_G_L_3_G_N_7_N_1_T_0">
+    <aapt:attr name="android:animation">
+      <set android:ordering="together">
+        <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="250" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+      </set>
+    </aapt:attr>
+  </target>
+  <target android:name="_R_G_L_2_C_0">
+    <aapt:attr name="android:animation">
+      <set android:ordering="together">
+        <objectAnimator android:propertyName="pathData" android:duration="517" android:startOffset="0" android:valueFrom="M4.96 -16.33 C4.96,-16.33 -4.87,-16.33 -4.87,-16.33 C-4.87,-16.33 -4.87,-6.41 -4.87,-6.41 C-4.87,-6.41 4.96,-6.41 4.96,-6.41 C4.96,-6.41 4.96,-16.33 4.96,-16.33c " android:valueTo="M4.96 -6.95 C4.96,-6.95 -4.87,-6.95 -4.87,-6.95 C-4.87,-6.95 -4.87,2.97 -4.87,2.97 C-4.87,2.97 4.96,2.97 4.96,2.97 C4.96,2.97 4.96,-6.95 4.96,-6.95c " android:valueType="pathType">
+          <aapt:attr name="android:interpolator">
+            <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0"/>
+          </aapt:attr>
+        </objectAnimator>
+      </set>
+    </aapt:attr>
+  </target>
+  <target android:name="_R_G_L_2_G">
+    <aapt:attr name="android:animation">
+      <set android:ordering="together">
+        <objectAnimator android:propertyName="translateXY" android:duration="517" android:startOffset="0" android:propertyXName="translateX" android:propertyYName="translateY" android:pathData="M 0,3.25C 0,3.042 0,2.208 0,2">
+          <aapt:attr name="android:interpolator">
+            <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0"/>
+          </aapt:attr>
+        </objectAnimator>
+      </set>
+    </aapt:attr>
+  </target>
+  <target android:name="_R_G_L_2_G_N_7_T_0">
+    <aapt:attr name="android:animation">
+      <set android:ordering="together">
+        <objectAnimator android:propertyName="translateXY" android:duration="517" android:startOffset="0" android:propertyXName="translateX" android:propertyYName="translateY" android:pathData="M 0,12.062C 0,10.998999999999999 0,4.281 0,4">
+          <aapt:attr name="android:interpolator">
+            <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0"/>
+          </aapt:attr>
+        </objectAnimator>
+      </set>
+    </aapt:attr>
+  </target>
+  <target android:name="_R_G_L_2_G_N_7_N_1_T_0">
+    <aapt:attr name="android:animation">
+      <set android:ordering="together">
+        <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="250" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+      </set>
+    </aapt:attr>
+  </target>
+  <target android:name="_R_G_L_1_G_D_0_P_0">
+    <aapt:attr name="android:animation">
+      <set android:ordering="together">
+        <objectAnimator android:propertyName="pathData" android:duration="200" android:startOffset="0" android:valueFrom="M-3 -1 C-3,-1 3,-1 3,-1 C3,-1 3,1 3,1 C3,1 -3,1 -3,1 C-3,1 -3,-1 -3,-1c " android:valueTo="M-3 -1 C-3,-1 3,-1 3,-1 C3,-1 3,1 3,1 C3,1 -3,1 -3,1 C-3,1 -3,-1 -3,-1c " android:valueType="pathType">
+          <aapt:attr name="android:interpolator">
+            <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0"/>
+          </aapt:attr>
+        </objectAnimator>
+        <objectAnimator android:propertyName="pathData" android:duration="317" android:startOffset="200" android:valueFrom="M-3 -1 C-3,-1 3,-1 3,-1 C3,-1 3,1 3,1 C3,1 -3,1 -3,1 C-3,1 -3,-1 -3,-1c " android:valueTo="M-0.75 -0.22 C-0.75,-0.22 1,-0.25 1,-0.25 C1,-0.25 3,1 3,1 C3,1 -3,1 -3,1 C-3,1 -0.75,-0.22 -0.75,-0.22c " android:valueType="pathType">
+          <aapt:attr name="android:interpolator">
+            <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0"/>
+          </aapt:attr>
+        </objectAnimator>
+      </set>
+    </aapt:attr>
+  </target>
+  <target android:name="_R_G_L_1_G_N_7_T_0">
+    <aapt:attr name="android:animation">
+      <set android:ordering="together">
+        <objectAnimator android:propertyName="translateXY" android:duration="517" android:startOffset="0" android:propertyXName="translateX" android:propertyYName="translateY" android:pathData="M 0,12.062C 0,10.998999999999999 0,4.281 0,4">
+          <aapt:attr name="android:interpolator">
+            <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0"/>
+          </aapt:attr>
+        </objectAnimator>
+      </set>
+    </aapt:attr>
+  </target>
+  <target android:name="_R_G_L_1_G_N_7_N_1_T_0">
+    <aapt:attr name="android:animation">
+      <set android:ordering="together">
+        <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="250" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+      </set>
+    </aapt:attr>
+  </target>
+  <target android:name="_R_G_L_0_G_N_1_T_0">
+    <aapt:attr name="android:animation">
+      <set android:ordering="together">
+        <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="250" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+      </set>
+    </aapt:attr>
+  </target>
+  <target android:name="time_group">
+    <aapt:attr name="android:animation">
+      <set android:ordering="together">
+        <objectAnimator android:propertyName="translateX" android:duration="750" android:startOffset="0" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+      </set>
+    </aapt:attr>
+  </target>
+</animated-vector>
diff --git a/packages/SystemUI/res/drawable/ic_device_gate.xml b/packages/SystemUI/res/drawable/ic_device_gate.xml
new file mode 100644
index 0000000..8fbf08b
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_device_gate.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2020 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
+  -->
+<selector
+    xmlns:android="http://schemas.android.com/apk/res/android">
+  <item
+      android:id="@+id/off"
+      android:state_enabled="false"
+      android:drawable="@drawable/ic_device_gate_off" />
+  <item
+      android:id="@+id/on"
+      android:state_enabled="true"
+      android:drawable="@drawable/ic_device_gate_on" />
+</selector>
diff --git a/packages/SystemUI/res/drawable/ic_device_hood.xml b/packages/SystemUI/res/drawable/ic_device_hood.xml
new file mode 100644
index 0000000..e376db8
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_device_hood.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2020 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
+  -->
+<selector
+    xmlns:android="http://schemas.android.com/apk/res/android">
+  <item
+      android:id="@+id/off"
+      android:state_enabled="false"
+      android:drawable="@drawable/ic_device_hood_off" />
+  <item
+      android:id="@+id/on"
+      android:state_enabled="true"
+      android:drawable="@drawable/ic_device_hood_on" />
+</selector>
diff --git a/packages/SystemUI/res/drawable/ic_device_kettle.xml b/packages/SystemUI/res/drawable/ic_device_kettle.xml
new file mode 100644
index 0000000..81ea390
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_device_kettle.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2020 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
+  -->
+<selector
+    xmlns:android="http://schemas.android.com/apk/res/android">
+  <item
+      android:id="@+id/off"
+      android:state_enabled="false"
+      android:drawable="@drawable/ic_device_kettle_off" />
+  <item
+      android:id="@+id/on"
+      android:state_enabled="true"
+      android:drawable="@drawable/ic_device_kettle_on" />
+</selector>
diff --git a/packages/SystemUI/res/drawable/ic_device_light.xml b/packages/SystemUI/res/drawable/ic_device_light.xml
new file mode 100644
index 0000000..ebd6c18b
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_device_light.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2020 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
+  -->
+<animated-selector
+    xmlns:android="http://schemas.android.com/apk/res/android">
+  <item
+      android:id="@+id/off"
+      android:state_enabled="false"
+      android:drawable="@drawable/ic_device_light_off" />
+  <item
+      android:id="@+id/on"
+      android:state_enabled="true"
+      android:drawable="@drawable/ic_device_light_on" />
+  <transition
+      android:fromId="@id/off"
+      android:toId="@id/on"
+      android:drawable="@drawable/ic_device_light_on_anim" />
+  <transition
+      android:fromId="@id/on"
+      android:toId="@id/off"
+      android:drawable="@drawable/ic_device_light_off_anim" />
+</animated-selector>
diff --git a/packages/SystemUI/res/drawable/ic_device_light_off_anim.xml b/packages/SystemUI/res/drawable/ic_device_light_off_anim.xml
new file mode 100644
index 0000000..213aa4e
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_device_light_off_anim.xml
@@ -0,0 +1,65 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2020 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
+  -->
+<animated-vector
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:aapt="http://schemas.android.com/aapt">
+  <aapt:attr name="android:drawable">
+    <vector android:height="24dp" android:width="24dp" android:viewportHeight="24" android:viewportWidth="24">
+      <group android:name="_R_G">
+        <group android:name="_R_G_L_1_G">
+          <path android:name="_R_G_L_1_G_D_0_P_0" android:fillColor="#000000" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M13.41 21.41 C13.04,21.79 12.53,22 12,22 C11.47,22 10.96,21.79 10.59,21.41 C10.21,21.04 10,20.53 10,20 C10,20 14,20 14,20 C14,20.53 13.79,21.04 13.41,21.41c "/>
+          <path android:name="_R_G_L_1_G_D_1_P_0" android:fillColor="#000000" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M8 17 C8,17 16,17 16,17 C16,17 16,19 16,19 C16,19 8,19 8,19 C8,19 8,17 8,17c "/>
+          <path android:name="_R_G_L_1_G_D_2_P_0" android:fillColor="#000000" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M8.85 14 C8.85,14 15.15,14 15.15,14 C15.15,14 15.15,14 15.15,14 C15.88,13.5 16.47,12.83 16.88,12.04 C17.29,11.26 17.5,10.39 17.5,9.5 C17.5,8.04 16.92,6.64 15.89,5.61 C14.85,4.58 13.46,4 12,4 C10.54,4 9.14,4.58 8.11,5.61 C7.08,6.64 6.5,8.04 6.5,9.5 C6.49,10.39 6.7,11.26 7.11,12.04 C7.52,12.83 8.12,13.5 8.85,14c  M7.44 3.56 C8.75,2.55 10.35,2 12,2 C12,2 12,2 12,2 C13.65,2 15.26,2.55 16.56,3.56 C17.87,4.56 18.81,5.97 19.24,7.57 C19.66,9.16 19.55,10.86 18.92,12.38 C18.28,13.9 17.16,15.18 15.73,16 C15.73,16 8.27,16 8.27,16 C6.84,15.18 5.72,13.9 5.09,12.38 C4.45,10.86 4.34,9.16 4.76,7.57 C5.19,5.97 6.13,4.56 7.44,3.56c "/>
+        </group>
+        <group android:name="_R_G_L_0_G" android:translateY="0.25" android:pivotX="11.996" android:pivotY="14" android:scaleX="1.1" android:scaleY="1.1">
+          <path android:name="_R_G_L_0_G_D_1_P_0" android:fillColor="#000000" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M8.85 14 C8.85,14 15.15,14 15.15,14 C15.15,14 15.15,14 15.15,14 C15.88,13.5 16.47,12.83 16.88,12.04 C17.29,11.26 17.5,10.39 17.5,9.5 C17.5,8.04 16.92,6.64 15.89,5.61 C14.85,4.58 13.46,4 12,4 C10.54,4 9.14,4.58 8.11,5.61 C7.08,6.64 6.5,8.04 6.5,9.5 C6.49,10.39 6.7,11.26 7.11,12.04 C7.52,12.83 8.12,13.5 8.85,14c "/>
+        </group>
+      </group>
+      <group android:name="time_group"/>
+    </vector>
+  </aapt:attr>
+  <target android:name="_R_G_L_0_G">
+    <aapt:attr name="android:animation">
+      <set android:ordering="together">
+        <objectAnimator android:propertyName="scaleX" android:duration="417" android:startOffset="0" android:valueFrom="1.1" android:valueTo="0" android:valueType="floatType">
+          <aapt:attr name="android:interpolator">
+            <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0"/>
+          </aapt:attr>
+        </objectAnimator>
+        <objectAnimator android:propertyName="scaleY" android:duration="417" android:startOffset="0" android:valueFrom="1.1" android:valueTo="0" android:valueType="floatType">
+          <aapt:attr name="android:interpolator">
+            <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0"/>
+          </aapt:attr>
+        </objectAnimator>
+      </set>
+    </aapt:attr>
+  </target>
+  <target android:name="_R_G_L_0_G">
+    <aapt:attr name="android:animation">
+      <set android:ordering="together">
+        <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="417" android:valueFrom="1.1" android:valueTo="0" android:valueType="floatType"/>
+      </set>
+    </aapt:attr>
+  </target>
+  <target android:name="time_group">
+    <aapt:attr name="android:animation">
+      <set android:ordering="together">
+        <objectAnimator android:propertyName="translateX" android:duration="750" android:startOffset="0" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+      </set>
+    </aapt:attr>
+  </target>
+</animated-vector>
diff --git a/packages/SystemUI/res/drawable/ic_device_light_on_anim.xml b/packages/SystemUI/res/drawable/ic_device_light_on_anim.xml
new file mode 100644
index 0000000..bb9c58b
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_device_light_on_anim.xml
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2020 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
+  -->
+<animated-vector
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:aapt="http://schemas.android.com/aapt">
+  <aapt:attr name="android:drawable">
+    <vector android:height="24dp" android:width="24dp" android:viewportHeight="24" android:viewportWidth="24">
+      <group android:name="_R_G">
+        <group android:name="_R_G_L_1_G" android:translateY="0.25" android:pivotX="11.996" android:pivotY="14" android:scaleX="0" android:scaleY="0">
+          <path android:name="_R_G_L_1_G_D_1_P_0" android:fillColor="#000000" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M8.85 14 C8.85,14 15.15,14 15.15,14 C15.15,14 15.15,14 15.15,14 C15.88,13.5 16.47,12.83 16.88,12.04 C17.29,11.26 17.5,10.39 17.5,9.5 C17.5,8.04 16.92,6.64 15.89,5.61 C14.85,4.58 13.46,4 12,4 C10.54,4 9.14,4.58 8.11,5.61 C7.08,6.64 6.5,8.04 6.5,9.5 C6.49,10.39 6.7,11.26 7.11,12.04 C7.52,12.83 8.12,13.5 8.85,14c "/>
+        </group>
+        <group android:name="_R_G_L_0_G">
+          <path android:name="_R_G_L_0_G_D_0_P_0" android:fillColor="#000000" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M13.41 21.41 C13.04,21.79 12.53,22 12,22 C11.47,22 10.96,21.79 10.59,21.41 C10.21,21.04 10,20.53 10,20 C10,20 14,20 14,20 C14,20.53 13.79,21.04 13.41,21.41c "/>
+          <path android:name="_R_G_L_0_G_D_1_P_0" android:fillColor="#000000" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M8 17 C8,17 16,17 16,17 C16,17 16,19 16,19 C16,19 8,19 8,19 C8,19 8,17 8,17c "/>
+          <path android:name="_R_G_L_0_G_D_2_P_0" android:fillColor="#000000" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M8.85 14 C8.85,14 15.15,14 15.15,14 C15.15,14 15.15,14 15.15,14 C15.88,13.5 16.47,12.83 16.88,12.04 C17.29,11.26 17.5,10.39 17.5,9.5 C17.5,8.04 16.92,6.64 15.89,5.61 C14.85,4.58 13.46,4 12,4 C10.54,4 9.14,4.58 8.11,5.61 C7.08,6.64 6.5,8.04 6.5,9.5 C6.49,10.39 6.7,11.26 7.11,12.04 C7.52,12.83 8.12,13.5 8.85,14c  M7.44 3.56 C8.75,2.55 10.35,2 12,2 C12,2 12,2 12,2 C13.65,2 15.26,2.55 16.56,3.56 C17.87,4.56 18.81,5.97 19.24,7.57 C19.66,9.16 19.55,10.86 18.92,12.38 C18.28,13.9 17.16,15.18 15.73,16 C15.73,16 8.27,16 8.27,16 C6.84,15.18 5.72,13.9 5.09,12.38 C4.45,10.86 4.34,9.16 4.76,7.57 C5.19,5.97 6.13,4.56 7.44,3.56c "/>
+        </group>
+      </group>
+      <group android:name="time_group"/>
+    </vector>
+  </aapt:attr>
+  <target android:name="_R_G_L_1_G">
+    <aapt:attr name="android:animation">
+      <set android:ordering="together">
+        <objectAnimator android:propertyName="scaleX" android:duration="417" android:startOffset="0" android:valueFrom="0" android:valueTo="1.1" android:valueType="floatType">
+          <aapt:attr name="android:interpolator">
+            <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0"/>
+          </aapt:attr>
+        </objectAnimator>
+        <objectAnimator android:propertyName="scaleY" android:duration="417" android:startOffset="0" android:valueFrom="0" android:valueTo="1.1" android:valueType="floatType">
+          <aapt:attr name="android:interpolator">
+            <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0"/>
+          </aapt:attr>
+        </objectAnimator>
+      </set>
+    </aapt:attr>
+  </target>
+  <target android:name="time_group">
+    <aapt:attr name="android:animation">
+      <set android:ordering="together">
+        <objectAnimator android:propertyName="translateX" android:duration="750" android:startOffset="0" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+      </set>
+    </aapt:attr>
+  </target>
+</animated-vector>
diff --git a/packages/SystemUI/res/drawable/ic_device_lock.xml b/packages/SystemUI/res/drawable/ic_device_lock.xml
new file mode 100644
index 0000000..d291ba4
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_device_lock.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2020 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
+  -->
+<animated-selector
+    xmlns:android="http://schemas.android.com/apk/res/android">
+  <item
+      android:id="@+id/off"
+      android:state_enabled="false"
+      android:drawable="@drawable/ic_device_lock_off" />
+  <item
+      android:id="@+id/on"
+      android:state_enabled="true"
+      android:drawable="@drawable/ic_device_lock_on" />
+  <transition
+      android:fromId="@id/off"
+      android:toId="@id/on"
+      android:drawable="@drawable/ic_device_lock_on_anim" />
+  <transition
+      android:fromId="@id/on"
+      android:toId="@id/off"
+      android:drawable="@drawable/ic_device_lock_off_anim" />
+</animated-selector>
diff --git a/packages/SystemUI/res/drawable/ic_device_lock_off_anim.xml b/packages/SystemUI/res/drawable/ic_device_lock_off_anim.xml
new file mode 100644
index 0000000..321bf10
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_device_lock_off_anim.xml
@@ -0,0 +1,164 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2020 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
+  -->
+<animated-vector
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:aapt="http://schemas.android.com/aapt">
+  <aapt:attr name="android:drawable">
+    <vector android:height="24dp" android:width="24dp" android:viewportHeight="24" android:viewportWidth="24">
+      <group android:name="_R_G">
+        <group android:name="_R_G_L_2_G_N_1_T_0" android:translateX="12.008" android:translateY="11.992">
+          <group android:name="_R_G_L_2_G" android:translateY="-0.5">
+            <path android:name="_R_G_L_2_G_D_0_P_0" android:fillColor="#000000" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M-6 8.5 C-6,8.5 6,8.5 6,8.5 C6,8.5 6,-1.5 6,-1.5 C6,-1.5 -6,-1.5 -6,-1.5 C-6,-1.5 -6,8.5 -6,8.5c  M5 -3.5 C5,-3.5 6,-3.5 6,-3.5 C6,-3.5 6,-3.5 6,-3.5 C6.53,-3.5 7.04,-3.29 7.41,-2.91 C7.79,-2.54 8,-2.03 8,-1.5 C8,-1.5 8,8.5 8,8.5 C8,9.03 7.79,9.54 7.41,9.91 C7.04,10.29 6.53,10.5 6,10.5 C6,10.5 -6,10.5 -6,10.5 C-6.53,10.5 -7.04,10.29 -7.41,9.91 C-7.79,9.54 -8,9.03 -8,8.5 C-8,8.5 -8,-1.5 -8,-1.5 C-8,-2.03 -7.79,-2.54 -7.41,-2.91 C-7.04,-3.29 -6.53,-3.5 -6,-3.5 C-6,-3.5 3.1,-3.5 3.1,-3.5 C3.1,-3.5 3.1,-5.5 3.1,-5.5 C3.1,-6.32 2.77,-7.11 2.19,-7.69 C1.61,-8.27 0.82,-8.6 0,-8.6 C-0.82,-8.6 -1.61,-8.27 -2.19,-7.69 C-2.76,-7.12 -3.09,-6.34 -3.1,-5.53 C-3.1,-5.52 -3.1,-3.48 -3.1,-3.47 C-3.1,-3.47 -5,-3.47 -5,-3.47 C-5,-3.48 -5,-5.52 -5,-5.54 C-4.99,-6.85 -4.46,-8.11 -3.54,-9.04 C-2.6,-9.97 -1.33,-10.5 0,-10.5 C1.33,-10.5 2.6,-9.97 3.54,-9.04 C4.47,-8.1 5,-6.83 5,-5.5 C5,-5.5 5,-3.5 5,-3.5c "/>
+          </group>
+        </group>
+        <group android:name="_R_G_L_1_G_N_1_T_0" android:translateX="12.008" android:translateY="11.992" android:scaleY="0">
+          <group android:name="_R_G_L_1_G" android:translateY="-0.5">
+            <group android:name="_R_G_L_1_C_0_G">
+              <clip-path android:name="_R_G_L_1_C_0" android:pathData=" M0 -4.8 C-4.6,-4.8 -8.32,-1.09 -8.32,3.5 C-8.32,8.08 -4.6,11.8 0,11.8 C4.59,11.8 8.32,8.08 8.32,3.5 C8.32,-1.09 4.59,-4.8 0,-4.8c "/>
+              <group android:name="_R_G_L_1_C_0_G_G">
+                <path android:name="_R_G_L_1_G_G_0_D_0_P_0" android:fillColor="#000000" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M5 -3.5 C5,-3.5 6,-3.5 6,-3.5 C6,-3.5 6,-3.5 6,-3.5 C6.53,-3.5 7.04,-3.29 7.41,-2.91 C7.79,-2.54 8,-2.03 8,-1.5 C8,-1.5 8,8.5 8,8.5 C8,9.03 7.79,9.54 7.41,9.91 C7.04,10.29 6.53,10.5 6,10.5 C6,10.5 -6,10.5 -6,10.5 C-6.53,10.5 -7.04,10.29 -7.41,9.91 C-7.79,9.54 -8,9.03 -8,8.5 C-8,8.5 -8,-1.5 -8,-1.5 C-8,-2.03 -7.79,-2.54 -7.41,-2.91 C-7.04,-3.29 -6.53,-3.5 -6,-3.5 C-6,-3.5 3.1,-3.5 3.1,-3.5 C3.1,-3.5 5,-3.5 5,-3.5c "/>
+              </group>
+            </group>
+          </group>
+        </group>
+        <group android:name="_R_G_L_0_G_N_1_T_0" android:translateX="12.008" android:translateY="11.992">
+          <group android:name="_R_G_L_0_G" android:translateX="-0.006" android:translateY="-0.5">
+            <group android:name="_R_G_L_0_C_0_G">
+              <clip-path android:name="_R_G_L_0_C_0" android:pathData=" M7.6 -2.1 C7.6,-2.1 -7.42,-2.1 -7.42,-2.1 C-7.42,-2.1 -7.42,9.61 -7.42,9.61 C-7.42,9.61 7.6,9.61 7.6,9.61 C7.6,9.61 7.6,-2.1 7.6,-2.1c "/>
+              <group android:name="_R_G_L_0_C_0_G_G">
+                <path android:name="_R_G_L_0_G_G_0_D_0_P_0" android:fillColor="#000000" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M-1.11 5.16 C-0.78,5.38 -0.4,5.5 0,5.5 C0,5.5 0,5.5 0,5.5 C0.53,5.5 1.04,5.29 1.41,4.91 C1.79,4.54 2,4.03 2,3.5 C2,3.1 1.88,2.72 1.66,2.39 C1.44,2.06 1.13,1.8 0.77,1.65 C0.4,1.5 0,1.46 -0.39,1.54 C-0.78,1.62 -1.13,1.81 -1.41,2.09 C-1.69,2.37 -1.88,2.72 -1.96,3.11 C-2.04,3.5 -2,3.9 -1.85,4.26 C-1.7,4.63 -1.44,4.94 -1.11,5.16c  M5 -3.5 C5,-3.5 6,-3.5 6,-3.5 C6,-3.5 6,-3.5 6,-3.5 C6.53,-3.5 7.04,-3.29 7.41,-2.91 C7.79,-2.54 8,-2.03 8,-1.5 C8,-1.5 8,8.5 8,8.5 C8,9.03 7.79,9.54 7.41,9.91 C7.04,10.29 6.53,10.5 6,10.5 C6,10.5 -6,10.5 -6,10.5 C-6.53,10.5 -7.04,10.29 -7.41,9.91 C-7.79,9.54 -8,9.03 -8,8.5 C-8,8.5 -8,-1.5 -8,-1.5 C-8,-2.03 -7.79,-2.54 -7.41,-2.91 C-7.04,-3.29 -6.53,-3.5 -6,-3.5 C-6,-3.5 3.1,-3.5 3.1,-3.5 C3.1,-3.5 3.1,-5.5 3.1,-5.5 C3.1,-5.91 3.02,-6.31 2.86,-6.69 C2.71,-7.06 2.48,-7.4 2.19,-7.69 C1.9,-7.98 1.56,-8.21 1.19,-8.36 C0.81,-8.52 0.41,-8.6 0,-8.6 C-0.41,-8.6 -0.81,-8.52 -1.19,-8.36 C-1.56,-8.21 -1.9,-7.98 -2.19,-7.69 C-2.48,-7.4 -2.71,-7.06 -2.86,-6.69 C-3.02,-6.31 -3.1,-5.91 -3.1,-5.5 C-3.1,-5.5 -5,-5.5 -5,-5.5 C-5,-6.83 -4.47,-8.1 -3.54,-9.04 C-2.6,-9.97 -1.33,-10.5 0,-10.5 C1.33,-10.5 2.6,-9.97 3.54,-9.04 C4.47,-8.1 5,-6.83 5,-5.5 C5,-5.5 5,-3.5 5,-3.5c "/>
+              </group>
+            </group>
+          </group>
+        </group>
+      </group>
+      <group android:name="time_group"/>
+    </vector>
+  </aapt:attr>
+  <target android:name="_R_G_L_2_G_D_0_P_0">
+    <aapt:attr name="android:animation">
+      <set android:ordering="together">
+        <objectAnimator android:propertyName="pathData" android:duration="283" android:startOffset="0" android:valueFrom=" M-6 8.5 C-6,8.5 6,8.5 6,8.5 C6,8.5 6,-1.5 6,-1.5 C6,-1.5 -6,-1.5 -6,-1.5 C-6,-1.5 -6,8.5 -6,8.5c M5 -3.5 C5,-3.5 6,-3.5 6,-3.5 C6,-3.5 6,-3.5 6,-3.5 C6.53,-3.5 7.04,-3.29 7.41,-2.91 C7.79,-2.54 8,-2.03 8,-1.5 C8,-1.5 8,8.5 8,8.5 C8,9.03 7.79,9.54 7.41,9.91 C7.04,10.29 6.53,10.5 6,10.5 C6,10.5 -6,10.5 -6,10.5 C-6.53,10.5 -7.04,10.29 -7.41,9.91 C-7.79,9.54 -8,9.03 -8,8.5 C-8,8.5 -8,-1.5 -8,-1.5 C-8,-2.03 -7.79,-2.54 -7.41,-2.91 C-7.04,-3.29 -6.53,-3.5 -6,-3.5 C-6,-3.5 3.1,-3.5 3.1,-3.5 C3.1,-3.5 3.1,-5.5 3.1,-5.5 C3.1,-6.32 2.77,-7.11 2.19,-7.69 C1.61,-8.27 0.82,-8.6 0,-8.6 C-0.82,-8.6 -1.61,-8.27 -2.19,-7.69 C-2.76,-7.12 -3.09,-6.34 -3.1,-5.53 C-3.1,-5.52 -3.1,-3.48 -3.1,-3.47 C-3.1,-3.47 -5,-3.47 -5,-3.47 C-5,-3.48 -5,-5.52 -5,-5.54 C-4.99,-6.85 -4.46,-8.11 -3.54,-9.04 C-2.6,-9.97 -1.33,-10.5 0,-10.5 C1.33,-10.5 2.6,-9.97 3.54,-9.04 C4.47,-8.1 5,-6.83 5,-5.5 C5,-5.5 5,-3.5 5,-3.5c " android:valueTo=" M-6 8.5 C-6,8.5 6,8.5 6,8.5 C6,8.5 6,-1.5 6,-1.5 C6,-1.5 -6,-1.5 -6,-1.5 C-6,-1.5 -6,8.5 -6,8.5c M5 -3.5 C5,-3.5 6,-3.5 6,-3.5 C6,-3.5 6,-3.5 6,-3.5 C6.53,-3.5 7.04,-3.29 7.41,-2.91 C7.79,-2.54 8,-2.03 8,-1.5 C8,-1.5 8,8.5 8,8.5 C8,9.03 7.79,9.54 7.41,9.91 C7.04,10.29 6.53,10.5 6,10.5 C6,10.5 -6,10.5 -6,10.5 C-6.53,10.5 -7.04,10.29 -7.41,9.91 C-7.79,9.54 -8,9.03 -8,8.5 C-8,8.5 -8,-1.5 -8,-1.5 C-8,-2.03 -7.79,-2.54 -7.41,-2.91 C-7.04,-3.29 -6.53,-3.5 -6,-3.5 C-6,-3.5 3.1,-3.5 3.1,-3.5 C3.1,-3.5 3.1,-5.5 3.1,-5.5 C3.1,-6.32 2.77,-7.11 2.19,-7.69 C1.61,-8.27 0.82,-8.6 0,-8.6 C-0.82,-8.6 -1.61,-8.27 -2.19,-7.69 C-2.76,-7.12 -3.09,-6.34 -3.1,-5.53 C-3.1,-5.52 -3.1,-3.48 -3.1,-3.47 C-3.1,-3.47 -5,-3.47 -5,-3.47 C-5,-3.48 -5,-5.52 -5,-5.54 C-4.99,-6.85 -4.46,-8.11 -3.54,-9.04 C-2.6,-9.97 -1.33,-10.5 0,-10.5 C1.33,-10.5 2.6,-9.97 3.54,-9.04 C4.47,-8.1 5,-6.83 5,-5.5 C5,-5.5 5,-3.5 5,-3.5c " android:valueType="pathType">
+          <aapt:attr name="android:interpolator">
+            <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0"/>
+          </aapt:attr>
+        </objectAnimator>
+        <objectAnimator android:propertyName="pathData" android:duration="217" android:startOffset="283" android:valueFrom=" M-6 8.5 C-6,8.5 6,8.5 6,8.5 C6,8.5 6,-1.5 6,-1.5 C6,-1.5 -6,-1.5 -6,-1.5 C-6,-1.5 -6,8.5 -6,8.5c M5 -3.5 C5,-3.5 6,-3.5 6,-3.5 C6,-3.5 6,-3.5 6,-3.5 C6.53,-3.5 7.04,-3.29 7.41,-2.91 C7.79,-2.54 8,-2.03 8,-1.5 C8,-1.5 8,8.5 8,8.5 C8,9.03 7.79,9.54 7.41,9.91 C7.04,10.29 6.53,10.5 6,10.5 C6,10.5 -6,10.5 -6,10.5 C-6.53,10.5 -7.04,10.29 -7.41,9.91 C-7.79,9.54 -8,9.03 -8,8.5 C-8,8.5 -8,-1.5 -8,-1.5 C-8,-2.03 -7.79,-2.54 -7.41,-2.91 C-7.04,-3.29 -6.53,-3.5 -6,-3.5 C-6,-3.5 3.1,-3.5 3.1,-3.5 C3.1,-3.5 3.1,-5.5 3.1,-5.5 C3.1,-6.32 2.77,-7.11 2.19,-7.69 C1.61,-8.27 0.82,-8.6 0,-8.6 C-0.82,-8.6 -1.61,-8.27 -2.19,-7.69 C-2.76,-7.12 -3.09,-6.34 -3.1,-5.53 C-3.1,-5.52 -3.1,-3.48 -3.1,-3.47 C-3.1,-3.47 -5,-3.47 -5,-3.47 C-5,-3.48 -5,-5.52 -5,-5.54 C-4.99,-6.85 -4.46,-8.11 -3.54,-9.04 C-2.6,-9.97 -1.33,-10.5 0,-10.5 C1.33,-10.5 2.6,-9.97 3.54,-9.04 C4.47,-8.1 5,-6.83 5,-5.5 C5,-5.5 5,-3.5 5,-3.5c " android:valueTo=" M-6 8.5 C-6,8.5 6,8.5 6,8.5 C6,8.5 6,-1.5 6,-1.5 C6,-1.5 -6,-1.5 -6,-1.5 C-6,-1.5 -6,8.5 -6,8.5c M5 -3.5 C5,-3.5 6,-3.5 6,-3.5 C6,-3.5 6,-3.5 6,-3.5 C6.53,-3.5 7.04,-3.29 7.41,-2.91 C7.79,-2.54 8,-2.03 8,-1.5 C8,-1.5 8,8.5 8,8.5 C8,9.03 7.79,9.54 7.41,9.91 C7.04,10.29 6.53,10.5 6,10.5 C6,10.5 -6,10.5 -6,10.5 C-6.53,10.5 -7.04,10.29 -7.41,9.91 C-7.79,9.54 -8,9.03 -8,8.5 C-8,8.5 -8,-1.5 -8,-1.5 C-8,-2.03 -7.79,-2.54 -7.41,-2.91 C-7.04,-3.29 -6.53,-3.5 -6,-3.5 C-6,-3.5 3.1,-3.5 3.1,-3.5 C3.1,-3.5 3.1,-5.5 3.1,-5.5 C3.1,-6.32 2.77,-7.11 2.19,-7.69 C1.61,-8.27 0.82,-8.6 0,-8.6 C-0.82,-8.6 -1.61,-8.27 -2.19,-7.69 C-2.76,-7.12 -3.09,-6.34 -3.1,-5.53 C-3.1,-5.52 -3.1,-5.51 -3.1,-5.5 C-3.1,-5.5 -5,-5.5 -5,-5.5 C-5,-5.51 -5,-5.52 -5,-5.54 C-4.99,-6.85 -4.46,-8.11 -3.54,-9.04 C-2.6,-9.97 -1.33,-10.5 0,-10.5 C1.33,-10.5 2.6,-9.97 3.54,-9.04 C4.47,-8.1 5,-6.83 5,-5.5 C5,-5.5 5,-3.5 5,-3.5c " android:valueType="pathType">
+          <aapt:attr name="android:interpolator">
+            <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0"/>
+          </aapt:attr>
+        </objectAnimator>
+      </set>
+    </aapt:attr>
+  </target>
+  <target android:name="_R_G_L_2_G_N_1_T_0">
+    <aapt:attr name="android:animation">
+      <set android:ordering="together">
+        <objectAnimator android:propertyName="translateXY" android:duration="211" android:startOffset="0" android:propertyXName="translateX" android:propertyYName="translateY" android:pathData="M 12.008,11.992C 12.008,12.159 12.008,12.992 12.008,12.992">
+          <aapt:attr name="android:interpolator">
+            <pathInterpolator android:pathData="M 0.0,0.0 c0.8,0 0.6,1 1.0,1.0"/>
+          </aapt:attr>
+        </objectAnimator>
+        <objectAnimator android:propertyName="translateXY" android:duration="106" android:startOffset="211" android:propertyXName="translateX" android:propertyYName="translateY" android:pathData="M 12.008,12.992C 12.008,12.992 12.008,12.159 12.008,11.992">
+          <aapt:attr name="android:interpolator">
+            <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0"/>
+          </aapt:attr>
+        </objectAnimator>
+      </set>
+    </aapt:attr>
+  </target>
+  <target android:name="_R_G_L_1_C_0">
+    <aapt:attr name="android:animation">
+      <set android:ordering="together">
+        <objectAnimator android:propertyName="pathData" android:duration="200" android:startOffset="0" android:valueFrom="M0 -4.8 C-4.6,-4.8 -8.32,-1.09 -8.32,3.5 C-8.32,8.08 -4.6,11.8 0,11.8 C4.59,11.8 8.32,8.08 8.32,3.5 C8.32,-1.09 4.59,-4.8 0,-4.8c " android:valueTo="M0 -4.8 C-4.6,-4.8 -8.32,-1.09 -8.32,3.5 C-8.32,8.08 -4.6,11.8 0,11.8 C4.59,11.8 8.32,8.08 8.32,3.5 C8.32,-1.09 4.59,-4.8 0,-4.8c " android:valueType="pathType">
+          <aapt:attr name="android:interpolator">
+            <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0"/>
+          </aapt:attr>
+        </objectAnimator>
+        <objectAnimator android:propertyName="pathData" android:duration="300" android:startOffset="200" android:valueFrom="M0 -4.8 C-4.6,-4.8 -8.32,-1.09 -8.32,3.5 C-8.32,8.08 -4.6,11.8 0,11.8 C4.59,11.8 8.32,8.08 8.32,3.5 C8.32,-1.09 4.59,-4.8 0,-4.8c " android:valueTo="M0 1.5 C-1.11,1.5 -2,2.4 -2,3.5 C-2,4.6 -1.11,5.49 0,5.49 C1.1,5.49 2,4.6 2,3.5 C2,2.4 1.1,1.5 0,1.5c " android:valueType="pathType">
+          <aapt:attr name="android:interpolator">
+            <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0"/>
+          </aapt:attr>
+        </objectAnimator>
+      </set>
+    </aapt:attr>
+  </target>
+  <target android:name="_R_G_L_1_G_N_1_T_0">
+    <aapt:attr name="android:animation">
+      <set android:ordering="together">
+        <objectAnimator android:propertyName="translateXY" android:duration="211" android:startOffset="0" android:propertyXName="translateX" android:propertyYName="translateY" android:pathData="M 12.008,11.992C 12.008,12.159 12.008,12.992 12.008,12.992">
+          <aapt:attr name="android:interpolator">
+            <pathInterpolator android:pathData="M 0.0,0.0 c0.8,0 0.6,1 1.0,1.0"/>
+          </aapt:attr>
+        </objectAnimator>
+        <objectAnimator android:propertyName="translateXY" android:duration="106" android:startOffset="211" android:propertyXName="translateX" android:propertyYName="translateY" android:pathData="M 12.008,12.992C 12.008,12.992 12.008,12.159 12.008,11.992">
+          <aapt:attr name="android:interpolator">
+            <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0"/>
+          </aapt:attr>
+        </objectAnimator>
+      </set>
+    </aapt:attr>
+  </target>
+  <target android:name="_R_G_L_1_G_N_1_T_0">
+    <aapt:attr name="android:animation">
+      <set android:ordering="together">
+        <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="200" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+      </set>
+    </aapt:attr>
+  </target>
+  <target android:name="_R_G_L_0_G_G_0_D_0_P_0">
+    <aapt:attr name="android:animation">
+      <set android:ordering="together">
+        <objectAnimator android:propertyName="pathData" android:duration="300" android:startOffset="0" android:valueFrom="M-1.11 5.16 C-0.78,5.38 -0.4,5.5 0,5.5 C0,5.5 0,5.5 0,5.5 C0.53,5.5 1.04,5.29 1.41,4.91 C1.79,4.54 2,4.03 2,3.5 C2,3.1 1.88,2.72 1.66,2.39 C1.44,2.06 1.13,1.8 0.77,1.65 C0.4,1.5 0,1.46 -0.39,1.54 C-0.78,1.62 -1.13,1.81 -1.41,2.09 C-1.69,2.37 -1.88,2.72 -1.96,3.11 C-2.04,3.5 -2,3.9 -1.85,4.26 C-1.7,4.63 -1.44,4.94 -1.11,5.16c  M5 -3.5 C5,-3.5 6,-3.5 6,-3.5 C6,-3.5 6,-3.5 6,-3.5 C6.53,-3.5 7.04,-3.29 7.41,-2.91 C7.79,-2.54 8,-2.03 8,-1.5 C8,-1.5 8,8.5 8,8.5 C8,9.03 7.79,9.54 7.41,9.91 C7.04,10.29 6.53,10.5 6,10.5 C6,10.5 -6,10.5 -6,10.5 C-6.53,10.5 -7.04,10.29 -7.41,9.91 C-7.79,9.54 -8,9.03 -8,8.5 C-8,8.5 -8,-1.5 -8,-1.5 C-8,-2.03 -7.79,-2.54 -7.41,-2.91 C-7.04,-3.29 -6.53,-3.5 -6,-3.5 C-6,-3.5 3.1,-3.5 3.1,-3.5 C3.1,-3.5 3.1,-5.5 3.1,-5.5 C3.1,-5.91 3.02,-6.31 2.86,-6.69 C2.71,-7.06 2.48,-7.4 2.19,-7.69 C1.9,-7.98 1.56,-8.21 1.19,-8.36 C0.81,-8.52 0.41,-8.6 0,-8.6 C-0.41,-8.6 -0.81,-8.52 -1.19,-8.36 C-1.56,-8.21 -1.9,-7.98 -2.19,-7.69 C-2.48,-7.4 -2.71,-7.06 -2.86,-6.69 C-3.02,-6.31 -3.1,-5.91 -3.1,-5.5 C-3.1,-5.5 -5,-5.5 -5,-5.5 C-5,-6.83 -4.47,-8.1 -3.54,-9.04 C-2.6,-9.97 -1.33,-10.5 0,-10.5 C1.33,-10.5 2.6,-9.97 3.54,-9.04 C4.47,-8.1 5,-6.83 5,-5.5 C5,-5.5 5,-3.5 5,-3.5c " android:valueTo="M-0.03 3.5 C-0.03,3.5 -0.02,3.5 -0.02,3.5 C-0.02,3.5 -0.02,3.5 -0.02,3.5 C-0.01,3.5 -0.01,3.5 -0.01,3.49 C0,3.49 0,3.49 0,3.48 C0,3.48 0,3.47 0,3.47 C0,3.47 -0.01,3.46 -0.01,3.46 C-0.02,3.46 -0.02,3.46 -0.02,3.46 C-0.03,3.46 -0.03,3.46 -0.03,3.47 C-0.04,3.47 -0.04,3.47 -0.04,3.48 C-0.04,3.48 -0.04,3.48 -0.04,3.49 C-0.04,3.49 -0.03,3.5 -0.03,3.5c  M5 -3.5 C5,-3.5 6,-3.5 6,-3.5 C6,-3.5 6,-3.5 6,-3.5 C6.53,-3.5 7.04,-3.29 7.41,-2.91 C7.79,-2.54 8,-2.03 8,-1.5 C8,-1.5 8,8.5 8,8.5 C8,9.03 7.79,9.54 7.41,9.91 C7.04,10.29 6.53,10.5 6,10.5 C6,10.5 -6,10.5 -6,10.5 C-6.53,10.5 -7.04,10.29 -7.41,9.91 C-7.79,9.54 -8,9.03 -8,8.5 C-8,8.5 -8,-1.5 -8,-1.5 C-8,-2.03 -7.79,-2.54 -7.41,-2.91 C-7.04,-3.29 -6.53,-3.5 -6,-3.5 C-6,-3.5 3.1,-3.5 3.1,-3.5 C3.1,-3.5 3.1,-5.5 3.1,-5.5 C3.1,-5.91 3.02,-6.31 2.86,-6.69 C2.71,-7.06 2.48,-7.4 2.19,-7.69 C1.9,-7.98 1.56,-8.21 1.19,-8.36 C0.81,-8.52 0.41,-8.6 0,-8.6 C-0.41,-8.6 -0.81,-8.52 -1.19,-8.36 C-1.56,-8.21 -1.9,-7.98 -2.19,-7.69 C-2.48,-7.4 -2.71,-7.06 -2.86,-6.69 C-3.02,-6.31 -3.1,-5.91 -3.1,-5.5 C-3.1,-5.5 -5,-5.5 -5,-5.5 C-5,-6.83 -4.47,-8.1 -3.54,-9.04 C-2.6,-9.97 -1.33,-10.5 0,-10.5 C1.33,-10.5 2.6,-9.97 3.54,-9.04 C4.47,-8.1 5,-6.83 5,-5.5 C5,-5.5 5,-3.5 5,-3.5c " android:valueType="pathType">
+          <aapt:attr name="android:interpolator">
+            <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0"/>
+          </aapt:attr>
+        </objectAnimator>
+      </set>
+    </aapt:attr>
+  </target>
+  <target android:name="_R_G_L_0_G_N_1_T_0">
+    <aapt:attr name="android:animation">
+      <set android:ordering="together">
+        <objectAnimator android:propertyName="translateXY" android:duration="211" android:startOffset="0" android:propertyXName="translateX" android:propertyYName="translateY" android:pathData="M 12.008,11.992C 12.008,12.159 12.008,12.992 12.008,12.992">
+          <aapt:attr name="android:interpolator">
+            <pathInterpolator android:pathData="M 0.0,0.0 c0.8,0 0.6,1 1.0,1.0"/>
+          </aapt:attr>
+        </objectAnimator>
+        <objectAnimator android:propertyName="translateXY" android:duration="106" android:startOffset="211" android:propertyXName="translateX" android:propertyYName="translateY" android:pathData="M 12.008,12.992C 12.008,12.992 12.008,12.159 12.008,11.992">
+          <aapt:attr name="android:interpolator">
+            <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0"/>
+          </aapt:attr>
+        </objectAnimator>
+      </set>
+    </aapt:attr>
+  </target>
+  <target android:name="_R_G_L_0_G_N_1_T_0">
+    <aapt:attr name="android:animation">
+      <set android:ordering="together">
+        <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="283" android:valueFrom="1" android:valueTo="0" android:valueType="floatType"/>
+      </set>
+    </aapt:attr>
+  </target>
+  <target android:name="time_group">
+    <aapt:attr name="android:animation">
+      <set android:ordering="together">
+        <objectAnimator android:propertyName="translateX" android:duration="750" android:startOffset="0" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+      </set>
+    </aapt:attr>
+  </target>
+</animated-vector>
diff --git a/packages/SystemUI/res/drawable/ic_device_lock_on_anim.xml b/packages/SystemUI/res/drawable/ic_device_lock_on_anim.xml
new file mode 100644
index 0000000..3c19a7b
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_device_lock_on_anim.xml
@@ -0,0 +1,159 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2020 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
+  -->
+<animated-vector
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:aapt="http://schemas.android.com/aapt">
+  <aapt:attr name="android:drawable">
+    <vector android:height="24dp" android:width="24dp" android:viewportHeight="24" android:viewportWidth="24">
+      <group android:name="_R_G">
+        <group android:name="_R_G_L_2_G_N_1_T_0" android:translateX="12.008" android:translateY="11.992">
+          <group android:name="_R_G_L_2_G" android:translateY="-0.5">
+            <path android:name="_R_G_L_2_G_D_0_P_0" android:fillColor="#000000" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M-6 8.5 C-6,8.5 6,8.5 6,8.5 C6,8.5 6,-1.5 6,-1.5 C6,-1.5 -6,-1.5 -6,-1.5 C-6,-1.5 -6,8.5 -6,8.5c  M5 -3.5 C5,-3.5 6,-3.5 6,-3.5 C6,-3.5 6,-3.5 6,-3.5 C6.53,-3.5 7.04,-3.29 7.41,-2.91 C7.79,-2.54 8,-2.03 8,-1.5 C8,-1.5 8,8.5 8,8.5 C8,9.03 7.79,9.54 7.41,9.91 C7.04,10.29 6.53,10.5 6,10.5 C6,10.5 -6,10.5 -6,10.5 C-6.53,10.5 -7.04,10.29 -7.41,9.91 C-7.79,9.54 -8,9.03 -8,8.5 C-8,8.5 -8,-1.5 -8,-1.5 C-8,-2.03 -7.79,-2.54 -7.41,-2.91 C-7.04,-3.29 -6.53,-3.5 -6,-3.5 C-6,-3.5 3.1,-3.5 3.1,-3.5 C3.1,-3.5 3.1,-5.5 3.1,-5.5 C3.1,-6.32 2.77,-7.11 2.19,-7.69 C1.61,-8.27 0.82,-8.6 0,-8.6 C-0.82,-8.6 -1.61,-8.27 -2.19,-7.69 C-2.76,-7.12 -3.09,-6.34 -3.1,-5.53 C-3.1,-5.52 -3.1,-5.51 -3.1,-5.5 C-3.1,-5.5 -5,-5.5 -5,-5.5 C-5,-5.51 -5,-5.52 -5,-5.54 C-4.99,-6.85 -4.46,-8.11 -3.54,-9.04 C-2.6,-9.97 -1.33,-10.5 0,-10.5 C1.33,-10.5 2.6,-9.97 3.54,-9.04 C4.47,-8.1 5,-6.83 5,-5.5 C5,-5.5 5,-3.5 5,-3.5c "/>
+          </group>
+        </group>
+        <group android:name="_R_G_L_1_G_N_1_T_0" android:translateX="12.008" android:translateY="11.992">
+          <group android:name="_R_G_L_1_G" android:translateY="-0.5">
+            <group android:name="_R_G_L_1_C_0_G">
+              <clip-path android:name="_R_G_L_1_C_0" android:pathData=" M0 1.5 C-1.11,1.5 -2,2.4 -2,3.5 C-2,4.6 -1.11,5.49 0,5.49 C1.1,5.49 2,4.6 2,3.5 C2,2.4 1.1,1.5 0,1.5c "/>
+              <group android:name="_R_G_L_1_C_0_G_G">
+                <path android:name="_R_G_L_1_G_G_0_D_0_P_0" android:fillColor="#000000" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M5 -3.5 C5,-3.5 6,-3.5 6,-3.5 C6,-3.5 6,-3.5 6,-3.5 C6.53,-3.5 7.04,-3.29 7.41,-2.91 C7.79,-2.54 8,-2.03 8,-1.5 C8,-1.5 8,8.5 8,8.5 C8,9.03 7.79,9.54 7.41,9.91 C7.04,10.29 6.53,10.5 6,10.5 C6,10.5 -6,10.5 -6,10.5 C-6.53,10.5 -7.04,10.29 -7.41,9.91 C-7.79,9.54 -8,9.03 -8,8.5 C-8,8.5 -8,-1.5 -8,-1.5 C-8,-2.03 -7.79,-2.54 -7.41,-2.91 C-7.04,-3.29 -6.53,-3.5 -6,-3.5 C-6,-3.5 3.1,-3.5 3.1,-3.5 C3.1,-3.5 5,-3.5 5,-3.5c "/>
+              </group>
+            </group>
+          </group>
+        </group>
+        <group android:name="_R_G_L_0_G_N_1_T_0" android:translateX="12.008" android:translateY="11.992" android:scaleY="0">
+          <group android:name="_R_G_L_0_G" android:translateX="-0.006" android:translateY="-0.5">
+            <group android:name="_R_G_L_0_C_0_G">
+              <clip-path android:name="_R_G_L_0_C_0" android:pathData=" M7.08 -2 C7.08,-2 -6.89,-2 -6.89,-2 C-6.89,-2 -6.89,9.51 -6.89,9.51 C-6.89,9.51 7.08,9.51 7.08,9.51 C7.08,9.51 7.08,-2 7.08,-2c "/>
+              <group android:name="_R_G_L_0_C_0_G_G">
+                <path android:name="_R_G_L_0_G_G_0_D_0_P_0" android:fillColor="#000000" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M-0.03 3.5 C-0.03,3.5 -0.02,3.5 -0.02,3.5 C-0.02,3.5 -0.02,3.5 -0.02,3.5 C-0.01,3.5 -0.01,3.5 -0.01,3.49 C0,3.49 0,3.49 0,3.48 C0,3.48 0,3.47 0,3.47 C0,3.47 -0.01,3.46 -0.01,3.46 C-0.02,3.46 -0.02,3.46 -0.02,3.46 C-0.03,3.46 -0.03,3.46 -0.03,3.47 C-0.04,3.47 -0.04,3.47 -0.04,3.48 C-0.04,3.48 -0.04,3.48 -0.04,3.49 C-0.04,3.49 -0.03,3.5 -0.03,3.5c  M5 -3.5 C5,-3.5 6,-3.5 6,-3.5 C6,-3.5 6,-3.5 6,-3.5 C6.53,-3.5 7.04,-3.29 7.41,-2.91 C7.79,-2.54 8,-2.03 8,-1.5 C8,-1.5 8,8.5 8,8.5 C8,9.03 7.79,9.54 7.41,9.91 C7.04,10.29 6.53,10.5 6,10.5 C6,10.5 -6,10.5 -6,10.5 C-6.53,10.5 -7.04,10.29 -7.41,9.91 C-7.79,9.54 -8,9.03 -8,8.5 C-8,8.5 -8,-1.5 -8,-1.5 C-8,-2.03 -7.79,-2.54 -7.41,-2.91 C-7.04,-3.29 -6.53,-3.5 -6,-3.5 C-6,-3.5 3.1,-3.5 3.1,-3.5 C3.1,-3.5 3.1,-5.5 3.1,-5.5 C3.1,-5.91 3.02,-6.31 2.86,-6.69 C2.71,-7.06 2.48,-7.4 2.19,-7.69 C1.9,-7.98 1.56,-8.21 1.19,-8.36 C0.81,-8.52 0.41,-8.6 0,-8.6 C-0.41,-8.6 -0.81,-8.52 -1.19,-8.36 C-1.56,-8.21 -1.9,-7.98 -2.19,-7.69 C-2.48,-7.4 -2.71,-7.06 -2.86,-6.69 C-3.02,-6.31 -3.1,-5.91 -3.1,-5.5 C-3.1,-5.5 -5,-5.5 -5,-5.5 C-5,-6.83 -4.47,-8.1 -3.54,-9.04 C-2.6,-9.97 -1.33,-10.5 0,-10.5 C1.33,-10.5 2.6,-9.97 3.54,-9.04 C4.47,-8.1 5,-6.83 5,-5.5 C5,-5.5 5,-3.5 5,-3.5c "/>
+              </group>
+            </group>
+          </group>
+        </group>
+      </group>
+      <group android:name="time_group"/>
+    </vector>
+  </aapt:attr>
+  <target android:name="_R_G_L_2_G_D_0_P_0">
+    <aapt:attr name="android:animation">
+      <set android:ordering="together">
+        <objectAnimator android:propertyName="pathData" android:duration="217" android:startOffset="0" android:valueFrom=" M-6 8.5 C-6,8.5 6,8.5 6,8.5 C6,8.5 6,-1.5 6,-1.5 C6,-1.5 -6,-1.5 -6,-1.5 C-6,-1.5 -6,8.5 -6,8.5c M5 -3.5 C5,-3.5 6,-3.5 6,-3.5 C6,-3.5 6,-3.5 6,-3.5 C6.53,-3.5 7.04,-3.29 7.41,-2.91 C7.79,-2.54 8,-2.03 8,-1.5 C8,-1.5 8,8.5 8,8.5 C8,9.03 7.79,9.54 7.41,9.91 C7.04,10.29 6.53,10.5 6,10.5 C6,10.5 -6,10.5 -6,10.5 C-6.53,10.5 -7.04,10.29 -7.41,9.91 C-7.79,9.54 -8,9.03 -8,8.5 C-8,8.5 -8,-1.5 -8,-1.5 C-8,-2.03 -7.79,-2.54 -7.41,-2.91 C-7.04,-3.29 -6.53,-3.5 -6,-3.5 C-6,-3.5 3.1,-3.5 3.1,-3.5 C3.1,-3.5 3.1,-5.5 3.1,-5.5 C3.1,-6.32 2.77,-7.11 2.19,-7.69 C1.61,-8.27 0.82,-8.6 0,-8.6 C-0.82,-8.6 -1.61,-8.27 -2.19,-7.69 C-2.76,-7.12 -3.09,-6.34 -3.1,-5.53 C-3.1,-5.52 -3.1,-5.51 -3.1,-5.5 C-3.1,-5.5 -5,-5.5 -5,-5.5 C-5,-5.51 -5,-5.52 -5,-5.54 C-4.99,-6.85 -4.46,-8.11 -3.54,-9.04 C-2.6,-9.97 -1.33,-10.5 0,-10.5 C1.33,-10.5 2.6,-9.97 3.54,-9.04 C4.47,-8.1 5,-6.83 5,-5.5 C5,-5.5 5,-3.5 5,-3.5c " android:valueTo=" M-6 8.5 C-6,8.5 6,8.5 6,8.5 C6,8.5 6,-1.5 6,-1.5 C6,-1.5 -6,-1.5 -6,-1.5 C-6,-1.5 -6,8.5 -6,8.5c M5 -3.5 C5,-3.5 6,-3.5 6,-3.5 C6,-3.5 6,-3.5 6,-3.5 C6.53,-3.5 7.04,-3.29 7.41,-2.91 C7.79,-2.54 8,-2.03 8,-1.5 C8,-1.5 8,8.5 8,8.5 C8,9.03 7.79,9.54 7.41,9.91 C7.04,10.29 6.53,10.5 6,10.5 C6,10.5 -6,10.5 -6,10.5 C-6.53,10.5 -7.04,10.29 -7.41,9.91 C-7.79,9.54 -8,9.03 -8,8.5 C-8,8.5 -8,-1.5 -8,-1.5 C-8,-2.03 -7.79,-2.54 -7.41,-2.91 C-7.04,-3.29 -6.53,-3.5 -6,-3.5 C-6,-3.5 3.1,-3.5 3.1,-3.5 C3.1,-3.5 3.1,-5.5 3.1,-5.5 C3.1,-6.32 2.77,-7.11 2.19,-7.69 C1.61,-8.27 0.82,-8.6 0,-8.6 C-0.82,-8.6 -1.61,-8.27 -2.19,-7.69 C-2.76,-7.12 -3.09,-6.34 -3.1,-5.53 C-3.1,-5.52 -3.1,-3.48 -3.1,-3.47 C-3.1,-3.47 -5,-3.47 -5,-3.47 C-5,-3.48 -5,-5.52 -5,-5.54 C-4.99,-6.85 -4.46,-8.11 -3.54,-9.04 C-2.6,-9.97 -1.33,-10.5 0,-10.5 C1.33,-10.5 2.6,-9.97 3.54,-9.04 C4.47,-8.1 5,-6.83 5,-5.5 C5,-5.5 5,-3.5 5,-3.5c " android:valueType="pathType">
+          <aapt:attr name="android:interpolator">
+            <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0"/>
+          </aapt:attr>
+        </objectAnimator>
+      </set>
+    </aapt:attr>
+  </target>
+  <target android:name="_R_G_L_2_G_N_1_T_0">
+    <aapt:attr name="android:animation">
+      <set android:ordering="together">
+        <objectAnimator android:propertyName="translateXY" android:duration="106" android:startOffset="0" android:propertyXName="translateX" android:propertyYName="translateY" android:pathData="M 12.008,11.992C 12.008,12.159 12.008,12.992 12.008,12.992">
+          <aapt:attr name="android:interpolator">
+            <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0"/>
+          </aapt:attr>
+        </objectAnimator>
+        <objectAnimator android:propertyName="translateXY" android:duration="211" android:startOffset="106" android:propertyXName="translateX" android:propertyYName="translateY" android:pathData="M 12.008,12.992C 12.008,12.992 12.008,12.159 12.008,11.992">
+          <aapt:attr name="android:interpolator">
+            <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0"/>
+          </aapt:attr>
+        </objectAnimator>
+      </set>
+    </aapt:attr>
+  </target>
+  <target android:name="_R_G_L_1_C_0">
+    <aapt:attr name="android:animation">
+      <set android:ordering="together">
+        <objectAnimator android:propertyName="pathData" android:duration="300" android:startOffset="0" android:valueFrom="M0 1.5 C-1.11,1.5 -2,2.4 -2,3.5 C-2,4.6 -1.11,5.49 0,5.49 C1.1,5.49 2,4.6 2,3.5 C2,2.4 1.1,1.5 0,1.5c " android:valueTo="M0 -4.8 C-4.6,-4.8 -8.32,-1.09 -8.32,3.5 C-8.32,8.08 -4.6,11.8 0,11.8 C4.59,11.8 8.32,8.08 8.32,3.5 C8.32,-1.09 4.59,-4.8 0,-4.8c " android:valueType="pathType">
+          <aapt:attr name="android:interpolator">
+            <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0"/>
+          </aapt:attr>
+        </objectAnimator>
+      </set>
+    </aapt:attr>
+  </target>
+  <target android:name="_R_G_L_1_G_N_1_T_0">
+    <aapt:attr name="android:animation">
+      <set android:ordering="together">
+        <objectAnimator android:propertyName="translateXY" android:duration="106" android:startOffset="0" android:propertyXName="translateX" android:propertyYName="translateY" android:pathData="M 12.008,11.992C 12.008,12.159 12.008,12.992 12.008,12.992">
+          <aapt:attr name="android:interpolator">
+            <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0"/>
+          </aapt:attr>
+        </objectAnimator>
+        <objectAnimator android:propertyName="translateXY" android:duration="211" android:startOffset="106" android:propertyXName="translateX" android:propertyYName="translateY" android:pathData="M 12.008,12.992C 12.008,12.992 12.008,12.159 12.008,11.992">
+          <aapt:attr name="android:interpolator">
+            <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0"/>
+          </aapt:attr>
+        </objectAnimator>
+      </set>
+    </aapt:attr>
+  </target>
+  <target android:name="_R_G_L_1_G_N_1_T_0">
+    <aapt:attr name="android:animation">
+      <set android:ordering="together">
+        <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="217" android:valueFrom="1" android:valueTo="0" android:valueType="floatType"/>
+      </set>
+    </aapt:attr>
+  </target>
+  <target android:name="_R_G_L_0_G_G_0_D_0_P_0">
+    <aapt:attr name="android:animation">
+      <set android:ordering="together">
+        <objectAnimator android:propertyName="pathData" android:duration="200" android:startOffset="0" android:valueFrom="M-0.03 3.5 C-0.03,3.5 -0.02,3.5 -0.02,3.5 C-0.02,3.5 -0.02,3.5 -0.02,3.5 C-0.01,3.5 -0.01,3.5 -0.01,3.49 C0,3.49 0,3.49 0,3.48 C0,3.48 0,3.47 0,3.47 C0,3.47 -0.01,3.46 -0.01,3.46 C-0.02,3.46 -0.02,3.46 -0.02,3.46 C-0.03,3.46 -0.03,3.46 -0.03,3.47 C-0.04,3.47 -0.04,3.47 -0.04,3.48 C-0.04,3.48 -0.04,3.48 -0.04,3.49 C-0.04,3.49 -0.03,3.5 -0.03,3.5c  M5 -3.5 C5,-3.5 6,-3.5 6,-3.5 C6,-3.5 6,-3.5 6,-3.5 C6.53,-3.5 7.04,-3.29 7.41,-2.91 C7.79,-2.54 8,-2.03 8,-1.5 C8,-1.5 8,8.5 8,8.5 C8,9.03 7.79,9.54 7.41,9.91 C7.04,10.29 6.53,10.5 6,10.5 C6,10.5 -6,10.5 -6,10.5 C-6.53,10.5 -7.04,10.29 -7.41,9.91 C-7.79,9.54 -8,9.03 -8,8.5 C-8,8.5 -8,-1.5 -8,-1.5 C-8,-2.03 -7.79,-2.54 -7.41,-2.91 C-7.04,-3.29 -6.53,-3.5 -6,-3.5 C-6,-3.5 3.1,-3.5 3.1,-3.5 C3.1,-3.5 3.1,-5.5 3.1,-5.5 C3.1,-5.91 3.02,-6.31 2.86,-6.69 C2.71,-7.06 2.48,-7.4 2.19,-7.69 C1.9,-7.98 1.56,-8.21 1.19,-8.36 C0.81,-8.52 0.41,-8.6 0,-8.6 C-0.41,-8.6 -0.81,-8.52 -1.19,-8.36 C-1.56,-8.21 -1.9,-7.98 -2.19,-7.69 C-2.48,-7.4 -2.71,-7.06 -2.86,-6.69 C-3.02,-6.31 -3.1,-5.91 -3.1,-5.5 C-3.1,-5.5 -5,-5.5 -5,-5.5 C-5,-6.83 -4.47,-8.1 -3.54,-9.04 C-2.6,-9.97 -1.33,-10.5 0,-10.5 C1.33,-10.5 2.6,-9.97 3.54,-9.04 C4.47,-8.1 5,-6.83 5,-5.5 C5,-5.5 5,-3.5 5,-3.5c " android:valueTo="M-0.03 3.5 C-0.03,3.5 -0.02,3.5 -0.02,3.5 C-0.02,3.5 -0.02,3.5 -0.02,3.5 C-0.01,3.5 -0.01,3.5 -0.01,3.49 C0,3.49 0,3.49 0,3.48 C0,3.48 0,3.47 0,3.47 C0,3.47 -0.01,3.46 -0.01,3.46 C-0.02,3.46 -0.02,3.46 -0.02,3.46 C-0.03,3.46 -0.03,3.46 -0.03,3.47 C-0.04,3.47 -0.04,3.47 -0.04,3.48 C-0.04,3.48 -0.04,3.48 -0.04,3.49 C-0.04,3.49 -0.03,3.5 -0.03,3.5c  M5 -3.5 C5,-3.5 6,-3.5 6,-3.5 C6,-3.5 6,-3.5 6,-3.5 C6.53,-3.5 7.04,-3.29 7.41,-2.91 C7.79,-2.54 8,-2.03 8,-1.5 C8,-1.5 8,8.5 8,8.5 C8,9.03 7.79,9.54 7.41,9.91 C7.04,10.29 6.53,10.5 6,10.5 C6,10.5 -6,10.5 -6,10.5 C-6.53,10.5 -7.04,10.29 -7.41,9.91 C-7.79,9.54 -8,9.03 -8,8.5 C-8,8.5 -8,-1.5 -8,-1.5 C-8,-2.03 -7.79,-2.54 -7.41,-2.91 C-7.04,-3.29 -6.53,-3.5 -6,-3.5 C-6,-3.5 3.1,-3.5 3.1,-3.5 C3.1,-3.5 3.1,-5.5 3.1,-5.5 C3.1,-5.91 3.02,-6.31 2.86,-6.69 C2.71,-7.06 2.48,-7.4 2.19,-7.69 C1.9,-7.98 1.56,-8.21 1.19,-8.36 C0.81,-8.52 0.41,-8.6 0,-8.6 C-0.41,-8.6 -0.81,-8.52 -1.19,-8.36 C-1.56,-8.21 -1.9,-7.98 -2.19,-7.69 C-2.48,-7.4 -2.71,-7.06 -2.86,-6.69 C-3.02,-6.31 -3.1,-5.91 -3.1,-5.5 C-3.1,-5.5 -5,-5.5 -5,-5.5 C-5,-6.83 -4.47,-8.1 -3.54,-9.04 C-2.6,-9.97 -1.33,-10.5 0,-10.5 C1.33,-10.5 2.6,-9.97 3.54,-9.04 C4.47,-8.1 5,-6.83 5,-5.5 C5,-5.5 5,-3.5 5,-3.5c " android:valueType="pathType">
+          <aapt:attr name="android:interpolator">
+            <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0"/>
+          </aapt:attr>
+        </objectAnimator>
+        <objectAnimator android:propertyName="pathData" android:duration="300" android:startOffset="200" android:valueFrom="M-0.03 3.5 C-0.03,3.5 -0.02,3.5 -0.02,3.5 C-0.02,3.5 -0.02,3.5 -0.02,3.5 C-0.01,3.5 -0.01,3.5 -0.01,3.49 C0,3.49 0,3.49 0,3.48 C0,3.48 0,3.47 0,3.47 C0,3.47 -0.01,3.46 -0.01,3.46 C-0.02,3.46 -0.02,3.46 -0.02,3.46 C-0.03,3.46 -0.03,3.46 -0.03,3.47 C-0.04,3.47 -0.04,3.47 -0.04,3.48 C-0.04,3.48 -0.04,3.48 -0.04,3.49 C-0.04,3.49 -0.03,3.5 -0.03,3.5c  M5 -3.5 C5,-3.5 6,-3.5 6,-3.5 C6,-3.5 6,-3.5 6,-3.5 C6.53,-3.5 7.04,-3.29 7.41,-2.91 C7.79,-2.54 8,-2.03 8,-1.5 C8,-1.5 8,8.5 8,8.5 C8,9.03 7.79,9.54 7.41,9.91 C7.04,10.29 6.53,10.5 6,10.5 C6,10.5 -6,10.5 -6,10.5 C-6.53,10.5 -7.04,10.29 -7.41,9.91 C-7.79,9.54 -8,9.03 -8,8.5 C-8,8.5 -8,-1.5 -8,-1.5 C-8,-2.03 -7.79,-2.54 -7.41,-2.91 C-7.04,-3.29 -6.53,-3.5 -6,-3.5 C-6,-3.5 3.1,-3.5 3.1,-3.5 C3.1,-3.5 3.1,-5.5 3.1,-5.5 C3.1,-5.91 3.02,-6.31 2.86,-6.69 C2.71,-7.06 2.48,-7.4 2.19,-7.69 C1.9,-7.98 1.56,-8.21 1.19,-8.36 C0.81,-8.52 0.41,-8.6 0,-8.6 C-0.41,-8.6 -0.81,-8.52 -1.19,-8.36 C-1.56,-8.21 -1.9,-7.98 -2.19,-7.69 C-2.48,-7.4 -2.71,-7.06 -2.86,-6.69 C-3.02,-6.31 -3.1,-5.91 -3.1,-5.5 C-3.1,-5.5 -5,-5.5 -5,-5.5 C-5,-6.83 -4.47,-8.1 -3.54,-9.04 C-2.6,-9.97 -1.33,-10.5 0,-10.5 C1.33,-10.5 2.6,-9.97 3.54,-9.04 C4.47,-8.1 5,-6.83 5,-5.5 C5,-5.5 5,-3.5 5,-3.5c " android:valueTo="M-1.11 5.16 C-0.78,5.38 -0.4,5.5 0,5.5 C0,5.5 0,5.5 0,5.5 C0.53,5.5 1.04,5.29 1.41,4.91 C1.79,4.54 2,4.03 2,3.5 C2,3.1 1.88,2.72 1.66,2.39 C1.44,2.06 1.13,1.8 0.77,1.65 C0.4,1.5 0,1.46 -0.39,1.54 C-0.78,1.62 -1.13,1.81 -1.41,2.09 C-1.69,2.37 -1.88,2.72 -1.96,3.11 C-2.04,3.5 -2,3.9 -1.85,4.26 C-1.7,4.63 -1.44,4.94 -1.11,5.16c  M5 -3.5 C5,-3.5 6,-3.5 6,-3.5 C6,-3.5 6,-3.5 6,-3.5 C6.53,-3.5 7.04,-3.29 7.41,-2.91 C7.79,-2.54 8,-2.03 8,-1.5 C8,-1.5 8,8.5 8,8.5 C8,9.03 7.79,9.54 7.41,9.91 C7.04,10.29 6.53,10.5 6,10.5 C6,10.5 -6,10.5 -6,10.5 C-6.53,10.5 -7.04,10.29 -7.41,9.91 C-7.79,9.54 -8,9.03 -8,8.5 C-8,8.5 -8,-1.5 -8,-1.5 C-8,-2.03 -7.79,-2.54 -7.41,-2.91 C-7.04,-3.29 -6.53,-3.5 -6,-3.5 C-6,-3.5 3.1,-3.5 3.1,-3.5 C3.1,-3.5 3.1,-5.5 3.1,-5.5 C3.1,-5.91 3.02,-6.31 2.86,-6.69 C2.71,-7.06 2.48,-7.4 2.19,-7.69 C1.9,-7.98 1.56,-8.21 1.19,-8.36 C0.81,-8.52 0.41,-8.6 0,-8.6 C-0.41,-8.6 -0.81,-8.52 -1.19,-8.36 C-1.56,-8.21 -1.9,-7.98 -2.19,-7.69 C-2.48,-7.4 -2.71,-7.06 -2.86,-6.69 C-3.02,-6.31 -3.1,-5.91 -3.1,-5.5 C-3.1,-5.5 -5,-5.5 -5,-5.5 C-5,-6.83 -4.47,-8.1 -3.54,-9.04 C-2.6,-9.97 -1.33,-10.5 0,-10.5 C1.33,-10.5 2.6,-9.97 3.54,-9.04 C4.47,-8.1 5,-6.83 5,-5.5 C5,-5.5 5,-3.5 5,-3.5c " android:valueType="pathType">
+          <aapt:attr name="android:interpolator">
+            <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0"/>
+          </aapt:attr>
+        </objectAnimator>
+      </set>
+    </aapt:attr>
+  </target>
+  <target android:name="_R_G_L_0_G_N_1_T_0">
+    <aapt:attr name="android:animation">
+      <set android:ordering="together">
+        <objectAnimator android:propertyName="translateXY" android:duration="106" android:startOffset="0" android:propertyXName="translateX" android:propertyYName="translateY" android:pathData="M 12.008,11.992C 12.008,12.159 12.008,12.992 12.008,12.992">
+          <aapt:attr name="android:interpolator">
+            <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0"/>
+          </aapt:attr>
+        </objectAnimator>
+        <objectAnimator android:propertyName="translateXY" android:duration="211" android:startOffset="106" android:propertyXName="translateX" android:propertyYName="translateY" android:pathData="M 12.008,12.992C 12.008,12.992 12.008,12.159 12.008,11.992">
+          <aapt:attr name="android:interpolator">
+            <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0"/>
+          </aapt:attr>
+        </objectAnimator>
+      </set>
+    </aapt:attr>
+  </target>
+  <target android:name="_R_G_L_0_G_N_1_T_0">
+    <aapt:attr name="android:animation">
+      <set android:ordering="together">
+        <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="217" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+      </set>
+    </aapt:attr>
+  </target>
+  <target android:name="time_group">
+    <aapt:attr name="android:animation">
+      <set android:ordering="together">
+        <objectAnimator android:propertyName="translateX" android:duration="750" android:startOffset="0" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+      </set>
+    </aapt:attr>
+  </target>
+</animated-vector>
diff --git a/packages/SystemUI/res/drawable/ic_device_microwave.xml b/packages/SystemUI/res/drawable/ic_device_microwave.xml
new file mode 100644
index 0000000..59d9284
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_device_microwave.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2020 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
+  -->
+<selector
+    xmlns:android="http://schemas.android.com/apk/res/android">
+  <item
+      android:id="@+id/off"
+      android:state_enabled="false"
+      android:drawable="@drawable/ic_device_microwave_off" />
+  <item
+      android:id="@+id/on"
+      android:state_enabled="true"
+      android:drawable="@drawable/ic_device_microwave_on" />
+</selector>
diff --git a/packages/SystemUI/res/drawable/ic_device_mop.xml b/packages/SystemUI/res/drawable/ic_device_mop.xml
new file mode 100644
index 0000000..7b36078
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_device_mop.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2020 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
+  -->
+<selector
+    xmlns:android="http://schemas.android.com/apk/res/android">
+  <item
+      android:id="@+id/off"
+      android:state_enabled="false"
+      android:drawable="@drawable/ic_device_mop_off" />
+  <item
+      android:id="@+id/on"
+      android:state_enabled="true"
+      android:drawable="@drawable/ic_device_mop_on" />
+</selector>
diff --git a/packages/SystemUI/res/drawable/ic_device_multicooker.xml b/packages/SystemUI/res/drawable/ic_device_multicooker.xml
new file mode 100644
index 0000000..8c9f608
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_device_multicooker.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2020 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
+  -->
+<selector
+    xmlns:android="http://schemas.android.com/apk/res/android">
+  <item
+      android:id="@+id/off"
+      android:state_enabled="false"
+      android:drawable="@drawable/ic_device_multicooker_off" />
+  <item
+      android:id="@+id/on"
+      android:state_enabled="true"
+      android:drawable="@drawable/ic_device_multicooker_on" />
+</selector>
diff --git a/packages/SystemUI/res/drawable/ic_device_outdoor_garden.xml b/packages/SystemUI/res/drawable/ic_device_outdoor_garden.xml
new file mode 100644
index 0000000..a6cb2d8
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_device_outdoor_garden.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2020 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
+  -->
+<selector
+    xmlns:android="http://schemas.android.com/apk/res/android">
+  <item
+      android:id="@+id/off"
+      android:state_enabled="false"
+      android:drawable="@drawable/ic_device_outdoor_garden_off" />
+  <item
+      android:id="@+id/on"
+      android:state_enabled="true"
+      android:drawable="@drawable/ic_device_outdoor_garden_on" />
+</selector>
diff --git a/packages/SystemUI/res/drawable/ic_device_outlet.xml b/packages/SystemUI/res/drawable/ic_device_outlet.xml
new file mode 100644
index 0000000..17f140e
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_device_outlet.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2020 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
+  -->
+<animated-selector
+    xmlns:android="http://schemas.android.com/apk/res/android">
+  <item
+      android:id="@+id/off"
+      android:state_enabled="false"
+      android:drawable="@drawable/ic_device_outlet_off" />
+  <item
+      android:id="@+id/on"
+      android:state_enabled="true"
+      android:drawable="@drawable/ic_device_outlet_on" />
+  <transition
+      android:fromId="@id/off"
+      android:toId="@id/on"
+      android:drawable="@drawable/ic_device_outlet_on_anim" />
+  <transition
+      android:fromId="@id/on"
+      android:toId="@id/off"
+      android:drawable="@drawable/ic_device_outlet_off_anim" />
+</animated-selector>
diff --git a/packages/SystemUI/res/drawable/ic_device_outlet_off_anim.xml b/packages/SystemUI/res/drawable/ic_device_outlet_off_anim.xml
new file mode 100644
index 0000000..85d645e
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_device_outlet_off_anim.xml
@@ -0,0 +1,86 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2020 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
+  -->
+<animated-vector
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:aapt="http://schemas.android.com/aapt">
+  <aapt:attr name="android:drawable">
+    <vector android:height="24dp" android:width="24dp" android:viewportHeight="24" android:viewportWidth="24">
+      <group android:name="_R_G">
+        <group android:name="_R_G_L_3_G_N_1_T_0" android:translateX="12" android:translateY="12" android:scaleY="0">
+          <group android:name="_R_G_L_3_G" android:translateX="-4" android:translateY="-1">
+            <path android:name="_R_G_L_3_G_D_0_P_0" android:fillColor="#000000" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M-1 -2 C-1,-2 1,-2 1,-2 C1,-2 1,2 1,2 C1,2 -1,2 -1,2 C-1,2 -1,-2 -1,-2c "/>
+          </group>
+        </group>
+        <group android:name="_R_G_L_2_G_N_1_T_0" android:translateX="12" android:translateY="12" android:scaleY="0">
+          <group android:name="_R_G_L_2_G" android:translateY="4">
+            <path android:name="_R_G_L_2_G_D_0_P_0" android:fillColor="#000000" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M-0.71 -0.71 C-0.52,-0.89 -0.26,-1 0,-1 C0.27,-1 0.52,-0.89 0.71,-0.71 C0.9,-0.52 1,-0.26 1,0 C1,0 1,1 1,1 C1,1 -1,1 -1,1 C-1,1 -1,0 -1,0 C-1,-0.26 -0.89,-0.52 -0.71,-0.71c "/>
+          </group>
+        </group>
+        <group android:name="_R_G_L_1_G_N_1_T_0" android:translateX="12" android:translateY="12" android:scaleY="0">
+          <group android:name="_R_G_L_1_G" android:translateX="4" android:translateY="-1">
+            <path android:name="_R_G_L_1_G_D_0_P_0" android:fillColor="#000000" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M-1 -2 C-1,-2 1,-2 1,-2 C1,-2 1,2 1,2 C1,2 -1,2 -1,2 C-1,2 -1,-2 -1,-2c "/>
+          </group>
+        </group>
+        <group android:name="_R_G_L_0_G_N_1_T_0" android:translateX="12" android:translateY="12">
+          <group android:name="_R_G_L_0_G">
+            <path android:name="_R_G_L_0_G_D_0_P_0" android:fillColor="#000000" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M-1 5 C-1,5 0,5 0,5 C0,5 1,5 1,5 C1,5 1,4.5 1,4.5 C1,4.5 1,4 1,4 C1,3.87 0.97,3.74 0.92,3.62 C0.87,3.5 0.8,3.39 0.71,3.29 C0.52,3.11 0.27,3 0,3 C-0.26,3 -0.52,3.11 -0.71,3.29 C-0.89,3.48 -1,3.74 -1,4 C-1,4 -1,5 -1,5c  M-5.56 -8.31 C-3.91,-9.41 -1.98,-10 0,-10 C0,-10 0,-10 0,-10 C2.65,-10 5.2,-8.95 7.07,-7.07 C8.95,-5.2 10,-2.65 10,0 C10,1.98 9.41,3.91 8.32,5.56 C7.22,7.2 5.65,8.48 3.83,9.24 C2,10 -0.01,10.19 -1.95,9.81 C-3.89,9.42 -5.67,8.47 -7.07,7.07 C-8.47,5.67 -9.42,3.89 -9.81,1.95 C-10.19,0.01 -10,-2 -9.24,-3.83 C-8.48,-5.65 -7.2,-7.22 -5.56,-8.31c  M3 1 C3,1 5,1 5,1 C5,1 5,-3 5,-3 C5,-3 3,-3 3,-3 C3,-3 3,1 3,1c  M-5 1 C-5,1 -3,1 -3,1 C-3,1 -3,-3 -3,-3 C-3,-3 -5,-3 -5,-3 C-5,-3 -5,1 -5,1c "/>
+          </group>
+        </group>
+      </group>
+      <group android:name="time_group"/>
+    </vector>
+  </aapt:attr>
+  <target android:name="_R_G_L_3_G_N_1_T_0">
+    <aapt:attr name="android:animation">
+      <set android:ordering="together">
+        <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="217" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+      </set>
+    </aapt:attr>
+  </target>
+  <target android:name="_R_G_L_2_G_N_1_T_0">
+    <aapt:attr name="android:animation">
+      <set android:ordering="together">
+        <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="217" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+      </set>
+    </aapt:attr>
+  </target>
+  <target android:name="_R_G_L_1_G_N_1_T_0">
+    <aapt:attr name="android:animation">
+      <set android:ordering="together">
+        <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="217" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+      </set>
+    </aapt:attr>
+  </target>
+  <target android:name="_R_G_L_0_G_D_0_P_0">
+    <aapt:attr name="android:animation">
+      <set android:ordering="together">
+        <objectAnimator android:propertyName="pathData" android:duration="500" android:startOffset="0" android:valueFrom="M-1 5 C-1,5 0,5 0,5 C0,5 1,5 1,5 C1,5 1,4.5 1,4.5 C1,4.5 1,4 1,4 C1,3.87 0.97,3.74 0.92,3.62 C0.87,3.5 0.8,3.39 0.71,3.29 C0.52,3.11 0.27,3 0,3 C-0.26,3 -0.52,3.11 -0.71,3.29 C-0.89,3.48 -1,3.74 -1,4 C-1,4 -1,5 -1,5c  M-5.56 -8.31 C-3.91,-9.41 -1.98,-10 0,-10 C0,-10 0,-10 0,-10 C2.65,-10 5.2,-8.95 7.07,-7.07 C8.95,-5.2 10,-2.65 10,0 C10,1.98 9.41,3.91 8.32,5.56 C7.22,7.2 5.65,8.48 3.83,9.24 C2,10 -0.01,10.19 -1.95,9.81 C-3.89,9.42 -5.67,8.47 -7.07,7.07 C-8.47,5.67 -9.42,3.89 -9.81,1.95 C-10.19,0.01 -10,-2 -9.24,-3.83 C-8.48,-5.65 -7.2,-7.22 -5.56,-8.31c  M3 1 C3,1 5,1 5,1 C5,1 5,-3 5,-3 C5,-3 3,-3 3,-3 C3,-3 3,1 3,1c M-0.02 4.03 C-0.02,4.03 0.03,4.03 0.03,4.03 C0.03,4.03 0.03,4 0.03,4 C0.03,3.99 0.02,3.99 0.02,3.98 C0.01,3.98 0.01,3.98 0,3.98 C-0.01,3.98 -0.01,3.98 -0.02,3.98 C-0.02,3.99 -0.02,3.99 -0.02,4 C-0.02,4 -0.02,4.03 -0.02,4.03c  M-5 1 C-5,1 -3,1 -3,1 C-3,1 -3,-3 -3,-3 C-3,-3 -5,-3 -5,-3 C-5,-3 -5,1 -5,1c " android:valueTo="M-4.44 6.65 C-3.13,7.53 -1.58,8 0,8 C2.12,8 4.16,7.16 5.66,5.66 C7.16,4.16 8,2.12 8,0 C8,-1.58 7.53,-3.13 6.65,-4.44 C5.77,-5.76 4.52,-6.79 3.06,-7.39 C1.6,-8 -0.01,-8.15 -1.56,-7.85 C-3.11,-7.54 -4.54,-6.78 -5.66,-5.66 C-6.78,-4.54 -7.54,-3.11 -7.85,-1.56 C-8.15,-0.01 -8,1.6 -7.39,3.06 C-6.79,4.52 -5.76,5.77 -4.44,6.65c  M-5.56 -8.31 C-3.91,-9.41 -1.98,-10 0,-10 C0,-10 0,-10 0,-10 C2.65,-10 5.2,-8.95 7.07,-7.07 C8.95,-5.2 10,-2.65 10,0 C10,1.98 9.41,3.91 8.32,5.56 C7.22,7.2 5.65,8.48 3.83,9.24 C2,10 -0.01,10.19 -1.95,9.81 C-3.89,9.42 -5.67,8.47 -7.07,7.07 C-8.47,5.67 -9.42,3.89 -9.81,1.95 C-10.19,0.01 -10,-2 -9.24,-3.83 C-8.48,-5.65 -7.2,-7.22 -5.56,-8.31c  M3 1 C3,1 5,1 5,1 C5,1 5,-3 5,-3 C5,-3 3,-3 3,-3 C3,-3 3,1 3,1c M-1 5 C-1,5 1,5 1,5 C1,5 1,4 1,4 C1,3.74 0.9,3.48 0.71,3.29 C0.52,3.11 0.27,3 0,3 C-0.26,3 -0.52,3.11 -0.71,3.29 C-0.89,3.48 -1,3.74 -1,4 C-1,4 -1,5 -1,5c  M-5 1 C-5,1 -3,1 -3,1 C-3,1 -3,-3 -3,-3 C-3,-3 -5,-3 -5,-3 C-5,-3 -5,1 -5,1c " android:valueType="pathType">
+          <aapt:attr name="android:interpolator">
+            <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0"/>
+          </aapt:attr>
+        </objectAnimator>
+      </set>
+    </aapt:attr>
+  </target>
+  <target android:name="time_group">
+    <aapt:attr name="android:animation">
+      <set android:ordering="together">
+        <objectAnimator android:propertyName="translateX" android:duration="750" android:startOffset="0" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+      </set>
+    </aapt:attr>
+  </target>
+</animated-vector>
diff --git a/packages/SystemUI/res/drawable/ic_device_outlet_on_anim.xml b/packages/SystemUI/res/drawable/ic_device_outlet_on_anim.xml
new file mode 100644
index 0000000..756f028
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_device_outlet_on_anim.xml
@@ -0,0 +1,107 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2020 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
+  -->
+<animated-vector
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:aapt="http://schemas.android.com/aapt">
+  <aapt:attr name="android:drawable">
+    <vector android:height="24dp" android:width="24dp" android:viewportHeight="24" android:viewportWidth="24">
+      <group android:name="_R_G">
+        <group android:name="_R_G_L_3_G_N_1_T_0" android:translateX="12" android:translateY="12">
+          <group android:name="_R_G_L_3_G" android:translateX="-4" android:translateY="-1">
+            <path android:name="_R_G_L_3_G_D_0_P_0" android:fillColor="#000000" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M-1 -2 C-1,-2 1,-2 1,-2 C1,-2 1,2 1,2 C1,2 -1,2 -1,2 C-1,2 -1,-2 -1,-2c "/>
+          </group>
+        </group>
+        <group android:name="_R_G_L_2_G_N_1_T_0" android:translateX="12" android:translateY="12">
+          <group android:name="_R_G_L_2_G" android:translateY="4">
+            <path android:name="_R_G_L_2_G_D_0_P_0" android:fillColor="#000000" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M-0.71 -0.71 C-0.52,-0.89 -0.26,-1 0,-1 C0.27,-1 0.52,-0.89 0.71,-0.71 C0.9,-0.52 1,-0.26 1,0 C1,0 1,1 1,1 C1,1 -1,1 -1,1 C-1,1 -1,0 -1,0 C-1,-0.26 -0.89,-0.52 -0.71,-0.71c "/>
+          </group>
+        </group>
+        <group android:name="_R_G_L_1_G_N_1_T_0" android:translateX="12" android:translateY="12">
+          <group android:name="_R_G_L_1_G" android:translateX="4" android:translateY="-1">
+            <path android:name="_R_G_L_1_G_D_0_P_0" android:fillColor="#000000" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M-1 -2 C-1,-2 1,-2 1,-2 C1,-2 1,2 1,2 C1,2 -1,2 -1,2 C-1,2 -1,-2 -1,-2c "/>
+          </group>
+        </group>
+        <group android:name="_R_G_L_0_G_N_1_T_0" android:translateX="12" android:translateY="12">
+          <group android:name="_R_G_L_0_G">
+            <path android:name="_R_G_L_0_G_D_0_P_0" android:fillColor="#000000" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M-4.44 6.65 C-3.13,7.53 -1.58,8 0,8 C2.12,8 4.16,7.16 5.66,5.66 C7.16,4.16 8,2.12 8,0 C8,-1.58 7.53,-3.13 6.65,-4.44 C5.77,-5.76 4.52,-6.79 3.06,-7.39 C1.6,-8 -0.01,-8.15 -1.56,-7.85 C-3.11,-7.54 -4.54,-6.78 -5.66,-5.66 C-6.78,-4.54 -7.54,-3.11 -7.85,-1.56 C-8.15,-0.01 -8,1.6 -7.39,3.06 C-6.79,4.52 -5.76,5.77 -4.44,6.65c  M-5.56 -8.31 C-3.91,-9.41 -1.98,-10 0,-10 C0,-10 0,-10 0,-10 C2.65,-10 5.2,-8.95 7.07,-7.07 C8.95,-5.2 10,-2.65 10,0 C10,1.98 9.41,3.91 8.32,5.56 C7.22,7.2 5.65,8.48 3.83,9.24 C2,10 -0.01,10.19 -1.95,9.81 C-3.89,9.42 -5.67,8.47 -7.07,7.07 C-8.47,5.67 -9.42,3.89 -9.81,1.95 C-10.19,0.01 -10,-2 -9.24,-3.83 C-8.48,-5.65 -7.2,-7.22 -5.56,-8.31c  M3 1 C3,1 5,1 5,1 C5,1 5,-3 5,-3 C5,-3 3,-3 3,-3 C3,-3 3,1 3,1c  M-5 1 C-5,1 -3,1 -3,1 C-3,1 -3,-3 -3,-3 C-3,-3 -5,-3 -5,-3 C-5,-3 -5,1 -5,1c "/>
+          </group>
+        </group>
+      </group>
+      <group android:name="time_group"/>
+    </vector>
+  </aapt:attr>
+  <target android:name="_R_G_L_3_G_N_1_T_0">
+    <aapt:attr name="android:animation">
+      <set android:ordering="together">
+        <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="0" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+      </set>
+    </aapt:attr>
+  </target>
+  <target android:name="_R_G_L_3_G_N_1_T_0">
+    <aapt:attr name="android:animation">
+      <set android:ordering="together">
+        <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="100" android:valueFrom="1" android:valueTo="0" android:valueType="floatType"/>
+      </set>
+    </aapt:attr>
+  </target>
+  <target android:name="_R_G_L_2_G_N_1_T_0">
+    <aapt:attr name="android:animation">
+      <set android:ordering="together">
+        <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="0" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+      </set>
+    </aapt:attr>
+  </target>
+  <target android:name="_R_G_L_2_G_N_1_T_0">
+    <aapt:attr name="android:animation">
+      <set android:ordering="together">
+        <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="100" android:valueFrom="1" android:valueTo="0" android:valueType="floatType"/>
+      </set>
+    </aapt:attr>
+  </target>
+  <target android:name="_R_G_L_1_G_N_1_T_0">
+    <aapt:attr name="android:animation">
+      <set android:ordering="together">
+        <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="0" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+      </set>
+    </aapt:attr>
+  </target>
+  <target android:name="_R_G_L_1_G_N_1_T_0">
+    <aapt:attr name="android:animation">
+      <set android:ordering="together">
+        <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="100" android:valueFrom="1" android:valueTo="0" android:valueType="floatType"/>
+      </set>
+    </aapt:attr>
+  </target>
+  <target android:name="_R_G_L_0_G_D_0_P_0">
+    <aapt:attr name="android:animation">
+      <set android:ordering="together">
+        <objectAnimator android:propertyName="pathData" android:duration="500" android:startOffset="0" android:valueFrom="M-4.44 6.65 C-3.13,7.53 -1.58,8 0,8 C2.12,8 4.16,7.16 5.66,5.66 C7.16,4.16 8,2.12 8,0 C8,-1.58 7.53,-3.13 6.65,-4.44 C5.77,-5.76 4.52,-6.79 3.06,-7.39 C1.6,-8 -0.01,-8.15 -1.56,-7.85 C-3.11,-7.54 -4.54,-6.78 -5.66,-5.66 C-6.78,-4.54 -7.54,-3.11 -7.85,-1.56 C-8.15,-0.01 -8,1.6 -7.39,3.06 C-6.79,4.52 -5.76,5.77 -4.44,6.65c  M-5.56 -8.31 C-3.91,-9.41 -1.98,-10 0,-10 C0,-10 0,-10 0,-10 C2.65,-10 5.2,-8.95 7.07,-7.07 C8.95,-5.2 10,-2.65 10,0 C10,1.98 9.41,3.91 8.32,5.56 C7.22,7.2 5.65,8.48 3.83,9.24 C2,10 -0.01,10.19 -1.95,9.81 C-3.89,9.42 -5.67,8.47 -7.07,7.07 C-8.47,5.67 -9.42,3.89 -9.81,1.95 C-10.19,0.01 -10,-2 -9.24,-3.83 C-8.48,-5.65 -7.2,-7.22 -5.56,-8.31c  M3 1 C3,1 5,1 5,1 C5,1 5,-3 5,-3 C5,-3 3,-3 3,-3 C3,-3 3,1 3,1c M-1 5 C-1,5 1,5 1,5 C1,5 1,4 1,4 C1,3.74 0.9,3.48 0.71,3.29 C0.52,3.11 0.27,3 0,3 C-0.26,3 -0.52,3.11 -0.71,3.29 C-0.89,3.48 -1,3.74 -1,4 C-1,4 -1,5 -1,5c  M-5 1 C-5,1 -3,1 -3,1 C-3,1 -3,-3 -3,-3 C-3,-3 -5,-3 -5,-3 C-5,-3 -5,1 -5,1c " android:valueTo="M-1 5 C-1,5 0,5 0,5 C0,5 1,5 1,5 C1,5 1,4.5 1,4.5 C1,4.5 1,4 1,4 C1,3.87 0.97,3.74 0.92,3.62 C0.87,3.5 0.8,3.39 0.71,3.29 C0.52,3.11 0.27,3 0,3 C-0.26,3 -0.52,3.11 -0.71,3.29 C-0.89,3.48 -1,3.74 -1,4 C-1,4 -1,5 -1,5c  M-5.56 -8.31 C-3.91,-9.41 -1.98,-10 0,-10 C0,-10 0,-10 0,-10 C2.65,-10 5.2,-8.95 7.07,-7.07 C8.95,-5.2 10,-2.65 10,0 C10,1.98 9.41,3.91 8.32,5.56 C7.22,7.2 5.65,8.48 3.83,9.24 C2,10 -0.01,10.19 -1.95,9.81 C-3.89,9.42 -5.67,8.47 -7.07,7.07 C-8.47,5.67 -9.42,3.89 -9.81,1.95 C-10.19,0.01 -10,-2 -9.24,-3.83 C-8.48,-5.65 -7.2,-7.22 -5.56,-8.31c  M3 1 C3,1 5,1 5,1 C5,1 5,-3 5,-3 C5,-3 3,-3 3,-3 C3,-3 3,1 3,1c M-0.02 4.03 C-0.02,4.03 0.03,4.03 0.03,4.03 C0.03,4.03 0.03,4 0.03,4 C0.03,3.99 0.02,3.99 0.02,3.98 C0.01,3.98 0.01,3.98 0,3.98 C-0.01,3.98 -0.01,3.98 -0.02,3.98 C-0.02,3.99 -0.02,3.99 -0.02,4 C-0.02,4 -0.02,4.03 -0.02,4.03c  M-5 1 C-5,1 -3,1 -3,1 C-3,1 -3,-3 -3,-3 C-3,-3 -5,-3 -5,-3 C-5,-3 -5,1 -5,1c " android:valueType="pathType">
+          <aapt:attr name="android:interpolator">
+            <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0"/>
+          </aapt:attr>
+        </objectAnimator>
+      </set>
+    </aapt:attr>
+  </target>
+  <target android:name="time_group">
+    <aapt:attr name="android:animation">
+      <set android:ordering="together">
+        <objectAnimator android:propertyName="translateX" android:duration="750" android:startOffset="0" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+      </set>
+    </aapt:attr>
+  </target>
+</animated-vector>
diff --git a/packages/SystemUI/res/drawable/ic_device_pergola.xml b/packages/SystemUI/res/drawable/ic_device_pergola.xml
new file mode 100644
index 0000000..347ed3d
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_device_pergola.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2020 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
+  -->
+<selector
+    xmlns:android="http://schemas.android.com/apk/res/android">
+  <item
+      android:id="@+id/off"
+      android:state_enabled="false"
+      android:drawable="@drawable/ic_device_pergola_off" />
+  <item
+      android:id="@+id/on"
+      android:state_enabled="true"
+      android:drawable="@drawable/ic_device_pergola_on" />
+</selector>
diff --git a/packages/SystemUI/res/drawable/ic_device_refrigerator.xml b/packages/SystemUI/res/drawable/ic_device_refrigerator.xml
new file mode 100644
index 0000000..d9d73a3
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_device_refrigerator.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2020 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
+  -->
+<selector
+    xmlns:android="http://schemas.android.com/apk/res/android">
+  <item
+      android:id="@+id/off"
+      android:state_enabled="false"
+      android:drawable="@drawable/ic_device_refrigerator_off" />
+  <item
+      android:id="@+id/on"
+      android:state_enabled="true"
+      android:drawable="@drawable/ic_device_refrigerator_on" />
+</selector>
diff --git a/packages/SystemUI/res/drawable/ic_device_remote_control.xml b/packages/SystemUI/res/drawable/ic_device_remote_control.xml
new file mode 100644
index 0000000..a950238
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_device_remote_control.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2020 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
+  -->
+<selector
+    xmlns:android="http://schemas.android.com/apk/res/android">
+  <item
+      android:id="@+id/off"
+      android:state_enabled="false"
+      android:drawable="@drawable/ic_device_remote_control_off" />
+  <item
+      android:id="@+id/on"
+      android:state_enabled="true"
+      android:drawable="@drawable/ic_device_remote_control_on" />
+</selector>
diff --git a/packages/SystemUI/res/drawable/ic_device_security_system.xml b/packages/SystemUI/res/drawable/ic_device_security_system.xml
new file mode 100644
index 0000000..a607c10
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_device_security_system.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2020 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
+  -->
+<animated-selector
+    xmlns:android="http://schemas.android.com/apk/res/android">
+  <item
+      android:id="@+id/off"
+      android:state_enabled="false"
+      android:drawable="@drawable/ic_device_security_system_off" />
+  <item
+      android:id="@+id/on"
+      android:state_enabled="true"
+      android:drawable="@drawable/ic_device_security_system_on" />
+  <transition
+      android:fromId="@id/off"
+      android:toId="@id/on"
+      android:drawable="@drawable/ic_device_security_system_on_anim" />
+  <transition
+      android:fromId="@id/on"
+      android:toId="@id/off"
+      android:drawable="@drawable/ic_device_security_system_off_anim" />
+</animated-selector>
diff --git a/packages/SystemUI/res/drawable/ic_device_security_system_off_anim.xml b/packages/SystemUI/res/drawable/ic_device_security_system_off_anim.xml
new file mode 100644
index 0000000..5d6c014
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_device_security_system_off_anim.xml
@@ -0,0 +1,91 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2020 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
+  -->
+<animated-vector
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:aapt="http://schemas.android.com/aapt">
+  <aapt:attr name="android:drawable">
+    <vector android:height="24dp" android:width="24dp" android:viewportHeight="24" android:viewportWidth="24">
+      <group android:name="_R_G">
+        <group android:name="_R_G_L_2_G" android:translateX="12" android:translateY="12">
+          <path android:name="_R_G_L_2_G_D_0_P_0" android:fillColor="#000000" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M3.54 -3.89 C3.54,-3.89 3.54,-3.89 3.54,-3.89 C3.54,-3.89 3.54,-3.89 3.54,-3.89 C3.54,-3.89 3.54,-3.89 3.54,-3.89 C3.54,-3.89 4.95,-2.47 4.95,-2.47 C4.95,-2.47 4.96,-2.46 4.96,-2.46 C4.96,-2.46 3.54,-3.89 3.54,-3.89c "/>
+        </group>
+        <group android:name="_R_G_L_1_G" android:translateX="12" android:translateY="12">
+          <path android:name="_R_G_L_1_G_D_0_P_0" android:fillColor="#000000" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M4.37 4.43 C5.44,2.86 6.01,1 6,-0.91 C6,-0.91 6,-5.61 6,-5.61 C6,-5.61 0,-7.86 0,-7.86 C0,-7.86 -6,-5.61 -6,-5.61 C-6,-5.61 -6,-0.91 -6,-0.91 C-6,1 -5.44,2.86 -4.36,4.43 C-3.29,6.01 -1.77,7.22 0,7.92 C1.77,7.22 3.3,6.01 4.37,4.43c  M-8 -7 C-8,-7 0,-10 0,-10 C0,-10 8,-7 8,-7 C8,-7 8,-0.91 8,-0.91 C8,4.14 4.59,8.85 0,10 C-4.59,8.85 -8,4.14 -8,-0.91 C-8,-0.91 -8,-7 -8,-7c "/>
+        </group>
+        <group android:name="_R_G_L_0_G" android:translateX="12" android:translateY="12">
+          <group android:name="_R_G_L_0_C_0_G">
+            <clip-path android:name="_R_G_L_0_C_0" android:pathData=" M-0.2 -11.3 C-6.22,-11.3 -11.1,-6.42 -11.1,-0.4 C-11.1,5.62 -6.22,10.5 -0.2,10.5 C5.82,10.5 10.7,5.62 10.7,-0.4 C10.7,-6.42 5.82,-11.3 -0.2,-11.3c "/>
+            <group android:name="_R_G_L_0_C_0_G_G">
+              <path android:name="_R_G_L_0_G_G_0_D_0_P_0" android:fillColor="#000000" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M-4.95 0.35 C-4.95,0.35 -1.41,3.89 -1.41,3.89 C-1.41,3.89 4.95,-2.47 4.95,-2.47 C4.95,-2.47 3.54,-3.89 3.54,-3.89 C3.54,-3.89 -1.41,1.06 -1.41,1.06 C-1.41,1.06 -3.54,-1.06 -3.54,-1.06 C-3.54,-1.06 -4.95,0.35 -4.95,0.35c  M-8 -7 C-8,-7 0,-10 0,-10 C0,-10 8,-7 8,-7 C8,-7 8,-0.91 8,-0.91 C8,4.14 4.59,8.85 0,10 C-4.59,8.85 -8,4.14 -8,-0.91 C-8,-0.91 -8,-7 -8,-7c "/>
+            </group>
+          </group>
+        </group>
+      </group>
+      <group android:name="time_group"/>
+    </vector>
+  </aapt:attr>
+  <target android:name="_R_G_L_2_G_D_0_P_0">
+    <aapt:attr name="android:animation">
+      <set android:ordering="together">
+        <objectAnimator android:propertyName="pathData" android:duration="167" android:startOffset="0" android:valueFrom="M3.54 -3.89 C3.54,-3.89 3.54,-3.89 3.54,-3.89 C3.54,-3.89 3.54,-3.89 3.54,-3.89 C3.54,-3.89 3.54,-3.89 3.54,-3.89 C3.54,-3.89 4.95,-2.47 4.95,-2.47 C4.95,-2.47 4.96,-2.46 4.96,-2.46 C4.96,-2.46 3.54,-3.89 3.54,-3.89c " android:valueTo="M-2.83 2.45 C-2.83,2.45 -1.42,1.06 -1.42,1.06 C-1.42,1.06 -1.41,1.06 -1.41,1.06 C-1.41,1.06 3.54,-3.89 3.54,-3.89 C3.54,-3.89 4.95,-2.47 4.95,-2.47 C4.95,-2.47 -1.41,3.89 -1.41,3.89 C-1.41,3.89 -2.83,2.45 -2.83,2.45c " android:valueType="pathType">
+          <aapt:attr name="android:interpolator">
+            <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0"/>
+          </aapt:attr>
+        </objectAnimator>
+        <objectAnimator android:propertyName="pathData" android:duration="333" android:startOffset="167" android:valueFrom="M-2.83 2.45 C-2.83,2.45 -1.42,1.06 -1.42,1.06 C-1.42,1.06 -1.41,1.06 -1.41,1.06 C-1.41,1.06 3.54,-3.89 3.54,-3.89 C3.54,-3.89 4.95,-2.47 4.95,-2.47 C4.95,-2.47 -1.41,3.89 -1.41,3.89 C-1.41,3.89 -2.83,2.45 -2.83,2.45c " android:valueTo="M-4.95 0.35 C-4.95,0.35 -3.54,-1.06 -3.54,-1.06 C-3.54,-1.06 -1.41,1.06 -1.41,1.06 C-1.41,1.06 3.54,-3.89 3.54,-3.89 C3.54,-3.89 4.95,-2.47 4.95,-2.47 C4.95,-2.47 -1.41,3.89 -1.41,3.89 C-1.41,3.89 -4.95,0.35 -4.95,0.35c " android:valueType="pathType">
+          <aapt:attr name="android:interpolator">
+            <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0"/>
+          </aapt:attr>
+        </objectAnimator>
+      </set>
+    </aapt:attr>
+  </target>
+  <target android:name="_R_G_L_0_C_0">
+    <aapt:attr name="android:animation">
+      <set android:ordering="together">
+        <objectAnimator android:propertyName="pathData" android:duration="500" android:startOffset="0" android:valueFrom="M-0.2 -11.3 C-6.22,-11.3 -11.1,-6.42 -11.1,-0.4 C-11.1,5.62 -6.22,10.5 -0.2,10.5 C5.82,10.5 10.7,5.62 10.7,-0.4 C10.7,-6.42 5.82,-11.3 -0.2,-11.3c " android:valueTo="M-0.2 10.1 C-4.17,10.1 -7.4,13.33 -7.4,17.3 C-7.4,21.28 -4.17,24.5 -0.2,24.5 C3.78,24.5 7,21.28 7,17.3 C7,13.33 3.78,10.1 -0.2,10.1c " android:valueType="pathType">
+          <aapt:attr name="android:interpolator">
+            <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0"/>
+          </aapt:attr>
+        </objectAnimator>
+      </set>
+    </aapt:attr>
+  </target>
+  <target android:name="_R_G_L_0_G_G_0_D_0_P_0">
+    <aapt:attr name="android:animation">
+      <set android:ordering="together">
+        <objectAnimator android:propertyName="pathData" android:duration="333" android:startOffset="0" android:valueFrom="M-4.95 0.35 C-4.95,0.35 -1.41,3.89 -1.41,3.89 C-1.41,3.89 4.95,-2.47 4.95,-2.47 C4.95,-2.47 3.54,-3.89 3.54,-3.89 C3.54,-3.89 -1.41,1.06 -1.41,1.06 C-1.41,1.06 -3.54,-1.06 -3.54,-1.06 C-3.54,-1.06 -4.95,0.35 -4.95,0.35c  M-8 -7 C-8,-7 0,-10 0,-10 C0,-10 8,-7 8,-7 C8,-7 8,-0.91 8,-0.91 C8,4.14 4.59,8.85 0,10 C-4.59,8.85 -8,4.14 -8,-0.91 C-8,-0.91 -8,-7 -8,-7c " android:valueTo="M-4.95 0.35 C-4.95,0.35 -1.41,3.89 -1.41,3.89 C-1.41,3.89 0,2.46 0,2.46 C0,2.46 -1.41,1.05 -1.41,1.05 C-1.41,1.05 -1.41,1.06 -1.41,1.06 C-1.41,1.06 -3.54,-1.06 -3.54,-1.06 C-3.54,-1.06 -4.95,0.35 -4.95,0.35c  M-8 -7 C-8,-7 0,-10 0,-10 C0,-10 8,-7 8,-7 C8,-7 8,-0.91 8,-0.91 C8,4.14 4.59,8.85 0,10 C-4.59,8.85 -8,4.14 -8,-0.91 C-8,-0.91 -8,-7 -8,-7c " android:valueType="pathType">
+          <aapt:attr name="android:interpolator">
+            <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0"/>
+          </aapt:attr>
+        </objectAnimator>
+        <objectAnimator android:propertyName="pathData" android:duration="167" android:startOffset="333" android:valueFrom="M-4.95 0.35 C-4.95,0.35 -1.41,3.89 -1.41,3.89 C-1.41,3.89 0,2.46 0,2.46 C0,2.46 -1.41,1.05 -1.41,1.05 C-1.41,1.05 -1.41,1.06 -1.41,1.06 C-1.41,1.06 -3.54,-1.06 -3.54,-1.06 C-3.54,-1.06 -4.95,0.35 -4.95,0.35c  M-8 -7 C-8,-7 0,-10 0,-10 C0,-10 8,-7 8,-7 C8,-7 8,-0.91 8,-0.91 C8,4.14 4.59,8.85 0,10 C-4.59,8.85 -8,4.14 -8,-0.91 C-8,-0.91 -8,-7 -8,-7c " android:valueTo="M-4.95 0.35 C-4.95,0.35 -4.95,0.35 -4.95,0.35 C-4.95,0.35 -3.54,-1.07 -3.54,-1.07 C-3.54,-1.07 -3.55,-1.09 -3.55,-1.09 C-3.55,-1.09 -3.55,-1.08 -3.55,-1.08 C-3.55,-1.08 -3.54,-1.06 -3.54,-1.06 C-3.54,-1.06 -4.95,0.35 -4.95,0.35c  M-8 -7 C-8,-7 0,-10 0,-10 C0,-10 8,-7 8,-7 C8,-7 8,-0.91 8,-0.91 C8,4.14 4.59,8.85 0,10 C-4.59,8.85 -8,4.14 -8,-0.91 C-8,-0.91 -8,-7 -8,-7c " android:valueType="pathType">
+          <aapt:attr name="android:interpolator">
+            <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0"/>
+          </aapt:attr>
+        </objectAnimator>
+      </set>
+    </aapt:attr>
+  </target>
+  <target android:name="time_group">
+    <aapt:attr name="android:animation">
+      <set android:ordering="together">
+        <objectAnimator android:propertyName="translateX" android:duration="750" android:startOffset="0" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+      </set>
+    </aapt:attr>
+  </target>
+</animated-vector>
diff --git a/packages/SystemUI/res/drawable/ic_device_security_system_on_anim.xml b/packages/SystemUI/res/drawable/ic_device_security_system_on_anim.xml
new file mode 100644
index 0000000..445c675
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_device_security_system_on_anim.xml
@@ -0,0 +1,91 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2020 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
+  -->
+<animated-vector
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:aapt="http://schemas.android.com/aapt">
+  <aapt:attr name="android:drawable">
+    <vector android:height="24dp" android:width="24dp" android:viewportHeight="24" android:viewportWidth="24">
+      <group android:name="_R_G">
+        <group android:name="_R_G_L_2_G" android:translateX="12" android:translateY="12">
+          <path android:name="_R_G_L_2_G_D_0_P_0" android:fillColor="#000000" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M-4.95 0.35 C-4.95,0.35 -3.54,-1.06 -3.54,-1.06 C-3.54,-1.06 -1.41,1.06 -1.41,1.06 C-1.41,1.06 3.54,-3.89 3.54,-3.89 C3.54,-3.89 4.95,-2.47 4.95,-2.47 C4.95,-2.47 -1.41,3.89 -1.41,3.89 C-1.41,3.89 -4.95,0.35 -4.95,0.35c "/>
+        </group>
+        <group android:name="_R_G_L_1_G" android:translateX="12" android:translateY="12">
+          <path android:name="_R_G_L_1_G_D_0_P_0" android:fillColor="#000000" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M4.37 4.43 C5.44,2.86 6.01,1 6,-0.91 C6,-0.91 6,-5.61 6,-5.61 C6,-5.61 0,-7.86 0,-7.86 C0,-7.86 -6,-5.61 -6,-5.61 C-6,-5.61 -6,-0.91 -6,-0.91 C-6,1 -5.44,2.86 -4.36,4.43 C-3.29,6.01 -1.77,7.22 0,7.92 C1.77,7.22 3.3,6.01 4.37,4.43c  M-8 -7 C-8,-7 0,-10 0,-10 C0,-10 8,-7 8,-7 C8,-7 8,-0.91 8,-0.91 C8,4.14 4.59,8.85 0,10 C-4.59,8.85 -8,4.14 -8,-0.91 C-8,-0.91 -8,-7 -8,-7c "/>
+        </group>
+        <group android:name="_R_G_L_0_G" android:translateX="12" android:translateY="12">
+          <group android:name="_R_G_L_0_C_0_G">
+            <clip-path android:name="_R_G_L_0_C_0" android:pathData=" M-0.2 10.1 C-4.17,10.1 -7.4,13.33 -7.4,17.3 C-7.4,21.28 -4.17,24.5 -0.2,24.5 C3.78,24.5 7,21.28 7,17.3 C7,13.33 3.78,10.1 -0.2,10.1c "/>
+            <group android:name="_R_G_L_0_C_0_G_G">
+              <path android:name="_R_G_L_0_G_G_0_D_0_P_0" android:fillColor="#000000" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M-4.95 0.35 C-4.95,0.35 -4.95,0.35 -4.95,0.35 C-4.95,0.35 -3.54,-1.07 -3.54,-1.07 C-3.54,-1.07 -3.55,-1.09 -3.55,-1.09 C-3.55,-1.09 -3.55,-1.08 -3.55,-1.08 C-3.55,-1.08 -3.54,-1.06 -3.54,-1.06 C-3.54,-1.06 -4.95,0.35 -4.95,0.35c  M-8 -7 C-8,-7 0,-10 0,-10 C0,-10 8,-7 8,-7 C8,-7 8,-0.91 8,-0.91 C8,4.14 4.59,8.85 0,10 C-4.59,8.85 -8,4.14 -8,-0.91 C-8,-0.91 -8,-7 -8,-7c "/>
+            </group>
+          </group>
+        </group>
+      </group>
+      <group android:name="time_group"/>
+    </vector>
+  </aapt:attr>
+  <target android:name="_R_G_L_2_G_D_0_P_0">
+    <aapt:attr name="android:animation">
+      <set android:ordering="together">
+        <objectAnimator android:propertyName="pathData" android:duration="167" android:startOffset="0" android:valueFrom="M-4.95 0.35 C-4.95,0.35 -3.54,-1.06 -3.54,-1.06 C-3.54,-1.06 -1.41,1.06 -1.41,1.06 C-1.41,1.06 3.54,-3.89 3.54,-3.89 C3.54,-3.89 4.95,-2.47 4.95,-2.47 C4.95,-2.47 -1.41,3.89 -1.41,3.89 C-1.41,3.89 -4.95,0.35 -4.95,0.35c " android:valueTo="M-2.83 2.45 C-2.83,2.45 -1.42,1.06 -1.42,1.06 C-1.42,1.06 -1.41,1.06 -1.41,1.06 C-1.41,1.06 3.54,-3.89 3.54,-3.89 C3.54,-3.89 4.95,-2.47 4.95,-2.47 C4.95,-2.47 -1.41,3.89 -1.41,3.89 C-1.41,3.89 -2.83,2.45 -2.83,2.45c " android:valueType="pathType">
+          <aapt:attr name="android:interpolator">
+            <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0"/>
+          </aapt:attr>
+        </objectAnimator>
+        <objectAnimator android:propertyName="pathData" android:duration="233" android:startOffset="167" android:valueFrom="M-2.83 2.45 C-2.83,2.45 -1.42,1.06 -1.42,1.06 C-1.42,1.06 -1.41,1.06 -1.41,1.06 C-1.41,1.06 3.54,-3.89 3.54,-3.89 C3.54,-3.89 4.95,-2.47 4.95,-2.47 C4.95,-2.47 -1.41,3.89 -1.41,3.89 C-1.41,3.89 -2.83,2.45 -2.83,2.45c " android:valueTo="M3.54 -3.89 C3.54,-3.89 3.54,-3.89 3.54,-3.89 C3.54,-3.89 3.54,-3.89 3.54,-3.89 C3.54,-3.89 3.54,-3.89 3.54,-3.89 C3.54,-3.89 4.95,-2.47 4.95,-2.47 C4.95,-2.47 4.96,-2.46 4.96,-2.46 C4.96,-2.46 3.54,-3.89 3.54,-3.89c " android:valueType="pathType">
+          <aapt:attr name="android:interpolator">
+            <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0"/>
+          </aapt:attr>
+        </objectAnimator>
+      </set>
+    </aapt:attr>
+  </target>
+  <target android:name="_R_G_L_0_C_0">
+    <aapt:attr name="android:animation">
+      <set android:ordering="together">
+        <objectAnimator android:propertyName="pathData" android:duration="500" android:startOffset="0" android:valueFrom="M-0.2 10.1 C-4.17,10.1 -7.4,13.33 -7.4,17.3 C-7.4,21.28 -4.17,24.5 -0.2,24.5 C3.78,24.5 7,21.28 7,17.3 C7,13.33 3.78,10.1 -0.2,10.1c " android:valueTo="M-0.2 -11.3 C-6.22,-11.3 -11.1,-6.42 -11.1,-0.4 C-11.1,5.62 -6.22,10.5 -0.2,10.5 C5.82,10.5 10.7,5.62 10.7,-0.4 C10.7,-6.42 5.82,-11.3 -0.2,-11.3c " android:valueType="pathType">
+          <aapt:attr name="android:interpolator">
+            <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0"/>
+          </aapt:attr>
+        </objectAnimator>
+      </set>
+    </aapt:attr>
+  </target>
+  <target android:name="_R_G_L_0_G_G_0_D_0_P_0">
+    <aapt:attr name="android:animation">
+      <set android:ordering="together">
+        <objectAnimator android:propertyName="pathData" android:duration="167" android:startOffset="0" android:valueFrom="M-4.95 0.35 C-4.95,0.35 -4.95,0.35 -4.95,0.35 C-4.95,0.35 -3.54,-1.07 -3.54,-1.07 C-3.54,-1.07 -3.55,-1.09 -3.55,-1.09 C-3.55,-1.09 -3.55,-1.08 -3.55,-1.08 C-3.55,-1.08 -3.54,-1.06 -3.54,-1.06 C-3.54,-1.06 -4.95,0.35 -4.95,0.35c  M-8 -7 C-8,-7 0,-10 0,-10 C0,-10 8,-7 8,-7 C8,-7 8,-0.91 8,-0.91 C8,4.14 4.59,8.85 0,10 C-4.59,8.85 -8,4.14 -8,-0.91 C-8,-0.91 -8,-7 -8,-7c " android:valueTo="M-4.95 0.35 C-4.95,0.35 -1.41,3.89 -1.41,3.89 C-1.41,3.89 0,2.46 0,2.46 C0,2.46 -1.41,1.05 -1.41,1.05 C-1.41,1.05 -1.41,1.06 -1.41,1.06 C-1.41,1.06 -3.54,-1.06 -3.54,-1.06 C-3.54,-1.06 -4.95,0.35 -4.95,0.35c  M-8 -7 C-8,-7 0,-10 0,-10 C0,-10 8,-7 8,-7 C8,-7 8,-0.91 8,-0.91 C8,4.14 4.59,8.85 0,10 C-4.59,8.85 -8,4.14 -8,-0.91 C-8,-0.91 -8,-7 -8,-7c " android:valueType="pathType">
+          <aapt:attr name="android:interpolator">
+            <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0 0.2,1 1.0,1.0"/>
+          </aapt:attr>
+        </objectAnimator>
+        <objectAnimator android:propertyName="pathData" android:duration="333" android:startOffset="167" android:valueFrom="M-4.95 0.35 C-4.95,0.35 -1.41,3.89 -1.41,3.89 C-1.41,3.89 0,2.46 0,2.46 C0,2.46 -1.41,1.05 -1.41,1.05 C-1.41,1.05 -1.41,1.06 -1.41,1.06 C-1.41,1.06 -3.54,-1.06 -3.54,-1.06 C-3.54,-1.06 -4.95,0.35 -4.95,0.35c  M-8 -7 C-8,-7 0,-10 0,-10 C0,-10 8,-7 8,-7 C8,-7 8,-0.91 8,-0.91 C8,4.14 4.59,8.85 0,10 C-4.59,8.85 -8,4.14 -8,-0.91 C-8,-0.91 -8,-7 -8,-7c " android:valueTo="M-4.95 0.35 C-4.95,0.35 -1.41,3.89 -1.41,3.89 C-1.41,3.89 4.95,-2.47 4.95,-2.47 C4.95,-2.47 3.54,-3.89 3.54,-3.89 C3.54,-3.89 -1.41,1.06 -1.41,1.06 C-1.41,1.06 -3.54,-1.06 -3.54,-1.06 C-3.54,-1.06 -4.95,0.35 -4.95,0.35c  M-8 -7 C-8,-7 0,-10 0,-10 C0,-10 8,-7 8,-7 C8,-7 8,-0.91 8,-0.91 C8,4.14 4.59,8.85 0,10 C-4.59,8.85 -8,4.14 -8,-0.91 C-8,-0.91 -8,-7 -8,-7c " android:valueType="pathType">
+          <aapt:attr name="android:interpolator">
+            <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0"/>
+          </aapt:attr>
+        </objectAnimator>
+      </set>
+    </aapt:attr>
+  </target>
+  <target android:name="time_group">
+    <aapt:attr name="android:animation">
+      <set android:ordering="together">
+        <objectAnimator android:propertyName="translateX" android:duration="750" android:startOffset="0" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+      </set>
+    </aapt:attr>
+  </target>
+</animated-vector>
diff --git a/packages/SystemUI/res/drawable/ic_device_set_top.xml b/packages/SystemUI/res/drawable/ic_device_set_top.xml
new file mode 100644
index 0000000..23a58c1
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_device_set_top.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2020 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
+  -->
+<selector
+    xmlns:android="http://schemas.android.com/apk/res/android">
+  <item
+      android:id="@+id/off"
+      android:state_enabled="false"
+      android:drawable="@drawable/ic_device_set_top_off" />
+  <item
+      android:id="@+id/on"
+      android:state_enabled="true"
+      android:drawable="@drawable/ic_device_set_top_on" />
+</selector>
diff --git a/packages/SystemUI/res/drawable/ic_device_sprinkler.xml b/packages/SystemUI/res/drawable/ic_device_sprinkler.xml
new file mode 100644
index 0000000..e1a1e046
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_device_sprinkler.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2020 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
+  -->
+<selector
+    xmlns:android="http://schemas.android.com/apk/res/android">
+  <item
+      android:id="@+id/off"
+      android:state_enabled="false"
+      android:drawable="@drawable/ic_device_sprinkler_off" />
+  <item
+      android:id="@+id/on"
+      android:state_enabled="true"
+      android:drawable="@drawable/ic_device_sprinkler_on" />
+</selector>
diff --git a/packages/SystemUI/res/drawable/ic_device_styler.xml b/packages/SystemUI/res/drawable/ic_device_styler.xml
new file mode 100644
index 0000000..4862905
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_device_styler.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2020 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
+  -->
+<selector
+    xmlns:android="http://schemas.android.com/apk/res/android">
+  <item
+      android:id="@+id/off"
+      android:state_enabled="false"
+      android:drawable="@drawable/ic_device_styler_off" />
+  <item
+      android:id="@+id/on"
+      android:state_enabled="true"
+      android:drawable="@drawable/ic_device_styler_on" />
+</selector>
diff --git a/packages/SystemUI/res/drawable/ic_device_switch.xml b/packages/SystemUI/res/drawable/ic_device_switch.xml
new file mode 100644
index 0000000..554612d
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_device_switch.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2020 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
+  -->
+<animated-selector
+    xmlns:android="http://schemas.android.com/apk/res/android">
+  <item
+      android:id="@+id/off"
+      android:state_enabled="false"
+      android:drawable="@drawable/ic_device_switch_off" />
+  <item
+      android:id="@+id/on"
+      android:state_enabled="true"
+      android:drawable="@drawable/ic_device_switch_on" />
+  <transition
+      android:fromId="@id/off"
+      android:toId="@id/on"
+      android:drawable="@drawable/ic_device_switch_on_anim" />
+  <transition
+      android:fromId="@id/on"
+      android:toId="@id/off"
+      android:drawable="@drawable/ic_device_switch_off_anim" />
+</animated-selector>
diff --git a/packages/SystemUI/res/drawable/ic_device_switch_off_anim.xml b/packages/SystemUI/res/drawable/ic_device_switch_off_anim.xml
new file mode 100644
index 0000000..ecfc5c1
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_device_switch_off_anim.xml
@@ -0,0 +1,106 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2020 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
+  -->
+<animated-vector
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:aapt="http://schemas.android.com/aapt">
+  <aapt:attr name="android:drawable">
+    <vector android:height="24dp" android:width="24dp" android:viewportHeight="24" android:viewportWidth="24">
+      <group android:name="_R_G">
+        <group android:name="_R_G_L_7_G" android:translateX="12" android:translateY="12" android:scaleY="0">
+          <path android:name="_R_G_L_7_G_D_0_P_0" android:fillColor="#000000" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M-7 7 C-7,7 7,7 7,7 C7,7 7,-7 7,-7 C7,-7 -7,-7 -7,-7 C-7,-7 -7,7 -7,7c  M-7 -9 C-7,-9 7,-9 7,-9 C7.53,-9 8.04,-8.79 8.41,-8.41 C8.79,-8.04 9,-7.53 9,-7 C9,-7 9,7 9,7 C9,7.53 8.79,8.04 8.41,8.41 C8.04,8.79 7.53,9 7,9 C7,9 -7,9 -7,9 C-7.53,9 -8.04,8.79 -8.41,8.41 C-8.79,8.04 -9,7.53 -9,7 C-9,7 -9,-7 -9,-7 C-9,-7.53 -8.79,-8.04 -8.41,-8.41 C-8.04,-8.79 -7.53,-9 -7,-9c "/>
+        </group>
+        <group android:name="_R_G_L_6_G" android:translateX="12" android:translateY="12" android:scaleY="0">
+          <path android:name="_R_G_L_6_G_D_0_P_0" android:fillColor="#000000" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M-2 3 C-2,3 2,3 2,3 C2,3 2,-3 2,-3 C2,-3 -2,-3 -2,-3 C-2,-3 -2,3 -2,3c  M-4 -5 C-4,-5 4,-5 4,-5 C4,-5 4,5 4,5 C4,5 -4,5 -4,5 C-4,5 -4,-5 -4,-5c "/>
+        </group>
+        <group android:name="_R_G_L_5_G" android:translateX="12" android:translateY="11" android:scaleY="0">
+          <path android:name="_R_G_L_5_G_D_0_P_0" android:fillColor="#000000" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M-1 -1 C-1,-1 1,-1 1,-1 C1,-1 1,1 1,1 C1,1 -1,1 -1,1 C-1,1 -1,-1 -1,-1c "/>
+        </group>
+        <group android:name="_R_G_L_4_G" android:translateX="12" android:translateY="12">
+          <path android:name="_R_G_L_4_G_D_0_P_0" android:fillColor="#000000" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M-1 0 C-1,0 1,0 1,0 C1,0 1,-2 1,-2 C1,-2 -1,-2 -1,-2 C-1,-2 -1,0 -1,0c  M-2 -3 C-2,-3 2,-3 2,-3 C2,-3 2,3 2,3 C2,3 -2,3 -2,3 C-2,3 -2,-3 -2,-3c "/>
+        </group>
+        <group android:name="_R_G_L_3_G" android:translateX="12" android:translateY="12" android:scaleY="0">
+          <path android:name="_R_G_L_3_G_D_0_P_0" android:fillColor="#000000" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M-4 5 C-4,5 4,5 4,5 C4,5 4,-5 4,-5 C4,-5 -4,-5 -4,-5 C-4,-5 -4,5 -4,5c  M-7 -9 C-7,-9 7,-9 7,-9 C7.53,-9 8.04,-8.79 8.41,-8.41 C8.79,-8.04 9,-7.53 9,-7 C9,-7 9,7 9,7 C9,7.53 8.79,8.04 8.41,8.41 C8.04,8.79 7.53,9 7,9 C7,9 -7,9 -7,9 C-7.53,9 -8.04,8.79 -8.41,8.41 C-8.79,8.04 -9,7.53 -9,7 C-9,7 -9,-7 -9,-7 C-9,-7.53 -8.79,-8.04 -8.41,-8.41 C-8.04,-8.79 -7.53,-9 -7,-9c "/>
+        </group>
+        <group android:name="_R_G_L_2_G" android:translateX="12" android:translateY="12">
+          <path android:name="_R_G_L_2_G_D_0_P_0" android:fillColor="#000000" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M-4 5 C-4,5 4.01,5 4.01,5 C4.01,5 4.01,-5 4.01,-5 C4.01,-5 -4,-5 -4,-5 C-4,-5 -4,5 -4,5c  M-7 -9 C-7,-9 7,-9 7,-9 C7.53,-9 8.04,-8.79 8.41,-8.41 C8.79,-8.04 9,-7.53 9,-7 C9,-7 9,7 9,7 C9,7.53 8.79,8.04 8.41,8.41 C8.04,8.79 7.53,9 7,9 C7,9 -7,9 -7,9 C-7.53,9 -8.04,8.79 -8.41,8.41 C-8.79,8.04 -9,7.53 -9,7 C-9,7 -9,-7 -9,-7 C-9,-7.53 -8.79,-8.04 -8.41,-8.41 C-8.04,-8.79 -7.53,-9 -7,-9c "/>
+        </group>
+        <group android:name="_R_G_L_1_G" android:translateX="12" android:translateY="12" android:scaleY="0">
+          <path android:name="_R_G_L_1_G_D_0_P_0" android:fillColor="#000000" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M-2 3 C-2,3 2,3 2,3 C2,3 2,-3 2,-3 C2,-3 -2,-3 -2,-3 C-2,-3 -2,3 -2,3c  M-4 -5 C-4,-5 4,-5 4,-5 C4,-5 4,5 4,5 C4,5 -4,5 -4,5 C-4,5 -4,-5 -4,-5c "/>
+        </group>
+        <group android:name="_R_G_L_0_G" android:translateX="12" android:translateY="13" android:scaleY="0">
+          <path android:name="_R_G_L_0_G_D_0_P_0" android:fillColor="#000000" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M-1 -1 C-1,-1 1,-1 1,-1 C1,-1 1,1 1,1 C1,1 -1,1 -1,1 C-1,1 -1,-1 -1,-1c "/>
+        </group>
+      </group>
+      <group android:name="time_group"/>
+    </vector>
+  </aapt:attr>
+  <target android:name="_R_G_L_4_G_D_0_P_0">
+    <aapt:attr name="android:animation">
+      <set android:ordering="together">
+        <objectAnimator android:propertyName="pathData" android:duration="350" android:startOffset="0" android:valueFrom="M-1 0 C-1,0 1,0 1,0 C1,0 1,-2 1,-2 C1,-2 -1,-2 -1,-2 C-1,-2 -1,0 -1,0c  M-2 -3 C-2,-3 2,-3 2,-3 C2,-3 2,3 2,3 C2,3 -2,3 -2,3 C-2,3 -2,-3 -2,-3c " android:valueTo="M-1 2 C-1,2 1,2 1,2 C1,2 1,0 1,0 C1,0 -1,0 -1,0 C-1,0 -1,2 -1,2c  M-2 -3 C-2,-3 2,-3 2,-3 C2,-3 2,3 2,3 C2,3 -2,3 -2,3 C-2,3 -2,-3 -2,-3c " android:valueType="pathType">
+          <aapt:attr name="android:interpolator">
+            <pathInterpolator android:pathData="M 0.0,0.0 c0.8,0 0.4,1 1.0,1.0"/>
+          </aapt:attr>
+        </objectAnimator>
+      </set>
+    </aapt:attr>
+  </target>
+  <target android:name="_R_G_L_4_G">
+    <aapt:attr name="android:animation">
+      <set android:ordering="together">
+        <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="333" android:valueFrom="1" android:valueTo="0" android:valueType="floatType"/>
+      </set>
+    </aapt:attr>
+  </target>
+  <target android:name="_R_G_L_2_G_D_0_P_0">
+    <aapt:attr name="android:animation">
+      <set android:ordering="together">
+        <objectAnimator android:propertyName="pathData" android:duration="133" android:startOffset="0" android:valueFrom="M-4 5 C-4,5 4.01,5 4.01,5 C4.01,5 4.01,-5 4.01,-5 C4.01,-5 -4,-5 -4,-5 C-4,-5 -4,5 -4,5c  M-7 -9 C-7,-9 7,-9 7,-9 C7.53,-9 8.04,-8.79 8.41,-8.41 C8.79,-8.04 9,-7.53 9,-7 C9,-7 9,7 9,7 C9,7.53 8.79,8.04 8.41,8.41 C8.04,8.79 7.53,9 7,9 C7,9 -7,9 -7,9 C-7.53,9 -8.04,8.79 -8.41,8.41 C-8.79,8.04 -9,7.53 -9,7 C-9,7 -9,-7 -9,-7 C-9,-7.53 -8.79,-8.04 -8.41,-8.41 C-8.04,-8.79 -7.53,-9 -7,-9c " android:valueTo="M-4 5 C-4,5 4.01,5 4.01,5 C4.01,5 4.01,-5 4.01,-5 C4.01,-5 -4,-5 -4,-5 C-4,-5 -4,5 -4,5c  M-7 -9 C-7,-9 7,-9 7,-9 C7.53,-9 8.04,-8.79 8.41,-8.41 C8.79,-8.04 9,-7.53 9,-7 C9,-7 9,7 9,7 C9,7.53 8.79,8.04 8.41,8.41 C8.04,8.79 7.53,9 7,9 C7,9 -7,9 -7,9 C-7.53,9 -8.04,8.79 -8.41,8.41 C-8.79,8.04 -9,7.53 -9,7 C-9,7 -9,-7 -9,-7 C-9,-7.53 -8.79,-8.04 -8.41,-8.41 C-8.04,-8.79 -7.53,-9 -7,-9c " android:valueType="pathType">
+          <aapt:attr name="android:interpolator">
+            <pathInterpolator android:pathData="M 0.0,0.0 c0.8,0 0.4,1 1.0,1.0"/>
+          </aapt:attr>
+        </objectAnimator>
+        <objectAnimator android:propertyName="pathData" android:duration="217" android:startOffset="133" android:valueFrom="M-4 5 C-4,5 4.01,5 4.01,5 C4.01,5 4.01,-5 4.01,-5 C4.01,-5 -4,-5 -4,-5 C-4,-5 -4,5 -4,5c  M-7 -9 C-7,-9 7,-9 7,-9 C7.53,-9 8.04,-8.79 8.41,-8.41 C8.79,-8.04 9,-7.53 9,-7 C9,-7 9,7 9,7 C9,7.53 8.79,8.04 8.41,8.41 C8.04,8.79 7.53,9 7,9 C7,9 -7,9 -7,9 C-7.53,9 -8.04,8.79 -8.41,8.41 C-8.79,8.04 -9,7.53 -9,7 C-9,7 -9,-7 -9,-7 C-9,-7.53 -8.79,-8.04 -8.41,-8.41 C-8.04,-8.79 -7.53,-9 -7,-9c " android:valueTo="M-7 7 C-7,7 7,7 7,7 C7,7 7,-7 7,-7 C7,-7 -7,-7 -7,-7 C-7,-7 -7,7 -7,7c  M-7 -9 C-7,-9 7,-9 7,-9 C7.53,-9 8.04,-8.79 8.41,-8.41 C8.79,-8.04 9,-7.53 9,-7 C9,-7 9,7 9,7 C9,7.53 8.79,8.04 8.41,8.41 C8.04,8.79 7.53,9 7,9 C7,9 -7,9 -7,9 C-7.53,9 -8.04,8.79 -8.41,8.41 C-8.79,8.04 -9,7.53 -9,7 C-9,7 -9,-7 -9,-7 C-9,-7.53 -8.79,-8.04 -8.41,-8.41 C-8.04,-8.79 -7.53,-9 -7,-9c " android:valueType="pathType">
+          <aapt:attr name="android:interpolator">
+            <pathInterpolator android:pathData="M 0.0,0.0 c0.8,0 0.4,1 1.0,1.0"/>
+          </aapt:attr>
+        </objectAnimator>
+      </set>
+    </aapt:attr>
+  </target>
+  <target android:name="_R_G_L_1_G">
+    <aapt:attr name="android:animation">
+      <set android:ordering="together">
+        <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="317" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+      </set>
+    </aapt:attr>
+  </target>
+  <target android:name="_R_G_L_0_G">
+    <aapt:attr name="android:animation">
+      <set android:ordering="together">
+        <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="317" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+      </set>
+    </aapt:attr>
+  </target>
+  <target android:name="time_group">
+    <aapt:attr name="android:animation">
+      <set android:ordering="together">
+        <objectAnimator android:propertyName="translateX" android:duration="750" android:startOffset="0" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+      </set>
+    </aapt:attr>
+  </target>
+</animated-vector>
diff --git a/packages/SystemUI/res/drawable/ic_device_switch_on_anim.xml b/packages/SystemUI/res/drawable/ic_device_switch_on_anim.xml
new file mode 100644
index 0000000..bd28519
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_device_switch_on_anim.xml
@@ -0,0 +1,106 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2020 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
+  -->
+<animated-vector
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:aapt="http://schemas.android.com/aapt">
+  <aapt:attr name="android:drawable">
+    <vector android:height="24dp" android:width="24dp" android:viewportHeight="24" android:viewportWidth="24">
+      <group android:name="_R_G">
+        <group android:name="_R_G_L_7_G" android:translateX="12" android:translateY="12" android:scaleY="0">
+          <path android:name="_R_G_L_7_G_D_0_P_0" android:fillColor="#000000" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M-7 7 C-7,7 7,7 7,7 C7,7 7,-7 7,-7 C7,-7 -7,-7 -7,-7 C-7,-7 -7,7 -7,7c  M-7 -9 C-7,-9 7,-9 7,-9 C7.53,-9 8.04,-8.79 8.41,-8.41 C8.79,-8.04 9,-7.53 9,-7 C9,-7 9,7 9,7 C9,7.53 8.79,8.04 8.41,8.41 C8.04,8.79 7.53,9 7,9 C7,9 -7,9 -7,9 C-7.53,9 -8.04,8.79 -8.41,8.41 C-8.79,8.04 -9,7.53 -9,7 C-9,7 -9,-7 -9,-7 C-9,-7.53 -8.79,-8.04 -8.41,-8.41 C-8.04,-8.79 -7.53,-9 -7,-9c "/>
+        </group>
+        <group android:name="_R_G_L_6_G" android:translateX="12" android:translateY="12" android:scaleY="0">
+          <path android:name="_R_G_L_6_G_D_0_P_0" android:fillColor="#000000" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M-2 3 C-2,3 2,3 2,3 C2,3 2,-3 2,-3 C2,-3 -2,-3 -2,-3 C-2,-3 -2,3 -2,3c  M-4 -5 C-4,-5 4,-5 4,-5 C4,-5 4,5 4,5 C4,5 -4,5 -4,5 C-4,5 -4,-5 -4,-5c "/>
+        </group>
+        <group android:name="_R_G_L_5_G" android:translateX="12" android:translateY="11" android:scaleY="0">
+          <path android:name="_R_G_L_5_G_D_0_P_0" android:fillColor="#000000" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M-1 -1 C-1,-1 1,-1 1,-1 C1,-1 1,1 1,1 C1,1 -1,1 -1,1 C-1,1 -1,-1 -1,-1c "/>
+        </group>
+        <group android:name="_R_G_L_4_G" android:translateX="12" android:translateY="12" android:scaleY="0">
+          <path android:name="_R_G_L_4_G_D_0_P_0" android:fillColor="#000000" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M-1 0 C-1,0 1,0 1,0 C1,0 1,-2 1,-2 C1,-2 -1,-2 -1,-2 C-1,-2 -1,0 -1,0c  M-2 -3 C-2,-3 2,-3 2,-3 C2,-3 2,3 2,3 C2,3 -2,3 -2,3 C-2,3 -2,-3 -2,-3c "/>
+        </group>
+        <group android:name="_R_G_L_3_G" android:translateX="12" android:translateY="12" android:scaleY="0">
+          <path android:name="_R_G_L_3_G_D_0_P_0" android:fillColor="#000000" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M-4 5 C-4,5 4,5 4,5 C4,5 4,-5 4,-5 C4,-5 -4,-5 -4,-5 C-4,-5 -4,5 -4,5c  M-7 -9 C-7,-9 7,-9 7,-9 C7.53,-9 8.04,-8.79 8.41,-8.41 C8.79,-8.04 9,-7.53 9,-7 C9,-7 9,7 9,7 C9,7.53 8.79,8.04 8.41,8.41 C8.04,8.79 7.53,9 7,9 C7,9 -7,9 -7,9 C-7.53,9 -8.04,8.79 -8.41,8.41 C-8.79,8.04 -9,7.53 -9,7 C-9,7 -9,-7 -9,-7 C-9,-7.53 -8.79,-8.04 -8.41,-8.41 C-8.04,-8.79 -7.53,-9 -7,-9c "/>
+        </group>
+        <group android:name="_R_G_L_2_G" android:translateX="12" android:translateY="12">
+          <path android:name="_R_G_L_2_G_D_0_P_0" android:fillColor="#000000" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M-7 7 C-7,7 7,7 7,7 C7,7 7,-7 7,-7 C7,-7 -7,-7 -7,-7 C-7,-7 -7,7 -7,7c  M-7 -9 C-7,-9 7,-9 7,-9 C7.53,-9 8.04,-8.79 8.41,-8.41 C8.79,-8.04 9,-7.53 9,-7 C9,-7 9,7 9,7 C9,7.53 8.79,8.04 8.41,8.41 C8.04,8.79 7.53,9 7,9 C7,9 -7,9 -7,9 C-7.53,9 -8.04,8.79 -8.41,8.41 C-8.79,8.04 -9,7.53 -9,7 C-9,7 -9,-7 -9,-7 C-9,-7.53 -8.79,-8.04 -8.41,-8.41 C-8.04,-8.79 -7.53,-9 -7,-9c "/>
+        </group>
+        <group android:name="_R_G_L_1_G" android:translateX="12" android:translateY="12">
+          <path android:name="_R_G_L_1_G_D_0_P_0" android:fillColor="#000000" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M-2 3 C-2,3 2,3 2,3 C2,3 2,-3 2,-3 C2,-3 -2,-3 -2,-3 C-2,-3 -2,3 -2,3c  M-4 -5 C-4,-5 4,-5 4,-5 C4,-5 4,5 4,5 C4,5 -4,5 -4,5 C-4,5 -4,-5 -4,-5c "/>
+        </group>
+        <group android:name="_R_G_L_0_G" android:translateX="12" android:translateY="13">
+          <path android:name="_R_G_L_0_G_D_0_P_0" android:fillColor="#000000" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M-1 -1 C-1,-1 1,-1 1,-1 C1,-1 1,1 1,1 C1,1 -1,1 -1,1 C-1,1 -1,-1 -1,-1c "/>
+        </group>
+      </group>
+      <group android:name="time_group"/>
+    </vector>
+  </aapt:attr>
+  <target android:name="_R_G_L_4_G">
+    <aapt:attr name="android:animation">
+      <set android:ordering="together">
+        <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="300" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+      </set>
+    </aapt:attr>
+  </target>
+  <target android:name="_R_G_L_2_G_D_0_P_0">
+    <aapt:attr name="android:animation">
+      <set android:ordering="together">
+        <objectAnimator android:propertyName="pathData" android:duration="133" android:startOffset="0" android:valueFrom="M-7 7 C-7,7 7,7 7,7 C7,7 7,-7 7,-7 C7,-7 -7,-7 -7,-7 C-7,-7 -7,7 -7,7c  M-7 -9 C-7,-9 7,-9 7,-9 C7.53,-9 8.04,-8.79 8.41,-8.41 C8.79,-8.04 9,-7.53 9,-7 C9,-7 9,7 9,7 C9,7.53 8.79,8.04 8.41,8.41 C8.04,8.79 7.53,9 7,9 C7,9 -7,9 -7,9 C-7.53,9 -8.04,8.79 -8.41,8.41 C-8.79,8.04 -9,7.53 -9,7 C-9,7 -9,-7 -9,-7 C-9,-7.53 -8.79,-8.04 -8.41,-8.41 C-8.04,-8.79 -7.53,-9 -7,-9c " android:valueTo="M-7 7 C-7,7 7,7 7,7 C7,7 7,-7 7,-7 C7,-7 -7,-7 -7,-7 C-7,-7 -7,7 -7,7c  M-7 -9 C-7,-9 7,-9 7,-9 C7.53,-9 8.04,-8.79 8.41,-8.41 C8.79,-8.04 9,-7.53 9,-7 C9,-7 9,7 9,7 C9,7.53 8.79,8.04 8.41,8.41 C8.04,8.79 7.53,9 7,9 C7,9 -7,9 -7,9 C-7.53,9 -8.04,8.79 -8.41,8.41 C-8.79,8.04 -9,7.53 -9,7 C-9,7 -9,-7 -9,-7 C-9,-7.53 -8.79,-8.04 -8.41,-8.41 C-8.04,-8.79 -7.53,-9 -7,-9c " android:valueType="pathType">
+          <aapt:attr name="android:interpolator">
+            <pathInterpolator android:pathData="M 0.0,0.0 c0.8,0 0.4,1 1.0,1.0"/>
+          </aapt:attr>
+        </objectAnimator>
+        <objectAnimator android:propertyName="pathData" android:duration="217" android:startOffset="133" android:valueFrom="M-7 7 C-7,7 7,7 7,7 C7,7 7,-7 7,-7 C7,-7 -7,-7 -7,-7 C-7,-7 -7,7 -7,7c  M-7 -9 C-7,-9 7,-9 7,-9 C7.53,-9 8.04,-8.79 8.41,-8.41 C8.79,-8.04 9,-7.53 9,-7 C9,-7 9,7 9,7 C9,7.53 8.79,8.04 8.41,8.41 C8.04,8.79 7.53,9 7,9 C7,9 -7,9 -7,9 C-7.53,9 -8.04,8.79 -8.41,8.41 C-8.79,8.04 -9,7.53 -9,7 C-9,7 -9,-7 -9,-7 C-9,-7.53 -8.79,-8.04 -8.41,-8.41 C-8.04,-8.79 -7.53,-9 -7,-9c " android:valueTo="M-4 5 C-4,5 4.01,5 4.01,5 C4.01,5 4.01,-5 4.01,-5 C4.01,-5 -4,-5 -4,-5 C-4,-5 -4,5 -4,5c  M-7 -9 C-7,-9 7,-9 7,-9 C7.53,-9 8.04,-8.79 8.41,-8.41 C8.79,-8.04 9,-7.53 9,-7 C9,-7 9,7 9,7 C9,7.53 8.79,8.04 8.41,8.41 C8.04,8.79 7.53,9 7,9 C7,9 -7,9 -7,9 C-7.53,9 -8.04,8.79 -8.41,8.41 C-8.79,8.04 -9,7.53 -9,7 C-9,7 -9,-7 -9,-7 C-9,-7.53 -8.79,-8.04 -8.41,-8.41 C-8.04,-8.79 -7.53,-9 -7,-9c " android:valueType="pathType">
+          <aapt:attr name="android:interpolator">
+            <pathInterpolator android:pathData="M 0.0,0.0 c0.8,0 0.4,1 1.0,1.0"/>
+          </aapt:attr>
+        </objectAnimator>
+      </set>
+    </aapt:attr>
+  </target>
+  <target android:name="_R_G_L_1_G">
+    <aapt:attr name="android:animation">
+      <set android:ordering="together">
+        <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="333" android:valueFrom="1" android:valueTo="0" android:valueType="floatType"/>
+      </set>
+    </aapt:attr>
+  </target>
+  <target android:name="_R_G_L_0_G">
+    <aapt:attr name="android:animation">
+      <set android:ordering="together">
+        <objectAnimator android:propertyName="translateXY" android:duration="350" android:startOffset="0" android:propertyXName="translateX" android:propertyYName="translateY" android:pathData="M 12,13C 12,12.667 12,11.333 12,11">
+          <aapt:attr name="android:interpolator">
+            <pathInterpolator android:pathData="M 0.0,0.0 c0.8,0 0.4,1 1.0,1.0"/>
+          </aapt:attr>
+        </objectAnimator>
+      </set>
+    </aapt:attr>
+  </target>
+  <target android:name="_R_G_L_0_G">
+    <aapt:attr name="android:animation">
+      <set android:ordering="together">
+        <objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="333" android:valueFrom="1" android:valueTo="0" android:valueType="floatType"/>
+      </set>
+    </aapt:attr>
+  </target>
+  <target android:name="time_group">
+    <aapt:attr name="android:animation">
+      <set android:ordering="together">
+        <objectAnimator android:propertyName="translateX" android:duration="750" android:startOffset="0" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+      </set>
+    </aapt:attr>
+  </target>
+</animated-vector>
diff --git a/packages/SystemUI/res/drawable/ic_device_thermostat.xml b/packages/SystemUI/res/drawable/ic_device_thermostat.xml
new file mode 100644
index 0000000..f73387d
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_device_thermostat.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2020 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
+  -->
+<animated-selector
+    xmlns:android="http://schemas.android.com/apk/res/android">
+  <item
+      android:id="@+id/off"
+      android:state_enabled="false"
+      android:drawable="@drawable/ic_device_thermostat_off" />
+  <item
+      android:id="@+id/on"
+      android:state_enabled="true"
+      android:drawable="@drawable/ic_device_thermostat_on" />
+  <transition
+      android:fromId="@id/off"
+      android:toId="@id/on"
+      android:drawable="@drawable/ic_device_thermostat_on_anim" />
+  <transition
+      android:fromId="@id/on"
+      android:toId="@id/off"
+      android:drawable="@drawable/ic_device_thermostat_off_anim" />
+</animated-selector>
diff --git a/packages/SystemUI/res/drawable/ic_device_thermostat_off_anim.xml b/packages/SystemUI/res/drawable/ic_device_thermostat_off_anim.xml
new file mode 100644
index 0000000..28ac615
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_device_thermostat_off_anim.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2020 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
+  -->
+<animated-vector
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:aapt="http://schemas.android.com/aapt">
+  <aapt:attr name="android:drawable">
+    <vector android:height="24dp" android:width="24dp" android:viewportHeight="24" android:viewportWidth="24">
+      <group android:name="_R_G">
+        <group android:name="_R_G_L_1_G" android:translateX="12" android:translateY="11.9" android:scaleX="1.05" android:scaleY="1.05">
+          <group android:name="_R_G_L_1_C_0_G">
+            <clip-path android:name="_R_G_L_1_C_0" android:pathData=" M5.32 -2.1 C5.32,-2.1 -4.85,-2.1 -4.85,-2.1 C-4.85,-2.1 -4.85,7.57 -4.85,7.57 C-4.85,7.57 5.32,7.57 5.32,7.57 C5.32,7.57 5.32,-2.1 5.32,-2.1c "/>
+            <group android:name="_R_G_L_1_C_0_G_G">
+              <path android:name="_R_G_L_1_G_G_0_D_0_P_0" android:fillColor="#000000" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M2.37 5.82 C2.37,5.82 2.4,5.77 2.4,5.77 C2.4,5.77 2.4,5.77 2.4,5.77 C2.79,5.26 3,4.64 3,4 C3,3.54 2.89,3.08 2.68,2.66 C2.47,2.24 2.17,1.88 1.8,1.6 C1.8,1.6 1,1 1,1 C1,1 1,-6 1,-6 C1,-6.26 0.9,-6.52 0.71,-6.71 C0.52,-6.89 0.27,-7 0,-7 C-0.26,-7 -0.52,-6.89 -0.71,-6.71 C-0.89,-6.52 -1,-6.26 -1,-6 C-1,-6 -1,1 -1,1 C-1,1 -1.8,1.6 -1.8,1.6 C-2.17,1.88 -2.47,2.24 -2.68,2.66 C-2.89,3.08 -3,3.54 -3,4 C-3,4.64 -2.78,5.27 -2.4,5.78 C-2.4,5.78 -2.32,5.88 -2.32,5.88 C-2.04,6.23 -1.68,6.52 -1.27,6.71 C-0.86,6.91 -0.41,7.01 0.04,7 C0.49,6.99 0.94,6.89 1.34,6.68 C1.75,6.48 2.09,6.18 2.37,5.82c "/>
+            </group>
+          </group>
+        </group>
+        <group android:name="_R_G_L_0_G" android:translateX="12" android:translateY="12">
+          <path android:name="_R_G_L_0_G_D_0_P_0" android:fillColor="#000000" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M2.37 5.82 C2.37,5.82 2.4,5.77 2.4,5.77 C2.4,5.77 2.4,5.77 2.4,5.77 C2.79,5.26 3,4.64 3,4 C3,3.54 2.89,3.08 2.68,2.66 C2.47,2.24 2.17,1.88 1.8,1.6 C1.8,1.6 1,1 1,1 C1,1 1,-6 1,-6 C1,-6.26 0.9,-6.52 0.71,-6.71 C0.52,-6.89 0.27,-7 0,-7 C-0.26,-7 -0.52,-6.89 -0.71,-6.71 C-0.89,-6.52 -1,-6.26 -1,-6 C-1,-6 -1,1 -1,1 C-1,1 -1.8,1.6 -1.8,1.6 C-2.17,1.88 -2.47,2.24 -2.68,2.66 C-2.89,3.08 -3,3.54 -3,4 C-3,4.64 -2.78,5.27 -2.4,5.78 C-2.4,5.78 -2.32,5.88 -2.32,5.88 C-2.04,6.23 -1.68,6.52 -1.27,6.71 C-0.86,6.91 -0.41,7.01 0.04,7 C0.49,6.99 0.94,6.89 1.34,6.68 C1.75,6.48 2.09,6.18 2.37,5.82c  M3 -6 C3,-6 3,0 3,0 C3.62,0.47 4.12,1.07 4.47,1.76 C4.82,2.46 5,3.22 5,4 C5,5.07 4.65,6.12 4,6.97 C4,6.97 4,7 4,7 C4,7 3.98,7 3.98,7 C3.52,7.62 2.92,8.13 2.23,8.47 C1.54,8.82 0.77,9 0,9 C-0.77,9 -1.54,8.82 -2.23,8.47 C-2.92,8.13 -3.52,7.62 -3.98,7 C-3.98,7 -4,7 -4,7 C-4,7 -4,6.97 -4,6.97 C-4.65,6.12 -5,5.07 -5,4 C-5,3.22 -4.82,2.46 -4.47,1.76 C-4.12,1.07 -3.62,0.47 -3,0 C-3,0 -3,-6 -3,-6 C-3,-6.8 -2.68,-7.56 -2.12,-8.12 C-1.56,-8.68 -0.8,-9 0,-9 C0.8,-9 1.56,-8.68 2.12,-8.12 C2.68,-7.56 3,-6.8 3,-6c "/>
+        </group>
+      </group>
+      <group android:name="time_group"/>
+    </vector>
+  </aapt:attr>
+  <target android:name="_R_G_L_1_C_0">
+    <aapt:attr name="android:animation">
+      <set android:ordering="together">
+        <objectAnimator android:propertyName="pathData" android:duration="500" android:startOffset="0" android:valueFrom="M5.32 -2.1 C5.32,-2.1 -4.85,-2.1 -4.85,-2.1 C-4.85,-2.1 -4.85,7.57 -4.85,7.57 C-4.85,7.57 5.32,7.57 5.32,7.57 C5.32,7.57 5.32,-2.1 5.32,-2.1c " android:valueTo="M5.32 7.6 C5.32,7.6 -4.85,7.6 -4.85,7.6 C-4.85,7.6 -4.85,7.57 -4.85,7.57 C-4.85,7.57 5.32,7.57 5.32,7.57 C5.32,7.57 5.32,7.6 5.32,7.6c " android:valueType="pathType">
+          <aapt:attr name="android:interpolator">
+            <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0"/>
+          </aapt:attr>
+        </objectAnimator>
+      </set>
+    </aapt:attr>
+  </target>
+  <target android:name="time_group">
+    <aapt:attr name="android:animation">
+      <set android:ordering="together">
+        <objectAnimator android:propertyName="translateX" android:duration="750" android:startOffset="0" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+      </set>
+    </aapt:attr>
+  </target>
+</animated-vector>
diff --git a/packages/SystemUI/res/drawable/ic_device_thermostat_on_anim.xml b/packages/SystemUI/res/drawable/ic_device_thermostat_on_anim.xml
new file mode 100644
index 0000000..36acf33
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_device_thermostat_on_anim.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2020 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
+  -->
+<animated-vector
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:aapt="http://schemas.android.com/aapt">
+  <aapt:attr name="android:drawable">
+    <vector android:height="24dp" android:width="24dp" android:viewportHeight="24" android:viewportWidth="24">
+      <group android:name="_R_G">
+        <group android:name="_R_G_L_1_G" android:translateX="12" android:translateY="11.9" android:scaleX="1.05" android:scaleY="1.05">
+          <group android:name="_R_G_L_1_C_0_G">
+            <clip-path android:name="_R_G_L_1_C_0" android:pathData=" M5.32 7.6 C5.32,7.6 -4.85,7.6 -4.85,7.6 C-4.85,7.6 -4.85,7.57 -4.85,7.57 C-4.85,7.57 5.32,7.57 5.32,7.57 C5.32,7.57 5.32,7.6 5.32,7.6c "/>
+            <group android:name="_R_G_L_1_C_0_G_G">
+              <path android:name="_R_G_L_1_G_G_0_D_0_P_0" android:fillColor="#000000" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M2.37 5.82 C2.37,5.82 2.4,5.77 2.4,5.77 C2.4,5.77 2.4,5.77 2.4,5.77 C2.79,5.26 3,4.64 3,4 C3,3.54 2.89,3.08 2.68,2.66 C2.47,2.24 2.17,1.88 1.8,1.6 C1.8,1.6 1,1 1,1 C1,1 1,-6 1,-6 C1,-6.26 0.9,-6.52 0.71,-6.71 C0.52,-6.89 0.27,-7 0,-7 C-0.26,-7 -0.52,-6.89 -0.71,-6.71 C-0.89,-6.52 -1,-6.26 -1,-6 C-1,-6 -1,1 -1,1 C-1,1 -1.8,1.6 -1.8,1.6 C-2.17,1.88 -2.47,2.24 -2.68,2.66 C-2.89,3.08 -3,3.54 -3,4 C-3,4.64 -2.78,5.27 -2.4,5.78 C-2.4,5.78 -2.32,5.88 -2.32,5.88 C-2.04,6.23 -1.68,6.52 -1.27,6.71 C-0.86,6.91 -0.41,7.01 0.04,7 C0.49,6.99 0.94,6.89 1.34,6.68 C1.75,6.48 2.09,6.18 2.37,5.82c "/>
+            </group>
+          </group>
+        </group>
+        <group android:name="_R_G_L_0_G" android:translateX="12" android:translateY="12">
+          <path android:name="_R_G_L_0_G_D_0_P_0" android:fillColor="#000000" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M2.37 5.82 C2.37,5.82 2.4,5.77 2.4,5.77 C2.4,5.77 2.4,5.77 2.4,5.77 C2.79,5.26 3,4.64 3,4 C3,3.54 2.89,3.08 2.68,2.66 C2.47,2.24 2.17,1.88 1.8,1.6 C1.8,1.6 1,1 1,1 C1,1 1,-6 1,-6 C1,-6.26 0.9,-6.52 0.71,-6.71 C0.52,-6.89 0.27,-7 0,-7 C-0.26,-7 -0.52,-6.89 -0.71,-6.71 C-0.89,-6.52 -1,-6.26 -1,-6 C-1,-6 -1,1 -1,1 C-1,1 -1.8,1.6 -1.8,1.6 C-2.17,1.88 -2.47,2.24 -2.68,2.66 C-2.89,3.08 -3,3.54 -3,4 C-3,4.64 -2.78,5.27 -2.4,5.78 C-2.4,5.78 -2.32,5.88 -2.32,5.88 C-2.04,6.23 -1.68,6.52 -1.27,6.71 C-0.86,6.91 -0.41,7.01 0.04,7 C0.49,6.99 0.94,6.89 1.34,6.68 C1.75,6.48 2.09,6.18 2.37,5.82c  M3 -6 C3,-6 3,0 3,0 C3.62,0.47 4.12,1.07 4.47,1.76 C4.82,2.46 5,3.22 5,4 C5,5.07 4.65,6.12 4,6.97 C4,6.97 4,7 4,7 C4,7 3.98,7 3.98,7 C3.52,7.62 2.92,8.13 2.23,8.47 C1.54,8.82 0.77,9 0,9 C-0.77,9 -1.54,8.82 -2.23,8.47 C-2.92,8.13 -3.52,7.62 -3.98,7 C-3.98,7 -4,7 -4,7 C-4,7 -4,6.97 -4,6.97 C-4.65,6.12 -5,5.07 -5,4 C-5,3.22 -4.82,2.46 -4.47,1.76 C-4.12,1.07 -3.62,0.47 -3,0 C-3,0 -3,-6 -3,-6 C-3,-6.8 -2.68,-7.56 -2.12,-8.12 C-1.56,-8.68 -0.8,-9 0,-9 C0.8,-9 1.56,-8.68 2.12,-8.12 C2.68,-7.56 3,-6.8 3,-6c "/>
+        </group>
+      </group>
+      <group android:name="time_group"/>
+    </vector>
+  </aapt:attr>
+  <target android:name="_R_G_L_1_C_0">
+    <aapt:attr name="android:animation">
+      <set android:ordering="together">
+        <objectAnimator android:propertyName="pathData" android:duration="500" android:startOffset="0" android:valueFrom="M5.32 7.6 C5.32,7.6 -4.85,7.6 -4.85,7.6 C-4.85,7.6 -4.85,7.57 -4.85,7.57 C-4.85,7.57 5.32,7.57 5.32,7.57 C5.32,7.57 5.32,7.6 5.32,7.6c " android:valueTo="M5.32 -2.1 C5.32,-2.1 -4.85,-2.1 -4.85,-2.1 C-4.85,-2.1 -4.85,7.57 -4.85,7.57 C-4.85,7.57 5.32,7.57 5.32,7.57 C5.32,7.57 5.32,-2.1 5.32,-2.1c " android:valueType="pathType">
+          <aapt:attr name="android:interpolator">
+            <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0"/>
+          </aapt:attr>
+        </objectAnimator>
+      </set>
+    </aapt:attr>
+  </target>
+  <target android:name="time_group">
+    <aapt:attr name="android:animation">
+      <set android:ordering="together">
+        <objectAnimator android:propertyName="translateX" android:duration="750" android:startOffset="0" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+      </set>
+    </aapt:attr>
+  </target>
+</animated-vector>
diff --git a/packages/SystemUI/res/drawable/ic_device_tv.xml b/packages/SystemUI/res/drawable/ic_device_tv.xml
new file mode 100644
index 0000000..4baf8a1
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_device_tv.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2020 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
+  -->
+<animated-selector
+    xmlns:android="http://schemas.android.com/apk/res/android">
+  <item
+      android:id="@+id/off"
+      android:state_enabled="false"
+      android:drawable="@drawable/ic_device_tv_off" />
+  <item
+      android:id="@+id/on"
+      android:state_enabled="true"
+      android:drawable="@drawable/ic_device_tv_on" />
+  <transition
+      android:fromId="@id/off"
+      android:toId="@id/on"
+      android:drawable="@drawable/ic_device_tv_on_anim" />
+  <transition
+      android:fromId="@id/on"
+      android:toId="@id/off"
+      android:drawable="@drawable/ic_device_tv_off_anim" />
+</animated-selector>
diff --git a/packages/SystemUI/res/drawable/ic_device_tv_off_anim.xml b/packages/SystemUI/res/drawable/ic_device_tv_off_anim.xml
new file mode 100644
index 0000000..0f5a5f5
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_device_tv_off_anim.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2020 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
+  -->
+<animated-vector
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:aapt="http://schemas.android.com/aapt">
+  <aapt:attr name="android:drawable">
+    <vector android:height="24dp" android:width="24dp" android:viewportHeight="24" android:viewportWidth="24">
+      <group android:name="_R_G">
+        <group android:name="_R_G_L_1_G" android:translateX="12" android:translateY="12.5">
+          <path android:name="_R_G_L_1_G_D_0_P_0" android:fillColor="#000000" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M-8 4.5 C-8,4.5 8,4.5 8,4.5 C8,4.5 8,-6.5 8,-6.5 C8,-6.5 -8,-6.5 -8,-6.5 C-8,-6.5 -8,4.5 -8,4.5c  M-8 -8.5 C-8,-8.5 8,-8.5 8,-8.5 C8,-8.5 8,-8.5 8,-8.5 C8.53,-8.5 9.04,-8.29 9.41,-7.91 C9.79,-7.54 10,-7.03 10,-6.5 C10,-6.5 10,4.5 10,4.5 C10,5.03 9.79,5.54 9.41,5.91 C9.04,6.29 8.53,6.5 8,6.5 C8,6.5 8,8.5 8,8.5 C8,8.5 7,8.5 7,8.5 C7,8.5 6.33,6.5 6.33,6.5 C6.33,6.5 -6.33,6.5 -6.33,6.5 C-6.33,6.5 -7,8.5 -7,8.5 C-7,8.5 -8,8.5 -8,8.5 C-8,8.5 -8,6.5 -8,6.5 C-8.53,6.5 -9.04,6.29 -9.41,5.91 C-9.79,5.54 -10,5.03 -10,4.5 C-10,4.5 -10,-6.5 -10,-6.5 C-10,-7.03 -9.79,-7.54 -9.41,-7.91 C-9.04,-8.29 -8.53,-8.5 -8,-8.5c "/>
+        </group>
+        <group android:name="_R_G_L_0_G">
+          <group android:name="_R_G_L_0_C_0_G">
+            <clip-path android:name="_R_G_L_0_C_0" android:pathData=" M11.94 32.38 C11.74,11.73 -9.06,11.38 -9.06,11.38 C-9.06,11.38 11.64,11.11 11.94,-9.62 C11.85,11.21 32.94,11.38 32.94,11.38 C32.94,11.38 11.74,11.52 11.94,32.38c "/>
+            <group android:name="_R_G_L_0_C_0_G_G">
+              <path android:name="_R_G_L_0_G_G_0_D_0_P_0" android:fillColor="#000000" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M5 7 C5,7 19,7 19,7 C19,7 19,16 19,16 C19,16 5,16 5,16 C5,16 5,7 5,7c "/>
+            </group>
+          </group>
+        </group>
+      </group>
+      <group android:name="time_group"/>
+    </vector>
+  </aapt:attr>
+  <target android:name="_R_G_L_0_C_0">
+    <aapt:attr name="android:animation">
+      <set android:ordering="together">
+        <objectAnimator android:propertyName="pathData" android:duration="500" android:startOffset="0" android:valueFrom="M11.94 32.38 C11.74,11.73 -9.06,11.38 -9.06,11.38 C-9.06,11.38 11.64,11.11 11.94,-9.62 C11.85,11.21 32.94,11.38 32.94,11.38 C32.94,11.38 11.74,11.52 11.94,32.38c " android:valueTo="M11.94 11.56 C11.94,11.38 11.75,11.38 11.75,11.38 C11.75,11.38 11.94,11.37 11.94,11.19 C11.94,11.37 12.13,11.38 12.13,11.38 C12.13,11.38 11.94,11.38 11.94,11.56c " android:valueType="pathType">
+          <aapt:attr name="android:interpolator">
+            <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0"/>
+          </aapt:attr>
+        </objectAnimator>
+      </set>
+    </aapt:attr>
+  </target>
+  <target android:name="time_group">
+    <aapt:attr name="android:animation">
+      <set android:ordering="together">
+        <objectAnimator android:propertyName="translateX" android:duration="750" android:startOffset="0" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+      </set>
+    </aapt:attr>
+  </target>
+</animated-vector>
diff --git a/packages/SystemUI/res/drawable/ic_device_tv_on_anim.xml b/packages/SystemUI/res/drawable/ic_device_tv_on_anim.xml
new file mode 100644
index 0000000..0bd7cf2
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_device_tv_on_anim.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2020 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
+  -->
+<animated-vector
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:aapt="http://schemas.android.com/aapt">
+  <aapt:attr name="android:drawable">
+    <vector android:height="24dp" android:width="24dp" android:viewportHeight="24" android:viewportWidth="24">
+      <group android:name="_R_G">
+        <group android:name="_R_G_L_1_G">
+          <group android:name="_R_G_L_1_C_0_G">
+            <clip-path android:name="_R_G_L_1_C_0" android:pathData=" M11.94 11.56 C11.94,11.38 11.75,11.38 11.75,11.38 C11.75,11.38 11.94,11.37 11.94,11.19 C11.94,11.37 12.13,11.38 12.13,11.38 C12.13,11.38 11.94,11.38 11.94,11.56c "/>
+            <group android:name="_R_G_L_1_C_0_G_G">
+              <path android:name="_R_G_L_1_G_G_0_D_0_P_0" android:fillColor="#000000" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M5 7 C5,7 19,7 19,7 C19,7 19,16 19,16 C19,16 5,16 5,16 C5,16 5,7 5,7c "/>
+            </group>
+          </group>
+        </group>
+        <group android:name="_R_G_L_0_G" android:translateX="12" android:translateY="12.5">
+          <path android:name="_R_G_L_0_G_D_0_P_0" android:fillColor="#000000" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M-8 4.5 C-8,4.5 8,4.5 8,4.5 C8,4.5 8,-6.5 8,-6.5 C8,-6.5 -8,-6.5 -8,-6.5 C-8,-6.5 -8,4.5 -8,4.5c  M-8 -8.5 C-8,-8.5 8,-8.5 8,-8.5 C8,-8.5 8,-8.5 8,-8.5 C8.53,-8.5 9.04,-8.29 9.41,-7.91 C9.79,-7.54 10,-7.03 10,-6.5 C10,-6.5 10,4.5 10,4.5 C10,5.03 9.79,5.54 9.41,5.91 C9.04,6.29 8.53,6.5 8,6.5 C8,6.5 8,8.5 8,8.5 C8,8.5 7,8.5 7,8.5 C7,8.5 6.33,6.5 6.33,6.5 C6.33,6.5 -6.33,6.5 -6.33,6.5 C-6.33,6.5 -7,8.5 -7,8.5 C-7,8.5 -8,8.5 -8,8.5 C-8,8.5 -8,6.5 -8,6.5 C-8.53,6.5 -9.04,6.29 -9.41,5.91 C-9.79,5.54 -10,5.03 -10,4.5 C-10,4.5 -10,-6.5 -10,-6.5 C-10,-7.03 -9.79,-7.54 -9.41,-7.91 C-9.04,-8.29 -8.53,-8.5 -8,-8.5c "/>
+        </group>
+      </group>
+      <group android:name="time_group"/>
+    </vector>
+  </aapt:attr>
+  <target android:name="_R_G_L_1_C_0">
+    <aapt:attr name="android:animation">
+      <set android:ordering="together">
+        <objectAnimator android:propertyName="pathData" android:duration="500" android:startOffset="0" android:valueFrom="M11.94 11.56 C11.94,11.38 11.75,11.38 11.75,11.38 C11.75,11.38 11.94,11.37 11.94,11.19 C11.94,11.37 12.13,11.38 12.13,11.38 C12.13,11.38 11.94,11.38 11.94,11.56c " android:valueTo="M11.94 32.38 C11.74,11.73 -9.06,11.38 -9.06,11.38 C-9.06,11.38 11.64,11.11 11.94,-9.62 C11.85,11.21 32.94,11.38 32.94,11.38 C32.94,11.38 11.74,11.52 11.94,32.38c " android:valueType="pathType">
+          <aapt:attr name="android:interpolator">
+            <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0"/>
+          </aapt:attr>
+        </objectAnimator>
+      </set>
+    </aapt:attr>
+  </target>
+  <target android:name="time_group">
+    <aapt:attr name="android:animation">
+      <set android:ordering="together">
+        <objectAnimator android:propertyName="translateX" android:duration="750" android:startOffset="0" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+      </set>
+    </aapt:attr>
+  </target>
+</animated-vector>
diff --git a/packages/SystemUI/res/drawable/ic_device_unknown.xml b/packages/SystemUI/res/drawable/ic_device_unknown.xml
new file mode 100644
index 0000000..b8bfe24
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_device_unknown.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2020 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
+  -->
+<selector
+    xmlns:android="http://schemas.android.com/apk/res/android">
+  <item
+      android:id="@+id/off"
+      android:state_enabled="false"
+      android:drawable="@drawable/ic_device_unknown_off" />
+  <item
+      android:id="@+id/on"
+      android:state_enabled="true"
+      android:drawable="@drawable/ic_device_unknown_on" />
+</selector>
diff --git a/packages/SystemUI/res/drawable/ic_device_vacuum.xml b/packages/SystemUI/res/drawable/ic_device_vacuum.xml
new file mode 100644
index 0000000..cbe42b9
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_device_vacuum.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2020 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
+  -->
+<animated-selector
+    xmlns:android="http://schemas.android.com/apk/res/android">
+  <item
+      android:id="@+id/off"
+      android:state_enabled="false"
+      android:drawable="@drawable/ic_device_vacuum_off" />
+  <item
+      android:id="@+id/on"
+      android:state_enabled="true"
+      android:drawable="@drawable/ic_device_vacuum_on" />
+  <transition
+      android:fromId="@id/off"
+      android:toId="@id/on"
+      android:drawable="@drawable/ic_device_vacuum_on_anim" />
+  <transition
+      android:fromId="@id/on"
+      android:toId="@id/off"
+      android:drawable="@drawable/ic_device_vacuum_off_anim" />
+</animated-selector>
diff --git a/packages/SystemUI/res/drawable/ic_device_vacuum_off_anim.xml b/packages/SystemUI/res/drawable/ic_device_vacuum_off_anim.xml
new file mode 100644
index 0000000..7e2d1df
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_device_vacuum_off_anim.xml
@@ -0,0 +1,72 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2020 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
+  -->
+<animated-vector
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:aapt="http://schemas.android.com/aapt">
+  <aapt:attr name="android:drawable">
+    <vector android:height="24dp" android:width="24dp" android:viewportHeight="24" android:viewportWidth="24">
+      <group android:name="_R_G">
+        <group android:name="_R_G_L_1_G" android:translateX="12" android:translateY="11.5">
+          <path android:name="_R_G_L_1_G_D_0_P_0" android:fillColor="#000000" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M11 10.5 C11,10.5 11,8.5 11,8.5 C11,8.5 8.66,8.5 8.66,8.5 C8.66,8.5 1.86,-7.68 1.86,-7.68 C1.45,-8.66 0.71,-9.47 -0.23,-9.97 C-1.17,-10.46 -2.26,-10.62 -3.3,-10.41 C-4.34,-10.2 -5.28,-9.63 -5.96,-8.81 C-6.63,-7.98 -7,-6.95 -7,-5.89 C-7,-5.89 -7,-2.5 -7,-2.5 C-7,-2.5 -10,-2.5 -10,-2.5 C-10,-2.5 -10,2.92 -10,2.92 C-9.37,2.64 -8.69,2.5 -8,2.5 C-8,2.5 -8,-0.5 -8,-0.5 C-8,-0.5 -3,-0.5 -3,-0.5 C-2.47,-0.5 -1.96,-0.29 -1.59,0.09 C-1.21,0.46 -1,0.97 -1,1.5 C-1,1.5 -1,8.5 -1,8.5 C-1,8.5 -3.1,8.5 -3.1,8.5 C-3.25,9.23 -3.56,9.91 -4.01,10.5 C-4.01,10.5 1,10.5 1,10.5 C1,10.5 1,1.5 1,1.5 C1,0.44 0.58,-0.58 -0.17,-1.33 C-0.92,-2.08 -1.94,-2.5 -3,-2.5 C-3,-2.5 -5,-2.5 -5,-2.5 C-5,-2.5 -5,-5.89 -5,-5.89 C-5,-6.49 -4.79,-7.07 -4.41,-7.54 C-4.03,-8.01 -3.5,-8.33 -2.91,-8.45 C-2.32,-8.57 -1.71,-8.48 -1.18,-8.2 C-0.64,-7.92 -0.22,-7.46 0.01,-6.91 C0.01,-6.91 6.49,8.5 6.49,8.5 C6.49,8.5 4,8.5 4,8.5 C4,8.5 4,10.5 4,10.5 C4,10.5 11,10.5 11,10.5c  M-8.56 8.33 C-8.39,8.44 -8.2,8.5 -8,8.5 C-7.73,8.5 -7.48,8.4 -7.29,8.21 C-7.1,8.02 -7,7.77 -7,7.5 C-7,7.3 -7.06,7.11 -7.17,6.94 C-7.28,6.78 -7.43,6.65 -7.62,6.58 C-7.8,6.5 -8,6.48 -8.19,6.52 C-8.39,6.56 -8.57,6.65 -8.71,6.79 C-8.85,6.93 -8.94,7.11 -8.98,7.31 C-9.02,7.5 -9,7.7 -8.92,7.88 C-8.85,8.07 -8.72,8.22 -8.56,8.33c  M-9.67 5.01 C-9.17,4.68 -8.59,4.5 -8,4.5 C-8,4.5 -8,4.5 -8,4.5 C-7.2,4.5 -6.44,4.82 -5.88,5.38 C-5.32,5.94 -5,6.7 -5,7.5 C-5,8.09 -5.18,8.67 -5.51,9.17 C-5.84,9.66 -6.3,10.05 -6.85,10.27 C-7.4,10.5 -8,10.56 -8.59,10.44 C-9.17,10.33 -9.7,10.04 -10.12,9.62 C-10.54,9.2 -10.83,8.67 -10.94,8.09 C-11.06,7.5 -11,6.9 -10.77,6.35 C-10.54,5.8 -10.16,5.34 -9.67,5.01c "/>
+        </group>
+        <group android:name="_R_G_L_0_G" android:translateX="12.5" android:translateY="11.5">
+          <group android:name="_R_G_L_0_C_0_G">
+            <clip-path android:name="_R_G_L_0_C_0" android:pathData=" M2.15 -2.94 C2.15,-2.94 -12,-2.94 -12,-2.94 C-12,-2.94 -12,10.58 -12,10.58 C-12,10.58 2.15,10.58 2.15,10.58 C2.15,10.58 2.15,-2.94 2.15,-2.94c "/>
+            <group android:name="_R_G_L_0_C_0_G_G">
+              <path android:name="_R_G_L_0_G_G_0_D_0_P_0" android:fillColor="#000000" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M-5.5 -2.5 C-5.5,-2.5 -3.5,-2.5 -3.5,-2.5 C-2.44,-2.5 -1.42,-2.08 -0.67,-1.33 C0.08,-0.58 0.5,0.44 0.5,1.5 C0.5,1.5 0.5,10.5 0.5,10.5 C0.5,10.5 -4.52,10.5 -4.52,10.5 C-3.86,9.64 -3.5,8.59 -3.5,7.5 C-3.5,6.67 -3.7,5.85 -4.1,5.12 C-4.49,4.39 -5.06,3.77 -5.76,3.31 C-6.45,2.86 -7.25,2.59 -8.08,2.52 C-8.91,2.45 -9.74,2.59 -10.5,2.93 C-10.5,2.93 -10.5,-2.5 -10.5,-2.5 C-10.5,-2.5 -7.5,-2.5 -7.5,-2.5 C-7.5,-2.5 -5.5,-2.5 -5.5,-2.5c "/>
+            </group>
+          </group>
+        </group>
+      </group>
+      <group android:name="time_group"/>
+    </vector>
+  </aapt:attr>
+  <target android:name="_R_G_L_1_G_D_0_P_0">
+    <aapt:attr name="android:animation">
+      <set android:ordering="together">
+        <objectAnimator android:propertyName="pathData" android:duration="83" android:startOffset="0" android:valueFrom="M11 10.5 C11,10.5 11,8.5 11,8.5 C11,8.5 8.66,8.5 8.66,8.5 C8.66,8.5 1.86,-7.68 1.86,-7.68 C1.45,-8.66 0.71,-9.47 -0.23,-9.97 C-1.17,-10.46 -2.26,-10.62 -3.3,-10.41 C-4.34,-10.2 -5.28,-9.63 -5.96,-8.81 C-6.63,-7.98 -7,-6.95 -7,-5.89 C-7,-5.89 -7,-2.5 -7,-2.5 C-7,-2.5 -10,-2.5 -10,-2.5 C-10,-2.5 -10,2.92 -10,2.92 C-9.37,2.64 -8.69,2.5 -8,2.5 C-8,2.5 -8,-0.5 -8,-0.5 C-8,-0.5 -3,-0.5 -3,-0.5 C-2.47,-0.5 -1.96,-0.29 -1.59,0.09 C-1.21,0.46 -1,0.97 -1,1.5 C-1,1.5 -1,8.5 -1,8.5 C-1,8.5 -3.1,8.5 -3.1,8.5 C-3.25,9.23 -3.56,9.91 -4.01,10.5 C-4.01,10.5 1,10.5 1,10.5 C1,10.5 1,1.5 1,1.5 C1,0.44 0.58,-0.58 -0.17,-1.33 C-0.92,-2.08 -1.94,-2.5 -3,-2.5 C-3,-2.5 -5,-2.5 -5,-2.5 C-5,-2.5 -5,-5.89 -5,-5.89 C-5,-6.49 -4.79,-7.07 -4.41,-7.54 C-4.03,-8.01 -3.5,-8.33 -2.91,-8.45 C-2.32,-8.57 -1.71,-8.48 -1.18,-8.2 C-0.64,-7.92 -0.22,-7.46 0.01,-6.91 C0.01,-6.91 6.49,8.5 6.49,8.5 C6.49,8.5 4,8.5 4,8.5 C4,8.5 4,10.5 4,10.5 C4,10.5 11,10.5 11,10.5c  M-8.56 8.33 C-8.39,8.44 -8.2,8.5 -8,8.5 C-7.73,8.5 -7.48,8.4 -7.29,8.21 C-7.1,8.02 -7,7.77 -7,7.5 C-7,7.3 -7.06,7.11 -7.17,6.94 C-7.28,6.78 -7.43,6.65 -7.62,6.58 C-7.8,6.5 -8,6.48 -8.19,6.52 C-8.39,6.56 -8.57,6.65 -8.71,6.79 C-8.85,6.93 -8.94,7.11 -8.98,7.31 C-9.02,7.5 -9,7.7 -8.92,7.88 C-8.85,8.07 -8.72,8.22 -8.56,8.33c  M-9.67 5.01 C-9.17,4.68 -8.59,4.5 -8,4.5 C-8,4.5 -8,4.5 -8,4.5 C-7.2,4.5 -6.44,4.82 -5.88,5.38 C-5.32,5.94 -5,6.7 -5,7.5 C-5,8.09 -5.18,8.67 -5.51,9.17 C-5.84,9.66 -6.3,10.05 -6.85,10.27 C-7.4,10.5 -8,10.56 -8.59,10.44 C-9.17,10.33 -9.7,10.04 -10.12,9.62 C-10.54,9.2 -10.83,8.67 -10.94,8.09 C-11.06,7.5 -11,6.9 -10.77,6.35 C-10.54,5.8 -10.16,5.34 -9.67,5.01c " android:valueTo="M6.47 10.5 C6.47,10.5 6.47,8.5 6.47,8.5 C6.47,8.5 4.13,8.5 4.13,8.5 C4.13,8.5 1.86,-7.68 1.86,-7.68 C1.45,-8.66 0.71,-9.47 -0.23,-9.97 C-1.17,-10.46 -2.26,-10.62 -3.3,-10.41 C-4.34,-10.2 -5.28,-9.63 -5.96,-8.81 C-6.63,-7.98 -7,-6.95 -7,-5.89 C-7,-5.89 -7,-2.5 -7,-2.5 C-7,-2.5 -10,-2.5 -10,-2.5 C-10,-2.5 -10,2.92 -10,2.92 C-9.37,2.64 -8.69,2.5 -8,2.5 C-8,2.5 -8,-0.5 -8,-0.5 C-8,-0.5 -3,-0.5 -3,-0.5 C-2.47,-0.5 -1.96,-0.29 -1.59,0.09 C-1.21,0.46 -1,0.97 -1,1.5 C-1,1.5 -1,8.5 -1,8.5 C-1,8.5 -3.1,8.5 -3.1,8.5 C-3.25,9.23 -3.56,9.91 -4.01,10.5 C-4.01,10.5 1,10.5 1,10.5 C1,10.5 1,1.5 1,1.5 C1,0.44 0.58,-0.58 -0.17,-1.33 C-0.92,-2.08 -1.94,-2.5 -3,-2.5 C-3,-2.5 -5,-2.5 -5,-2.5 C-5,-2.5 -5,-5.89 -5,-5.89 C-5,-6.49 -4.79,-7.07 -4.41,-7.54 C-4.03,-8.01 -3.5,-8.33 -2.91,-8.45 C-2.32,-8.57 -1.71,-8.48 -1.18,-8.2 C-0.64,-7.92 -0.22,-7.46 0.01,-6.91 C0.01,-6.91 1.96,8.5 1.96,8.5 C1.96,8.5 -0.53,8.5 -0.53,8.5 C-0.53,8.5 -0.53,10.5 -0.53,10.5 C-0.53,10.5 6.47,10.5 6.47,10.5c  M-8.56 8.33 C-8.39,8.44 -8.2,8.5 -8,8.5 C-7.73,8.5 -7.48,8.4 -7.29,8.21 C-7.1,8.02 -7,7.77 -7,7.5 C-7,7.3 -7.06,7.11 -7.17,6.94 C-7.28,6.78 -7.43,6.65 -7.62,6.58 C-7.8,6.5 -8,6.48 -8.19,6.52 C-8.39,6.56 -8.57,6.65 -8.71,6.79 C-8.85,6.93 -8.94,7.11 -8.98,7.31 C-9.02,7.5 -9,7.7 -8.92,7.88 C-8.85,8.07 -8.72,8.22 -8.56,8.33c  M-9.67 5.01 C-9.17,4.68 -8.59,4.5 -8,4.5 C-8,4.5 -8,4.5 -8,4.5 C-7.2,4.5 -6.44,4.82 -5.88,5.38 C-5.32,5.94 -5,6.7 -5,7.5 C-5,8.09 -5.18,8.67 -5.51,9.17 C-5.84,9.66 -6.3,10.05 -6.85,10.27 C-7.4,10.5 -8,10.56 -8.59,10.44 C-9.17,10.33 -9.7,10.04 -10.12,9.62 C-10.54,9.2 -10.83,8.67 -10.94,8.09 C-11.06,7.5 -11,6.9 -10.77,6.35 C-10.54,5.8 -10.16,5.34 -9.67,5.01c " android:valueType="pathType">
+          <aapt:attr name="android:interpolator">
+            <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0"/>
+          </aapt:attr>
+        </objectAnimator>
+        <objectAnimator android:propertyName="pathData" android:duration="417" android:startOffset="83" android:valueFrom="M6.47 10.5 C6.47,10.5 6.47,8.5 6.47,8.5 C6.47,8.5 4.13,8.5 4.13,8.5 C4.13,8.5 1.86,-7.68 1.86,-7.68 C1.45,-8.66 0.71,-9.47 -0.23,-9.97 C-1.17,-10.46 -2.26,-10.62 -3.3,-10.41 C-4.34,-10.2 -5.28,-9.63 -5.96,-8.81 C-6.63,-7.98 -7,-6.95 -7,-5.89 C-7,-5.89 -7,-2.5 -7,-2.5 C-7,-2.5 -10,-2.5 -10,-2.5 C-10,-2.5 -10,2.92 -10,2.92 C-9.37,2.64 -8.69,2.5 -8,2.5 C-8,2.5 -8,-0.5 -8,-0.5 C-8,-0.5 -3,-0.5 -3,-0.5 C-2.47,-0.5 -1.96,-0.29 -1.59,0.09 C-1.21,0.46 -1,0.97 -1,1.5 C-1,1.5 -1,8.5 -1,8.5 C-1,8.5 -3.1,8.5 -3.1,8.5 C-3.25,9.23 -3.56,9.91 -4.01,10.5 C-4.01,10.5 1,10.5 1,10.5 C1,10.5 1,1.5 1,1.5 C1,0.44 0.58,-0.58 -0.17,-1.33 C-0.92,-2.08 -1.94,-2.5 -3,-2.5 C-3,-2.5 -5,-2.5 -5,-2.5 C-5,-2.5 -5,-5.89 -5,-5.89 C-5,-6.49 -4.79,-7.07 -4.41,-7.54 C-4.03,-8.01 -3.5,-8.33 -2.91,-8.45 C-2.32,-8.57 -1.71,-8.48 -1.18,-8.2 C-0.64,-7.92 -0.22,-7.46 0.01,-6.91 C0.01,-6.91 1.96,8.5 1.96,8.5 C1.96,8.5 -0.53,8.5 -0.53,8.5 C-0.53,8.5 -0.53,10.5 -0.53,10.5 C-0.53,10.5 6.47,10.5 6.47,10.5c  M-8.56 8.33 C-8.39,8.44 -8.2,8.5 -8,8.5 C-7.73,8.5 -7.48,8.4 -7.29,8.21 C-7.1,8.02 -7,7.77 -7,7.5 C-7,7.3 -7.06,7.11 -7.17,6.94 C-7.28,6.78 -7.43,6.65 -7.62,6.58 C-7.8,6.5 -8,6.48 -8.19,6.52 C-8.39,6.56 -8.57,6.65 -8.71,6.79 C-8.85,6.93 -8.94,7.11 -8.98,7.31 C-9.02,7.5 -9,7.7 -8.92,7.88 C-8.85,8.07 -8.72,8.22 -8.56,8.33c  M-9.67 5.01 C-9.17,4.68 -8.59,4.5 -8,4.5 C-8,4.5 -8,4.5 -8,4.5 C-7.2,4.5 -6.44,4.82 -5.88,5.38 C-5.32,5.94 -5,6.7 -5,7.5 C-5,8.09 -5.18,8.67 -5.51,9.17 C-5.84,9.66 -6.3,10.05 -6.85,10.27 C-7.4,10.5 -8,10.56 -8.59,10.44 C-9.17,10.33 -9.7,10.04 -10.12,9.62 C-10.54,9.2 -10.83,8.67 -10.94,8.09 C-11.06,7.5 -11,6.9 -10.77,6.35 C-10.54,5.8 -10.16,5.34 -9.67,5.01c " android:valueTo="M11 10.5 C11,10.5 11,8.5 11,8.5 C11,8.5 8.66,8.5 8.66,8.5 C8.66,8.5 1.86,-7.68 1.86,-7.68 C1.45,-8.66 0.71,-9.47 -0.23,-9.97 C-1.17,-10.46 -2.26,-10.62 -3.3,-10.41 C-4.34,-10.2 -5.28,-9.63 -5.96,-8.81 C-6.63,-7.98 -7,-6.95 -7,-5.89 C-7,-5.89 -7,-2.5 -7,-2.5 C-7,-2.5 -10,-2.5 -10,-2.5 C-10,-2.5 -10,2.92 -10,2.92 C-9.37,2.64 -8.69,2.5 -8,2.5 C-8,2.5 -8,-0.5 -8,-0.5 C-8,-0.5 -3,-0.5 -3,-0.5 C-2.47,-0.5 -1.96,-0.29 -1.59,0.09 C-1.21,0.46 -1,0.97 -1,1.5 C-1,1.5 -1,8.5 -1,8.5 C-1,8.5 -3.1,8.5 -3.1,8.5 C-3.25,9.23 -3.56,9.91 -4.01,10.5 C-4.01,10.5 1,10.5 1,10.5 C1,10.5 1,1.5 1,1.5 C1,0.44 0.58,-0.58 -0.17,-1.33 C-0.92,-2.08 -1.94,-2.5 -3,-2.5 C-3,-2.5 -5,-2.5 -5,-2.5 C-5,-2.5 -5,-5.89 -5,-5.89 C-5,-6.49 -4.79,-7.07 -4.41,-7.54 C-4.03,-8.01 -3.5,-8.33 -2.91,-8.45 C-2.32,-8.57 -1.71,-8.48 -1.18,-8.2 C-0.64,-7.92 -0.22,-7.46 0.01,-6.91 C0.01,-6.91 6.49,8.5 6.49,8.5 C6.49,8.5 4,8.5 4,8.5 C4,8.5 4,10.5 4,10.5 C4,10.5 11,10.5 11,10.5c  M-8.56 8.33 C-8.39,8.44 -8.2,8.5 -8,8.5 C-7.73,8.5 -7.48,8.4 -7.29,8.21 C-7.1,8.02 -7,7.77 -7,7.5 C-7,7.3 -7.06,7.11 -7.17,6.94 C-7.28,6.78 -7.43,6.65 -7.62,6.58 C-7.8,6.5 -8,6.48 -8.19,6.52 C-8.39,6.56 -8.57,6.65 -8.71,6.79 C-8.85,6.93 -8.94,7.11 -8.98,7.31 C-9.02,7.5 -9,7.7 -8.92,7.88 C-8.85,8.07 -8.72,8.22 -8.56,8.33c  M-9.67 5.01 C-9.17,4.68 -8.59,4.5 -8,4.5 C-8,4.5 -8,4.5 -8,4.5 C-7.2,4.5 -6.44,4.82 -5.88,5.38 C-5.32,5.94 -5,6.7 -5,7.5 C-5,8.09 -5.18,8.67 -5.51,9.17 C-5.84,9.66 -6.3,10.05 -6.85,10.27 C-7.4,10.5 -8,10.56 -8.59,10.44 C-9.17,10.33 -9.7,10.04 -10.12,9.62 C-10.54,9.2 -10.83,8.67 -10.94,8.09 C-11.06,7.5 -11,6.9 -10.77,6.35 C-10.54,5.8 -10.16,5.34 -9.67,5.01c " android:valueType="pathType">
+          <aapt:attr name="android:interpolator">
+            <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0"/>
+          </aapt:attr>
+        </objectAnimator>
+      </set>
+    </aapt:attr>
+  </target>
+  <target android:name="_R_G_L_0_C_0">
+    <aapt:attr name="android:animation">
+      <set android:ordering="together">
+        <objectAnimator android:propertyName="pathData" android:duration="500" android:startOffset="0" android:valueFrom="M2.15 -2.94 C2.15,-2.94 -12,-2.94 -12,-2.94 C-12,-2.94 -12,10.58 -12,10.58 C-12,10.58 2.15,10.58 2.15,10.58 C2.15,10.58 2.15,-2.94 2.15,-2.94c " android:valueTo="M2.15 11.63 C2.15,11.63 -12,11.63 -12,11.63 C-12,11.63 -12,10.58 -12,10.58 C-12,10.58 2.15,10.58 2.15,10.58 C2.15,10.58 2.15,11.63 2.15,11.63c " android:valueType="pathType">
+          <aapt:attr name="android:interpolator">
+            <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0"/>
+          </aapt:attr>
+        </objectAnimator>
+      </set>
+    </aapt:attr>
+  </target>
+  <target android:name="time_group">
+    <aapt:attr name="android:animation">
+      <set android:ordering="together">
+        <objectAnimator android:propertyName="translateX" android:duration="750" android:startOffset="0" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+      </set>
+    </aapt:attr>
+  </target>
+</animated-vector>
diff --git a/packages/SystemUI/res/drawable/ic_device_vacuum_on_anim.xml b/packages/SystemUI/res/drawable/ic_device_vacuum_on_anim.xml
new file mode 100644
index 0000000..3c101d3
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_device_vacuum_on_anim.xml
@@ -0,0 +1,72 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2020 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
+  -->
+<animated-vector
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:aapt="http://schemas.android.com/aapt">
+  <aapt:attr name="android:drawable">
+    <vector android:height="24dp" android:width="24dp" android:viewportHeight="24" android:viewportWidth="24">
+      <group android:name="_R_G">
+        <group android:name="_R_G_L_1_G" android:translateX="12" android:translateY="11.5">
+          <path android:name="_R_G_L_1_G_D_0_P_0" android:fillColor="#000000" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M11 10.5 C11,10.5 11,8.5 11,8.5 C11,8.5 8.66,8.5 8.66,8.5 C8.66,8.5 1.86,-7.68 1.86,-7.68 C1.45,-8.66 0.71,-9.47 -0.23,-9.97 C-1.17,-10.46 -2.26,-10.62 -3.3,-10.41 C-4.34,-10.2 -5.28,-9.63 -5.96,-8.81 C-6.63,-7.98 -7,-6.95 -7,-5.89 C-7,-5.89 -7,-2.5 -7,-2.5 C-7,-2.5 -10,-2.5 -10,-2.5 C-10,-2.5 -10,2.92 -10,2.92 C-9.37,2.64 -8.69,2.5 -8,2.5 C-8,2.5 -8,-0.5 -8,-0.5 C-8,-0.5 -3,-0.5 -3,-0.5 C-2.47,-0.5 -1.96,-0.29 -1.59,0.09 C-1.21,0.46 -1,0.97 -1,1.5 C-1,1.5 -1,8.5 -1,8.5 C-1,8.5 -3.1,8.5 -3.1,8.5 C-3.25,9.23 -3.56,9.91 -4.01,10.5 C-4.01,10.5 1,10.5 1,10.5 C1,10.5 1,1.5 1,1.5 C1,0.44 0.58,-0.58 -0.17,-1.33 C-0.92,-2.08 -1.94,-2.5 -3,-2.5 C-3,-2.5 -5,-2.5 -5,-2.5 C-5,-2.5 -5,-5.89 -5,-5.89 C-5,-6.49 -4.79,-7.07 -4.41,-7.54 C-4.03,-8.01 -3.5,-8.33 -2.91,-8.45 C-2.32,-8.57 -1.71,-8.48 -1.18,-8.2 C-0.64,-7.92 -0.22,-7.46 0.01,-6.91 C0.01,-6.91 6.49,8.5 6.49,8.5 C6.49,8.5 4,8.5 4,8.5 C4,8.5 4,10.5 4,10.5 C4,10.5 11,10.5 11,10.5c  M-8.56 8.33 C-8.39,8.44 -8.2,8.5 -8,8.5 C-7.73,8.5 -7.48,8.4 -7.29,8.21 C-7.1,8.02 -7,7.77 -7,7.5 C-7,7.3 -7.06,7.11 -7.17,6.94 C-7.28,6.78 -7.43,6.65 -7.62,6.58 C-7.8,6.5 -8,6.48 -8.19,6.52 C-8.39,6.56 -8.57,6.65 -8.71,6.79 C-8.85,6.93 -8.94,7.11 -8.98,7.31 C-9.02,7.5 -9,7.7 -8.92,7.88 C-8.85,8.07 -8.72,8.22 -8.56,8.33c  M-9.67 5.01 C-9.17,4.68 -8.59,4.5 -8,4.5 C-8,4.5 -8,4.5 -8,4.5 C-7.2,4.5 -6.44,4.82 -5.88,5.38 C-5.32,5.94 -5,6.7 -5,7.5 C-5,8.09 -5.18,8.67 -5.51,9.17 C-5.84,9.66 -6.3,10.05 -6.85,10.27 C-7.4,10.5 -8,10.56 -8.59,10.44 C-9.17,10.33 -9.7,10.04 -10.12,9.62 C-10.54,9.2 -10.83,8.67 -10.94,8.09 C-11.06,7.5 -11,6.9 -10.77,6.35 C-10.54,5.8 -10.16,5.34 -9.67,5.01c "/>
+        </group>
+        <group android:name="_R_G_L_0_G" android:translateX="12.5" android:translateY="11.5">
+          <group android:name="_R_G_L_0_C_0_G">
+            <clip-path android:name="_R_G_L_0_C_0" android:pathData=" M2.15 11.63 C2.15,11.63 -12,11.63 -12,11.63 C-12,11.63 -12,10.58 -12,10.58 C-12,10.58 2.15,10.58 2.15,10.58 C2.15,10.58 2.15,11.63 2.15,11.63c "/>
+            <group android:name="_R_G_L_0_C_0_G_G">
+              <path android:name="_R_G_L_0_G_G_0_D_0_P_0" android:fillColor="#000000" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M-5.5 -2.5 C-5.5,-2.5 -3.5,-2.5 -3.5,-2.5 C-2.44,-2.5 -1.42,-2.08 -0.67,-1.33 C0.08,-0.58 0.5,0.44 0.5,1.5 C0.5,1.5 0.5,10.5 0.5,10.5 C0.5,10.5 -4.52,10.5 -4.52,10.5 C-3.86,9.64 -3.5,8.59 -3.5,7.5 C-3.5,6.67 -3.7,5.85 -4.1,5.12 C-4.49,4.39 -5.06,3.77 -5.76,3.31 C-6.45,2.86 -7.25,2.59 -8.08,2.52 C-8.91,2.45 -9.74,2.59 -10.5,2.93 C-10.5,2.93 -10.5,-2.5 -10.5,-2.5 C-10.5,-2.5 -7.5,-2.5 -7.5,-2.5 C-7.5,-2.5 -5.5,-2.5 -5.5,-2.5c "/>
+            </group>
+          </group>
+        </group>
+      </group>
+      <group android:name="time_group"/>
+    </vector>
+  </aapt:attr>
+  <target android:name="_R_G_L_1_G_D_0_P_0">
+    <aapt:attr name="android:animation">
+      <set android:ordering="together">
+        <objectAnimator android:propertyName="pathData" android:duration="83" android:startOffset="0" android:valueFrom="M11 10.5 C11,10.5 11,8.5 11,8.5 C11,8.5 8.66,8.5 8.66,8.5 C8.66,8.5 1.86,-7.68 1.86,-7.68 C1.45,-8.66 0.71,-9.47 -0.23,-9.97 C-1.17,-10.46 -2.26,-10.62 -3.3,-10.41 C-4.34,-10.2 -5.28,-9.63 -5.96,-8.81 C-6.63,-7.98 -7,-6.95 -7,-5.89 C-7,-5.89 -7,-2.5 -7,-2.5 C-7,-2.5 -10,-2.5 -10,-2.5 C-10,-2.5 -10,2.92 -10,2.92 C-9.37,2.64 -8.69,2.5 -8,2.5 C-8,2.5 -8,-0.5 -8,-0.5 C-8,-0.5 -3,-0.5 -3,-0.5 C-2.47,-0.5 -1.96,-0.29 -1.59,0.09 C-1.21,0.46 -1,0.97 -1,1.5 C-1,1.5 -1,8.5 -1,8.5 C-1,8.5 -3.1,8.5 -3.1,8.5 C-3.25,9.23 -3.56,9.91 -4.01,10.5 C-4.01,10.5 1,10.5 1,10.5 C1,10.5 1,1.5 1,1.5 C1,0.44 0.58,-0.58 -0.17,-1.33 C-0.92,-2.08 -1.94,-2.5 -3,-2.5 C-3,-2.5 -5,-2.5 -5,-2.5 C-5,-2.5 -5,-5.89 -5,-5.89 C-5,-6.49 -4.79,-7.07 -4.41,-7.54 C-4.03,-8.01 -3.5,-8.33 -2.91,-8.45 C-2.32,-8.57 -1.71,-8.48 -1.18,-8.2 C-0.64,-7.92 -0.22,-7.46 0.01,-6.91 C0.01,-6.91 6.49,8.5 6.49,8.5 C6.49,8.5 4,8.5 4,8.5 C4,8.5 4,10.5 4,10.5 C4,10.5 11,10.5 11,10.5c  M-8.56 8.33 C-8.39,8.44 -8.2,8.5 -8,8.5 C-7.73,8.5 -7.48,8.4 -7.29,8.21 C-7.1,8.02 -7,7.77 -7,7.5 C-7,7.3 -7.06,7.11 -7.17,6.94 C-7.28,6.78 -7.43,6.65 -7.62,6.58 C-7.8,6.5 -8,6.48 -8.19,6.52 C-8.39,6.56 -8.57,6.65 -8.71,6.79 C-8.85,6.93 -8.94,7.11 -8.98,7.31 C-9.02,7.5 -9,7.7 -8.92,7.88 C-8.85,8.07 -8.72,8.22 -8.56,8.33c  M-9.67 5.01 C-9.17,4.68 -8.59,4.5 -8,4.5 C-8,4.5 -8,4.5 -8,4.5 C-7.2,4.5 -6.44,4.82 -5.88,5.38 C-5.32,5.94 -5,6.7 -5,7.5 C-5,8.09 -5.18,8.67 -5.51,9.17 C-5.84,9.66 -6.3,10.05 -6.85,10.27 C-7.4,10.5 -8,10.56 -8.59,10.44 C-9.17,10.33 -9.7,10.04 -10.12,9.62 C-10.54,9.2 -10.83,8.67 -10.94,8.09 C-11.06,7.5 -11,6.9 -10.77,6.35 C-10.54,5.8 -10.16,5.34 -9.67,5.01c " android:valueTo="M6.47 10.5 C6.47,10.5 6.47,8.5 6.47,8.5 C6.47,8.5 4.13,8.5 4.13,8.5 C4.13,8.5 1.86,-7.68 1.86,-7.68 C1.45,-8.66 0.71,-9.47 -0.23,-9.97 C-1.17,-10.46 -2.26,-10.62 -3.3,-10.41 C-4.34,-10.2 -5.28,-9.63 -5.96,-8.81 C-6.63,-7.98 -7,-6.95 -7,-5.89 C-7,-5.89 -7,-2.5 -7,-2.5 C-7,-2.5 -10,-2.5 -10,-2.5 C-10,-2.5 -10,2.92 -10,2.92 C-9.37,2.64 -8.69,2.5 -8,2.5 C-8,2.5 -8,-0.5 -8,-0.5 C-8,-0.5 -3,-0.5 -3,-0.5 C-2.47,-0.5 -1.96,-0.29 -1.59,0.09 C-1.21,0.46 -1,0.97 -1,1.5 C-1,1.5 -1,8.5 -1,8.5 C-1,8.5 -3.1,8.5 -3.1,8.5 C-3.25,9.23 -3.56,9.91 -4.01,10.5 C-4.01,10.5 1,10.5 1,10.5 C1,10.5 1,1.5 1,1.5 C1,0.44 0.58,-0.58 -0.17,-1.33 C-0.92,-2.08 -1.94,-2.5 -3,-2.5 C-3,-2.5 -5,-2.5 -5,-2.5 C-5,-2.5 -5,-5.89 -5,-5.89 C-5,-6.49 -4.79,-7.07 -4.41,-7.54 C-4.03,-8.01 -3.5,-8.33 -2.91,-8.45 C-2.32,-8.57 -1.71,-8.48 -1.18,-8.2 C-0.64,-7.92 -0.22,-7.46 0.01,-6.91 C0.01,-6.91 1.96,8.5 1.96,8.5 C1.96,8.5 -0.53,8.5 -0.53,8.5 C-0.53,8.5 -0.53,10.5 -0.53,10.5 C-0.53,10.5 6.47,10.5 6.47,10.5c  M-8.56 8.33 C-8.39,8.44 -8.2,8.5 -8,8.5 C-7.73,8.5 -7.48,8.4 -7.29,8.21 C-7.1,8.02 -7,7.77 -7,7.5 C-7,7.3 -7.06,7.11 -7.17,6.94 C-7.28,6.78 -7.43,6.65 -7.62,6.58 C-7.8,6.5 -8,6.48 -8.19,6.52 C-8.39,6.56 -8.57,6.65 -8.71,6.79 C-8.85,6.93 -8.94,7.11 -8.98,7.31 C-9.02,7.5 -9,7.7 -8.92,7.88 C-8.85,8.07 -8.72,8.22 -8.56,8.33c  M-9.67 5.01 C-9.17,4.68 -8.59,4.5 -8,4.5 C-8,4.5 -8,4.5 -8,4.5 C-7.2,4.5 -6.44,4.82 -5.88,5.38 C-5.32,5.94 -5,6.7 -5,7.5 C-5,8.09 -5.18,8.67 -5.51,9.17 C-5.84,9.66 -6.3,10.05 -6.85,10.27 C-7.4,10.5 -8,10.56 -8.59,10.44 C-9.17,10.33 -9.7,10.04 -10.12,9.62 C-10.54,9.2 -10.83,8.67 -10.94,8.09 C-11.06,7.5 -11,6.9 -10.77,6.35 C-10.54,5.8 -10.16,5.34 -9.67,5.01c " android:valueType="pathType">
+          <aapt:attr name="android:interpolator">
+            <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0"/>
+          </aapt:attr>
+        </objectAnimator>
+        <objectAnimator android:propertyName="pathData" android:duration="417" android:startOffset="83" android:valueFrom="M6.47 10.5 C6.47,10.5 6.47,8.5 6.47,8.5 C6.47,8.5 4.13,8.5 4.13,8.5 C4.13,8.5 1.86,-7.68 1.86,-7.68 C1.45,-8.66 0.71,-9.47 -0.23,-9.97 C-1.17,-10.46 -2.26,-10.62 -3.3,-10.41 C-4.34,-10.2 -5.28,-9.63 -5.96,-8.81 C-6.63,-7.98 -7,-6.95 -7,-5.89 C-7,-5.89 -7,-2.5 -7,-2.5 C-7,-2.5 -10,-2.5 -10,-2.5 C-10,-2.5 -10,2.92 -10,2.92 C-9.37,2.64 -8.69,2.5 -8,2.5 C-8,2.5 -8,-0.5 -8,-0.5 C-8,-0.5 -3,-0.5 -3,-0.5 C-2.47,-0.5 -1.96,-0.29 -1.59,0.09 C-1.21,0.46 -1,0.97 -1,1.5 C-1,1.5 -1,8.5 -1,8.5 C-1,8.5 -3.1,8.5 -3.1,8.5 C-3.25,9.23 -3.56,9.91 -4.01,10.5 C-4.01,10.5 1,10.5 1,10.5 C1,10.5 1,1.5 1,1.5 C1,0.44 0.58,-0.58 -0.17,-1.33 C-0.92,-2.08 -1.94,-2.5 -3,-2.5 C-3,-2.5 -5,-2.5 -5,-2.5 C-5,-2.5 -5,-5.89 -5,-5.89 C-5,-6.49 -4.79,-7.07 -4.41,-7.54 C-4.03,-8.01 -3.5,-8.33 -2.91,-8.45 C-2.32,-8.57 -1.71,-8.48 -1.18,-8.2 C-0.64,-7.92 -0.22,-7.46 0.01,-6.91 C0.01,-6.91 1.96,8.5 1.96,8.5 C1.96,8.5 -0.53,8.5 -0.53,8.5 C-0.53,8.5 -0.53,10.5 -0.53,10.5 C-0.53,10.5 6.47,10.5 6.47,10.5c  M-8.56 8.33 C-8.39,8.44 -8.2,8.5 -8,8.5 C-7.73,8.5 -7.48,8.4 -7.29,8.21 C-7.1,8.02 -7,7.77 -7,7.5 C-7,7.3 -7.06,7.11 -7.17,6.94 C-7.28,6.78 -7.43,6.65 -7.62,6.58 C-7.8,6.5 -8,6.48 -8.19,6.52 C-8.39,6.56 -8.57,6.65 -8.71,6.79 C-8.85,6.93 -8.94,7.11 -8.98,7.31 C-9.02,7.5 -9,7.7 -8.92,7.88 C-8.85,8.07 -8.72,8.22 -8.56,8.33c  M-9.67 5.01 C-9.17,4.68 -8.59,4.5 -8,4.5 C-8,4.5 -8,4.5 -8,4.5 C-7.2,4.5 -6.44,4.82 -5.88,5.38 C-5.32,5.94 -5,6.7 -5,7.5 C-5,8.09 -5.18,8.67 -5.51,9.17 C-5.84,9.66 -6.3,10.05 -6.85,10.27 C-7.4,10.5 -8,10.56 -8.59,10.44 C-9.17,10.33 -9.7,10.04 -10.12,9.62 C-10.54,9.2 -10.83,8.67 -10.94,8.09 C-11.06,7.5 -11,6.9 -10.77,6.35 C-10.54,5.8 -10.16,5.34 -9.67,5.01c " android:valueTo="M11 10.5 C11,10.5 11,8.5 11,8.5 C11,8.5 8.66,8.5 8.66,8.5 C8.66,8.5 1.86,-7.68 1.86,-7.68 C1.45,-8.66 0.71,-9.47 -0.23,-9.97 C-1.17,-10.46 -2.26,-10.62 -3.3,-10.41 C-4.34,-10.2 -5.28,-9.63 -5.96,-8.81 C-6.63,-7.98 -7,-6.95 -7,-5.89 C-7,-5.89 -7,-2.5 -7,-2.5 C-7,-2.5 -10,-2.5 -10,-2.5 C-10,-2.5 -10,2.92 -10,2.92 C-9.37,2.64 -8.69,2.5 -8,2.5 C-8,2.5 -8,-0.5 -8,-0.5 C-8,-0.5 -3,-0.5 -3,-0.5 C-2.47,-0.5 -1.96,-0.29 -1.59,0.09 C-1.21,0.46 -1,0.97 -1,1.5 C-1,1.5 -1,8.5 -1,8.5 C-1,8.5 -3.1,8.5 -3.1,8.5 C-3.25,9.23 -3.56,9.91 -4.01,10.5 C-4.01,10.5 1,10.5 1,10.5 C1,10.5 1,1.5 1,1.5 C1,0.44 0.58,-0.58 -0.17,-1.33 C-0.92,-2.08 -1.94,-2.5 -3,-2.5 C-3,-2.5 -5,-2.5 -5,-2.5 C-5,-2.5 -5,-5.89 -5,-5.89 C-5,-6.49 -4.79,-7.07 -4.41,-7.54 C-4.03,-8.01 -3.5,-8.33 -2.91,-8.45 C-2.32,-8.57 -1.71,-8.48 -1.18,-8.2 C-0.64,-7.92 -0.22,-7.46 0.01,-6.91 C0.01,-6.91 6.49,8.5 6.49,8.5 C6.49,8.5 4,8.5 4,8.5 C4,8.5 4,10.5 4,10.5 C4,10.5 11,10.5 11,10.5c  M-8.56 8.33 C-8.39,8.44 -8.2,8.5 -8,8.5 C-7.73,8.5 -7.48,8.4 -7.29,8.21 C-7.1,8.02 -7,7.77 -7,7.5 C-7,7.3 -7.06,7.11 -7.17,6.94 C-7.28,6.78 -7.43,6.65 -7.62,6.58 C-7.8,6.5 -8,6.48 -8.19,6.52 C-8.39,6.56 -8.57,6.65 -8.71,6.79 C-8.85,6.93 -8.94,7.11 -8.98,7.31 C-9.02,7.5 -9,7.7 -8.92,7.88 C-8.85,8.07 -8.72,8.22 -8.56,8.33c  M-9.67 5.01 C-9.17,4.68 -8.59,4.5 -8,4.5 C-8,4.5 -8,4.5 -8,4.5 C-7.2,4.5 -6.44,4.82 -5.88,5.38 C-5.32,5.94 -5,6.7 -5,7.5 C-5,8.09 -5.18,8.67 -5.51,9.17 C-5.84,9.66 -6.3,10.05 -6.85,10.27 C-7.4,10.5 -8,10.56 -8.59,10.44 C-9.17,10.33 -9.7,10.04 -10.12,9.62 C-10.54,9.2 -10.83,8.67 -10.94,8.09 C-11.06,7.5 -11,6.9 -10.77,6.35 C-10.54,5.8 -10.16,5.34 -9.67,5.01c " android:valueType="pathType">
+          <aapt:attr name="android:interpolator">
+            <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0"/>
+          </aapt:attr>
+        </objectAnimator>
+      </set>
+    </aapt:attr>
+  </target>
+  <target android:name="_R_G_L_0_C_0">
+    <aapt:attr name="android:animation">
+      <set android:ordering="together">
+        <objectAnimator android:propertyName="pathData" android:duration="500" android:startOffset="0" android:valueFrom="M2.15 11.63 C2.15,11.63 -12,11.63 -12,11.63 C-12,11.63 -12,10.58 -12,10.58 C-12,10.58 2.15,10.58 2.15,10.58 C2.15,10.58 2.15,11.63 2.15,11.63c " android:valueTo="M2.15 -2.94 C2.15,-2.94 -12,-2.94 -12,-2.94 C-12,-2.94 -12,10.58 -12,10.58 C-12,10.58 2.15,10.58 2.15,10.58 C2.15,10.58 2.15,-2.94 2.15,-2.94c " android:valueType="pathType">
+          <aapt:attr name="android:interpolator">
+            <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0"/>
+          </aapt:attr>
+        </objectAnimator>
+      </set>
+    </aapt:attr>
+  </target>
+  <target android:name="time_group">
+    <aapt:attr name="android:animation">
+      <set android:ordering="together">
+        <objectAnimator android:propertyName="translateX" android:duration="750" android:startOffset="0" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+      </set>
+    </aapt:attr>
+  </target>
+</animated-vector>
diff --git a/packages/SystemUI/res/drawable/ic_device_valve.xml b/packages/SystemUI/res/drawable/ic_device_valve.xml
new file mode 100644
index 0000000..ce8342a
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_device_valve.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2020 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
+  -->
+<selector
+    xmlns:android="http://schemas.android.com/apk/res/android">
+  <item
+      android:id="@+id/off"
+      android:state_enabled="false"
+      android:drawable="@drawable/ic_device_valve_off" />
+  <item
+      android:id="@+id/on"
+      android:state_enabled="true"
+      android:drawable="@drawable/ic_device_valve_on" />
+</selector>
diff --git a/packages/SystemUI/res/drawable/ic_device_washer.xml b/packages/SystemUI/res/drawable/ic_device_washer.xml
new file mode 100644
index 0000000..5cc82d9
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_device_washer.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2020 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
+  -->
+<selector
+    xmlns:android="http://schemas.android.com/apk/res/android">
+  <item
+      android:id="@+id/off"
+      android:state_enabled="false"
+      android:drawable="@drawable/ic_device_washer_off" />
+  <item
+      android:id="@+id/on"
+      android:state_enabled="true"
+      android:drawable="@drawable/ic_device_washer_on" />
+</selector>
diff --git a/packages/SystemUI/res/drawable/ic_device_water.xml b/packages/SystemUI/res/drawable/ic_device_water.xml
new file mode 100644
index 0000000..2ec76df
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_device_water.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2020 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
+  -->
+<selector
+    xmlns:android="http://schemas.android.com/apk/res/android">
+  <item
+      android:id="@+id/off"
+      android:state_enabled="false"
+      android:drawable="@drawable/ic_device_water_off" />
+  <item
+      android:id="@+id/on"
+      android:state_enabled="true"
+      android:drawable="@drawable/ic_device_water_on" />
+</selector>
diff --git a/packages/SystemUI/res/drawable/ic_device_water_heater.xml b/packages/SystemUI/res/drawable/ic_device_water_heater.xml
new file mode 100644
index 0000000..71eddf9
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_device_water_heater.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2020 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
+  -->
+<selector
+    xmlns:android="http://schemas.android.com/apk/res/android">
+  <item
+      android:id="@+id/off"
+      android:state_enabled="false"
+      android:drawable="@drawable/ic_device_water_heater_off" />
+  <item
+      android:id="@+id/on"
+      android:state_enabled="true"
+      android:drawable="@drawable/ic_device_water_heater_on" />
+</selector>
diff --git a/packages/SystemUI/res/drawable/ic_device_window.xml b/packages/SystemUI/res/drawable/ic_device_window.xml
new file mode 100644
index 0000000..4ec61c1
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_device_window.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2020 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
+  -->
+<selector
+    xmlns:android="http://schemas.android.com/apk/res/android">
+  <item
+      android:id="@+id/off"
+      android:state_enabled="false"
+      android:drawable="@drawable/ic_device_window_off" />
+  <item
+      android:id="@+id/on"
+      android:state_enabled="true"
+      android:drawable="@drawable/ic_device_window_on" />
+</selector>
diff --git a/packages/SystemUI/res/layout/global_screenshot.xml b/packages/SystemUI/res/layout/global_screenshot.xml
index d469e0f..fce4610 100644
--- a/packages/SystemUI/res/layout/global_screenshot.xml
+++ b/packages/SystemUI/res/layout/global_screenshot.xml
@@ -14,9 +14,8 @@
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
   -->
-<androidx.constraintlayout.widget.ConstraintLayout
+<FrameLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:app="http://schemas.android.com/apk/res-auto"
     android:id="@+id/global_screenshot_frame"
     android:layout_width="match_parent"
     android:layout_height="match_parent">
@@ -24,72 +23,18 @@
         android:id="@+id/global_screenshot_actions_background"
         android:layout_height="@dimen/screenshot_bg_protection_height"
         android:layout_width="match_parent"
+        android:layout_gravity="bottom"
         android:alpha="0.0"
-        android:src="@drawable/screenshot_actions_background_protection"
-        app:layout_constraintBottom_toBottomOf="parent"
-        app:layout_constraintStart_toStartOf="parent"
-        app:layout_constraintEnd_toEndOf="parent"/>
-    <ImageView
-        android:id="@+id/global_screenshot_actions_container_background"
-        android:visibility="gone"
-        android:layout_height="0dp"
-        android:layout_width="0dp"
-        android:elevation="1dp"
-        android:background="@drawable/action_chip_container_background"
-        android:layout_marginStart="@dimen/screenshot_action_container_margin_horizontal"
-        app:layout_constraintBottom_toBottomOf="@+id/global_screenshot_actions_container"
-        app:layout_constraintStart_toStartOf="parent"
-        app:layout_constraintTop_toTopOf="@+id/global_screenshot_actions_container"
-        app:layout_constraintEnd_toEndOf="@+id/global_screenshot_actions_container"/>
-    <HorizontalScrollView
-        android:id="@+id/global_screenshot_actions_container"
-        android:layout_width="0dp"
-        android:layout_height="wrap_content"
-        android:layout_marginEnd="@dimen/screenshot_action_container_margin_horizontal"
-        android:layout_marginBottom="@dimen/screenshot_action_container_offset_y"
-        android:paddingHorizontal="@dimen/screenshot_action_container_padding_right"
-        android:paddingVertical="@dimen/screenshot_action_container_padding_vertical"
-        android:elevation="1dp"
-        android:scrollbars="none"
-        app:layout_constraintHorizontal_bias="0"
-        app:layout_constraintWidth_percent="1.0"
-        app:layout_constraintWidth_max="wrap"
-        app:layout_constraintBottom_toBottomOf="parent"
-        app:layout_constraintStart_toEndOf="@+id/global_screenshot_preview"
-        app:layout_constraintEnd_toEndOf="parent">
-        <LinearLayout
-            android:id="@+id/global_screenshot_actions"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"/>
-    </HorizontalScrollView>
+        android:src="@drawable/screenshot_actions_background_protection"/>
     <ImageView
         android:id="@+id/global_screenshot_animated_view"
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
         android:layout_gravity="center"
         android:visibility="gone"
         android:elevation="@dimen/screenshot_preview_elevation"
         android:background="@drawable/screenshot_rounded_corners"
         android:adjustViewBounds="true"/>
-    <include layout="@layout/global_screenshot_preview"/>
-    <FrameLayout
-        android:id="@+id/global_screenshot_dismiss_button"
-        android:layout_width="@dimen/screenshot_dismiss_button_tappable_size"
-        android:layout_height="@dimen/screenshot_dismiss_button_tappable_size"
-        android:elevation="7dp"
-        android:visibility="gone"
-        android:contentDescription="@string/screenshot_dismiss_ui_description"
-        app:layout_constraintStart_toEndOf="@+id/global_screenshot_preview"
-        app:layout_constraintEnd_toEndOf="@+id/global_screenshot_preview"
-        app:layout_constraintTop_toTopOf="@+id/global_screenshot_preview"
-        app:layout_constraintBottom_toTopOf="@+id/global_screenshot_preview">
-        <ImageView
-            android:id="@+id/global_screenshot_dismiss_image"
-            android:layout_width="match_parent"
-            android:layout_height="match_parent"
-            android:layout_margin="@dimen/screenshot_dismiss_button_margin"
-            android:src="@drawable/screenshot_cancel"/>
-    </FrameLayout>
     <ImageView
         android:id="@+id/global_screenshot_flash"
         android:layout_width="match_parent"
@@ -103,4 +48,5 @@
         android:layout_height="match_parent"
         android:visibility="gone"
         android:pointerIcon="crosshair"/>
-</androidx.constraintlayout.widget.ConstraintLayout>
+    <include layout="@layout/global_screenshot_static"/>
+</FrameLayout>
diff --git a/packages/SystemUI/res/layout/global_screenshot_static.xml b/packages/SystemUI/res/layout/global_screenshot_static.xml
new file mode 100644
index 0000000..a46823d
--- /dev/null
+++ b/packages/SystemUI/res/layout/global_screenshot_static.xml
@@ -0,0 +1,84 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2020 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.
+  -->
+<androidx.constraintlayout.widget.ConstraintLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:fitsSystemWindows="true"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+    <ImageView
+        android:id="@+id/global_screenshot_actions_container_background"
+        android:visibility="gone"
+        android:layout_height="0dp"
+        android:layout_width="0dp"
+        android:elevation="1dp"
+        android:background="@drawable/action_chip_container_background"
+        android:layout_marginStart="@dimen/screenshot_action_container_margin_horizontal"
+        app:layout_constraintBottom_toBottomOf="@+id/global_screenshot_actions_container"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toTopOf="@+id/global_screenshot_actions_container"
+        app:layout_constraintEnd_toEndOf="@+id/global_screenshot_actions_container"/>
+    <HorizontalScrollView
+        android:id="@+id/global_screenshot_actions_container"
+        android:layout_width="0dp"
+        android:layout_height="wrap_content"
+        android:layout_marginEnd="@dimen/screenshot_action_container_margin_horizontal"
+        android:layout_marginBottom="@dimen/screenshot_action_container_offset_y"
+        android:paddingHorizontal="@dimen/screenshot_action_container_padding_right"
+        android:paddingVertical="@dimen/screenshot_action_container_padding_vertical"
+        android:elevation="1dp"
+        android:scrollbars="none"
+        app:layout_constraintHorizontal_bias="0"
+        app:layout_constraintWidth_percent="1.0"
+        app:layout_constraintWidth_max="wrap"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintStart_toEndOf="@+id/global_screenshot_preview"
+        app:layout_constraintEnd_toEndOf="parent">
+        <LinearLayout
+            android:id="@+id/global_screenshot_actions"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"/>
+    </HorizontalScrollView>
+    <ImageView
+        android:id="@+id/global_screenshot_animated_view"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:layout_gravity="center"
+        android:visibility="gone"
+        android:elevation="@dimen/screenshot_preview_elevation"
+        android:background="@drawable/screenshot_rounded_corners"
+        android:adjustViewBounds="true"/>
+    <include layout="@layout/global_screenshot_preview"/>
+    <FrameLayout
+        android:id="@+id/global_screenshot_dismiss_button"
+        android:layout_width="@dimen/screenshot_dismiss_button_tappable_size"
+        android:layout_height="@dimen/screenshot_dismiss_button_tappable_size"
+        android:elevation="7dp"
+        android:visibility="gone"
+        android:contentDescription="@string/screenshot_dismiss_ui_description"
+        app:layout_constraintStart_toEndOf="@+id/global_screenshot_preview"
+        app:layout_constraintEnd_toEndOf="@+id/global_screenshot_preview"
+        app:layout_constraintTop_toTopOf="@+id/global_screenshot_preview"
+        app:layout_constraintBottom_toTopOf="@+id/global_screenshot_preview">
+        <ImageView
+            android:id="@+id/global_screenshot_dismiss_image"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:layout_margin="@dimen/screenshot_dismiss_button_margin"
+            android:src="@drawable/screenshot_cancel"/>
+    </FrameLayout>
+</androidx.constraintlayout.widget.ConstraintLayout>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 7f1763d..a7d1764 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -308,11 +308,11 @@
     <dimen name="global_screenshot_x_scale">80dp</dimen>
     <dimen name="screenshot_bg_protection_height">242dp</dimen>
     <dimen name="screenshot_preview_elevation">6dp</dimen>
-    <dimen name="screenshot_offset_y">48dp</dimen>
+    <dimen name="screenshot_offset_y">32dp</dimen>
     <dimen name="screenshot_offset_x">16dp</dimen>
     <dimen name="screenshot_dismiss_button_tappable_size">48dp</dimen>
     <dimen name="screenshot_dismiss_button_margin">8dp</dimen>
-    <dimen name="screenshot_action_container_offset_y">32dp</dimen>
+    <dimen name="screenshot_action_container_offset_y">16dp</dimen>
     <dimen name="screenshot_action_container_corner_radius">10dp</dimen>
     <dimen name="screenshot_action_container_padding_vertical">6dp</dimen>
     <dimen name="screenshot_action_container_margin_horizontal">8dp</dimen>
diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIService.java b/packages/SystemUI/src/com/android/systemui/SystemUIService.java
index f1cb667..708002d 100644
--- a/packages/SystemUI/src/com/android/systemui/SystemUIService.java
+++ b/packages/SystemUI/src/com/android/systemui/SystemUIService.java
@@ -27,8 +27,10 @@
 import android.util.Slog;
 
 import com.android.internal.os.BinderInternal;
+import com.android.systemui.broadcast.BroadcastDispatcher;
 import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.dump.DumpHandler;
+import com.android.systemui.dump.LogBufferFreezer;
 import com.android.systemui.dump.SystemUIAuxiliaryDumpService;
 
 import java.io.FileDescriptor;
@@ -40,21 +42,32 @@
 
     private final Handler mMainHandler;
     private final DumpHandler mDumpHandler;
+    private final BroadcastDispatcher mBroadcastDispatcher;
+    private final LogBufferFreezer mLogBufferFreezer;
 
     @Inject
     public SystemUIService(
             @Main Handler mainHandler,
-            DumpHandler dumpHandler) {
+            DumpHandler dumpHandler,
+            BroadcastDispatcher broadcastDispatcher,
+            LogBufferFreezer logBufferFreezer) {
         super();
         mMainHandler = mainHandler;
         mDumpHandler = dumpHandler;
+        mBroadcastDispatcher = broadcastDispatcher;
+        mLogBufferFreezer = logBufferFreezer;
     }
 
     @Override
     public void onCreate() {
         super.onCreate();
+
+        // Start all of SystemUI
         ((SystemUIApplication) getApplication()).startServicesIfNeeded();
 
+        // Finish initializing dump logic
+        mLogBufferFreezer.attach(mBroadcastDispatcher);
+
         // For debugging RescueParty
         if (Build.IS_DEBUGGABLE && SystemProperties.getBoolean("debug.crash_sysui", false)) {
             throw new RuntimeException();
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleLoggerImpl.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleLoggerImpl.java
index 0327cb4..c5faae0 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleLoggerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleLoggerImpl.java
@@ -17,6 +17,7 @@
 package com.android.systemui.bubbles;
 
 import android.service.notification.StatusBarNotification;
+
 import com.android.internal.logging.UiEventLoggerImpl;
 
 /**
@@ -31,6 +32,10 @@
      * @param e UI event
      */
     public void log(Bubble b, UiEventEnum e) {
+        if (b.getEntry() == null) {
+            // Added from persistence -- TODO log this with specific event?
+            return;
+        }
         StatusBarNotification sbn = b.getEntry().getSbn();
         logWithInstanceId(e, sbn.getUid(), sbn.getPackageName(), sbn.getInstanceId());
     }
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/animation/PhysicsAnimationLayout.java b/packages/SystemUI/src/com/android/systemui/bubbles/animation/PhysicsAnimationLayout.java
index 942b9a7..98a7cc2 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/animation/PhysicsAnimationLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/animation/PhysicsAnimationLayout.java
@@ -1037,6 +1037,11 @@
             if (view != null) {
                 final SpringAnimation animation =
                         (SpringAnimation) view.getTag(getTagIdForProperty(property));
+
+                if (animation == null) {
+                    return;
+                }
+
                 final SpringForce animationSpring = animation.getSpring();
 
                 if (animationSpring == null) {
diff --git a/packages/SystemUI/src/com/android/systemui/controls/management/ControlAdapter.kt b/packages/SystemUI/src/com/android/systemui/controls/management/ControlAdapter.kt
index 2f91710..26124f7 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/management/ControlAdapter.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/management/ControlAdapter.kt
@@ -251,7 +251,7 @@
         component: ComponentName,
         @DeviceTypes.DeviceType deviceType: Int
     ): RenderInfo {
-        return RenderInfo.lookup(itemView.context, component, deviceType, true)
+        return RenderInfo.lookup(itemView.context, component, deviceType)
     }
 
     private fun applyRenderInfo(ri: RenderInfo) {
diff --git a/packages/SystemUI/src/com/android/systemui/controls/management/ControlsRequestDialog.kt b/packages/SystemUI/src/com/android/systemui/controls/management/ControlsRequestDialog.kt
index 9b8c036..15d15e8 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/management/ControlsRequestDialog.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/management/ControlsRequestDialog.kt
@@ -136,7 +136,7 @@
     }
 
     fun createDialog(label: CharSequence): Dialog {
-        val renderInfo = RenderInfo.lookup(this, component, control.deviceType, true)
+        val renderInfo = RenderInfo.lookup(this, component, control.deviceType)
         val frame = LayoutInflater.from(this).inflate(R.layout.controls_dialog, null).apply {
             requireViewById<ImageView>(R.id.icon).apply {
                 setImageDrawable(renderInfo.icon)
diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlViewHolder.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlViewHolder.kt
index f979bbb..f07f316 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlViewHolder.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlViewHolder.kt
@@ -29,6 +29,7 @@
 import android.graphics.drawable.Drawable
 import android.graphics.drawable.GradientDrawable
 import android.graphics.drawable.LayerDrawable
+import android.graphics.drawable.StateListDrawable
 import android.service.controls.Control
 import android.service.controls.DeviceTypes
 import android.service.controls.actions.ControlAction
@@ -75,7 +76,8 @@
             DeviceTypes.TYPE_THERMOSTAT,
             DeviceTypes.TYPE_CAMERA
         )
-
+        private val ATTR_ENABLED = intArrayOf(android.R.attr.state_enabled)
+        private val ATTR_DISABLED = intArrayOf(-android.R.attr.state_enabled)
         const val MIN_LEVEL = 0
         const val MAX_LEVEL = 10000
 
@@ -243,7 +245,7 @@
     }
 
     internal fun applyRenderInfo(enabled: Boolean, offset: Int, animated: Boolean = true) {
-        val ri = RenderInfo.lookup(context, cws.componentName, deviceType, enabled, offset)
+        val ri = RenderInfo.lookup(context, cws.componentName, deviceType, offset)
         val fg = context.resources.getColorStateList(ri.foreground, context.theme)
         val newText = nextStatusText
         nextStatusText = ""
@@ -394,7 +396,17 @@
             icon.imageTintList = null
             icon.setImageIcon(it)
         } ?: run {
-            icon.setImageDrawable(drawable)
+            if (drawable is StateListDrawable) {
+                // Only reset the drawable if it is a different resource, as it will interfere
+                // with the image state and animation.
+                if (icon.drawable == null || !(icon.drawable is StateListDrawable)) {
+                    icon.setImageDrawable(drawable)
+                }
+                val state = if (enabled) ATTR_ENABLED else ATTR_DISABLED
+                icon.setImageState(state, true)
+            } else {
+                icon.setImageDrawable(drawable)
+            }
 
             // do not color app icons
             if (deviceType != DeviceTypes.TYPE_ROUTINE) {
diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/RenderInfo.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/RenderInfo.kt
index ba331f4..09d41bd 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/ui/RenderInfo.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/ui/RenderInfo.kt
@@ -28,16 +28,6 @@
 
 import com.android.systemui.R
 
-data class IconState(val disabledResourceId: Int, val enabledResourceId: Int) {
-    operator fun get(state: Boolean): Int {
-        return if (state) {
-            enabledResourceId
-        } else {
-            disabledResourceId
-        }
-    }
-}
-
 data class RenderInfo(
     val icon: Drawable,
     val foreground: Int,
@@ -53,7 +43,6 @@
             context: Context,
             componentName: ComponentName,
             deviceType: Int,
-            enabled: Boolean,
             offset: Int = 0
         ): RenderInfo {
             val key = if (offset > 0) {
@@ -61,8 +50,7 @@
             } else deviceType
 
             val (fg, bg) = deviceColorMap.getValue(key)
-            val iconState = deviceIconMap.getValue(key)
-            val resourceId = iconState[enabled]
+            val resourceId = deviceIconMap.getValue(key)
             var icon: Drawable?
             if (resourceId == APP_ICON_ID) {
                 icon = appIconMap.get(componentName)
@@ -75,11 +63,10 @@
                 icon = iconMap.get(resourceId)
                 if (icon == null) {
                     icon = context.resources.getDrawable(resourceId, null)
-                    icon.mutate()
                     iconMap.put(resourceId, icon)
                 }
             }
-            return RenderInfo(icon!!, fg, bg)
+            return RenderInfo(icon!!.constantState.newDrawable(context.resources), fg, bg)
         }
 
         fun registerComponentIcon(componentName: ComponentName, icon: Drawable) {
@@ -109,230 +96,67 @@
         Pair(R.color.control_foreground, R.color.control_enabled_default_background)
 }
 
-private val deviceIconMap = mapOf<Int, IconState>(
-    (THERMOSTAT_RANGE + TemperatureControlTemplate.MODE_OFF) to IconState(
+private val deviceIconMap = mapOf<Int, Int>(
+    (THERMOSTAT_RANGE + TemperatureControlTemplate.MODE_OFF) to
         R.drawable.ic_device_thermostat_off,
-        R.drawable.ic_device_thermostat_off
-    ),
-    (THERMOSTAT_RANGE + TemperatureControlTemplate.MODE_HEAT) to IconState(
+    (THERMOSTAT_RANGE + TemperatureControlTemplate.MODE_HEAT) to
+        R.drawable.ic_device_thermostat,
+    (THERMOSTAT_RANGE + TemperatureControlTemplate.MODE_COOL) to
+        R.drawable.ic_device_thermostat,
+    (THERMOSTAT_RANGE + TemperatureControlTemplate.MODE_HEAT_COOL) to
+        R.drawable.ic_device_thermostat,
+    (THERMOSTAT_RANGE + TemperatureControlTemplate.MODE_ECO) to
         R.drawable.ic_device_thermostat_off,
-        R.drawable.ic_device_thermostat_on
-    ),
-    (THERMOSTAT_RANGE + TemperatureControlTemplate.MODE_COOL) to IconState(
-        R.drawable.ic_device_thermostat_off,
-        R.drawable.ic_device_thermostat_on
-    ),
-    (THERMOSTAT_RANGE + TemperatureControlTemplate.MODE_HEAT_COOL) to IconState(
-        R.drawable.ic_device_thermostat_off,
-        R.drawable.ic_device_thermostat_on
-    ),
-    (THERMOSTAT_RANGE + TemperatureControlTemplate.MODE_ECO) to IconState(
-        R.drawable.ic_device_thermostat_off,
-        R.drawable.ic_device_thermostat_off
-    ),
-    DeviceTypes.TYPE_THERMOSTAT to IconState(
-        R.drawable.ic_device_thermostat_off,
-        R.drawable.ic_device_thermostat_on
-    ),
-    DeviceTypes.TYPE_LIGHT to IconState(
-        R.drawable.ic_device_light_off,
-        R.drawable.ic_device_light_on
-    ),
-    DeviceTypes.TYPE_CAMERA to IconState(
-        R.drawable.ic_device_camera_off,
-        R.drawable.ic_device_camera_on
-    ),
-    DeviceTypes.TYPE_LOCK to IconState(
-        R.drawable.ic_device_lock_off,
-        R.drawable.ic_device_lock_on
-    ),
-    DeviceTypes.TYPE_SWITCH to IconState(
-        R.drawable.ic_device_switch_off,
-        R.drawable.ic_device_switch_on
-    ),
-    DeviceTypes.TYPE_OUTLET to IconState(
-        R.drawable.ic_device_outlet_off,
-        R.drawable.ic_device_outlet_on
-    ),
-    DeviceTypes.TYPE_VACUUM to IconState(
-        R.drawable.ic_device_vacuum_off,
-        R.drawable.ic_device_vacuum_on
-    ),
-    DeviceTypes.TYPE_MOP to IconState(
-        R.drawable.ic_device_mop_off,
-        R.drawable.ic_device_mop_on
-    ),
-    DeviceTypes.TYPE_AIR_FRESHENER to IconState(
-        R.drawable.ic_device_air_freshener_off,
-        R.drawable.ic_device_air_freshener_on
-    ),
-    DeviceTypes.TYPE_AIR_PURIFIER to IconState(
-        R.drawable.ic_device_air_purifier_off,
-        R.drawable.ic_device_air_purifier_on
-    ),
-    DeviceTypes.TYPE_FAN to IconState(
-        R.drawable.ic_device_fan_off,
-        R.drawable.ic_device_fan_on
-    ),
-    DeviceTypes.TYPE_HOOD to IconState(
-        R.drawable.ic_device_hood_off,
-        R.drawable.ic_device_hood_on
-    ),
-    DeviceTypes.TYPE_KETTLE to IconState(
-        R.drawable.ic_device_kettle_off,
-        R.drawable.ic_device_kettle_on
-    ),
-    DeviceTypes.TYPE_MICROWAVE to IconState(
-        R.drawable.ic_device_microwave_off,
-        R.drawable.ic_device_microwave_on
-    ),
-    DeviceTypes.TYPE_REMOTE_CONTROL to IconState(
-        R.drawable.ic_device_remote_control_off,
-        R.drawable.ic_device_remote_control_on
-    ),
-    DeviceTypes.TYPE_SET_TOP to IconState(
-        R.drawable.ic_device_set_top_off,
-        R.drawable.ic_device_set_top_on
-    ),
-    DeviceTypes.TYPE_STYLER to IconState(
-        R.drawable.ic_device_styler_off,
-        R.drawable.ic_device_styler_on
-    ),
-    DeviceTypes.TYPE_TV to IconState(
-        R.drawable.ic_device_tv_off,
-        R.drawable.ic_device_tv_on
-    ),
-    DeviceTypes.TYPE_WATER_HEATER to IconState(
-        R.drawable.ic_device_water_heater_off,
-        R.drawable.ic_device_water_heater_on
-    ),
-    DeviceTypes.TYPE_DISHWASHER to IconState(
-        R.drawable.ic_device_dishwasher_off,
-        R.drawable.ic_device_dishwasher_on
-    ),
-    DeviceTypes.TYPE_MULTICOOKER to IconState(
-        R.drawable.ic_device_multicooker_off,
-        R.drawable.ic_device_multicooker_on
-    ),
-    DeviceTypes.TYPE_SPRINKLER to IconState(
-        R.drawable.ic_device_sprinkler_off,
-        R.drawable.ic_device_sprinkler_on
-    ),
-    DeviceTypes.TYPE_WASHER to IconState(
-        R.drawable.ic_device_washer_off,
-        R.drawable.ic_device_washer_on
-    ),
-    DeviceTypes.TYPE_BLINDS to IconState(
-        R.drawable.ic_device_blinds_off,
-        R.drawable.ic_device_blinds_on
-    ),
-    DeviceTypes.TYPE_DRAWER to IconState(
-        R.drawable.ic_device_drawer_off,
-        R.drawable.ic_device_drawer_on
-    ),
-    DeviceTypes.TYPE_GARAGE to IconState(
-        R.drawable.ic_device_garage_off,
-        R.drawable.ic_device_garage_on
-    ),
-    DeviceTypes.TYPE_GATE to IconState(
-        R.drawable.ic_device_gate_off,
-        R.drawable.ic_device_gate_on
-    ),
-    DeviceTypes.TYPE_PERGOLA to IconState(
-        R.drawable.ic_device_pergola_off,
-        R.drawable.ic_device_pergola_on
-    ),
-    DeviceTypes.TYPE_WINDOW to IconState(
-        R.drawable.ic_device_window_off,
-        R.drawable.ic_device_window_on
-    ),
-    DeviceTypes.TYPE_VALVE to IconState(
-        R.drawable.ic_device_valve_off,
-        R.drawable.ic_device_valve_on
-    ),
-    DeviceTypes.TYPE_SECURITY_SYSTEM to IconState(
-        R.drawable.ic_device_security_system_off,
-        R.drawable.ic_device_security_system_on
-    ),
-    DeviceTypes.TYPE_REFRIGERATOR to IconState(
-        R.drawable.ic_device_refrigerator_off,
-        R.drawable.ic_device_refrigerator_on
-    ),
-    DeviceTypes.TYPE_DOORBELL to IconState(
-        R.drawable.ic_device_doorbell_off,
-        R.drawable.ic_device_doorbell_on
-    ),
-    DeviceTypes.TYPE_ROUTINE to IconState(
-        RenderInfo.APP_ICON_ID,
-        RenderInfo.APP_ICON_ID
-    ),
-    DeviceTypes.TYPE_AC_HEATER to IconState(
-        R.drawable.ic_device_thermostat_off,
-        R.drawable.ic_device_thermostat_on
-    ),
-    DeviceTypes.TYPE_AC_UNIT to IconState(
-        R.drawable.ic_device_thermostat_off,
-        R.drawable.ic_device_thermostat_on
-    ),
-    DeviceTypes.TYPE_COFFEE_MAKER to IconState(
-        R.drawable.ic_device_kettle_off,
-        R.drawable.ic_device_kettle_on
-    ),
-    DeviceTypes.TYPE_DEHUMIDIFIER to IconState(
-        R.drawable.ic_device_air_freshener_off,
-        R.drawable.ic_device_air_freshener_on
-    ),
-    DeviceTypes.TYPE_RADIATOR to IconState(
-        R.drawable.ic_device_thermostat_off,
-        R.drawable.ic_device_thermostat_on
-    ),
-    DeviceTypes.TYPE_STANDMIXER to IconState(
-        R.drawable.ic_device_cooking_off,
-        R.drawable.ic_device_cooking_on
-    ),
-    DeviceTypes.TYPE_DISPLAY to IconState(
-        R.drawable.ic_device_display_off,
-        R.drawable.ic_device_display_on
-    ),
-    DeviceTypes.TYPE_DRYER to IconState(
-        R.drawable.ic_device_washer_off,
-        R.drawable.ic_device_washer_on
-    ),
-    DeviceTypes.TYPE_MOWER to IconState(
-        R.drawable.ic_device_outdoor_garden_off,
-        R.drawable.ic_device_outdoor_garden_on
-    ),
-    DeviceTypes.TYPE_SHOWER to IconState(
-        R.drawable.ic_device_water_off,
-        R.drawable.ic_device_water_on
-    ),
-    DeviceTypes.TYPE_AWNING to IconState(
-        R.drawable.ic_device_pergola_off,
-        R.drawable.ic_device_pergola_on
-    ),
-    DeviceTypes.TYPE_CLOSET to IconState(
-        R.drawable.ic_device_drawer_off,
-        R.drawable.ic_device_drawer_on
-    ),
-    DeviceTypes.TYPE_CURTAIN to IconState(
-        R.drawable.ic_device_blinds_off,
-        R.drawable.ic_device_blinds_on
-    ),
-    DeviceTypes.TYPE_DOOR to IconState(
-        R.drawable.ic_device_door_off,
-        R.drawable.ic_device_door_on
-    ),
-    DeviceTypes.TYPE_SHUTTER to IconState(
-        R.drawable.ic_device_window_off,
-        R.drawable.ic_device_window_on
-    ),
-    DeviceTypes.TYPE_HEATER to IconState(
-        R.drawable.ic_device_thermostat_off,
-        R.drawable.ic_device_thermostat_on
-    )
+    DeviceTypes.TYPE_THERMOSTAT to R.drawable.ic_device_thermostat,
+    DeviceTypes.TYPE_LIGHT to R.drawable.ic_device_light,
+    DeviceTypes.TYPE_CAMERA to R.drawable.ic_device_camera,
+    DeviceTypes.TYPE_LOCK to R.drawable.ic_device_lock,
+    DeviceTypes.TYPE_SWITCH to R.drawable.ic_device_switch,
+    DeviceTypes.TYPE_OUTLET to R.drawable.ic_device_outlet,
+    DeviceTypes.TYPE_VACUUM to R.drawable.ic_device_vacuum,
+    DeviceTypes.TYPE_MOP to R.drawable.ic_device_mop,
+    DeviceTypes.TYPE_AIR_FRESHENER to R.drawable.ic_device_air_freshener,
+    DeviceTypes.TYPE_AIR_PURIFIER to R.drawable.ic_device_air_purifier,
+    DeviceTypes.TYPE_FAN to R.drawable.ic_device_fan,
+    DeviceTypes.TYPE_HOOD to R.drawable.ic_device_hood,
+    DeviceTypes.TYPE_KETTLE to R.drawable.ic_device_kettle,
+    DeviceTypes.TYPE_MICROWAVE to R.drawable.ic_device_microwave,
+    DeviceTypes.TYPE_REMOTE_CONTROL to R.drawable.ic_device_remote_control,
+    DeviceTypes.TYPE_SET_TOP to R.drawable.ic_device_set_top,
+    DeviceTypes.TYPE_STYLER to R.drawable.ic_device_styler,
+    DeviceTypes.TYPE_TV to R.drawable.ic_device_tv,
+    DeviceTypes.TYPE_WATER_HEATER to R.drawable.ic_device_water_heater,
+    DeviceTypes.TYPE_DISHWASHER to R.drawable.ic_device_dishwasher,
+    DeviceTypes.TYPE_MULTICOOKER to R.drawable.ic_device_multicooker,
+    DeviceTypes.TYPE_SPRINKLER to R.drawable.ic_device_sprinkler,
+    DeviceTypes.TYPE_WASHER to R.drawable.ic_device_washer,
+    DeviceTypes.TYPE_BLINDS to R.drawable.ic_device_blinds,
+    DeviceTypes.TYPE_DRAWER to R.drawable.ic_device_drawer,
+    DeviceTypes.TYPE_GARAGE to R.drawable.ic_device_garage,
+    DeviceTypes.TYPE_GATE to R.drawable.ic_device_gate,
+    DeviceTypes.TYPE_PERGOLA to R.drawable.ic_device_pergola,
+    DeviceTypes.TYPE_WINDOW to R.drawable.ic_device_window,
+    DeviceTypes.TYPE_VALVE to R.drawable.ic_device_valve,
+    DeviceTypes.TYPE_SECURITY_SYSTEM to R.drawable.ic_device_security_system,
+    DeviceTypes.TYPE_REFRIGERATOR to R.drawable.ic_device_refrigerator,
+    DeviceTypes.TYPE_DOORBELL to R.drawable.ic_device_doorbell,
+    DeviceTypes.TYPE_ROUTINE to RenderInfo.APP_ICON_ID,
+    DeviceTypes.TYPE_AC_HEATER to R.drawable.ic_device_thermostat,
+    DeviceTypes.TYPE_AC_UNIT to R.drawable.ic_device_thermostat,
+    DeviceTypes.TYPE_COFFEE_MAKER to R.drawable.ic_device_kettle,
+    DeviceTypes.TYPE_DEHUMIDIFIER to R.drawable.ic_device_air_freshener,
+    DeviceTypes.TYPE_RADIATOR to R.drawable.ic_device_thermostat,
+    DeviceTypes.TYPE_STANDMIXER to R.drawable.ic_device_cooking,
+    DeviceTypes.TYPE_DISPLAY to R.drawable.ic_device_display,
+    DeviceTypes.TYPE_DRYER to R.drawable.ic_device_washer,
+    DeviceTypes.TYPE_MOWER to R.drawable.ic_device_outdoor_garden,
+    DeviceTypes.TYPE_SHOWER to R.drawable.ic_device_water,
+    DeviceTypes.TYPE_AWNING to R.drawable.ic_device_pergola,
+    DeviceTypes.TYPE_CLOSET to R.drawable.ic_device_drawer,
+    DeviceTypes.TYPE_CURTAIN to R.drawable.ic_device_blinds,
+    DeviceTypes.TYPE_DOOR to R.drawable.ic_device_door,
+    DeviceTypes.TYPE_SHUTTER to R.drawable.ic_device_window,
+    DeviceTypes.TYPE_HEATER to R.drawable.ic_device_thermostat
 ).withDefault {
-    IconState(
-        R.drawable.ic_device_unknown_off,
-        R.drawable.ic_device_unknown_on
-    )
+    R.drawable.ic_device_unknown
 }
diff --git a/packages/SystemUI/src/com/android/systemui/dump/DumpManager.kt b/packages/SystemUI/src/com/android/systemui/dump/DumpManager.kt
index a4141b1..bbb7750 100644
--- a/packages/SystemUI/src/com/android/systemui/dump/DumpManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/dump/DumpManager.kt
@@ -140,6 +140,20 @@
         }
     }
 
+    @Synchronized
+    fun freezeBuffers() {
+        for (buffer in buffers.values) {
+            buffer.dumpable.freeze()
+        }
+    }
+
+    @Synchronized
+    fun unfreezeBuffers() {
+        for (buffer in buffers.values) {
+            buffer.dumpable.unfreeze()
+        }
+    }
+
     private fun dumpDumpable(
         dumpable: RegisteredDumpable<Dumpable>,
         fd: FileDescriptor,
@@ -174,3 +188,5 @@
     val name: String,
     val dumpable: T
 )
+
+private const val TAG = "DumpManager"
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/dump/LogBufferFreezer.kt b/packages/SystemUI/src/com/android/systemui/dump/LogBufferFreezer.kt
new file mode 100644
index 0000000..29f4642
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/dump/LogBufferFreezer.kt
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2020 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 com.android.systemui.dump
+
+import android.content.BroadcastReceiver
+import android.content.Context
+import android.content.Intent
+import android.content.IntentFilter
+import android.os.UserHandle
+import android.util.Log
+import com.android.systemui.broadcast.BroadcastDispatcher
+import com.android.systemui.dagger.qualifiers.Main
+import com.android.systemui.util.concurrency.DelayableExecutor
+import java.util.concurrent.TimeUnit
+import javax.inject.Inject
+
+class LogBufferFreezer constructor(
+    private val dumpManager: DumpManager,
+    @Main private val executor: DelayableExecutor,
+    private val freezeDuration: Long
+) {
+    @Inject constructor(
+        dumpManager: DumpManager,
+        @Main executor: DelayableExecutor
+    ) : this(dumpManager, executor, TimeUnit.MINUTES.toMillis(5))
+
+    private var pendingToken: Runnable? = null
+
+    fun attach(broadcastDispatcher: BroadcastDispatcher) {
+        broadcastDispatcher.registerReceiver(
+                object : BroadcastReceiver() {
+                    override fun onReceive(context: Context?, intent: Intent?) {
+                        onBugreportStarted()
+                    }
+                },
+                IntentFilter("com.android.internal.intent.action.BUGREPORT_STARTED"),
+                executor,
+                UserHandle.ALL)
+    }
+
+    private fun onBugreportStarted() {
+        pendingToken?.run()
+
+        Log.i(TAG, "Freezing log buffers")
+        dumpManager.freezeBuffers()
+
+        pendingToken = executor.executeDelayed({
+            Log.i(TAG, "Unfreezing log buffers")
+            pendingToken = null
+            dumpManager.unfreezeBuffers()
+        }, freezeDuration)
+    }
+}
+
+private const val TAG = "LogBufferFreezer"
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/log/LogBuffer.kt b/packages/SystemUI/src/com/android/systemui/log/LogBuffer.kt
index 342db34..78d7087 100644
--- a/packages/SystemUI/src/com/android/systemui/log/LogBuffer.kt
+++ b/packages/SystemUI/src/com/android/systemui/log/LogBuffer.kt
@@ -74,6 +74,9 @@
 ) {
     private val buffer: ArrayDeque<LogMessageImpl> = ArrayDeque()
 
+    var frozen = false
+        private set
+
     fun attach(dumpManager: DumpManager) {
         dumpManager.registerBuffer(name, this)
     }
@@ -112,9 +115,11 @@
         initializer: LogMessage.() -> Unit,
         noinline printer: LogMessage.() -> String
     ) {
-        val message = obtain(tag, level, printer)
-        initializer(message)
-        push(message)
+        if (!frozen) {
+            val message = obtain(tag, level, printer)
+            initializer(message)
+            push(message)
+        }
     }
 
     /**
@@ -139,17 +144,16 @@
      *
      * In general, you should call [log] or [document] instead of this method.
      */
+    @Synchronized
     fun obtain(
         tag: String,
         level: LogLevel,
         printer: (LogMessage) -> String
     ): LogMessageImpl {
-        val message = synchronized(buffer) {
-            if (buffer.size > maxLogs - poolSize) {
-                buffer.removeFirst()
-            } else {
-                LogMessageImpl.create()
-            }
+        val message = when {
+            frozen -> LogMessageImpl.create()
+            buffer.size > maxLogs - poolSize -> buffer.removeFirst()
+            else -> LogMessageImpl.create()
         }
         message.reset(tag, level, System.currentTimeMillis(), printer)
         return message
@@ -158,33 +162,58 @@
     /**
      * Pushes a message into buffer, possibly evicting an older message if the buffer is full.
      */
+    @Synchronized
     fun push(message: LogMessage) {
-        synchronized(buffer) {
-            if (buffer.size == maxLogs) {
-                Log.e(TAG, "LogBuffer $name has exceeded its pool size")
-                buffer.removeFirst()
-            }
-            buffer.add(message as LogMessageImpl)
-            if (logcatEchoTracker.isBufferLoggable(name, message.level) ||
-                    logcatEchoTracker.isTagLoggable(message.tag, message.level)) {
-                echoToLogcat(message)
-            }
+        if (frozen) {
+            return
+        }
+        if (buffer.size == maxLogs) {
+            Log.e(TAG, "LogBuffer $name has exceeded its pool size")
+            buffer.removeFirst()
+        }
+        buffer.add(message as LogMessageImpl)
+        if (logcatEchoTracker.isBufferLoggable(name, message.level) ||
+                logcatEchoTracker.isTagLoggable(message.tag, message.level)) {
+            echoToLogcat(message)
         }
     }
 
     /** Converts the entire buffer to a newline-delimited string */
+    @Synchronized
     fun dump(pw: PrintWriter, tailLength: Int) {
-        synchronized(buffer) {
-            val start = if (tailLength <= 0) { 0 } else { buffer.size - tailLength }
+        val start = if (tailLength <= 0) { 0 } else { buffer.size - tailLength }
 
-            for ((i, message) in buffer.withIndex()) {
-                if (i >= start) {
-                    dumpMessage(message, pw)
-                }
+        for ((i, message) in buffer.withIndex()) {
+            if (i >= start) {
+                dumpMessage(message, pw)
             }
         }
     }
 
+    /**
+     * "Freezes" the contents of the buffer, making them immutable until [unfreeze] is called.
+     * Calls to [log], [document], [obtain], and [push] will not affect the buffer and will return
+     * dummy values if necessary.
+     */
+    @Synchronized
+    fun freeze() {
+        if (!frozen) {
+            log(TAG, LogLevel.DEBUG, { str1 = name }, { "$str1 frozen" })
+            frozen = true
+        }
+    }
+
+    /**
+     * Undoes the effects of calling [freeze].
+     */
+    @Synchronized
+    fun unfreeze() {
+        if (frozen) {
+            log(TAG, LogLevel.DEBUG, { str1 = name }, { "$str1 unfrozen" })
+            frozen = false
+        }
+    }
+
     private fun dumpMessage(message: LogMessage, pw: PrintWriter) {
         pw.print(DATE_FORMAT.format(message.timestamp))
         pw.print(" ")
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaData.kt b/packages/SystemUI/src/com/android/systemui/media/MediaData.kt
index 330a5c0..a94f6a8 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaData.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaData.kt
@@ -35,7 +35,8 @@
     val packageName: String?,
     val token: MediaSession.Token?,
     val clickIntent: PendingIntent?,
-    val device: MediaDeviceData?
+    val device: MediaDeviceData?,
+    val notificationKey: String = "INVALID"
 )
 
 /** State of a media action. */
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt b/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt
index cf7fbfa..d949857 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt
@@ -35,6 +35,8 @@
 import com.android.systemui.dagger.qualifiers.Background
 import com.android.systemui.dagger.qualifiers.Main
 import com.android.systemui.statusbar.notification.MediaNotificationProcessor
+import com.android.systemui.statusbar.notification.NotificationEntryManager
+import com.android.systemui.statusbar.notification.NotificationEntryManager.UNDEFINED_DISMISS_REASON
 import com.android.systemui.statusbar.notification.row.HybridGroupManager
 import com.android.systemui.util.Assert
 import com.android.systemui.util.Utils
@@ -77,6 +79,8 @@
 class MediaDataManager @Inject constructor(
     private val context: Context,
     private val mediaControllerFactory: MediaControllerFactory,
+    private val mediaTimeoutListener: MediaTimeoutListener,
+    private val notificationEntryManager: NotificationEntryManager,
     @Background private val backgroundExecutor: Executor,
     @Main private val foregroundExecutor: Executor
 ) {
@@ -84,6 +88,12 @@
     private val listeners: MutableSet<Listener> = mutableSetOf()
     private val mediaEntries: LinkedHashMap<String, MediaData> = LinkedHashMap()
 
+    init {
+        mediaTimeoutListener.timeoutCallback = { token: String, timedOut: Boolean ->
+            setTimedOut(token, timedOut) }
+        addListener(mediaTimeoutListener)
+    }
+
     fun onNotificationAdded(key: String, sbn: StatusBarNotification) {
         if (Utils.useQsMediaPlayer(context) && isMediaNotification(sbn)) {
             Assert.isMainThread()
@@ -112,6 +122,16 @@
      */
     fun removeListener(listener: Listener) = listeners.remove(listener)
 
+    private fun setTimedOut(token: String, timedOut: Boolean) {
+        if (!timedOut) {
+            return
+        }
+        mediaEntries[token]?.let {
+            notificationEntryManager.removeNotification(it.notificationKey, null /* ranking */,
+                    UNDEFINED_DISMISS_REASON)
+        }
+    }
+
     private fun loadMediaDataInBg(key: String, sbn: StatusBarNotification) {
         val token = sbn.notification.extras.getParcelable(Notification.EXTRA_MEDIA_SESSION)
                 as MediaSession.Token?
@@ -223,7 +243,7 @@
         foregroundExecutor.execute {
             onMediaDataLoaded(key, MediaData(true, bgColor, app, smallIconDrawable, artist, song,
                     artWorkIcon, actionIcons, actionsToShowCollapsed, sbn.packageName, token,
-                    notif.contentIntent, null))
+                    notif.contentIntent, null, key))
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaTimeoutListener.kt b/packages/SystemUI/src/com/android/systemui/media/MediaTimeoutListener.kt
new file mode 100644
index 0000000..92a1ab1
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaTimeoutListener.kt
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2020 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 com.android.systemui.media
+
+import android.media.session.MediaController
+import android.media.session.PlaybackState
+import android.os.SystemProperties
+import android.util.Log
+import com.android.systemui.dagger.qualifiers.Main
+import com.android.systemui.statusbar.NotificationMediaManager.isPlayingState
+import com.android.systemui.util.concurrency.DelayableExecutor
+import java.util.concurrent.TimeUnit
+import javax.inject.Inject
+import javax.inject.Singleton
+
+private const val DEBUG = true
+private const val TAG = "MediaTimeout"
+private val PAUSED_MEDIA_TIMEOUT = SystemProperties
+        .getLong("debug.sysui.media_timeout", TimeUnit.MINUTES.toMillis(10))
+
+/**
+ * Controller responsible for keeping track of playback states and expiring inactive streams.
+ */
+@Singleton
+class MediaTimeoutListener @Inject constructor(
+    private val mediaControllerFactory: MediaControllerFactory,
+    @Main private val mainExecutor: DelayableExecutor
+) : MediaDataManager.Listener {
+
+    private val mediaListeners: MutableMap<String, PlaybackStateListener> = mutableMapOf()
+
+    lateinit var timeoutCallback: (String, Boolean) -> Unit
+
+    override fun onMediaDataLoaded(key: String, data: MediaData) {
+        if (mediaListeners.containsKey(key)) {
+            return
+        }
+        mediaListeners[key] = PlaybackStateListener(key, data)
+    }
+
+    override fun onMediaDataRemoved(key: String) {
+        mediaListeners.remove(key)?.destroy()
+    }
+
+    fun isTimedOut(key: String): Boolean {
+        return mediaListeners[key]?.timedOut ?: false
+    }
+
+    private inner class PlaybackStateListener(
+        private val key: String,
+        data: MediaData
+    ) : MediaController.Callback() {
+
+        var timedOut = false
+
+        private val mediaController = mediaControllerFactory.create(data.token)
+        private var cancellation: Runnable? = null
+
+        init {
+            mediaController.registerCallback(this)
+        }
+
+        fun destroy() {
+            mediaController.unregisterCallback(this)
+        }
+
+        override fun onPlaybackStateChanged(state: PlaybackState?) {
+            if (DEBUG) {
+                Log.v(TAG, "onPlaybackStateChanged: $state")
+            }
+            expireMediaTimeout(key, "playback state ativity - $state, $key")
+
+            if (state == null || !isPlayingState(state.state)) {
+                if (DEBUG) {
+                    Log.v(TAG, "schedule timeout for $key")
+                }
+                expireMediaTimeout(key, "PLAYBACK STATE CHANGED - $state")
+                cancellation = mainExecutor.executeDelayed({
+                    cancellation = null
+                    if (DEBUG) {
+                        Log.v(TAG, "Execute timeout for $key")
+                    }
+                    timedOut = true
+                    timeoutCallback(key, timedOut)
+                }, PAUSED_MEDIA_TIMEOUT)
+            } else {
+                timedOut = false
+                timeoutCallback(key, timedOut)
+            }
+        }
+
+        private fun expireMediaTimeout(mediaNotificationKey: String, reason: String) {
+            cancellation?.apply {
+                if (DEBUG) {
+                    Log.v(TAG,
+                            "media timeout cancelled for  $mediaNotificationKey, reason: $reason")
+                }
+                run()
+            }
+            cancellation = null
+        }
+    }
+}
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
index 33d692f..a9d3772 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
@@ -64,7 +64,6 @@
 import android.view.Display;
 import android.view.LayoutInflater;
 import android.view.MotionEvent;
-import android.view.Surface;
 import android.view.SurfaceControl;
 import android.view.View;
 import android.view.ViewGroup;
@@ -212,8 +211,6 @@
     private boolean mDirectionLTR = true;
     private boolean mOrientationPortrait = true;
 
-    private float mScreenshotOffsetXPx;
-    private float mScreenshotOffsetYPx;
     private float mCornerSizeX;
     private float mDismissDeltaY;
 
@@ -273,8 +270,6 @@
         mDisplayMetrics = new DisplayMetrics();
         mDisplay.getRealMetrics(mDisplayMetrics);
 
-        mScreenshotOffsetXPx = resources.getDimensionPixelSize(R.dimen.screenshot_offset_x);
-        mScreenshotOffsetYPx = resources.getDimensionPixelSize(R.dimen.screenshot_offset_y);
         mCornerSizeX = resources.getDimensionPixelSize(R.dimen.global_screenshot_x_scale);
         mDismissDeltaY = resources.getDimensionPixelSize(R.dimen.screenshot_dismissal_height_delta);
 
@@ -448,12 +443,11 @@
      * Takes a screenshot of the current display and shows an animation.
      */
     private void takeScreenshot(Consumer<Uri> finisher, Rect crop) {
+        // copy the input Rect, since SurfaceControl.screenshot can mutate it
+        Rect screenRect = new Rect(crop);
         int rot = mDisplay.getRotation();
         int width = crop.width();
         int height = crop.height();
-
-        Rect screenRect = new Rect(0, 0, mDisplayMetrics.widthPixels, mDisplayMetrics.heightPixels);
-
         takeScreenshot(SurfaceControl.screenshot(crop, width, height, rot), finisher, screenRect);
     }
 
@@ -483,12 +477,11 @@
 
         onConfigChanged(mContext.getResources().getConfiguration());
 
-
         if (mDismissAnimation != null && mDismissAnimation.isRunning()) {
             mDismissAnimation.cancel();
         }
         // Start the post-screenshot animation
-        startAnimation(finisher, screenRect.width(), screenRect.height(), screenRect);
+        startAnimation(finisher, mScreenBitmap.getWidth(), mScreenBitmap.getHeight(), screenRect);
     }
 
     void takeScreenshot(Consumer<Uri> finisher, Runnable onComplete) {
@@ -691,8 +684,8 @@
     /**
      * Starts the animation after taking the screenshot
      */
-    private void startAnimation(final Consumer<Uri> finisher, int w, int h,
-            @Nullable Rect screenRect) {
+    private void startAnimation(
+            final Consumer<Uri> finisher, int bitmapWidth, int bitmapHeight, Rect screenRect) {
         // If power save is on, show a toast so there is some visual indication that a
         // screenshot has been taken.
         PowerManager powerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
@@ -700,21 +693,28 @@
             Toast.makeText(mContext, R.string.screenshot_saved_title, Toast.LENGTH_SHORT).show();
         }
 
-        mScreenshotAnimation = createScreenshotDropInAnimation(w, h, screenRect);
-
-        saveScreenshotInWorkerThread(finisher, new ActionsReadyListener() {
-                    @Override
-                    void onActionsReady(SavedImageData imageData) {
-                        showUiOnActionsReady(imageData);
-                    }
-                });
         mScreenshotHandler.post(() -> {
             if (!mScreenshotLayout.isAttachedToWindow()) {
                 mWindowManager.addView(mScreenshotLayout, mWindowLayoutParams);
             }
-            mScreenshotLayout.getViewTreeObserver().addOnComputeInternalInsetsListener(this);
+            mScreenshotAnimatedView.setImageBitmap(mScreenBitmap);
+            mScreenshotPreview.setImageBitmap(mScreenBitmap);
+
+            // make static preview invisible (from gone) so we can query its location on screen
+            mScreenshotPreview.setVisibility(View.INVISIBLE);
 
             mScreenshotHandler.post(() -> {
+                mScreenshotLayout.getViewTreeObserver().addOnComputeInternalInsetsListener(this);
+
+                mScreenshotAnimation =
+                        createScreenshotDropInAnimation(bitmapWidth, bitmapHeight, screenRect);
+
+                saveScreenshotInWorkerThread(finisher, new ActionsReadyListener() {
+                            @Override
+                            void onActionsReady(SavedImageData imageData) {
+                                showUiOnActionsReady(imageData);
+                            }
+                        });
 
                 // Play the shutter sound to notify that we've taken a screenshot
                 mCameraSound.play(MediaActionSound.SHUTTER_CLICK);
@@ -726,18 +726,13 @@
         });
     }
 
-    private AnimatorSet createScreenshotDropInAnimation(int width, int height, Rect bounds) {
-        float screenWidth = mDisplayMetrics.widthPixels;
-        float screenHeight = mDisplayMetrics.heightPixels;
+    private AnimatorSet createScreenshotDropInAnimation(
+            int bitmapWidth, int bitmapHeight, Rect bounds) {
+        Rect previewBounds = new Rect();
+        mScreenshotPreview.getBoundsOnScreen(previewBounds);
 
-        int rotation = mContext.getDisplay().getRotation();
-        float cornerScale;
-        if (rotation == Surface.ROTATION_90 || rotation == Surface.ROTATION_270) {
-            cornerScale = (mCornerSizeX /  screenHeight);
-        } else {
-            cornerScale = (mCornerSizeX / screenWidth);
-        }
-        float currentScale = width / screenWidth;
+        float cornerScale = mCornerSizeX / (mOrientationPortrait ? bitmapWidth : bitmapHeight);
+        float currentScale = bounds.height() / (float) bitmapHeight;
 
         mScreenshotAnimatedView.setScaleX(currentScale);
         mScreenshotAnimatedView.setScaleY(currentScale);
@@ -745,9 +740,6 @@
         mScreenshotAnimatedView.setPivotX(0);
         mScreenshotAnimatedView.setPivotY(0);
 
-        mScreenshotAnimatedView.setImageBitmap(mScreenBitmap);
-        mScreenshotPreview.setImageBitmap(mScreenBitmap);
-
         AnimatorSet dropInAnimation = new AnimatorSet();
         ValueAnimator flashInAnimator = ValueAnimator.ofFloat(0, 1);
         flashInAnimator.setDuration(SCREENSHOT_FLASH_IN_DURATION_MS);
@@ -761,15 +753,9 @@
         flashOutAnimator.addUpdateListener(animation ->
                 mScreenshotFlash.setAlpha((float) animation.getAnimatedValue()));
 
+        // animate from the current location, to the static preview location
         final PointF startPos = new PointF(bounds.centerX(), bounds.centerY());
-        float finalX;
-        if (mDirectionLTR) {
-            finalX = mScreenshotOffsetXPx + screenWidth * cornerScale / 2f;
-        } else {
-            finalX = screenWidth - mScreenshotOffsetXPx - screenWidth * cornerScale / 2f;
-        }
-        float finalY = screenHeight - mScreenshotOffsetYPx - screenHeight * cornerScale / 2f;
-        final PointF finalPos = new PointF(finalX, finalY);
+        final PointF finalPos = new PointF(previewBounds.centerX(), previewBounds.centerY());
 
         ValueAnimator toCorner = ValueAnimator.ofFloat(0, 1);
         toCorner.setDuration(SCREENSHOT_TO_CORNER_Y_DURATION_MS);
@@ -795,13 +781,13 @@
             if (t < xPositionPct) {
                 float xCenter = MathUtils.lerp(startPos.x, finalPos.x,
                         mFastOutSlowIn.getInterpolation(t / xPositionPct));
-                mScreenshotAnimatedView.setX(xCenter - screenWidth * currentScaleX / 2f);
+                mScreenshotAnimatedView.setX(xCenter - bitmapWidth * currentScaleX / 2f);
             } else {
-                mScreenshotAnimatedView.setX(finalPos.x - screenWidth * currentScaleX / 2f);
+                mScreenshotAnimatedView.setX(finalPos.x - bitmapWidth * currentScaleX / 2f);
             }
-            float yCenter = MathUtils.lerp(startPos.y, finalPos.y,
-                    mFastOutSlowIn.getInterpolation(t));
-            mScreenshotAnimatedView.setY(yCenter - screenHeight * currentScaleY / 2f);
+            float yCenter = MathUtils.lerp(
+                    startPos.y, finalPos.y, mFastOutSlowIn.getInterpolation(t));
+            mScreenshotAnimatedView.setY(yCenter - bitmapHeight * currentScaleY / 2f);
         });
 
         toCorner.addListener(new AnimatorListenerAdapter() {
@@ -824,10 +810,8 @@
                 super.onAnimationEnd(animation);
                 mScreenshotAnimatedView.setScaleX(1);
                 mScreenshotAnimatedView.setScaleY(1);
-                mScreenshotAnimatedView.setX(finalPos.x - width * cornerScale / 2f);
-                mScreenshotAnimatedView.setY(finalPos.y - height * cornerScale / 2f);
-                Rect bounds = new Rect();
-                mDismissButton.getBoundsOnScreen(bounds);
+                mScreenshotAnimatedView.setX(finalPos.x - bounds.width() * cornerScale / 2f);
+                mScreenshotAnimatedView.setY(finalPos.y - bounds.height() * cornerScale / 2f);
                 mScreenshotAnimatedView.setVisibility(View.GONE);
                 mScreenshotPreview.setVisibility(View.VISIBLE);
                 mDismissButton.setVisibility(View.VISIBLE);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java
index db5329a..217148d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java
@@ -16,7 +16,6 @@
 package com.android.systemui.statusbar;
 
 import static com.android.systemui.statusbar.StatusBarState.KEYGUARD;
-import static com.android.systemui.statusbar.notification.NotificationEntryManager.UNDEFINED_DISMISS_REASON;
 import static com.android.systemui.statusbar.phone.StatusBar.DEBUG_MEDIA_FAKE_ARTWORK;
 import static com.android.systemui.statusbar.phone.StatusBar.ENABLE_LOCKSCREEN_WALLPAPER;
 import static com.android.systemui.statusbar.phone.StatusBar.SHOW_LOCKSCREEN_MEDIA_ARTWORK;
@@ -36,7 +35,6 @@
 import android.media.session.MediaSessionManager;
 import android.media.session.PlaybackState;
 import android.os.AsyncTask;
-import android.os.SystemProperties;
 import android.os.Trace;
 import android.os.UserHandle;
 import android.provider.DeviceConfig;
@@ -80,7 +78,6 @@
 import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
-import java.util.concurrent.TimeUnit;
 
 import dagger.Lazy;
 
@@ -91,8 +88,6 @@
 public class NotificationMediaManager implements Dumpable {
     private static final String TAG = "NotificationMediaManager";
     public static final boolean DEBUG_MEDIA = false;
-    private static final long PAUSED_MEDIA_TIMEOUT = SystemProperties
-            .getLong("debug.sysui.media_timeout", TimeUnit.MINUTES.toMillis(10));
 
     private final StatusBarStateController mStatusBarStateController
             = Dependency.get(StatusBarStateController.class);
@@ -134,7 +129,6 @@
     private MediaController mMediaController;
     private String mMediaNotificationKey;
     private MediaMetadata mMediaMetadata;
-    private Runnable mMediaTimeoutCancellation;
 
     private BackDropView mBackdrop;
     private ImageView mBackdropFront;
@@ -164,47 +158,11 @@
             if (DEBUG_MEDIA) {
                 Log.v(TAG, "DEBUG_MEDIA: onPlaybackStateChanged: " + state);
             }
-            if (mMediaTimeoutCancellation != null) {
-                if (DEBUG_MEDIA) {
-                    Log.v(TAG, "DEBUG_MEDIA: media timeout cancelled");
-                }
-                mMediaTimeoutCancellation.run();
-                mMediaTimeoutCancellation = null;
-            }
             if (state != null) {
                 if (!isPlaybackActive(state.getState())) {
                     clearCurrentMediaNotification();
                 }
                 findAndUpdateMediaNotifications();
-                scheduleMediaTimeout(state);
-            }
-        }
-
-        private void scheduleMediaTimeout(PlaybackState state) {
-            final NotificationEntry entry;
-            synchronized (mEntryManager) {
-                entry = mEntryManager.getActiveNotificationUnfiltered(mMediaNotificationKey);
-            }
-            if (entry != null) {
-                if (!isPlayingState(state.getState())) {
-                    if (DEBUG_MEDIA) {
-                        Log.v(TAG, "DEBUG_MEDIA: schedule timeout for "
-                                + mMediaNotificationKey);
-                    }
-                    mMediaTimeoutCancellation = mMainExecutor.executeDelayed(() -> {
-                        synchronized (mEntryManager) {
-                            if (DEBUG_MEDIA) {
-                                Log.v(TAG, "DEBUG_MEDIA: execute timeout for "
-                                        + mMediaNotificationKey);
-                            }
-                            if (mMediaNotificationKey == null) {
-                                return;
-                            }
-                            mEntryManager.removeNotification(mMediaNotificationKey, null,
-                                    UNDEFINED_DISMISS_REASON);
-                        }
-                    }, PAUSED_MEDIA_TIMEOUT);
-                }
             }
         }
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/dump/LogBufferFreezerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/dump/LogBufferFreezerTest.kt
new file mode 100644
index 0000000..eb38073
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/dump/LogBufferFreezerTest.kt
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 2020 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 com.android.systemui.dump
+
+import android.content.BroadcastReceiver
+import android.content.IntentFilter
+import android.os.UserHandle
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.broadcast.BroadcastDispatcher
+import com.android.systemui.util.concurrency.FakeExecutor
+import com.android.systemui.util.mockito.any
+import com.android.systemui.util.mockito.capture
+import com.android.systemui.util.mockito.eq
+import com.android.systemui.util.time.FakeSystemClock
+import org.junit.Before
+import org.junit.Test
+import org.mockito.ArgumentCaptor
+import org.mockito.Captor
+import org.mockito.Mock
+import org.mockito.Mockito.never
+import org.mockito.Mockito.times
+import org.mockito.Mockito.verify
+import org.mockito.MockitoAnnotations
+
+@SmallTest
+class LogBufferFreezerTest : SysuiTestCase() {
+
+    lateinit var freezer: LogBufferFreezer
+    lateinit var receiver: BroadcastReceiver
+
+    @Mock
+    lateinit var dumpManager: DumpManager
+    @Mock
+    lateinit var broadcastDispatcher: BroadcastDispatcher
+    @Captor
+    lateinit var receiverCaptor: ArgumentCaptor<BroadcastReceiver>
+
+    val clock = FakeSystemClock()
+    val executor = FakeExecutor(clock)
+
+    @Before
+    fun setUp() {
+        MockitoAnnotations.initMocks(this)
+
+        freezer = LogBufferFreezer(dumpManager, executor, 500)
+
+        freezer.attach(broadcastDispatcher)
+
+        verify(broadcastDispatcher)
+                .registerReceiver(
+                        capture(receiverCaptor),
+                        any(IntentFilter::class.java),
+                        eq(executor),
+                        any(UserHandle::class.java))
+        receiver = receiverCaptor.value
+    }
+
+    @Test
+    fun testBuffersAreFrozenInResponseToBroadcast() {
+        // WHEN the bugreport intent is fired
+        receiver.onReceive(null, null)
+
+        // THEN the buffers are frozen
+        verify(dumpManager).freezeBuffers()
+    }
+
+    @Test
+    fun testBuffersAreUnfrozenAfterTimeout() {
+        // GIVEN that we've already frozen the buffers in response to a broadcast
+        receiver.onReceive(null, null)
+        verify(dumpManager).freezeBuffers()
+
+        // WHEN the timeout expires
+        clock.advanceTime(501)
+
+        // THEN the buffers are unfrozen
+        verify(dumpManager).unfreezeBuffers()
+    }
+
+    @Test
+    fun testBuffersAreNotPrematurelyUnfrozen() {
+        // GIVEN that we received a broadcast 499ms ago (shortly before the timeout would expire)
+        receiver.onReceive(null, null)
+        verify(dumpManager).freezeBuffers()
+        clock.advanceTime(499)
+
+        // WHEN we receive a second broadcast
+        receiver.onReceive(null, null)
+
+        // THEN the buffers are frozen a second time
+        verify(dumpManager, times(2)).freezeBuffers()
+
+        // THEN when we advance beyond the first timeout, nothing happens
+        clock.advanceTime(101)
+        verify(dumpManager, never()).unfreezeBuffers()
+
+        // THEN only when we advance past the reset timeout window are the buffers unfrozen
+        clock.advanceTime(401)
+        verify(dumpManager).unfreezeBuffers()
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataCombineLatestTest.java b/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataCombineLatestTest.java
index aa889a6..48e3b0a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataCombineLatestTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataCombineLatestTest.java
@@ -79,7 +79,7 @@
         mManager.addListener(mListener);
 
         mMediaData = new MediaData(true, BG_COLOR, APP, null, ARTIST, TITLE, null,
-                new ArrayList<>(), new ArrayList<>(), PACKAGE, null, null, null);
+                new ArrayList<>(), new ArrayList<>(), PACKAGE, null, null, null, KEY);
         mDeviceData = new MediaDeviceData(true, null, DEVICE_NAME);
     }
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/MediaTimeoutListenerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/MediaTimeoutListenerTest.kt
new file mode 100644
index 0000000..c21343c
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/MediaTimeoutListenerTest.kt
@@ -0,0 +1,130 @@
+/*
+ * Copyright (C) 2020 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 com.android.systemui.media
+
+import android.media.session.MediaController
+import android.media.session.PlaybackState
+import android.testing.AndroidTestingRunner
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.util.concurrency.DelayableExecutor
+import com.android.systemui.util.mockito.capture
+import com.google.common.truth.Truth.assertThat
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.ArgumentCaptor
+import org.mockito.ArgumentMatchers.any
+import org.mockito.ArgumentMatchers.anyLong
+import org.mockito.Captor
+import org.mockito.Mock
+import org.mockito.Mockito
+import org.mockito.Mockito.`when`
+import org.mockito.Mockito.clearInvocations
+import org.mockito.Mockito.never
+import org.mockito.Mockito.verify
+import org.mockito.junit.MockitoJUnit
+
+private const val KEY = "KEY"
+
+private fun <T> eq(value: T): T = Mockito.eq(value) ?: value
+private fun <T> anyObject(): T {
+    return Mockito.anyObject<T>()
+}
+
+@SmallTest
+@RunWith(AndroidTestingRunner::class)
+class MediaTimeoutListenerTest : SysuiTestCase() {
+
+    @Mock private lateinit var mediaControllerFactory: MediaControllerFactory
+    @Mock private lateinit var mediaController: MediaController
+    @Mock private lateinit var executor: DelayableExecutor
+    @Mock private lateinit var mediaData: MediaData
+    @Mock private lateinit var timeoutCallback: (String, Boolean) -> Unit
+    @Mock private lateinit var cancellationRunnable: Runnable
+    @Captor private lateinit var timeoutCaptor: ArgumentCaptor<Runnable>
+    @Captor private lateinit var mediaCallbackCaptor: ArgumentCaptor<MediaController.Callback>
+    @JvmField @Rule val mockito = MockitoJUnit.rule()
+    private lateinit var mediaTimeoutListener: MediaTimeoutListener
+
+    @Before
+    fun setup() {
+        `when`(mediaControllerFactory.create(any())).thenReturn(mediaController)
+        `when`(executor.executeDelayed(any(), anyLong())).thenReturn(cancellationRunnable)
+        mediaTimeoutListener = MediaTimeoutListener(mediaControllerFactory, executor)
+        mediaTimeoutListener.timeoutCallback = timeoutCallback
+    }
+
+    @Test
+    fun testOnMediaDataLoaded_registersPlaybackListener() {
+        mediaTimeoutListener.onMediaDataLoaded(KEY, mediaData)
+        verify(mediaController).registerCallback(capture(mediaCallbackCaptor))
+
+        // Ignores is same key
+        clearInvocations(mediaController)
+        mediaTimeoutListener.onMediaDataLoaded(KEY, mediaData)
+        verify(mediaController, never()).registerCallback(anyObject())
+    }
+
+    @Test
+    fun testOnMediaDataRemoved_unregistersPlaybackListener() {
+        mediaTimeoutListener.onMediaDataLoaded(KEY, mediaData)
+        mediaTimeoutListener.onMediaDataRemoved(KEY)
+        verify(mediaController).unregisterCallback(anyObject())
+
+        // Ignores duplicate requests
+        clearInvocations(mediaController)
+        mediaTimeoutListener.onMediaDataRemoved(KEY)
+        verify(mediaController, never()).unregisterCallback(anyObject())
+    }
+
+    @Test
+    fun testOnPlaybackStateChanged_schedulesTimeout_whenPaused() {
+        // Assuming we're registered
+        testOnMediaDataLoaded_registersPlaybackListener()
+
+        mediaCallbackCaptor.value.onPlaybackStateChanged(PlaybackState.Builder()
+                .setState(PlaybackState.STATE_PAUSED, 0L, 0f).build())
+        verify(executor).executeDelayed(capture(timeoutCaptor), anyLong())
+    }
+
+    @Test
+    fun testOnPlaybackStateChanged_cancelsTimeout_whenResumed() {
+        // Assuming we're have a pending timeout
+        testOnPlaybackStateChanged_schedulesTimeout_whenPaused()
+
+        mediaCallbackCaptor.value.onPlaybackStateChanged(PlaybackState.Builder()
+                .setState(PlaybackState.STATE_PLAYING, 0L, 0f).build())
+        verify(cancellationRunnable).run()
+    }
+
+    @Test
+    fun testTimeoutCallback_invokedIfTimeout() {
+        // Assuming we're have a pending timeout
+        testOnPlaybackStateChanged_schedulesTimeout_whenPaused()
+
+        timeoutCaptor.value.run()
+        verify(timeoutCallback).invoke(eq(KEY), eq(true))
+    }
+
+    @Test
+    fun testIsTimedOut() {
+        mediaTimeoutListener.onMediaDataLoaded(KEY, mediaData)
+        assertThat(mediaTimeoutListener.isTimedOut(KEY)).isFalse()
+    }
+}
\ No newline at end of file
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
index 22b082f..7f912a4 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -16,6 +16,7 @@
 
 package com.android.server.accessibility;
 
+import static android.provider.Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_NAVBAR_ENABLED;
 import static android.view.accessibility.AccessibilityManager.ACCESSIBILITY_BUTTON;
 import static android.view.accessibility.AccessibilityManager.ACCESSIBILITY_SHORTCUT_KEY;
 import static android.view.accessibility.AccessibilityManager.ShortcutType;
@@ -542,12 +543,56 @@
                                     intent.getStringExtra(Intent.EXTRA_SETTING_PREVIOUS_VALUE),
                                     intent.getStringExtra(Intent.EXTRA_SETTING_NEW_VALUE));
                         }
+                    } else if (ACCESSIBILITY_DISPLAY_MAGNIFICATION_NAVBAR_ENABLED.equals(which)) {
+                        synchronized (mLock) {
+                            restoreLegacyDisplayMagnificationNavBarIfNeededLocked(
+                                    intent.getStringExtra(Intent.EXTRA_SETTING_NEW_VALUE),
+                                    intent.getIntExtra(Intent.EXTRA_SETTING_RESTORED_FROM_SDK_INT,
+                                            0));
+                        }
                     }
                 }
             }
         }, UserHandle.ALL, intentFilter, null, null);
     }
 
+    // Called only during settings restore; currently supports only the owner user
+    // TODO: b/22388012
+    private void restoreLegacyDisplayMagnificationNavBarIfNeededLocked(String newSetting,
+            int restoreFromSdkInt) {
+        if (restoreFromSdkInt >= Build.VERSION_CODES.R) {
+            return;
+        }
+
+        boolean displayMagnificationNavBarEnabled;
+        try {
+            displayMagnificationNavBarEnabled = Integer.parseInt(newSetting) == 1;
+        } catch (NumberFormatException e) {
+            Slog.w(LOG_TAG, "number format is incorrect" + e);
+            return;
+        }
+
+        final AccessibilityUserState userState = getUserStateLocked(UserHandle.USER_SYSTEM);
+        final Set<String> targetsFromSetting = new ArraySet<>();
+        readColonDelimitedSettingToSet(Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS,
+                userState.mUserId, targetsFromSetting, str -> str);
+        final boolean targetsContainMagnification = targetsFromSetting.contains(
+                MAGNIFICATION_CONTROLLER_NAME);
+        if (targetsContainMagnification == displayMagnificationNavBarEnabled) {
+            return;
+        }
+
+        if (displayMagnificationNavBarEnabled) {
+            targetsFromSetting.add(MAGNIFICATION_CONTROLLER_NAME);
+        } else {
+            targetsFromSetting.remove(MAGNIFICATION_CONTROLLER_NAME);
+        }
+        persistColonDelimitedSetToSettingLocked(Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS,
+                userState.mUserId, targetsFromSetting, str -> str);
+        readAccessibilityButtonTargetsLocked(userState);
+        onUserStateChangedLocked(userState);
+    }
+
     @Override
     public long addClient(IAccessibilityManagerClient callback, int userId) {
         synchronized (mLock) {
diff --git a/services/core/java/com/android/server/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java
index ee0f71b..b5aec8e 100644
--- a/services/core/java/com/android/server/StorageManagerService.java
+++ b/services/core/java/com/android/server/StorageManagerService.java
@@ -376,6 +376,7 @@
     private class WatchedLockedUsers {
         private int[] users = EmptyArray.INT;
         public WatchedLockedUsers() {
+            invalidateIsUserUnlockedCache();
         }
         public void append(int userId) {
             users = ArrayUtils.appendInt(users, userId);
@@ -1134,6 +1135,8 @@
             Slog.wtf(TAG, e);
         }
 
+        onKeyguardStateChanged(false);
+
         mHandler.obtainMessage(H_COMPLETE_UNLOCK_USER, userId).sendToTarget();
     }
 
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index 5046070..c5c3caf 100644
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -2460,16 +2460,22 @@
                             && mAm.isValidSingletonCall(callingUid, sInfo.applicationInfo.uid)) {
                         userId = 0;
                         smap = getServiceMapLocked(0);
-                        ResolveInfo rInfoForUserId0 =
-                                mAm.getPackageManagerInternalLocked().resolveService(service,
-                                        resolvedType, flags, userId, callingUid);
-                        if (rInfoForUserId0 == null) {
-                            Slog.w(TAG_SERVICE,
-                                    "Unable to resolve service " + service + " U=" + userId
-                                            + ": not found");
-                            return null;
+                        // Bypass INTERACT_ACROSS_USERS permission check
+                        final long token = Binder.clearCallingIdentity();
+                        try {
+                            ResolveInfo rInfoForUserId0 =
+                                    mAm.getPackageManagerInternalLocked().resolveService(service,
+                                            resolvedType, flags, userId, callingUid);
+                            if (rInfoForUserId0 == null) {
+                                Slog.w(TAG_SERVICE,
+                                        "Unable to resolve service " + service + " U=" + userId
+                                                + ": not found");
+                                return null;
+                            }
+                            sInfo = rInfoForUserId0.serviceInfo;
+                        } finally {
+                            Binder.restoreCallingIdentity(token);
                         }
-                        sInfo = rInfoForUserId0.serviceInfo;
                     }
                     sInfo = new ServiceInfo(sInfo);
                     sInfo.applicationInfo = mAm.getAppInfoForUser(sInfo.applicationInfo, userId);
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index a4e45cd..caaa837 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -18900,30 +18900,8 @@
         @Override
         public int checkContentProviderUriPermission(Uri uri, int userId,
                 int callingUid, int modeFlags) {
-            // We can find ourselves needing to check Uri permissions while
-            // already holding the WM lock, which means reaching back here for
-            // the AM lock would cause an inversion. The WM team has requested
-            // that we use the strategy below instead of shifting where Uri
-            // grants are calculated.
-
-            // Since we could also arrive here while holding the AM lock, we
-            // can't always delegate the call through the handler, and we need
-            // to delicately dance between the deadlocks.
-            if (Thread.currentThread().holdsLock(ActivityManagerService.this)) {
-                return ActivityManagerService.this.checkContentProviderUriPermission(uri,
-                        userId, callingUid, modeFlags);
-            } else {
-                final CompletableFuture<Integer> res = new CompletableFuture<>();
-                mHandler.post(() -> {
-                    res.complete(ActivityManagerService.this.checkContentProviderUriPermission(uri,
-                            userId, callingUid, modeFlags));
-                });
-                try {
-                    return res.get();
-                } catch (InterruptedException | ExecutionException e) {
-                    throw new RuntimeException(e);
-                }
-            }
+            return ActivityManagerService.this.checkContentProviderUriPermission(uri,
+                    userId, callingUid, modeFlags);
         }
 
         @Override
diff --git a/services/core/java/com/android/server/biometrics/AuthService.java b/services/core/java/com/android/server/biometrics/AuthService.java
index a0876c0..061972c 100644
--- a/services/core/java/com/android/server/biometrics/AuthService.java
+++ b/services/core/java/com/android/server/biometrics/AuthService.java
@@ -290,9 +290,10 @@
             // The permission check should be restored once Android Keystore no longer invokes this
             // method from inside app processes.
 
+            final int callingUserId = UserHandle.getCallingUserId();
             final long identity = Binder.clearCallingIdentity();
             try {
-                return mBiometricService.getAuthenticatorIds();
+                return mBiometricService.getAuthenticatorIds(callingUserId);
             } finally {
                 Binder.restoreCallingIdentity(identity);
             }
diff --git a/services/core/java/com/android/server/biometrics/BiometricService.java b/services/core/java/com/android/server/biometrics/BiometricService.java
index 4ddfe1b..540c6ff 100644
--- a/services/core/java/com/android/server/biometrics/BiometricService.java
+++ b/services/core/java/com/android/server/biometrics/BiometricService.java
@@ -879,13 +879,13 @@
         }
 
         @Override // Binder call
-        public long[] getAuthenticatorIds() {
+        public long[] getAuthenticatorIds(int callingUserId) {
             checkInternalPermission();
 
             final List<Long> ids = new ArrayList<>();
             for (AuthenticatorWrapper authenticator : mAuthenticators) {
                 try {
-                    final long id = authenticator.impl.getAuthenticatorId();
+                    final long id = authenticator.impl.getAuthenticatorId(callingUserId);
                     if (Utils.isAtLeastStrength(authenticator.getActualStrength(),
                             Authenticators.BIOMETRIC_STRONG) && id != 0) {
                         ids.add(id);
diff --git a/services/core/java/com/android/server/biometrics/BiometricServiceBase.java b/services/core/java/com/android/server/biometrics/BiometricServiceBase.java
index 5a6ab4e5..75452ea 100644
--- a/services/core/java/com/android/server/biometrics/BiometricServiceBase.java
+++ b/services/core/java/com/android/server/biometrics/BiometricServiceBase.java
@@ -1250,9 +1250,8 @@
     /***
      * @return authenticator id for the calling user
      */
-    protected long getAuthenticatorId() {
-        final int userId = getUserOrWorkProfileId(null /* clientPackage */,
-                UserHandle.getCallingUserId());
+    protected long getAuthenticatorId(int callingUserId) {
+        final int userId = getUserOrWorkProfileId(null /* clientPackage */, callingUserId);
         return mAuthenticatorIds.getOrDefault(userId, 0L);
     }
 
diff --git a/services/core/java/com/android/server/biometrics/face/FaceAuthenticator.java b/services/core/java/com/android/server/biometrics/face/FaceAuthenticator.java
index 9d8fcc3..405c54e 100644
--- a/services/core/java/com/android/server/biometrics/face/FaceAuthenticator.java
+++ b/services/core/java/com/android/server/biometrics/face/FaceAuthenticator.java
@@ -74,7 +74,7 @@
     }
 
     @Override
-    public long getAuthenticatorId() throws RemoteException {
-        return mFaceService.getAuthenticatorId();
+    public long getAuthenticatorId(int callingUserId) throws RemoteException {
+        return mFaceService.getAuthenticatorId(callingUserId);
     }
 }
diff --git a/services/core/java/com/android/server/biometrics/face/FaceService.java b/services/core/java/com/android/server/biometrics/face/FaceService.java
index ad73b64..72e1bbb 100644
--- a/services/core/java/com/android/server/biometrics/face/FaceService.java
+++ b/services/core/java/com/android/server/biometrics/face/FaceService.java
@@ -608,9 +608,9 @@
         }
 
         @Override // Binder call
-        public long getAuthenticatorId() {
+        public long getAuthenticatorId(int callingUserId) {
             checkPermission(USE_BIOMETRIC_INTERNAL);
-            return FaceService.this.getAuthenticatorId();
+            return FaceService.this.getAuthenticatorId(callingUserId);
         }
 
         @Override // Binder call
diff --git a/services/core/java/com/android/server/biometrics/fingerprint/FingerprintAuthenticator.java b/services/core/java/com/android/server/biometrics/fingerprint/FingerprintAuthenticator.java
index 4604752..61ddada 100644
--- a/services/core/java/com/android/server/biometrics/fingerprint/FingerprintAuthenticator.java
+++ b/services/core/java/com/android/server/biometrics/fingerprint/FingerprintAuthenticator.java
@@ -74,7 +74,7 @@
     }
 
     @Override
-    public long getAuthenticatorId() throws RemoteException {
-        return mFingerprintService.getAuthenticatorId();
+    public long getAuthenticatorId(int callingUserId) throws RemoteException {
+        return mFingerprintService.getAuthenticatorId(callingUserId);
     }
 }
diff --git a/services/core/java/com/android/server/biometrics/fingerprint/FingerprintService.java b/services/core/java/com/android/server/biometrics/fingerprint/FingerprintService.java
index d90f3af..6b7ba6a 100644
--- a/services/core/java/com/android/server/biometrics/fingerprint/FingerprintService.java
+++ b/services/core/java/com/android/server/biometrics/fingerprint/FingerprintService.java
@@ -412,9 +412,9 @@
         }
 
         @Override // Binder call
-        public long getAuthenticatorId() {
+        public long getAuthenticatorId(int callingUserId) {
             checkPermission(USE_BIOMETRIC_INTERNAL);
-            return FingerprintService.this.getAuthenticatorId();
+            return FingerprintService.this.getAuthenticatorId(callingUserId);
         }
 
         @Override // Binder call
diff --git a/services/core/java/com/android/server/biometrics/iris/IrisAuthenticator.java b/services/core/java/com/android/server/biometrics/iris/IrisAuthenticator.java
index 6789a12..03818ed 100644
--- a/services/core/java/com/android/server/biometrics/iris/IrisAuthenticator.java
+++ b/services/core/java/com/android/server/biometrics/iris/IrisAuthenticator.java
@@ -67,7 +67,7 @@
     }
 
     @Override
-    public long getAuthenticatorId() throws RemoteException {
+    public long getAuthenticatorId(int callingUserId) throws RemoteException {
         return 0;
     }
 }
diff --git a/services/core/java/com/android/server/integrity/AppIntegrityManagerServiceImpl.java b/services/core/java/com/android/server/integrity/AppIntegrityManagerServiceImpl.java
index 3d4efe6..817902d 100644
--- a/services/core/java/com/android/server/integrity/AppIntegrityManagerServiceImpl.java
+++ b/services/core/java/com/android/server/integrity/AppIntegrityManagerServiceImpl.java
@@ -182,7 +182,7 @@
                 },
                 integrityVerificationFilter,
                 /* broadcastPermission= */ null,
-                /* scheduler= */ null);
+                mHandler);
     }
 
     @Override
diff --git a/services/core/java/com/android/server/notification/BubbleExtractor.java b/services/core/java/com/android/server/notification/BubbleExtractor.java
index 0fa339f..fd92c4c 100644
--- a/services/core/java/com/android/server/notification/BubbleExtractor.java
+++ b/services/core/java/com/android/server/notification/BubbleExtractor.java
@@ -78,6 +78,7 @@
         boolean canPresentAsBubble = canPresentAsBubble(record)
                 && !mActivityManager.isLowRamDevice()
                 && record.isConversation()
+                && record.getShortcutInfo() != null
                 && (record.getNotification().flags & FLAG_FOREGROUND_SERVICE) == 0;
 
         if (!mConfig.bubblesEnabled()
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 6ae58ec..9d3385f 100755
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -1952,7 +1952,8 @@
                 mRankingHandler,
                 mZenModeHelper,
                 new NotificationChannelLoggerImpl(),
-                mAppOps);
+                mAppOps,
+                new SysUiStatsEvent.BuilderFactory());
         mRankingHelper = new RankingHelper(getContext(),
                 mRankingHandler,
                 mPreferencesHelper,
@@ -6802,9 +6803,13 @@
         boolean hasValidVibrate = false;
         boolean hasValidSound = false;
         boolean sentAccessibilityEvent = false;
-        // If the notification will appear in the status bar, it should send an accessibility
-        // event
-        if (!record.isUpdate && record.getImportance() > IMPORTANCE_MIN) {
+
+        // If the notification will appear in the status bar, it should send an accessibility event
+        final boolean suppressedByDnd = record.isIntercepted()
+                && (record.getSuppressedVisualEffects() & SUPPRESSED_EFFECT_STATUS_BAR) != 0;
+        if (!record.isUpdate
+                && record.getImportance() > IMPORTANCE_MIN
+                && !suppressedByDnd) {
             sendAccessibilityEvent(notification, record.getSbn().getPackageName());
             sentAccessibilityEvent = true;
         }
diff --git a/services/core/java/com/android/server/notification/PreferencesHelper.java b/services/core/java/com/android/server/notification/PreferencesHelper.java
index 77b030f..e472e30 100644
--- a/services/core/java/com/android/server/notification/PreferencesHelper.java
+++ b/services/core/java/com/android/server/notification/PreferencesHelper.java
@@ -140,6 +140,7 @@
      * fields.
      */
     private static final int DEFAULT_LOCKED_APP_FIELDS = 0;
+    private final SysUiStatsEvent.BuilderFactory mStatsEventBuilderFactory;
 
     /**
      * All user-lockable fields for a given application.
@@ -171,13 +172,15 @@
 
     public PreferencesHelper(Context context, PackageManager pm, RankingHandler rankingHandler,
             ZenModeHelper zenHelper, NotificationChannelLogger notificationChannelLogger,
-            AppOpsManager appOpsManager) {
+            AppOpsManager appOpsManager,
+            SysUiStatsEvent.BuilderFactory statsEventBuilderFactory) {
         mContext = context;
         mZenModeHelper = zenHelper;
         mRankingHandler = rankingHandler;
         mPm = pm;
         mNotificationChannelLogger = notificationChannelLogger;
         mAppOps = appOpsManager;
+        mStatsEventBuilderFactory = statsEventBuilderFactory;
 
         updateBadgingEnabled();
         updateBubblesEnabled();
@@ -1898,7 +1901,7 @@
                 if (i > NOTIFICATION_PREFERENCES_PULL_LIMIT) {
                     break;
                 }
-                StatsEvent.Builder event = StatsEvent.newBuilder()
+                SysUiStatsEvent.Builder event = mStatsEventBuilderFactory.newBuilder()
                         .setAtomId(PACKAGE_NOTIFICATION_PREFERENCES);
                 final PackagePreferences r = mPackagePreferences.valueAt(i);
                 event.writeInt(r.uid);
@@ -1927,7 +1930,7 @@
                     if (++totalChannelsPulled > NOTIFICATION_CHANNEL_PULL_LIMIT) {
                         break;
                     }
-                    StatsEvent.Builder event = StatsEvent.newBuilder()
+                    SysUiStatsEvent.Builder event = mStatsEventBuilderFactory.newBuilder()
                             .setAtomId(PACKAGE_NOTIFICATION_CHANNEL_PREFERENCES);
                     event.writeInt(r.uid);
                     event.addBooleanAnnotation(ANNOTATION_ID_IS_UID, true);
@@ -1962,7 +1965,7 @@
                     if (++totalGroupsPulled > NOTIFICATION_CHANNEL_GROUP_PULL_LIMIT) {
                         break;
                     }
-                    StatsEvent.Builder event = StatsEvent.newBuilder()
+                    SysUiStatsEvent.Builder event = mStatsEventBuilderFactory.newBuilder()
                             .setAtomId(PACKAGE_NOTIFICATION_CHANNEL_GROUP_PREFERENCES);
                     event.writeInt(r.uid);
                     event.addBooleanAnnotation(ANNOTATION_ID_IS_UID, true);
diff --git a/services/core/java/com/android/server/notification/SysUiStatsEvent.java b/services/core/java/com/android/server/notification/SysUiStatsEvent.java
new file mode 100644
index 0000000..9bc2346
--- /dev/null
+++ b/services/core/java/com/android/server/notification/SysUiStatsEvent.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2020 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 com.android.server.notification;
+
+import android.util.StatsEvent;
+
+/**
+ * Wrapper for StatsEvent that enables unit testing.
+ */
+public class SysUiStatsEvent {
+
+    static class Builder {
+        private final StatsEvent.Builder mBuilder;
+
+        protected Builder(StatsEvent.Builder builder) {
+            mBuilder = builder;
+        }
+
+        public StatsEvent build() {
+            return mBuilder.build();
+        }
+
+        public Builder setAtomId(int atomId) {
+            mBuilder.setAtomId(atomId);
+            return this;
+        }
+
+        public Builder writeInt(int value) {
+            mBuilder.writeInt(value);
+            return this;
+        }
+
+        public Builder addBooleanAnnotation(byte annotation, boolean value) {
+            mBuilder.addBooleanAnnotation(annotation, value);
+            return this;
+        }
+
+        public Builder writeString(String value) {
+            mBuilder.writeString(value);
+            return this;
+        }
+
+        public Builder writeBoolean(boolean value) {
+            mBuilder.writeBoolean(value);
+            return this;
+        }
+    }
+
+    static class BuilderFactory {
+        Builder newBuilder() {
+            return new Builder(StatsEvent.newBuilder());
+        }
+    }
+}
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index b0e3ecb..d5c9424 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -491,6 +491,7 @@
         final SparseIntArray states;
         public WatchedUserStates() {
             states = new SparseIntArray();
+            invalidateIsUserUnlockedCache();
         }
         public int get(int userId) {
             return states.get(userId);
diff --git a/services/core/java/com/android/server/textclassifier/TextClassificationManagerService.java b/services/core/java/com/android/server/textclassifier/TextClassificationManagerService.java
index e675f4e..cd65c6c 100644
--- a/services/core/java/com/android/server/textclassifier/TextClassificationManagerService.java
+++ b/services/core/java/com/android/server/textclassifier/TextClassificationManagerService.java
@@ -74,7 +74,6 @@
 import java.util.Map;
 import java.util.Objects;
 import java.util.Queue;
-import java.util.stream.Collectors;
 
 /**
  * A manager for TextClassifier services.
@@ -1047,18 +1046,26 @@
         private static void rewriteTextClassificationIcons(Bundle result) {
             final TextClassification classification = TextClassifierService.getResponse(result);
             boolean rewrite = false;
-            for (RemoteAction action : classification.getActions()) {
-                rewrite |= shouldRewriteIcon(action);
+            final List<RemoteAction> actions = classification.getActions();
+            final int size = actions.size();
+            final List<RemoteAction> validActions = new ArrayList<>(size);
+            for (int i = 0; i < size; i++) {
+                final RemoteAction action = actions.get(i);
+                final RemoteAction validAction;
+                if (shouldRewriteIcon(action)) {
+                    rewrite = true;
+                    validAction = validAction(action);
+                } else {
+                    validAction = action;
+                }
+                validActions.add(validAction);
             }
             if (rewrite) {
                 TextClassifierService.putResponse(
                         result,
                         classification.toBuilder()
                                 .clearActions()
-                                .addActions(classification.getActions()
-                                        .stream()
-                                        .map(action -> validAction(action))
-                                        .collect(Collectors.toList()))
+                                .addActions(validActions)
                                 .build());
             }
         }
@@ -1066,29 +1073,30 @@
         private static void rewriteConversationActionsIcons(Bundle result) {
             final ConversationActions convActions = TextClassifierService.getResponse(result);
             boolean rewrite = false;
-            for (ConversationAction convAction : convActions.getConversationActions()) {
-                rewrite |= shouldRewriteIcon(convAction.getAction());
+            final List<ConversationAction> origConvActions = convActions.getConversationActions();
+            final int size = origConvActions.size();
+            final List<ConversationAction> validConvActions = new ArrayList<>(size);
+            for (int i = 0; i < size; i++) {
+                final ConversationAction convAction = origConvActions.get(i);
+                final ConversationAction validConvAction;
+                if (shouldRewriteIcon(convAction.getAction())) {
+                    rewrite = true;
+                    validConvAction = convAction.toBuilder()
+                            .setAction(validAction(convAction.getAction()))
+                            .build();
+                } else {
+                    validConvAction = convAction;
+                }
+                validConvActions.add(validConvAction);
             }
             if (rewrite) {
                 TextClassifierService.putResponse(
                         result,
-                        new ConversationActions(
-                                convActions.getConversationActions()
-                                        .stream()
-                                        .map(convAction -> convAction.toBuilder()
-                                                .setAction(validAction(convAction.getAction()))
-                                                .build())
-                                        .collect(Collectors.toList()),
-                                convActions.getId()));
+                        new ConversationActions(validConvActions, convActions.getId()));
             }
         }
 
-        @Nullable
-        private static RemoteAction validAction(@Nullable RemoteAction action) {
-            if (!shouldRewriteIcon(action)) {
-                return action;
-            }
-
+        private static RemoteAction validAction(RemoteAction action) {
             final RemoteAction newAction = new RemoteAction(
                     changeIcon(action.getIcon()),
                     action.getTitle(),
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index 7c33c7c..fe2b144 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -1001,6 +1001,9 @@
             if (info.minAspectRatio != 0) {
                 pw.println(prefix + "minAspectRatio=" + info.minAspectRatio);
             }
+            if (info.supportsSizeChanges) {
+                pw.println(prefix + "supportsSizeChanges=true");
+            }
         }
     }
 
@@ -6376,6 +6379,9 @@
      *         aspect ratio.
      */
     boolean shouldUseSizeCompatMode() {
+        if (info.supportsSizeChanges) {
+            return false;
+        }
         if (inMultiWindowMode() || getWindowConfiguration().hasWindowDecorCaption()) {
             final ActivityRecord root = task != null ? task.getRootActivity() : null;
             if (root != null && root != this && !root.shouldUseSizeCompatMode()) {
diff --git a/services/incremental/IncrementalService.cpp b/services/incremental/IncrementalService.cpp
index 2fcb005..885f4d2 100644
--- a/services/incremental/IncrementalService.cpp
+++ b/services/incremental/IncrementalService.cpp
@@ -268,22 +268,14 @@
         mAppOpsManager(sm.getAppOpsManager()),
         mJni(sm.getJni()),
         mLooper(sm.getLooper()),
+        mTimedQueue(sm.getTimedQueue()),
         mIncrementalDir(rootDir) {
-    if (!mVold) {
-        LOG(FATAL) << "Vold service is unavailable";
-    }
-    if (!mDataLoaderManager) {
-        LOG(FATAL) << "DataLoaderManagerService is unavailable";
-    }
-    if (!mAppOpsManager) {
-        LOG(FATAL) << "AppOpsManager is unavailable";
-    }
-    if (!mJni) {
-        LOG(FATAL) << "JNI is unavailable";
-    }
-    if (!mLooper) {
-        LOG(FATAL) << "Looper is unavailable";
-    }
+    CHECK(mVold) << "Vold service is unavailable";
+    CHECK(mDataLoaderManager) << "DataLoaderManagerService is unavailable";
+    CHECK(mAppOpsManager) << "AppOpsManager is unavailable";
+    CHECK(mJni) << "JNI is unavailable";
+    CHECK(mLooper) << "Looper is unavailable";
+    CHECK(mTimedQueue) << "TimedQueue is unavailable";
 
     mJobQueue.reserve(16);
     mJobProcessor = std::thread([this]() {
@@ -294,10 +286,6 @@
         mJni->initializeForCurrentThread();
         runCmdLooper();
     });
-    mTimerThread = std::thread([this]() {
-        mJni->initializeForCurrentThread();
-        runTimers();
-    });
 
     const auto mountedRootNames = adoptMountedInstances();
     mountExistingImages(mountedRootNames);
@@ -310,10 +298,8 @@
     }
     mJobCondition.notify_all();
     mJobProcessor.join();
-    mTimerCondition.notify_all();
-    mTimerThread.join();
     mCmdLooperThread.join();
-    mTimedJobs.clear();
+    mTimedQueue->stop();
     // Ensure that mounts are destroyed while the service is still valid.
     mBindsByPath.clear();
     mMounts.clear();
@@ -1710,53 +1696,18 @@
     }
 }
 
-void IncrementalService::addTimedJob(MountId id, TimePoint when, Job what) {
+void IncrementalService::addTimedJob(MountId id, Milliseconds after, Job what) {
     if (id == kInvalidStorageId) {
         return;
     }
-    {
-        std::unique_lock lock(mTimerMutex);
-        mTimedJobs.insert(TimedJob{id, when, std::move(what)});
-    }
-    mTimerCondition.notify_all();
+    mTimedQueue->addJob(id, after, std::move(what));
 }
 
 void IncrementalService::removeTimedJobs(MountId id) {
     if (id == kInvalidStorageId) {
         return;
     }
-    {
-        std::unique_lock lock(mTimerMutex);
-        std::erase_if(mTimedJobs, [id](auto&& item) { return item.id == id; });
-    }
-}
-
-void IncrementalService::runTimers() {
-    static constexpr TimePoint kInfinityTs{Clock::duration::max()};
-    TimePoint nextTaskTs = kInfinityTs;
-    for (;;) {
-        std::unique_lock lock(mTimerMutex);
-        mTimerCondition.wait_until(lock, nextTaskTs, [this]() {
-            auto now = Clock::now();
-            return !mRunning || (!mTimedJobs.empty() && mTimedJobs.begin()->when <= now);
-        });
-        if (!mRunning) {
-            return;
-        }
-
-        auto now = Clock::now();
-        auto it = mTimedJobs.begin();
-        // Always acquire begin(). We can't use it after unlock as mTimedJobs can change.
-        for (; it != mTimedJobs.end() && it->when <= now; it = mTimedJobs.begin()) {
-            auto job = it->what;
-            mTimedJobs.erase(it);
-
-            lock.unlock();
-            job();
-            lock.lock();
-        }
-        nextTaskTs = it != mTimedJobs.end() ? it->when : kInfinityTs;
-    }
+    mTimedQueue->removeJobs(id);
 }
 
 IncrementalService::DataLoaderStub::DataLoaderStub(IncrementalService& service, MountId id,
@@ -2029,8 +1980,8 @@
             mHealthBase = {now, kernelTsUs};
         }
 
-        if (kernelTsUs == kMaxBootClockTsUs || mHealthBase.userTs > now ||
-            mHealthBase.kernelTsUs > kernelTsUs) {
+        if (kernelTsUs == kMaxBootClockTsUs || mHealthBase.kernelTsUs == kMaxBootClockTsUs ||
+            mHealthBase.userTs > now) {
             LOG(DEBUG) << id() << ": No pending reads or invalid base, report Ok and wait.";
             registerForPendingReads();
             healthStatusToReport = IStorageHealthListener::HEALTH_STATUS_OK;
@@ -2056,6 +2007,9 @@
             return;
         }
 
+        // Don't schedule timer job less than 500ms in advance.
+        static constexpr auto kTolerance = 500ms;
+
         const auto blockedTimeout = std::chrono::milliseconds(mHealthCheckParams.blockedTimeoutMs);
         const auto unhealthyTimeout =
                 std::chrono::milliseconds(mHealthCheckParams.unhealthyTimeoutMs);
@@ -2065,31 +2019,28 @@
 
         const auto kernelDeltaUs = kernelTsUs - mHealthBase.kernelTsUs;
         const auto userTs = mHealthBase.userTs + std::chrono::microseconds(kernelDeltaUs);
-        const auto delta = now - userTs;
+        const auto delta = std::chrono::duration_cast<std::chrono::milliseconds>(now - userTs);
 
-        TimePoint whenToCheckBack;
-        if (delta < blockedTimeout) {
+        Milliseconds checkBackAfter;
+        if (delta + kTolerance < blockedTimeout) {
             LOG(DEBUG) << id() << ": Report reads pending and wait for blocked status.";
-            whenToCheckBack = userTs + blockedTimeout;
+            checkBackAfter = blockedTimeout - delta;
             healthStatusToReport = IStorageHealthListener::HEALTH_STATUS_READS_PENDING;
-        } else if (delta < unhealthyTimeout) {
+        } else if (delta + kTolerance < unhealthyTimeout) {
             LOG(DEBUG) << id() << ": Report blocked and wait for unhealthy.";
-            whenToCheckBack = userTs + unhealthyTimeout;
+            checkBackAfter = unhealthyTimeout - delta;
             healthStatusToReport = IStorageHealthListener::HEALTH_STATUS_BLOCKED;
         } else {
             LOG(DEBUG) << id() << ": Report unhealthy and continue monitoring.";
-            whenToCheckBack = now + unhealthyMonitoring;
+            checkBackAfter = unhealthyMonitoring;
             healthStatusToReport = IStorageHealthListener::HEALTH_STATUS_UNHEALTHY;
         }
-        LOG(DEBUG) << id() << ": updateHealthStatus in "
-                   << double(std::chrono::duration_cast<std::chrono::milliseconds>(whenToCheckBack -
-                                                                                   now)
-                                     .count()) /
-                        1000.0
+        LOG(DEBUG) << id() << ": updateHealthStatus in " << double(checkBackAfter.count()) / 1000.0
                    << "secs";
-        mService.addTimedJob(id(), whenToCheckBack, [this]() { updateHealthStatus(); });
+        mService.addTimedJob(id(), checkBackAfter, [this]() { updateHealthStatus(); });
     }
 
+    // With kTolerance we are expecting these to execute before the next update.
     if (healthStatusToReport != -1) {
         onHealthStatus(healthListener, healthStatusToReport);
     }
@@ -2178,6 +2129,16 @@
     dprintf(fd, "      targetStatus: %d\n", mTargetStatus);
     dprintf(fd, "      targetStatusTs: %lldmcs\n",
             (long long)(elapsedMcs(mTargetStatusTs, Clock::now())));
+    dprintf(fd, "      health: {\n");
+    dprintf(fd, "        path: %s\n", mHealthPath.c_str());
+    dprintf(fd, "        base: %lldmcs (%lld)\n",
+            (long long)(elapsedMcs(mHealthBase.userTs, Clock::now())),
+            (long long)mHealthBase.kernelTsUs);
+    dprintf(fd, "        blockedTimeoutMs: %d\n", int(mHealthCheckParams.blockedTimeoutMs));
+    dprintf(fd, "        unhealthyTimeoutMs: %d\n", int(mHealthCheckParams.unhealthyTimeoutMs));
+    dprintf(fd, "        unhealthyMonitoringMs: %d\n",
+            int(mHealthCheckParams.unhealthyMonitoringMs));
+    dprintf(fd, "      }\n");
     const auto& params = mParams;
     dprintf(fd, "      dataLoaderParams: {\n");
     dprintf(fd, "        type: %s\n", toString(params.type).c_str());
diff --git a/services/incremental/IncrementalService.h b/services/incremental/IncrementalService.h
index 57e4669..918531b 100644
--- a/services/incremental/IncrementalService.h
+++ b/services/incremental/IncrementalService.h
@@ -56,8 +56,6 @@
 using FileId = incfs::FileId;
 using BlockIndex = incfs::BlockIndex;
 using RawMetadata = incfs::RawMetadata;
-using Clock = std::chrono::steady_clock;
-using TimePoint = std::chrono::time_point<Clock>;
 using Seconds = std::chrono::seconds;
 using BootClockTsUs = uint64_t;
 
@@ -338,8 +336,6 @@
     bool unregisterAppOpsCallback(const std::string& packageName);
     void onAppOpChanged(const std::string& packageName);
 
-    using Job = std::function<void()>;
-
     void runJobProcessing();
     void extractZipFile(const IfsMountPtr& ifs, ZipArchiveHandle zipFile, ZipEntry& entry,
                         const incfs::FileId& libFileId, std::string_view targetLibPath,
@@ -347,9 +343,8 @@
 
     void runCmdLooper();
 
-    void addTimedJob(MountId id, TimePoint when, Job what);
+    void addTimedJob(MountId id, Milliseconds after, Job what);
     void removeTimedJobs(MountId id);
-    void runTimers();
 
 private:
     const std::unique_ptr<VoldServiceWrapper> mVold;
@@ -358,6 +353,7 @@
     const std::unique_ptr<AppOpsManagerWrapper> mAppOpsManager;
     const std::unique_ptr<JniWrapper> mJni;
     const std::unique_ptr<LooperWrapper> mLooper;
+    const std::unique_ptr<TimedQueueWrapper> mTimedQueue;
     const std::string mIncrementalDir;
 
     mutable std::mutex mLock;
@@ -380,19 +376,6 @@
     std::thread mJobProcessor;
 
     std::thread mCmdLooperThread;
-
-    struct TimedJob {
-        MountId id;
-        TimePoint when;
-        Job what;
-        friend bool operator<(const TimedJob& lhs, const TimedJob& rhs) {
-            return lhs.when < rhs.when;
-        }
-    };
-    std::set<TimedJob> mTimedJobs;
-    std::condition_variable mTimerCondition;
-    std::mutex mTimerMutex;
-    std::thread mTimerThread;
 };
 
 } // namespace android::incremental
diff --git a/services/incremental/ServiceWrappers.cpp b/services/incremental/ServiceWrappers.cpp
index a76aa62..99a35ad 100644
--- a/services/incremental/ServiceWrappers.cpp
+++ b/services/incremental/ServiceWrappers.cpp
@@ -25,6 +25,8 @@
 #include <binder/AppOpsManager.h>
 #include <utils/String16.h>
 
+#include <thread>
+
 #include "IncrementalServiceValidation.h"
 
 using namespace std::literals;
@@ -181,6 +183,88 @@
     }
 };
 
+static JNIEnv* getOrAttachJniEnv(JavaVM* jvm);
+
+class RealTimedQueueWrapper : public TimedQueueWrapper {
+public:
+    RealTimedQueueWrapper(JavaVM* jvm) {
+        mThread = std::thread([this, jvm]() {
+            (void)getOrAttachJniEnv(jvm);
+            runTimers();
+        });
+    }
+    ~RealTimedQueueWrapper() final {
+        CHECK(!mRunning) << "call stop first";
+        CHECK(!mThread.joinable()) << "call stop first";
+    }
+
+    void addJob(MountId id, Milliseconds after, Job what) final {
+        const auto now = Clock::now();
+        {
+            std::unique_lock lock(mMutex);
+            mJobs.insert(TimedJob{id, now + after, std::move(what)});
+        }
+        mCondition.notify_all();
+    }
+    void removeJobs(MountId id) final {
+        std::unique_lock lock(mMutex);
+        std::erase_if(mJobs, [id](auto&& item) { return item.id == id; });
+    }
+    void stop() final {
+        {
+            std::unique_lock lock(mMutex);
+            mRunning = false;
+        }
+        mCondition.notify_all();
+        mThread.join();
+        mJobs.clear();
+    }
+
+private:
+    void runTimers() {
+        static constexpr TimePoint kInfinityTs{Clock::duration::max()};
+        TimePoint nextJobTs = kInfinityTs;
+        std::unique_lock lock(mMutex);
+        for (;;) {
+            mCondition.wait_until(lock, nextJobTs, [this, nextJobTs]() {
+                const auto now = Clock::now();
+                const auto firstJobTs = !mJobs.empty() ? mJobs.begin()->when : kInfinityTs;
+                return !mRunning || firstJobTs <= now || firstJobTs < nextJobTs;
+            });
+            if (!mRunning) {
+                return;
+            }
+
+            const auto now = Clock::now();
+            auto it = mJobs.begin();
+            // Always acquire begin(). We can't use it after unlock as mTimedJobs can change.
+            for (; it != mJobs.end() && it->when <= now; it = mJobs.begin()) {
+                auto job = std::move(it->what);
+                mJobs.erase(it);
+
+                lock.unlock();
+                job();
+                lock.lock();
+            }
+            nextJobTs = it != mJobs.end() ? it->when : kInfinityTs;
+        }
+    }
+
+    struct TimedJob {
+        MountId id;
+        TimePoint when;
+        Job what;
+        friend bool operator<(const TimedJob& lhs, const TimedJob& rhs) {
+            return lhs.when < rhs.when;
+        }
+    };
+    bool mRunning = true;
+    std::set<TimedJob> mJobs;
+    std::condition_variable mCondition;
+    std::mutex mMutex;
+    std::thread mThread;
+};
+
 RealServiceManager::RealServiceManager(sp<IServiceManager> serviceManager, JNIEnv* env)
       : mServiceManager(std::move(serviceManager)), mJvm(RealJniWrapper::getJvm(env)) {}
 
@@ -228,6 +312,10 @@
     return std::make_unique<RealLooperWrapper>();
 }
 
+std::unique_ptr<TimedQueueWrapper> RealServiceManager::getTimedQueue() {
+    return std::make_unique<RealTimedQueueWrapper>(mJvm);
+}
+
 static JavaVM* getJavaVm(JNIEnv* env) {
     CHECK(env);
     JavaVM* jvm = nullptr;
diff --git a/services/incremental/ServiceWrappers.h b/services/incremental/ServiceWrappers.h
index a935ab9..8cd726fd 100644
--- a/services/incremental/ServiceWrappers.h
+++ b/services/incremental/ServiceWrappers.h
@@ -35,6 +35,11 @@
 
 namespace android::incremental {
 
+using Clock = std::chrono::steady_clock;
+using TimePoint = std::chrono::time_point<Clock>;
+using Milliseconds = std::chrono::milliseconds;
+using Job = std::function<void()>;
+
 // --- Wrapper interfaces ---
 
 using MountId = int32_t;
@@ -121,6 +126,14 @@
     virtual int pollAll(int timeoutMillis) = 0;
 };
 
+class TimedQueueWrapper {
+public:
+    virtual ~TimedQueueWrapper() = default;
+    virtual void addJob(MountId id, Milliseconds after, Job what) = 0;
+    virtual void removeJobs(MountId id) = 0;
+    virtual void stop() = 0;
+};
+
 class ServiceManagerWrapper {
 public:
     virtual ~ServiceManagerWrapper() = default;
@@ -130,6 +143,7 @@
     virtual std::unique_ptr<AppOpsManagerWrapper> getAppOpsManager() = 0;
     virtual std::unique_ptr<JniWrapper> getJni() = 0;
     virtual std::unique_ptr<LooperWrapper> getLooper() = 0;
+    virtual std::unique_ptr<TimedQueueWrapper> getTimedQueue() = 0;
 };
 
 // --- Real stuff ---
@@ -144,6 +158,7 @@
     std::unique_ptr<AppOpsManagerWrapper> getAppOpsManager() final;
     std::unique_ptr<JniWrapper> getJni() final;
     std::unique_ptr<LooperWrapper> getLooper() final;
+    std::unique_ptr<TimedQueueWrapper> getTimedQueue() final;
 
 private:
     template <class INTERFACE>
diff --git a/services/incremental/test/IncrementalServiceTest.cpp b/services/incremental/test/IncrementalServiceTest.cpp
index 84ec7d3..26b5094 100644
--- a/services/incremental/test/IncrementalServiceTest.cpp
+++ b/services/incremental/test/IncrementalServiceTest.cpp
@@ -22,6 +22,7 @@
 #include <gtest/gtest.h>
 #include <utils/Log.h>
 
+#include <chrono>
 #include <future>
 
 #include "IncrementalService.h"
@@ -295,9 +296,21 @@
     void openMountSuccess() {
         ON_CALL(*this, openMount(_)).WillByDefault(Invoke(this, &MockIncFs::openMountForHealth));
     }
-    void waitForPendingReadsSuccess() {
+
+    // 1000ms
+    void waitForPendingReadsSuccess(uint64_t ts = 0) {
         ON_CALL(*this, waitForPendingReads(_, _, _))
-                .WillByDefault(Invoke(this, &MockIncFs::waitForPendingReadsForHealth));
+                .WillByDefault(
+                        Invoke([ts](const Control& control, std::chrono::milliseconds timeout,
+                                    std::vector<incfs::ReadInfo>* pendingReadsBuffer) {
+                            pendingReadsBuffer->push_back({.bootClockTsUs = ts});
+                            return android::incfs::WaitResult::HaveData;
+                        }));
+    }
+
+    void waitForPendingReadsTimeout() {
+        ON_CALL(*this, waitForPendingReads(_, _, _))
+                .WillByDefault(Return(android::incfs::WaitResult::Timeout));
     }
 
     static constexpr auto kPendingReadsFd = 42;
@@ -305,13 +318,6 @@
         return UniqueControl(IncFs_CreateControl(-1, kPendingReadsFd, -1));
     }
 
-    WaitResult waitForPendingReadsForHealth(
-            const Control& control, std::chrono::milliseconds timeout,
-            std::vector<incfs::ReadInfo>* pendingReadsBuffer) const {
-        pendingReadsBuffer->push_back({.bootClockTsUs = 0});
-        return android::incfs::WaitResult::HaveData;
-    }
-
     RawMetadata getMountInfoMetadata(const Control& control, std::string_view path) {
         metadata::Mount m;
         m.mutable_storage()->set_id(100);
@@ -371,7 +377,7 @@
 public:
     MOCK_CONST_METHOD0(initializeForCurrentThread, void());
 
-    MockJniWrapper() { EXPECT_CALL(*this, initializeForCurrentThread()).Times(3); }
+    MockJniWrapper() { EXPECT_CALL(*this, initializeForCurrentThread()).Times(2); }
 };
 
 class MockLooperWrapper : public LooperWrapper {
@@ -385,7 +391,7 @@
         ON_CALL(*this, addFd(_, _, _, _, _))
                 .WillByDefault(Invoke(this, &MockLooperWrapper::storeCallback));
         ON_CALL(*this, removeFd(_)).WillByDefault(Invoke(this, &MockLooperWrapper::clearCallback));
-        ON_CALL(*this, pollAll(_)).WillByDefault(Invoke(this, &MockLooperWrapper::sleepFor));
+        ON_CALL(*this, pollAll(_)).WillByDefault(Invoke(this, &MockLooperWrapper::wait10Ms));
     }
 
     int storeCallback(int, int, int, android::Looper_callbackFunc callback, void* data) {
@@ -400,8 +406,10 @@
         return 0;
     }
 
-    int sleepFor(int timeoutMillis) {
-        std::this_thread::sleep_for(std::chrono::milliseconds(timeoutMillis));
+    int wait10Ms(int) {
+        // This is called from a loop in runCmdLooper.
+        // Sleeping for 10ms only to avoid busy looping.
+        std::this_thread::sleep_for(10ms);
         return 0;
     }
 
@@ -409,6 +417,55 @@
     void* mCallbackData = nullptr;
 };
 
+class MockTimedQueueWrapper : public TimedQueueWrapper {
+public:
+    MOCK_METHOD3(addJob, void(MountId, Milliseconds, Job));
+    MOCK_METHOD1(removeJobs, void(MountId));
+    MOCK_METHOD0(stop, void());
+
+    MockTimedQueueWrapper() {
+        ON_CALL(*this, addJob(_, _, _))
+                .WillByDefault(Invoke(this, &MockTimedQueueWrapper::storeJob));
+        ON_CALL(*this, removeJobs(_)).WillByDefault(Invoke(this, &MockTimedQueueWrapper::clearJob));
+    }
+
+    void storeJob(MountId id, Milliseconds after, Job what) {
+        mId = id;
+        mAfter = after;
+        mWhat = std::move(what);
+    }
+
+    void clearJob(MountId id) {
+        if (mId == id) {
+            mAfter = {};
+            mWhat = {};
+        }
+    }
+
+    MountId mId = -1;
+    Milliseconds mAfter;
+    Job mWhat;
+};
+
+class MockStorageHealthListener : public os::incremental::BnStorageHealthListener {
+public:
+    MOCK_METHOD2(onHealthStatus, binder::Status(int32_t storageId, int32_t status));
+
+    MockStorageHealthListener() {
+        ON_CALL(*this, onHealthStatus(_, _))
+                .WillByDefault(Invoke(this, &MockStorageHealthListener::storeStorageIdAndStatus));
+    }
+
+    binder::Status storeStorageIdAndStatus(int32_t storageId, int32_t status) {
+        mStorageId = storageId;
+        mStatus = status;
+        return binder::Status::ok();
+    }
+
+    int32_t mStorageId = -1;
+    int32_t mStatus = -1;
+};
+
 class MockServiceManager : public ServiceManagerWrapper {
 public:
     MockServiceManager(std::unique_ptr<MockVoldService> vold,
@@ -416,13 +473,15 @@
                        std::unique_ptr<MockIncFs> incfs,
                        std::unique_ptr<MockAppOpsManager> appOpsManager,
                        std::unique_ptr<MockJniWrapper> jni,
-                       std::unique_ptr<MockLooperWrapper> looper)
+                       std::unique_ptr<MockLooperWrapper> looper,
+                       std::unique_ptr<MockTimedQueueWrapper> timedQueue)
           : mVold(std::move(vold)),
             mDataLoaderManager(std::move(dataLoaderManager)),
             mIncFs(std::move(incfs)),
             mAppOpsManager(std::move(appOpsManager)),
             mJni(std::move(jni)),
-            mLooper(std::move(looper)) {}
+            mLooper(std::move(looper)),
+            mTimedQueue(std::move(timedQueue)) {}
     std::unique_ptr<VoldServiceWrapper> getVoldService() final { return std::move(mVold); }
     std::unique_ptr<DataLoaderManagerWrapper> getDataLoaderManager() final {
         return std::move(mDataLoaderManager);
@@ -431,6 +490,7 @@
     std::unique_ptr<AppOpsManagerWrapper> getAppOpsManager() final { return std::move(mAppOpsManager); }
     std::unique_ptr<JniWrapper> getJni() final { return std::move(mJni); }
     std::unique_ptr<LooperWrapper> getLooper() final { return std::move(mLooper); }
+    std::unique_ptr<TimedQueueWrapper> getTimedQueue() final { return std::move(mTimedQueue); }
 
 private:
     std::unique_ptr<MockVoldService> mVold;
@@ -439,6 +499,7 @@
     std::unique_ptr<MockAppOpsManager> mAppOpsManager;
     std::unique_ptr<MockJniWrapper> mJni;
     std::unique_ptr<MockLooperWrapper> mLooper;
+    std::unique_ptr<MockTimedQueueWrapper> mTimedQueue;
 };
 
 // --- IncrementalServiceTest ---
@@ -460,6 +521,8 @@
         mJni = jni.get();
         auto looper = std::make_unique<NiceMock<MockLooperWrapper>>();
         mLooper = looper.get();
+        auto timedQueue = std::make_unique<NiceMock<MockTimedQueueWrapper>>();
+        mTimedQueue = timedQueue.get();
         mIncrementalService =
                 std::make_unique<IncrementalService>(MockServiceManager(std::move(vold),
                                                                         std::move(
@@ -467,7 +530,8 @@
                                                                         std::move(incFs),
                                                                         std::move(appOps),
                                                                         std::move(jni),
-                                                                        std::move(looper)),
+                                                                        std::move(looper),
+                                                                        std::move(timedQueue)),
                                                      mRootDir.path);
         mDataLoaderParcel.packageName = "com.test";
         mDataLoaderParcel.arguments = "uri";
@@ -503,6 +567,7 @@
     NiceMock<MockAppOpsManager>* mAppOpsManager = nullptr;
     NiceMock<MockJniWrapper>* mJni = nullptr;
     NiceMock<MockLooperWrapper>* mLooper = nullptr;
+    NiceMock<MockTimedQueueWrapper>* mTimedQueue = nullptr;
     NiceMock<MockDataLoader>* mDataLoader = nullptr;
     std::unique_ptr<IncrementalService> mIncrementalService;
     TemporaryDir mRootDir;
@@ -710,6 +775,136 @@
     mLooper->mCallback(-1, -1, mLooper->mCallbackData);
 }
 
+TEST_F(IncrementalServiceTest, testStartDataLoaderUnhealthyStorage) {
+    mVold->mountIncFsSuccess();
+    mIncFs->makeFileSuccess();
+    mIncFs->openMountSuccess();
+    mVold->bindMountSuccess();
+    mDataLoaderManager->bindToDataLoaderSuccess();
+    mDataLoaderManager->getDataLoaderSuccess();
+    EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _)).Times(1);
+    EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(1);
+    EXPECT_CALL(*mDataLoader, create(_, _, _, _)).Times(1);
+    EXPECT_CALL(*mDataLoader, start(_)).Times(1);
+    EXPECT_CALL(*mDataLoader, destroy(_)).Times(1);
+    EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
+    EXPECT_CALL(*mLooper, addFd(MockIncFs::kPendingReadsFd, _, _, _, _)).Times(2);
+    EXPECT_CALL(*mLooper, removeFd(MockIncFs::kPendingReadsFd)).Times(2);
+    EXPECT_CALL(*mTimedQueue, addJob(_, _, _)).Times(4);
+
+    sp<NiceMock<MockStorageHealthListener>> listener{new NiceMock<MockStorageHealthListener>};
+    NiceMock<MockStorageHealthListener>* listenerMock = listener.get();
+    EXPECT_CALL(*listenerMock, onHealthStatus(_, IStorageHealthListener::HEALTH_STATUS_OK))
+            .Times(2);
+    EXPECT_CALL(*listenerMock,
+                onHealthStatus(_, IStorageHealthListener::HEALTH_STATUS_READS_PENDING))
+            .Times(1);
+    EXPECT_CALL(*listenerMock, onHealthStatus(_, IStorageHealthListener::HEALTH_STATUS_BLOCKED))
+            .Times(1);
+    EXPECT_CALL(*listenerMock, onHealthStatus(_, IStorageHealthListener::HEALTH_STATUS_UNHEALTHY))
+            .Times(2);
+
+    StorageHealthCheckParams params;
+    params.blockedTimeoutMs = 10000;
+    params.unhealthyTimeoutMs = 20000;
+    params.unhealthyMonitoringMs = 30000;
+
+    using MS = std::chrono::milliseconds;
+    using MCS = std::chrono::microseconds;
+
+    const auto blockedTimeout = MS(params.blockedTimeoutMs);
+    const auto unhealthyTimeout = MS(params.unhealthyTimeoutMs);
+    const auto unhealthyMonitoring = MS(params.unhealthyMonitoringMs);
+
+    const uint64_t kFirstTimestampUs = 1000000000ll;
+    const uint64_t kBlockedTimestampUs =
+            kFirstTimestampUs - std::chrono::duration_cast<MCS>(blockedTimeout).count();
+    const uint64_t kUnhealthyTimestampUs =
+            kFirstTimestampUs - std::chrono::duration_cast<MCS>(unhealthyTimeout).count();
+
+    TemporaryDir tempDir;
+    int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel),
+                                                       IncrementalService::CreateOptions::CreateNew,
+                                                       {}, std::move(params), listener);
+    ASSERT_GE(storageId, 0);
+
+    // Healthy state, registered for pending reads.
+    ASSERT_NE(nullptr, mLooper->mCallback);
+    ASSERT_NE(nullptr, mLooper->mCallbackData);
+    ASSERT_EQ(storageId, listener->mStorageId);
+    ASSERT_EQ(IStorageHealthListener::HEALTH_STATUS_OK, listener->mStatus);
+
+    // Looper/epoll callback.
+    mIncFs->waitForPendingReadsSuccess(kFirstTimestampUs);
+    mLooper->mCallback(-1, -1, mLooper->mCallbackData);
+
+    // Unregister from pending reads and wait.
+    ASSERT_EQ(nullptr, mLooper->mCallback);
+    ASSERT_EQ(nullptr, mLooper->mCallbackData);
+    ASSERT_EQ(storageId, listener->mStorageId);
+    ASSERT_EQ(IStorageHealthListener::HEALTH_STATUS_READS_PENDING, listener->mStatus);
+    // Timed callback present.
+    ASSERT_EQ(storageId, mTimedQueue->mId);
+    ASSERT_GE(mTimedQueue->mAfter, blockedTimeout);
+    auto timedCallback = mTimedQueue->mWhat;
+    mTimedQueue->clearJob(storageId);
+
+    // Timed job callback for blocked.
+    mIncFs->waitForPendingReadsSuccess(kBlockedTimestampUs);
+    timedCallback();
+
+    // Still not registered, and blocked.
+    ASSERT_EQ(nullptr, mLooper->mCallback);
+    ASSERT_EQ(nullptr, mLooper->mCallbackData);
+    ASSERT_EQ(storageId, listener->mStorageId);
+    ASSERT_EQ(IStorageHealthListener::HEALTH_STATUS_BLOCKED, listener->mStatus);
+    // Timed callback present.
+    ASSERT_EQ(storageId, mTimedQueue->mId);
+    ASSERT_GE(mTimedQueue->mAfter, 1000ms);
+    timedCallback = mTimedQueue->mWhat;
+    mTimedQueue->clearJob(storageId);
+
+    // Timed job callback for unhealthy.
+    mIncFs->waitForPendingReadsSuccess(kUnhealthyTimestampUs);
+    timedCallback();
+
+    // Still not registered, and blocked.
+    ASSERT_EQ(nullptr, mLooper->mCallback);
+    ASSERT_EQ(nullptr, mLooper->mCallbackData);
+    ASSERT_EQ(storageId, listener->mStorageId);
+    ASSERT_EQ(IStorageHealthListener::HEALTH_STATUS_UNHEALTHY, listener->mStatus);
+    // Timed callback present.
+    ASSERT_EQ(storageId, mTimedQueue->mId);
+    ASSERT_GE(mTimedQueue->mAfter, unhealthyMonitoring);
+    timedCallback = mTimedQueue->mWhat;
+    mTimedQueue->clearJob(storageId);
+
+    // One more unhealthy.
+    mIncFs->waitForPendingReadsSuccess(kUnhealthyTimestampUs);
+    timedCallback();
+
+    // Still not registered, and blocked.
+    ASSERT_EQ(nullptr, mLooper->mCallback);
+    ASSERT_EQ(nullptr, mLooper->mCallbackData);
+    ASSERT_EQ(storageId, listener->mStorageId);
+    ASSERT_EQ(IStorageHealthListener::HEALTH_STATUS_UNHEALTHY, listener->mStatus);
+    // Timed callback present.
+    ASSERT_EQ(storageId, mTimedQueue->mId);
+    ASSERT_GE(mTimedQueue->mAfter, unhealthyMonitoring);
+    timedCallback = mTimedQueue->mWhat;
+    mTimedQueue->clearJob(storageId);
+
+    // And now healthy.
+    mIncFs->waitForPendingReadsTimeout();
+    timedCallback();
+
+    // Healthy state, registered for pending reads.
+    ASSERT_NE(nullptr, mLooper->mCallback);
+    ASSERT_NE(nullptr, mLooper->mCallbackData);
+    ASSERT_EQ(storageId, listener->mStorageId);
+    ASSERT_EQ(IStorageHealthListener::HEALTH_STATUS_OK, listener->mStatus);
+}
+
 TEST_F(IncrementalServiceTest, testSetIncFsMountOptionsSuccess) {
     mVold->mountIncFsSuccess();
     mIncFs->makeFileSuccess();
diff --git a/services/people/java/com/android/server/people/data/UsageStatsQueryHelper.java b/services/people/java/com/android/server/people/data/UsageStatsQueryHelper.java
index d89bbe9..d008b72 100644
--- a/services/people/java/com/android/server/people/data/UsageStatsQueryHelper.java
+++ b/services/people/java/com/android/server/people/data/UsageStatsQueryHelper.java
@@ -148,6 +148,9 @@
                 UsageStatsManager.INTERVAL_BEST, startTime, endTime,
                 /* obfuscateInstantApps= */ false);
         Map<String, AppUsageStatsData> aggregatedStats = new ArrayMap<>();
+        if (stats == null) {
+            return aggregatedStats;
+        }
         for (UsageStats stat : stats) {
             String packageName = stat.getPackageName();
             if (packageNameFilter.contains(packageName)) {
diff --git a/services/tests/servicestests/src/com/android/server/people/data/UsageStatsQueryHelperTest.java b/services/tests/servicestests/src/com/android/server/people/data/UsageStatsQueryHelperTest.java
index 30ff119..e968607 100644
--- a/services/tests/servicestests/src/com/android/server/people/data/UsageStatsQueryHelperTest.java
+++ b/services/tests/servicestests/src/com/android/server/people/data/UsageStatsQueryHelperTest.java
@@ -18,6 +18,8 @@
 
 import static com.android.server.people.data.TestUtils.timestamp;
 
+import static com.google.common.truth.Truth.assertThat;
+
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
@@ -235,6 +237,19 @@
         assertEquals(5, (long) appLaunchChooserCountCounts.get(PKG_NAME_1).getLaunchCount());
     }
 
+    @Test
+    public void testQueryAppUsageStats_nullUsageStats() {
+        when(mUsageStatsManagerInternal.queryUsageStatsForUser(anyInt(), anyInt(), anyLong(),
+                anyLong(), anyBoolean())).thenReturn(null);
+
+        Map<String, AppUsageStatsData> appLaunchChooserCountCounts =
+                mHelper.queryAppUsageStats(USER_ID_PRIMARY, 90_000L,
+                        200_000L,
+                        Set.of(PKG_NAME_1));
+
+        assertThat(appLaunchChooserCountCounts).isEmpty();
+    }
+
     private void addUsageEvents(UsageEvents.Event... events) {
         UsageEvents usageEvents = new UsageEvents(Arrays.asList(events), new String[]{});
         when(mUsageStatsManagerInternal.queryEventsForUser(anyInt(), anyLong(), anyLong(),
diff --git a/services/tests/uiservicestests/Android.bp b/services/tests/uiservicestests/Android.bp
index b7199f7..4439f99 100644
--- a/services/tests/uiservicestests/Android.bp
+++ b/services/tests/uiservicestests/Android.bp
@@ -21,6 +21,7 @@
         "mockito-target-inline-minus-junit4",
         "platform-test-annotations",
         "platformprotosnano",
+        "statsdprotolite",
         "hamcrest-library",
         "testables",
         "truth-prebuilt",
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/BubbleExtractorTest.java b/services/tests/uiservicestests/src/com/android/server/notification/BubbleExtractorTest.java
index 13457f0..162b2c4 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/BubbleExtractorTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/BubbleExtractorTest.java
@@ -431,6 +431,25 @@
     }
 
     @Test
+    public void testFlagBubble_false_noShortcut() {
+        setUpBubblesEnabled(true /* feature */,
+                BUBBLE_PREFERENCE_ALL /* app */,
+                DEFAULT_ALLOW_BUBBLE /* channel */);
+        when(mActivityManager.isLowRamDevice()).thenReturn(false);
+        setUpIntentBubble(true /* isValid */);
+
+        NotificationRecord r = getNotificationRecord(true /* bubble */);
+        r.setShortcutInfo(null);
+        r.getNotification().extras.putString(Notification.EXTRA_TEMPLATE, null);
+
+        mBubbleExtractor.process(r);
+
+        assertFalse(r.canBubble());
+        assertNull(r.getNotification().getBubbleMetadata());
+        assertFalse(r.getNotification().isBubbleNotification());
+    }
+
+    @Test
     public void testFlagBubble_false_notConversation() {
         setUpBubblesEnabled(true /* feature */,
                 BUBBLE_PREFERENCE_ALL /* app */,
@@ -439,8 +458,7 @@
         setUpIntentBubble(true /* isValid */);
 
         NotificationRecord r = getNotificationRecord(true /* bubble */);
-        // No longer a conversation:
-        r.setShortcutInfo(null);
+        r.userDemotedAppFromConvoSpace(true);
         r.getNotification().extras.putString(Notification.EXTRA_TEMPLATE, null);
 
         mBubbleExtractor.process(r);
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
index cf63682..de9b77c 100755
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
@@ -5309,6 +5309,28 @@
     }
 
     @Test
+    public void testFlagBubbleNotifs_noFlag_noShortcut() throws RemoteException {
+        setUpPrefsForBubbles(PKG, mUid,
+                true /* global */,
+                BUBBLE_PREFERENCE_ALL /* app */,
+                true /* channel */);
+
+        Notification.Builder nb = getMessageStyleNotifBuilder(true, null, false);
+        nb.setShortcutId(null);
+        StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 1,
+                null, mUid, 0,
+                nb.build(), new UserHandle(mUid), null, 0);
+
+        mBinderService.enqueueNotificationWithTag(PKG, PKG, sbn.getTag(),
+                sbn.getId(), sbn.getNotification(), sbn.getUserId());
+        waitForIdle();
+
+        // no shortcut no bubble
+        assertFalse(mService.getNotificationRecord(
+                sbn.getKey()).getNotification().isBubbleNotification());
+    }
+
+    @Test
     public void testFlagBubbleNotifs_noFlag_messaging_appNotAllowed() throws RemoteException {
         setUpPrefsForBubbles(PKG, mUid,
                 true /* global */,
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java
index 1d6f823..622a203 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java
@@ -29,6 +29,16 @@
 import static android.app.NotificationManager.IMPORTANCE_NONE;
 import static android.app.NotificationManager.IMPORTANCE_UNSPECIFIED;
 
+import static com.android.internal.util.FrameworkStatsLog.ANNOTATION_ID_IS_UID;
+import static com.android.internal.util.FrameworkStatsLog.PACKAGE_NOTIFICATION_CHANNEL_PREFERENCES;
+import static com.android.os.AtomsProto.PackageNotificationChannelPreferences.CHANNEL_ID_FIELD_NUMBER;
+import static com.android.os.AtomsProto.PackageNotificationChannelPreferences.CHANNEL_NAME_FIELD_NUMBER;
+import static com.android.os.AtomsProto.PackageNotificationChannelPreferences.IMPORTANCE_FIELD_NUMBER;
+import static com.android.os.AtomsProto.PackageNotificationChannelPreferences.IS_CONVERSATION_FIELD_NUMBER;
+import static com.android.os.AtomsProto.PackageNotificationChannelPreferences.IS_DELETED_FIELD_NUMBER;
+import static com.android.os.AtomsProto.PackageNotificationChannelPreferences.IS_DEMOTED_CONVERSATION_FIELD_NUMBER;
+import static com.android.os.AtomsProto.PackageNotificationChannelPreferences.IS_IMPORTANT_CONVERSATION_FIELD_NUMBER;
+import static com.android.os.AtomsProto.PackageNotificationChannelPreferences.UID_FIELD_NUMBER;
 import static com.android.server.notification.PreferencesHelper.DEFAULT_BUBBLE_PREFERENCE;
 import static com.android.server.notification.PreferencesHelper.NOTIFICATION_CHANNEL_COUNT_LIMIT;
 import static com.android.server.notification.PreferencesHelper.UNKNOWN_UID;
@@ -91,7 +101,6 @@
 import com.android.internal.util.FastXmlSerializer;
 import com.android.server.UiServiceTestCase;
 
-
 import org.json.JSONArray;
 import org.json.JSONObject;
 import org.junit.Before;
@@ -110,6 +119,7 @@
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.HashMap;
+import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
@@ -146,6 +156,7 @@
     private PreferencesHelper mHelper;
     private AudioAttributes mAudioAttributes;
     private NotificationChannelLoggerFake mLogger = new NotificationChannelLoggerFake();
+    private WrappedSysUiStatsEvent.WrappedBuilderFactory mStatsEventBuilderFactory;
 
     @Before
     public void setUp() throws Exception {
@@ -197,8 +208,11 @@
         when(mMockZenModeHelper.getNotificationPolicy()).thenReturn(mTestNotificationPolicy);
         when(mAppOpsManager.noteOpNoThrow(anyInt(), anyInt(),
                 anyString(), eq(null), anyString())).thenReturn(MODE_DEFAULT);
+
+        mStatsEventBuilderFactory = new WrappedSysUiStatsEvent.WrappedBuilderFactory();
+
         mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger,
-                mAppOpsManager);
+                mAppOpsManager, mStatsEventBuilderFactory);
         resetZenModeHelper();
 
         mAudioAttributes = new AudioAttributes.Builder()
@@ -1483,7 +1497,7 @@
                 NotificationManager.Policy.STATE_CHANNELS_BYPASSING_DND, 0);
         when(mMockZenModeHelper.getNotificationPolicy()).thenReturn(mTestNotificationPolicy);
         mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger,
-                mAppOpsManager);
+                mAppOpsManager, mStatsEventBuilderFactory);
         assertFalse(mHelper.areChannelsBypassingDnd());
         verify(mMockZenModeHelper, times(1)).setNotificationPolicy(any());
         resetZenModeHelper();
@@ -1495,7 +1509,7 @@
         mTestNotificationPolicy = new NotificationManager.Policy(0, 0, 0, 0, 0, 0);
         when(mMockZenModeHelper.getNotificationPolicy()).thenReturn(mTestNotificationPolicy);
         mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger,
-                mAppOpsManager);
+                mAppOpsManager, mStatsEventBuilderFactory);
         assertFalse(mHelper.areChannelsBypassingDnd());
         verify(mMockZenModeHelper, never()).setNotificationPolicy(any());
         resetZenModeHelper();
@@ -2262,7 +2276,7 @@
                 + "</package>\n"
                 + "</ranking>\n";
         mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger,
-                mAppOpsManager);
+                mAppOpsManager, mStatsEventBuilderFactory);
         loadByteArrayXml(preQXml.getBytes(), true, UserHandle.USER_SYSTEM);
 
         assertEquals(PreferencesHelper.DEFAULT_HIDE_SILENT_STATUS_BAR_ICONS,
@@ -2275,7 +2289,7 @@
 
         ByteArrayOutputStream baos = writeXmlAndPurge(PKG_O, UID_O, false, UserHandle.USER_ALL);
         mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger,
-                mAppOpsManager);
+                mAppOpsManager, mStatsEventBuilderFactory);
         loadStreamXml(baos, false, UserHandle.USER_ALL);
 
         assertEquals(!PreferencesHelper.DEFAULT_HIDE_SILENT_STATUS_BAR_ICONS,
@@ -2372,7 +2386,7 @@
 
         ByteArrayOutputStream baos = writeXmlAndPurge(PKG_O, UID_O, false, UserHandle.USER_ALL);
         mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger,
-                mAppOpsManager);
+                mAppOpsManager, mStatsEventBuilderFactory);
         loadStreamXml(baos, false, UserHandle.USER_ALL);
 
         assertNull(mHelper.getNotificationDelegate(PKG_O, UID_O));
@@ -2384,7 +2398,7 @@
 
         ByteArrayOutputStream baos = writeXmlAndPurge(PKG_O, UID_O, false, UserHandle.USER_ALL);
         mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger,
-                mAppOpsManager);
+                mAppOpsManager, mStatsEventBuilderFactory);
         loadStreamXml(baos, false, UserHandle.USER_ALL);
 
         assertEquals("other", mHelper.getNotificationDelegate(PKG_O, UID_O));
@@ -2397,7 +2411,7 @@
 
         ByteArrayOutputStream baos = writeXmlAndPurge(PKG_O, UID_O, false, UserHandle.USER_ALL);
         mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger,
-                mAppOpsManager);
+                mAppOpsManager, mStatsEventBuilderFactory);
         loadStreamXml(baos, false, UserHandle.USER_ALL);
 
         assertNull(mHelper.getNotificationDelegate(PKG_O, UID_O));
@@ -2410,7 +2424,7 @@
 
         ByteArrayOutputStream baos = writeXmlAndPurge(PKG_O, UID_O, false, UserHandle.USER_ALL);
         mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger,
-                mAppOpsManager);
+                mAppOpsManager, mStatsEventBuilderFactory);
         loadStreamXml(baos, false, UserHandle.USER_ALL);
 
         // appears disabled
@@ -2429,7 +2443,7 @@
 
         ByteArrayOutputStream baos = writeXmlAndPurge(PKG_O, UID_O, false, UserHandle.USER_ALL);
         mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger,
-                mAppOpsManager);
+                mAppOpsManager, mStatsEventBuilderFactory);
         loadStreamXml(baos, false, UserHandle.USER_ALL);
 
         // appears disabled
@@ -2448,7 +2462,7 @@
 
         ByteArrayOutputStream baos = writeXmlAndPurge(PKG_O, UID_O, false, UserHandle.USER_ALL);
         mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger,
-                mAppOpsManager);
+                mAppOpsManager, mStatsEventBuilderFactory);
         loadStreamXml(baos, false, UserHandle.USER_ALL);
 
         assertEquals(BUBBLE_PREFERENCE_NONE, mHelper.getBubblePreference(PKG_O, UID_O));
@@ -2503,7 +2517,7 @@
 
         ByteArrayOutputStream baos = writeXmlAndPurge(PKG_O, UID_O, false, UserHandle.USER_ALL);
         mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger,
-                mAppOpsManager);
+                mAppOpsManager, mStatsEventBuilderFactory);
         loadStreamXml(baos, false, UserHandle.USER_ALL);
 
         assertEquals(BUBBLE_PREFERENCE_SELECTED, mHelper.getBubblePreference(PKG_O, UID_O));
@@ -2540,7 +2554,7 @@
 
         ByteArrayOutputStream baos = writeXmlAndPurge(PKG_O, UID_O, false, UserHandle.USER_ALL);
         mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger,
-                mAppOpsManager);
+                mAppOpsManager, mStatsEventBuilderFactory);
         loadStreamXml(baos, false, UserHandle.USER_ALL);
 
         assertEquals(mHelper.getBubblePreference(PKG_O, UID_O), BUBBLE_PREFERENCE_NONE);
@@ -3019,31 +3033,6 @@
                 PKG_O, UID_O, parent.getId(), conversationId, false, false), conversationId);
     }
 
-
-    @Test
-    public void testPullConversationNotificationChannel() {
-        String conversationId = "friend";
-
-        NotificationChannel parent =
-                new NotificationChannel("parent", "messages", IMPORTANCE_DEFAULT);
-        mHelper.createNotificationChannel(PKG_O, UID_O, parent, true, false);
-
-        String channelId = String.format(
-                CONVERSATION_CHANNEL_ID_FORMAT, parent.getId(), conversationId);
-        NotificationChannel friend = new NotificationChannel(channelId,
-                "messages", IMPORTANCE_DEFAULT);
-        friend.setConversationId(parent.getId(), conversationId);
-        mHelper.createNotificationChannel(PKG_O, UID_O, friend, true, false);
-        ArrayList<StatsEvent> events = new ArrayList<>();
-        mHelper.pullPackageChannelPreferencesStats(events);
-        boolean found = false;
-        for (StatsEvent event : events) {
-            // TODO(b/153195691): inspect the content once it is possible to do so
-            found = true;
-        }
-        assertTrue("conversation was not in the pull", found);
-    }
-
     @Test
     public void testGetNotificationChannel_conversationProvidedByNotCustomizedYet() {
         String conversationId = "friend";
@@ -3077,7 +3066,7 @@
     @Test
     public void testPlaceholderConversationId_shortcutRequired() throws Exception {
         mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger,
-                mAppOpsManager);
+                mAppOpsManager, mStatsEventBuilderFactory);
 
         final String xml = "<ranking version=\"1\">\n"
                 + "<package name=\"" + PKG_O + "\" uid=\"" + UID_O + "\" >\n"
@@ -3096,7 +3085,7 @@
     @Test
     public void testNormalConversationId_shortcutRequired() throws Exception {
         mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger,
-                mAppOpsManager);
+                mAppOpsManager, mStatsEventBuilderFactory);
 
         final String xml = "<ranking version=\"1\">\n"
                 + "<package name=\"" + PKG_O + "\" uid=\"" + UID_O + "\" >\n"
@@ -3115,7 +3104,7 @@
     @Test
     public void testNoConversationId_shortcutRequired() throws Exception {
         mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger,
-                mAppOpsManager);
+                mAppOpsManager, mStatsEventBuilderFactory);
 
         final String xml = "<ranking version=\"1\">\n"
                 + "<package name=\"" + PKG_O + "\" uid=\"" + UID_O + "\" >\n"
@@ -3477,4 +3466,151 @@
         mHelper.setValidMessageSent(PKG_P, UID_P);
         assertFalse(mHelper.hasUserDemotedInvalidMsgApp(PKG_P, UID_P));
     }
+
+    @Test
+    public void testPullPackageChannelPreferencesStats() {
+        String channelId = "parent";
+        String name = "messages";
+        NotificationChannel fodderA = new NotificationChannel("a", "a", IMPORTANCE_LOW);
+        mHelper.createNotificationChannel(PKG_O, UID_O, fodderA, true, false);
+        NotificationChannel channel =
+                new NotificationChannel(channelId, name, IMPORTANCE_DEFAULT);
+        mHelper.createNotificationChannel(PKG_O, UID_O, channel, true, false);
+        NotificationChannel fodderB = new NotificationChannel("b", "b", IMPORTANCE_HIGH);
+        mHelper.createNotificationChannel(PKG_O, UID_O, fodderB, true, false);
+
+        ArrayList<StatsEvent> events = new ArrayList<>();
+        mHelper.pullPackageChannelPreferencesStats(events);
+
+        int found = 0;
+        for (WrappedSysUiStatsEvent.WrappedBuilder builder : mStatsEventBuilderFactory.builders) {
+            if (builder.getAtomId() == PACKAGE_NOTIFICATION_CHANNEL_PREFERENCES
+                    && channelId.equals(builder.getValue(CHANNEL_ID_FIELD_NUMBER))) {
+                ++found;
+                assertEquals("uid", UID_O, builder.getValue(UID_FIELD_NUMBER));
+                assertTrue("uid annotation", builder.getBooleanAnnotation(
+                        UID_FIELD_NUMBER, ANNOTATION_ID_IS_UID));
+                assertEquals("importance", IMPORTANCE_DEFAULT, builder.getValue(
+                        IMPORTANCE_FIELD_NUMBER));
+                assertEquals("name", name, builder.getValue(CHANNEL_NAME_FIELD_NUMBER));
+                assertFalse("isconv", builder.getBoolean(IS_CONVERSATION_FIELD_NUMBER));
+                assertFalse("deleted", builder.getBoolean(IS_DELETED_FIELD_NUMBER));
+            }
+        }
+    }
+
+    @Test
+    public void testPullPackageChannelPreferencesStats_one_to_one() {
+        NotificationChannel channelA = new NotificationChannel("a", "a", IMPORTANCE_LOW);
+        mHelper.createNotificationChannel(PKG_O, UID_O, channelA, true, false);
+        NotificationChannel channelB = new NotificationChannel("b", "b", IMPORTANCE_LOW);
+        mHelper.createNotificationChannel(PKG_O, UID_O, channelB, true, false);
+        NotificationChannel channelC = new NotificationChannel("c", "c", IMPORTANCE_HIGH);
+        mHelper.createNotificationChannel(PKG_O, UID_O, channelC, true, false);
+
+        List<String> channels = new LinkedList<>(Arrays.asList("a", "b", "c"));
+
+        ArrayList<StatsEvent> events = new ArrayList<>();
+        mHelper.pullPackageChannelPreferencesStats(events);
+
+        int found = 0;
+        for (WrappedSysUiStatsEvent.WrappedBuilder builder : mStatsEventBuilderFactory.builders) {
+            if (builder.getAtomId() == PACKAGE_NOTIFICATION_CHANNEL_PREFERENCES) {
+                Object id = builder.getValue(CHANNEL_ID_FIELD_NUMBER);
+                assertTrue("missing channel in the output", channels.contains(id));
+                channels.remove(id);
+            }
+        }
+        assertTrue("unexpected channel in output", channels.isEmpty());
+    }
+
+    @Test
+    public void testPullPackageChannelPreferencesStats_conversation() {
+        String conversationId = "friend";
+
+        NotificationChannel parent =
+                new NotificationChannel("parent", "messages", IMPORTANCE_DEFAULT);
+        mHelper.createNotificationChannel(PKG_O, UID_O, parent, true, false);
+
+        String channelId = String.format(
+                CONVERSATION_CHANNEL_ID_FORMAT, parent.getId(), conversationId);
+        String name = "conversation";
+        NotificationChannel friend = new NotificationChannel(channelId,
+                name, IMPORTANCE_DEFAULT);
+        friend.setConversationId(parent.getId(), conversationId);
+        mHelper.createNotificationChannel(PKG_O, UID_O, friend, true, false);
+
+        ArrayList<StatsEvent> events = new ArrayList<>();
+        mHelper.pullPackageChannelPreferencesStats(events);
+
+        for (WrappedSysUiStatsEvent.WrappedBuilder builder : mStatsEventBuilderFactory.builders) {
+            if (builder.getAtomId() == PACKAGE_NOTIFICATION_CHANNEL_PREFERENCES
+                    && channelId.equals(builder.getValue(CHANNEL_ID_FIELD_NUMBER))) {
+                assertTrue("isConveration should be true", builder.getBoolean(
+                        IS_CONVERSATION_FIELD_NUMBER));
+                assertFalse("not demoted", builder.getBoolean(
+                        IS_DEMOTED_CONVERSATION_FIELD_NUMBER));
+                assertFalse("not important", builder.getBoolean(
+                        IS_IMPORTANT_CONVERSATION_FIELD_NUMBER));
+            }
+        }
+    }
+
+    @Test
+    public void testPullPackageChannelPreferencesStats_conversation_demoted() {
+        NotificationChannel parent =
+                new NotificationChannel("parent", "messages", IMPORTANCE_DEFAULT);
+        mHelper.createNotificationChannel(PKG_O, UID_O, parent, true, false);
+        String channelId = String.format(
+                CONVERSATION_CHANNEL_ID_FORMAT, parent.getId(), "friend");
+        NotificationChannel friend = new NotificationChannel(channelId,
+                "conversation", IMPORTANCE_DEFAULT);
+        friend.setConversationId(parent.getId(), "friend");
+        friend.setDemoted(true);
+        mHelper.createNotificationChannel(PKG_O, UID_O, friend, true, false);
+
+        ArrayList<StatsEvent> events = new ArrayList<>();
+        mHelper.pullPackageChannelPreferencesStats(events);
+
+        for (WrappedSysUiStatsEvent.WrappedBuilder builder : mStatsEventBuilderFactory.builders) {
+            if (builder.getAtomId() == PACKAGE_NOTIFICATION_CHANNEL_PREFERENCES
+                    && channelId.equals(builder.getValue(CHANNEL_ID_FIELD_NUMBER))) {
+                assertTrue("isConveration should be true", builder.getBoolean(
+                        IS_CONVERSATION_FIELD_NUMBER));
+                assertTrue("is demoted", builder.getBoolean(
+                        IS_DEMOTED_CONVERSATION_FIELD_NUMBER));
+                assertFalse("not important", builder.getBoolean(
+                        IS_IMPORTANT_CONVERSATION_FIELD_NUMBER));
+            }
+        }
+    }
+
+    @Test
+    public void testPullPackageChannelPreferencesStats_conversation_priority() {
+        NotificationChannel parent =
+                new NotificationChannel("parent", "messages", IMPORTANCE_DEFAULT);
+        mHelper.createNotificationChannel(PKG_O, UID_O, parent, true, false);
+        String channelId = String.format(
+                CONVERSATION_CHANNEL_ID_FORMAT, parent.getId(), "friend");
+        NotificationChannel friend = new NotificationChannel(channelId,
+                "conversation", IMPORTANCE_DEFAULT);
+        friend.setConversationId(parent.getId(), "friend");
+        friend.setImportantConversation(true);
+        mHelper.createNotificationChannel(PKG_O, UID_O, friend, true, false);
+
+        ArrayList<StatsEvent> events = new ArrayList<>();
+        mHelper.pullPackageChannelPreferencesStats(events);
+
+        for (WrappedSysUiStatsEvent.WrappedBuilder builder : mStatsEventBuilderFactory.builders) {
+            if (builder.getAtomId() == PACKAGE_NOTIFICATION_CHANNEL_PREFERENCES
+                    && channelId.equals(builder.getValue(CHANNEL_ID_FIELD_NUMBER))) {
+                assertTrue("isConveration should be true", builder.getBoolean(
+                        IS_CONVERSATION_FIELD_NUMBER));
+                assertFalse("not demoted", builder.getBoolean(
+                        IS_DEMOTED_CONVERSATION_FIELD_NUMBER));
+                assertTrue("is important", builder.getBoolean(
+                        IS_IMPORTANT_CONVERSATION_FIELD_NUMBER));
+            }
+        }
+    }
 }
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/WrappedSysUiStatsEvent.java b/services/tests/uiservicestests/src/com/android/server/notification/WrappedSysUiStatsEvent.java
new file mode 100644
index 0000000..f4f64d7
--- /dev/null
+++ b/services/tests/uiservicestests/src/com/android/server/notification/WrappedSysUiStatsEvent.java
@@ -0,0 +1,133 @@
+/*
+ * Copyright (C) 2020 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 com.android.server.notification;
+
+import android.util.StatsEvent;
+
+import com.android.server.notification.SysUiStatsEvent.Builder;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+/**
+ * Wrapper for SysUiStatsEvent that implements validation.
+ */
+public class WrappedSysUiStatsEvent {
+
+    static class WrappedBuilder extends Builder {
+        private ArrayList<Object> mValues;
+        private HashMap<Integer, HashMap<Byte, Object>> mAnnotations;
+        private int mAtomId;
+        private int mLastIndex;
+        private boolean mBuilt;
+
+        WrappedBuilder(StatsEvent.Builder builder) {
+            super(builder);
+            mValues = new ArrayList<>();
+            mAnnotations = new HashMap<>();
+            mValues.add(0); // proto fields are 1-based
+        }
+
+        @Override
+        public Builder setAtomId(int atomId) {
+            mAtomId = atomId;
+            super.setAtomId(atomId);
+            return this;
+        }
+
+        @Override
+        public Builder writeInt(int value) {
+            addValue(Integer.valueOf(value));
+            super.writeInt(value);
+            return this;
+        }
+
+        @Override
+        public Builder addBooleanAnnotation(byte annotation, boolean value) {
+            addAnnotation(annotation, Boolean.valueOf(value));
+            super.addBooleanAnnotation(annotation, value);
+            return this;
+        }
+
+        @Override
+        public Builder writeString(String value) {
+            addValue(value);
+            super.writeString(value);
+            return this;
+        }
+
+        @Override
+        public Builder writeBoolean(boolean value) {
+            addValue(Boolean.valueOf(value));
+            super.writeBoolean(value);
+            return this;
+        }
+
+        @Override
+        public StatsEvent build() {
+            mBuilt = true;
+            return super.build();
+        }
+
+        public Object getValue(int index) {
+            return index < mValues.size() ? mValues.get(index) : null;
+        }
+
+        /** useful to make assertTrue() statemetns more readable. */
+        public boolean getBoolean(int index) {
+            return (Boolean) mValues.get(index);
+        }
+
+        private void addValue(Object value) {
+            mLastIndex = mValues.size();
+            mValues.add(value);
+        }
+
+        private void addAnnotation(byte annotation, Object value) {
+            Integer key = Integer.valueOf(mLastIndex);
+            if (!mAnnotations.containsKey(key)) {
+                mAnnotations.put(key, new HashMap<>());
+            }
+            mAnnotations.get(key).put(Byte.valueOf(annotation), value);
+        }
+
+        public boolean getBooleanAnnotation(int i, byte a) {
+            return ((Boolean) mAnnotations.get(Integer.valueOf(i)).get(Byte.valueOf(a)))
+                    .booleanValue();
+        }
+
+        public int getAtomId() {
+            return mAtomId;
+        }
+    }
+
+    static class WrappedBuilderFactory extends SysUiStatsEvent.BuilderFactory {
+        public List<WrappedBuilder> builders;
+
+        WrappedBuilderFactory() {
+            builders = new ArrayList<>();
+        }
+
+        @Override
+        Builder newBuilder() {
+            WrappedBuilder b = new WrappedBuilder(StatsEvent.newBuilder());
+            builders.add(b);
+            return b;
+        }
+    }
+}
diff --git a/wifi/jarjar-rules.txt b/wifi/jarjar-rules.txt
index 26927e5..f0555e6 100644
--- a/wifi/jarjar-rules.txt
+++ b/wifi/jarjar-rules.txt
@@ -31,6 +31,7 @@
 rule android.net.ip.IIpClientCallbacks* com.android.wifi.x.@0
 rule android.net.ipmemorystore.Blob* com.android.wifi.x.@0
 rule android.net.ipmemorystore.IOnBlobRetrievedListener* com.android.wifi.x.@0
+rule android.net.ipmemorystore.IOnStatusAndCountListener* com.android.wifi.x.@0
 rule android.net.ipmemorystore.IOnStatusListener* com.android.wifi.x.@0
 rule android.net.ipmemorystore.NetworkAttributesParcelable* com.android.wifi.x.@0
 rule android.net.ipmemorystore.SameL3NetworkResponseParcelable* com.android.wifi.x.@0
@@ -46,7 +47,9 @@
 rule android.net.ip.IpClientCallbacks* com.android.wifi.x.@0
 rule android.net.ip.IpClientManager* com.android.wifi.x.@0
 rule android.net.ip.IpClientUtil* com.android.wifi.x.@0
+rule android.net.ipmemorystore.NetworkAttributes* com.android.wifi.x.@0
 rule android.net.ipmemorystore.OnBlobRetrievedListener* com.android.wifi.x.@0
+rule android.net.ipmemorystore.OnDeleteStatusListener* com.android.wifi.x.@0
 rule android.net.ipmemorystore.OnStatusListener* com.android.wifi.x.@0
 rule android.net.ipmemorystore.Status* com.android.wifi.x.@0
 rule android.net.networkstack.ModuleNetworkStackClient* com.android.wifi.x.@0