Merge "Add privapp permissions permission for com.android.cellbroadcastreceiver package." into rvc-dev
diff --git a/cmds/statsd/src/anomaly/AlarmTracker.cpp b/cmds/statsd/src/anomaly/AlarmTracker.cpp
index 5722f92..6d9beb8 100644
--- a/cmds/statsd/src/anomaly/AlarmTracker.cpp
+++ b/cmds/statsd/src/anomaly/AlarmTracker.cpp
@@ -60,11 +60,11 @@
}
int64_t AlarmTracker::findNextAlarmSec(int64_t currentTimeSec) {
- if (currentTimeSec <= mAlarmSec) {
+ if (currentTimeSec < mAlarmSec) {
return mAlarmSec;
}
int64_t periodsForward =
- ((currentTimeSec - mAlarmSec) * MS_PER_SEC - 1) / mAlarmConfig.period_millis() + 1;
+ ((currentTimeSec - mAlarmSec) * MS_PER_SEC) / mAlarmConfig.period_millis() + 1;
return mAlarmSec + periodsForward * mAlarmConfig.period_millis() / MS_PER_SEC;
}
diff --git a/cmds/statsd/tests/anomaly/AlarmTracker_test.cpp b/cmds/statsd/tests/anomaly/AlarmTracker_test.cpp
index 322cfaf..64ea219 100644
--- a/cmds/statsd/tests/anomaly/AlarmTracker_test.cpp
+++ b/cmds/statsd/tests/anomaly/AlarmTracker_test.cpp
@@ -43,23 +43,47 @@
alarm.set_offset_millis(15 * MS_PER_SEC);
alarm.set_period_millis(60 * 60 * MS_PER_SEC); // 1hr
int64_t startMillis = 100000000 * MS_PER_SEC;
+ int64_t nextAlarmTime = startMillis / MS_PER_SEC + 15;
AlarmTracker tracker(startMillis, startMillis, alarm, kConfigKey, subscriberAlarmMonitor);
- EXPECT_EQ(tracker.mAlarmSec, (int64_t)(startMillis / MS_PER_SEC + 15));
+ EXPECT_EQ(tracker.mAlarmSec, nextAlarmTime);
uint64_t currentTimeSec = startMillis / MS_PER_SEC + 10;
std::unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>> firedAlarmSet =
subscriberAlarmMonitor->popSoonerThan(static_cast<uint32_t>(currentTimeSec));
EXPECT_TRUE(firedAlarmSet.empty());
tracker.informAlarmsFired(currentTimeSec * NS_PER_SEC, firedAlarmSet);
- EXPECT_EQ(tracker.mAlarmSec, (int64_t)(startMillis / MS_PER_SEC + 15));
+ EXPECT_EQ(tracker.mAlarmSec, nextAlarmTime);
+ EXPECT_EQ(tracker.getAlarmTimestampSec(), nextAlarmTime);
currentTimeSec = startMillis / MS_PER_SEC + 7000;
+ nextAlarmTime = startMillis / MS_PER_SEC + 15 + 2 * 60 * 60;
firedAlarmSet = subscriberAlarmMonitor->popSoonerThan(static_cast<uint32_t>(currentTimeSec));
ASSERT_EQ(firedAlarmSet.size(), 1u);
tracker.informAlarmsFired(currentTimeSec * NS_PER_SEC, firedAlarmSet);
EXPECT_TRUE(firedAlarmSet.empty());
- EXPECT_EQ(tracker.mAlarmSec, (int64_t)(startMillis / MS_PER_SEC + 15 + 2 * 60 * 60));
+ EXPECT_EQ(tracker.mAlarmSec, nextAlarmTime);
+ EXPECT_EQ(tracker.getAlarmTimestampSec(), nextAlarmTime);
+
+ // Alarm fires exactly on time.
+ currentTimeSec = startMillis / MS_PER_SEC + 15 + 2 * 60 * 60;
+ nextAlarmTime = startMillis / MS_PER_SEC + 15 + 3 * 60 * 60;
+ firedAlarmSet = subscriberAlarmMonitor->popSoonerThan(static_cast<uint32_t>(currentTimeSec));
+ ASSERT_EQ(firedAlarmSet.size(), 1u);
+ tracker.informAlarmsFired(currentTimeSec * NS_PER_SEC, firedAlarmSet);
+ EXPECT_TRUE(firedAlarmSet.empty());
+ EXPECT_EQ(tracker.mAlarmSec, nextAlarmTime);
+ EXPECT_EQ(tracker.getAlarmTimestampSec(), nextAlarmTime);
+
+ // Alarm fires exactly 1 period late.
+ currentTimeSec = startMillis / MS_PER_SEC + 15 + 4 * 60 * 60;
+ nextAlarmTime = startMillis / MS_PER_SEC + 15 + 5 * 60 * 60;
+ firedAlarmSet = subscriberAlarmMonitor->popSoonerThan(static_cast<uint32_t>(currentTimeSec));
+ ASSERT_EQ(firedAlarmSet.size(), 1u);
+ tracker.informAlarmsFired(currentTimeSec * NS_PER_SEC, firedAlarmSet);
+ EXPECT_TRUE(firedAlarmSet.empty());
+ EXPECT_EQ(tracker.mAlarmSec, nextAlarmTime);
+ EXPECT_EQ(tracker.getAlarmTimestampSec(), nextAlarmTime);
}
} // namespace statsd
diff --git a/core/java/android/hardware/biometrics/BiometricManager.java b/core/java/android/hardware/biometrics/BiometricManager.java
index 2d2dda0..e385cd2 100644
--- a/core/java/android/hardware/biometrics/BiometricManager.java
+++ b/core/java/android/hardware/biometrics/BiometricManager.java
@@ -121,7 +121,7 @@
/**
* Any biometric (e.g. fingerprint, iris, or face) on the device that meets or exceeds the
- * requirements for <strong>Tier 3</strong> (formerly <strong>Strong</strong>), as defined
+ * requirements for <strong>Class 3</strong> (formerly <strong>Strong</strong>), as defined
* by the Android CDD.
*
* <p>This corresponds to {@link KeyProperties#AUTH_BIOMETRIC_STRONG} during key generation.
@@ -132,7 +132,7 @@
/**
* Any biometric (e.g. fingerprint, iris, or face) on the device that meets or exceeds the
- * requirements for <strong>Tier 2</strong> (formerly <strong>Weak</strong>), as defined by
+ * requirements for <strong>Class 2</strong> (formerly <strong>Weak</strong>), as defined by
* the Android CDD.
*
* <p>Note that this is a superset of {@link #BIOMETRIC_STRONG} and is defined such that
@@ -142,7 +142,7 @@
/**
* Any biometric (e.g. fingerprint, iris, or face) on the device that meets or exceeds the
- * requirements for <strong>Tier 1</strong> (formerly <strong>Convenience</strong>), as
+ * requirements for <strong>Class 1</strong> (formerly <strong>Convenience</strong>), as
* defined by the Android CDD.
*
* <p>This constant is intended for use by {@link android.provider.DeviceConfig} to adjust
diff --git a/packages/SystemUI/res/layout/media_view.xml b/packages/SystemUI/res/layout/media_view.xml
index 3cafa1d..8441282 100644
--- a/packages/SystemUI/res/layout/media_view.xml
+++ b/packages/SystemUI/res/layout/media_view.xml
@@ -141,6 +141,7 @@
android:layout_width="@dimen/qs_seamless_icon_size"
android:layout_height="@dimen/qs_seamless_icon_size"
android:layout_marginEnd="8dp"
+ android:layout_gravity="center_vertical"
android:tint="@color/media_primary_text"
android:src="@*android:drawable/ic_media_seamless" />
@@ -148,6 +149,7 @@
android:id="@+id/media_seamless_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
+ android:layout_gravity="center_vertical"
android:fontFamily="@*android:string/config_headlineFontFamily"
android:singleLine="true"
android:text="@*android:string/ext_media_seamless_action"
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
index ee31706..7792afa 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -251,7 +251,8 @@
private boolean mDeviceProvisioned;
// Battery status
- private BatteryStatus mBatteryStatus;
+ @VisibleForTesting
+ BatteryStatus mBatteryStatus;
private StrongAuthTracker mStrongAuthTracker;
@@ -1698,6 +1699,17 @@
.getServiceStateForSubscriber(subId);
mHandler.sendMessage(
mHandler.obtainMessage(MSG_SERVICE_STATE_CHANGE, subId, 0, serviceState));
+
+ // Get initial state. Relying on Sticky behavior until API for getting info.
+ if (mBatteryStatus == null) {
+ Intent intent = mContext.registerReceiver(
+ null,
+ new IntentFilter(Intent.ACTION_BATTERY_CHANGED)
+ );
+ if (intent != null && mBatteryStatus == null) {
+ mBroadcastReceiver.onReceive(mContext, intent);
+ }
+ }
});
mHandler.post(this::registerRingerTracker);
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java
index 2bfe015..1211fb4 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java
@@ -495,12 +495,9 @@
}
final float alpha = visibility ? 1f : 0f;
- if (alpha == mActivityView.getAlpha()) {
- return;
- }
-
mPointerView.setAlpha(alpha);
- if (mActivityView != null) {
+
+ if (mActivityView != null && alpha != mActivityView.getAlpha()) {
mActivityView.setAlpha(alpha);
mActivityView.bringToFront();
}
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt b/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt
index 5052386..d6b6660 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt
@@ -193,12 +193,15 @@
private fun clearData() {
// Called on user change. Remove all current MediaData objects and inform listeners
val listenersCopy = listeners.toSet()
- mediaEntries.forEach {
+ val keyCopy = mediaEntries.keys.toMutableList()
+ // Clear the list first, to make sure callbacks from listeners if we have any entries
+ // are up to date
+ mediaEntries.clear()
+ keyCopy.forEach {
listenersCopy.forEach { listener ->
- listener.onMediaDataRemoved(it.key)
+ listener.onMediaDataRemoved(it)
}
}
- mediaEntries.clear()
}
private fun removeAllForPackage(packageName: String) {
diff --git a/packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java b/packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java
index 330b20e..a7dd53e4 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java
@@ -224,6 +224,16 @@
return new Rect(mLastReportedBounds);
}
+ public Rect getCurrentOrAnimatingBounds() {
+ PipAnimationController.PipTransitionAnimator animator =
+ mPipAnimationController.getCurrentAnimator();
+ if (animator != null && animator.isRunning()) {
+ System.out.println("RUNNING ANIM: anim=" + animator.getDestinationBounds() + " last=" + getLastReportedBounds());
+ return new Rect(animator.getDestinationBounds());
+ }
+ return getLastReportedBounds();
+ }
+
public boolean isInPip() {
return mInPip;
}
@@ -406,7 +416,7 @@
private void sendOnPipTransitionStarted(
@PipAnimationController.TransitionDirection int direction) {
- mMainHandler.post(() -> {
+ runOnMainHandler(() -> {
for (int i = mPipTransitionCallbacks.size() - 1; i >= 0; i--) {
final PipTransitionCallback callback = mPipTransitionCallbacks.get(i);
callback.onPipTransitionStarted(mTaskInfo.baseActivity, direction);
@@ -416,7 +426,7 @@
private void sendOnPipTransitionFinished(
@PipAnimationController.TransitionDirection int direction) {
- mMainHandler.post(() -> {
+ runOnMainHandler(() -> {
for (int i = mPipTransitionCallbacks.size() - 1; i >= 0; i--) {
final PipTransitionCallback callback = mPipTransitionCallbacks.get(i);
callback.onPipTransitionFinished(mTaskInfo.baseActivity, direction);
@@ -426,7 +436,7 @@
private void sendOnPipTransitionCancelled(
@PipAnimationController.TransitionDirection int direction) {
- mMainHandler.post(() -> {
+ runOnMainHandler(() -> {
for (int i = mPipTransitionCallbacks.size() - 1; i >= 0; i--) {
final PipTransitionCallback callback = mPipTransitionCallbacks.get(i);
callback.onPipTransitionCanceled(mTaskInfo.baseActivity, direction);
@@ -434,6 +444,14 @@
});
}
+ private void runOnMainHandler(Runnable r) {
+ if (Looper.getMainLooper() == Looper.myLooper()) {
+ r.run();
+ } else {
+ mMainHandler.post(r);
+ }
+ }
+
/**
* Note that dismissing PiP is now originated from SystemUI, see {@link #exitPip(int)}.
* Meanwhile this callback is invoked whenever the task is removed. For instance:
@@ -505,15 +523,29 @@
*/
@SuppressWarnings("unchecked")
public void onMovementBoundsChanged(Rect destinationBoundsOut, boolean fromRotation,
- boolean fromImeAdjustment, boolean fromShelfAdjustment) {
+ boolean fromImeAdjustment, boolean fromShelfAdjustment,
+ WindowContainerTransaction wct) {
final PipAnimationController.PipTransitionAnimator animator =
mPipAnimationController.getCurrentAnimator();
if (animator == null || !animator.isRunning()
|| animator.getTransitionDirection() != TRANSITION_DIRECTION_TO_PIP) {
if (mInPip && fromRotation) {
- // this could happen if rotation finishes before the animation
+ // If we are rotating while there is a current animation, immediately cancel the
+ // animation (remove the listeners so we don't trigger the normal finish resize
+ // call that should only happen on the update thread)
+ int direction = animator.getTransitionDirection();
+ animator.removeAllUpdateListeners();
+ animator.removeAllListeners();
+ animator.cancel();
+ // Do notify the listeners that this was canceled
+ sendOnPipTransitionCancelled(direction);
mLastReportedBounds.set(destinationBoundsOut);
- scheduleFinishResizePip(mLastReportedBounds);
+
+ // Create a reset surface transaction for the new bounds and update the window
+ // container transaction
+ final SurfaceControl.Transaction tx = createFinishResizeSurfaceTransaction(
+ destinationBoundsOut);
+ prepareFinishResizeTransaction(destinationBoundsOut, direction, tx, wct);
} else {
// There could be an animation on-going. If there is one on-going, last-reported
// bounds isn't yet updated. We'll use the animator's bounds instead.
@@ -622,7 +654,7 @@
* {@link #scheduleResizePip}.
*/
public void scheduleFinishResizePip(Rect destinationBounds) {
- scheduleFinishResizePip(destinationBounds, null);
+ scheduleFinishResizePip(destinationBounds, null /* updateBoundsCallback */);
}
/**
@@ -630,30 +662,36 @@
*/
public void scheduleFinishResizePip(Rect destinationBounds,
Consumer<Rect> updateBoundsCallback) {
- final SurfaceControl.Transaction tx = mSurfaceControlTransactionFactory.getTransaction();
- mSurfaceTransactionHelper
- .crop(tx, mLeash, destinationBounds)
- .resetScale(tx, mLeash, destinationBounds)
- .round(tx, mLeash, mInPip);
- scheduleFinishResizePip(tx, destinationBounds, TRANSITION_DIRECTION_NONE,
- updateBoundsCallback);
+ scheduleFinishResizePip(destinationBounds, TRANSITION_DIRECTION_NONE, updateBoundsCallback);
}
- private void scheduleFinishResizePip(SurfaceControl.Transaction tx,
- Rect destinationBounds, @PipAnimationController.TransitionDirection int direction,
+ private void scheduleFinishResizePip(Rect destinationBounds,
+ @PipAnimationController.TransitionDirection int direction,
Consumer<Rect> updateBoundsCallback) {
if (!mInPip) {
// can be initiated in other component, ignore if we are no longer in PIP
return;
}
+
SomeArgs args = SomeArgs.obtain();
args.arg1 = updateBoundsCallback;
- args.arg2 = tx;
+ args.arg2 = createFinishResizeSurfaceTransaction(
+ destinationBounds);
args.arg3 = destinationBounds;
args.argi1 = direction;
mUpdateHandler.sendMessage(mUpdateHandler.obtainMessage(MSG_FINISH_RESIZE, args));
}
+ private SurfaceControl.Transaction createFinishResizeSurfaceTransaction(
+ Rect destinationBounds) {
+ final SurfaceControl.Transaction tx = mSurfaceControlTransactionFactory.getTransaction();
+ mSurfaceTransactionHelper
+ .crop(tx, mLeash, destinationBounds)
+ .resetScale(tx, mLeash, destinationBounds)
+ .round(tx, mLeash, mInPip);
+ return tx;
+ }
+
/**
* Offset the PiP window by a given offset on Y-axis, triggered also from screen rotation.
*/
@@ -741,7 +779,15 @@
return;
}
- final WindowContainerTransaction wct = new WindowContainerTransaction();
+ WindowContainerTransaction wct = new WindowContainerTransaction();
+ prepareFinishResizeTransaction(destinationBounds, direction, tx, wct);
+ applyFinishBoundsResize(wct, direction);
+ }
+
+ private void prepareFinishResizeTransaction(Rect destinationBounds,
+ @PipAnimationController.TransitionDirection int direction,
+ SurfaceControl.Transaction tx,
+ WindowContainerTransaction wct) {
final Rect taskBounds;
if (isInPipDirection(direction)) {
// If we are animating from fullscreen using a bounds animation, then reset the
@@ -762,7 +808,6 @@
wct.setBounds(mToken, taskBounds);
wct.setBoundsChangeTransaction(mToken, tx);
- applyFinishBoundsResize(wct, direction);
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java
index 7a18ec3..1fbe58d 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java
@@ -36,6 +36,7 @@
import android.util.Pair;
import android.view.DisplayInfo;
import android.view.IPinnedStackController;
+import android.view.SurfaceControl;
import android.window.WindowContainerTransaction;
import com.android.systemui.Dependency;
@@ -94,9 +95,12 @@
*/
private final DisplayChangeController.OnDisplayChangingListener mRotationController = (
int displayId, int fromRotation, int toRotation, WindowContainerTransaction t) -> {
+ // If there is an animation running (ie. from a shelf offset), then ensure that we calculate
+ // the bounds for the next orientation using the destination bounds of the animation
+ // TODO: Techincally this should account for movement animation bounds as well
+ Rect currentBounds = mPipTaskOrganizer.getCurrentOrAnimatingBounds();
final boolean changed = mPipBoundsHandler.onDisplayRotationChanged(mTmpNormalBounds,
- mPipTaskOrganizer.getLastReportedBounds(), mTmpInsetBounds, displayId, fromRotation,
- toRotation, t);
+ currentBounds, mTmpInsetBounds, displayId, fromRotation, toRotation, t);
if (changed) {
// If the pip was in the offset zone earlier, adjust the new bounds to the bottom of the
// movement bounds
@@ -116,7 +120,7 @@
}
updateMovementBounds(mTmpNormalBounds, true /* fromRotation */,
- false /* fromImeAdjustment */, false /* fromShelfAdjustment */);
+ false /* fromImeAdjustment */, false /* fromShelfAdjustment */, t);
}
};
@@ -194,7 +198,8 @@
@Override
public void onMovementBoundsChanged(boolean fromImeAdjustment) {
mHandler.post(() -> updateMovementBounds(null /* toBounds */,
- false /* fromRotation */, fromImeAdjustment, false /* fromShelfAdjustment */));
+ false /* fromRotation */, fromImeAdjustment, false /* fromShelfAdjustment */,
+ null /* windowContainerTransaction */));
}
@Override
@@ -327,7 +332,7 @@
mTouchHandler.onShelfVisibilityChanged(visible, shelfHeight);
updateMovementBounds(mPipTaskOrganizer.getLastReportedBounds(),
false /* fromRotation */, false /* fromImeAdjustment */,
- true /* fromShelfAdjustment */);
+ true /* fromShelfAdjustment */, null /* windowContainerTransaction */);
}
});
}
@@ -387,15 +392,16 @@
}
private void updateMovementBounds(@Nullable Rect toBounds, boolean fromRotation,
- boolean fromImeAdjustment, boolean fromShelfAdjustment) {
+ boolean fromImeAdjustment, boolean fromShelfAdjustment,
+ WindowContainerTransaction wct) {
// Populate inset / normal bounds and DisplayInfo from mPipBoundsHandler before
// passing to mTouchHandler/mPipTaskOrganizer
final Rect outBounds = new Rect(toBounds);
mPipBoundsHandler.onMovementBoundsChanged(mTmpInsetBounds, mTmpNormalBounds,
outBounds, mTmpDisplayInfo);
// mTouchHandler would rely on the bounds populated from mPipTaskOrganizer
- mPipTaskOrganizer.onMovementBoundsChanged(outBounds, fromRotation,
- fromImeAdjustment, fromShelfAdjustment);
+ mPipTaskOrganizer.onMovementBoundsChanged(outBounds, fromRotation, fromImeAdjustment,
+ fromShelfAdjustment, wct);
mTouchHandler.onMovementBoundsChanged(mTmpInsetBounds, mTmpNormalBounds,
outBounds, fromImeAdjustment, fromShelfAdjustment,
mTmpDisplayInfo.rotation);
diff --git a/packages/SystemUI/src/com/android/systemui/power/PowerUI.java b/packages/SystemUI/src/com/android/systemui/power/PowerUI.java
index 078c540..66804be 100644
--- a/packages/SystemUI/src/com/android/systemui/power/PowerUI.java
+++ b/packages/SystemUI/src/com/android/systemui/power/PowerUI.java
@@ -225,6 +225,8 @@
@VisibleForTesting
final class Receiver extends BroadcastReceiver {
+ private boolean mHasReceivedBattery = false;
+
public void init() {
// Register for Intent broadcasts for...
IntentFilter filter = new IntentFilter();
@@ -234,6 +236,17 @@
filter.addAction(Intent.ACTION_SCREEN_ON);
filter.addAction(Intent.ACTION_USER_SWITCHED);
mBroadcastDispatcher.registerReceiverWithHandler(this, filter, mHandler);
+ // Force get initial values. Relying on Sticky behavior until API for getting info.
+ if (!mHasReceivedBattery) {
+ // Get initial state
+ Intent intent = mContext.registerReceiver(
+ null,
+ new IntentFilter(Intent.ACTION_BATTERY_CHANGED)
+ );
+ if (intent != null) {
+ onReceive(mContext, intent);
+ }
+ }
}
@Override
@@ -246,6 +259,7 @@
}
});
} else if (Intent.ACTION_BATTERY_CHANGED.equals(action)) {
+ mHasReceivedBattery = true;
final int oldBatteryLevel = mBatteryLevel;
mBatteryLevel = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, 100);
final int oldBatteryStatus = mBatteryStatus;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerImpl.java
index 00419e6..7f35161 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerImpl.java
@@ -74,7 +74,8 @@
protected boolean mPowerSave;
private boolean mAodPowerSave;
private boolean mTestmode = false;
- private boolean mHasReceivedBattery = false;
+ @VisibleForTesting
+ boolean mHasReceivedBattery = false;
private Estimate mEstimate;
private boolean mFetchingEstimate = false;
@@ -102,6 +103,16 @@
@Override
public void init() {
registerReceiver();
+ if (!mHasReceivedBattery) {
+ // Get initial state. Relying on Sticky behavior until API for getting info.
+ Intent intent = mContext.registerReceiver(
+ null,
+ new IntentFilter(Intent.ACTION_BATTERY_CHANGED)
+ );
+ if (intent != null && !mHasReceivedBattery) {
+ onReceive(mContext, intent);
+ }
+ }
updatePowerSave();
updateEstimate();
}
diff --git a/packages/SystemUI/src/com/android/systemui/usb/UsbDebuggingActivity.java b/packages/SystemUI/src/com/android/systemui/usb/UsbDebuggingActivity.java
index bc2a55c..7561af7 100644
--- a/packages/SystemUI/src/com/android/systemui/usb/UsbDebuggingActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/usb/UsbDebuggingActivity.java
@@ -139,13 +139,18 @@
if (mDisconnectedReceiver != null) {
mBroadcastDispatcher.unregisterReceiver(mDisconnectedReceiver);
}
+ super.onStop();
+ }
+
+ @Override
+ protected void onDestroy() {
// If the ADB service has not yet been notified due to this dialog being closed in some
// other way then notify the service to deny the connection to ensure system_server sends
// a response to adbd.
if (!mServiceNotified) {
notifyService(false);
}
- super.onStop();
+ super.onDestroy();
}
@Override
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
index 7bc453a..9e056cf 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
@@ -211,6 +211,13 @@
}
@Test
+ public void testInitialBatteryLevelRequested() {
+ mTestableLooper.processAllMessages();
+
+ assertThat(mKeyguardUpdateMonitor.mBatteryStatus).isNotNull();
+ }
+
+ @Test
public void testReceiversRegistered() {
verify(mBroadcastDispatcher, atLeastOnce()).registerReceiverWithHandler(
eq(mKeyguardUpdateMonitor.mBroadcastReceiver),
diff --git a/packages/SystemUI/tests/src/com/android/systemui/SysuiTestableContext.java b/packages/SystemUI/tests/src/com/android/systemui/SysuiTestableContext.java
index 95ff98a..f29f042 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/SysuiTestableContext.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/SysuiTestableContext.java
@@ -67,27 +67,35 @@
@Override
public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
- mRegisteredReceivers.add(receiver);
+ if (receiver != null) {
+ mRegisteredReceivers.add(receiver);
+ }
return super.registerReceiver(receiver, filter);
}
@Override
public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter,
String broadcastPermission, Handler scheduler) {
- mRegisteredReceivers.add(receiver);
+ if (receiver != null) {
+ mRegisteredReceivers.add(receiver);
+ }
return super.registerReceiver(receiver, filter, broadcastPermission, scheduler);
}
@Override
public Intent registerReceiverAsUser(BroadcastReceiver receiver, UserHandle user,
IntentFilter filter, String broadcastPermission, Handler scheduler) {
- mRegisteredReceivers.add(receiver);
+ if (receiver != null) {
+ mRegisteredReceivers.add(receiver);
+ }
return super.registerReceiverAsUser(receiver, user, filter, broadcastPermission, scheduler);
}
@Override
public void unregisterReceiver(BroadcastReceiver receiver) {
- mRegisteredReceivers.remove(receiver);
+ if (receiver != null) {
+ mRegisteredReceivers.remove(receiver);
+ }
super.unregisterReceiver(receiver);
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/BatteryControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/BatteryControllerTest.java
index f83fbd4..eca48c8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/BatteryControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/BatteryControllerTest.java
@@ -59,6 +59,11 @@
}
@Test
+ public void testBatteryInitialized() {
+ Assert.assertTrue(mBatteryController.mHasReceivedBattery);
+ }
+
+ @Test
public void testIndependentAODBatterySaver_true() {
PowerSaveState state = new PowerSaveState.Builder()
.setBatterySaverEnabled(true)
diff --git a/services/core/java/com/android/server/adb/AdbDebuggingManager.java b/services/core/java/com/android/server/adb/AdbDebuggingManager.java
index df3b688..ed83a64 100644
--- a/services/core/java/com/android/server/adb/AdbDebuggingManager.java
+++ b/services/core/java/com/android/server/adb/AdbDebuggingManager.java
@@ -878,6 +878,7 @@
case MESSAGE_ADB_DENY:
if (mThread != null) {
+ Slog.w(TAG, "Denying adb confirmation");
mThread.sendResponse("NO");
logAdbConnectionChanged(null, AdbProtoEnums.USER_DENIED, false);
}
@@ -887,7 +888,7 @@
String key = (String) msg.obj;
if ("trigger_restart_min_framework".equals(
SystemProperties.get("vold.decrypt"))) {
- Slog.d(TAG, "Deferring adb confirmation until after vold decrypt");
+ Slog.w(TAG, "Deferring adb confirmation until after vold decrypt");
if (mThread != null) {
mThread.sendResponse("NO");
logAdbConnectionChanged(key, AdbProtoEnums.DENIED_VOLD_DECRYPT, false);
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index e77b361..c9dbacd 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -8086,6 +8086,12 @@
}
int checkContentProviderUriPermission(Uri uri, int userId, int callingUid, int modeFlags) {
+ if (Thread.holdsLock(mActivityTaskManager.getGlobalLock())) {
+ Slog.wtf(TAG, new IllegalStateException("Unable to check Uri permission"
+ + " because caller is holding WM lock; assuming permission denied"));
+ return PackageManager.PERMISSION_DENIED;
+ }
+
final String name = uri.getAuthority();
final long ident = Binder.clearCallingIdentity();
ContentProviderHolder holder = null;
diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java
index 31712ef..b378621 100644
--- a/services/core/java/com/android/server/wm/ActivityStarter.java
+++ b/services/core/java/com/android/server/wm/ActivityStarter.java
@@ -640,13 +640,10 @@
}
// If the caller hasn't already resolved the activity, we're willing
- // to do so here, but because that may require acquiring the AM lock
- // as part of calculating the NeededUriGrants, we must never hold
- // the WM lock here to avoid deadlocking.
+ // to do so here. If the caller is already holding the WM lock here,
+ // and we need to check dynamic Uri permissions, then we're forced
+ // to assume those permissions are denied to avoid deadlocking.
if (mRequest.activityInfo == null) {
- if (Thread.holdsLock(mService.mGlobalLock)) {
- Slog.wtf(TAG, new IllegalStateException("Caller must not hold WM lock"));
- }
mRequest.resolveActivity(mSupervisor);
}