Merge "Watchdog: add Audio HAL v4.0 to the dump list" into pi-dev
diff --git a/cmds/statsd/src/metrics/CountMetricProducer.cpp b/cmds/statsd/src/metrics/CountMetricProducer.cpp
index e21392c..511aec3 100644
--- a/cmds/statsd/src/metrics/CountMetricProducer.cpp
+++ b/cmds/statsd/src/metrics/CountMetricProducer.cpp
@@ -122,6 +122,12 @@
VLOG("Metric %lld onSlicedConditionMayChange", (long long)mMetricId);
}
+
+void CountMetricProducer::clearPastBucketsLocked(const int64_t dumpTimeNs) {
+ flushIfNeededLocked(dumpTimeNs);
+ mPastBuckets.clear();
+}
+
void CountMetricProducer::onDumpReportLocked(const int64_t dumpTimeNs,
const bool include_current_partial_bucket,
ProtoOutputStream* protoOutput) {
diff --git a/cmds/statsd/src/metrics/CountMetricProducer.h b/cmds/statsd/src/metrics/CountMetricProducer.h
index cafc882..8e94a75 100644
--- a/cmds/statsd/src/metrics/CountMetricProducer.h
+++ b/cmds/statsd/src/metrics/CountMetricProducer.h
@@ -59,6 +59,8 @@
const bool include_current_partial_bucket,
android::util::ProtoOutputStream* protoOutput) override;
+ void clearPastBucketsLocked(const int64_t dumpTimeNs) override;
+
// Internal interface to handle condition change.
void onConditionChangedLocked(const bool conditionMet, const int64_t eventTime) override;
diff --git a/cmds/statsd/src/metrics/DurationMetricProducer.cpp b/cmds/statsd/src/metrics/DurationMetricProducer.cpp
index 3661b31..5610492 100644
--- a/cmds/statsd/src/metrics/DurationMetricProducer.cpp
+++ b/cmds/statsd/src/metrics/DurationMetricProducer.cpp
@@ -438,6 +438,11 @@
mPastBuckets.clear();
}
+void DurationMetricProducer::clearPastBucketsLocked(const int64_t dumpTimeNs) {
+ flushIfNeededLocked(dumpTimeNs);
+ mPastBuckets.clear();
+}
+
void DurationMetricProducer::onDumpReportLocked(const int64_t dumpTimeNs,
const bool include_current_partial_bucket,
ProtoOutputStream* protoOutput) {
diff --git a/cmds/statsd/src/metrics/DurationMetricProducer.h b/cmds/statsd/src/metrics/DurationMetricProducer.h
index 80fbdde..f755294 100644
--- a/cmds/statsd/src/metrics/DurationMetricProducer.h
+++ b/cmds/statsd/src/metrics/DurationMetricProducer.h
@@ -65,6 +65,8 @@
const bool include_current_partial_bucket,
android::util::ProtoOutputStream* protoOutput) override;
+ void clearPastBucketsLocked(const int64_t dumpTimeNs) override;
+
// Internal interface to handle condition change.
void onConditionChangedLocked(const bool conditionMet, const int64_t eventTime) override;
diff --git a/cmds/statsd/src/metrics/EventMetricProducer.cpp b/cmds/statsd/src/metrics/EventMetricProducer.cpp
index 2f2679e..23f780a 100644
--- a/cmds/statsd/src/metrics/EventMetricProducer.cpp
+++ b/cmds/statsd/src/metrics/EventMetricProducer.cpp
@@ -100,6 +100,10 @@
return buffer;
}
+void EventMetricProducer::clearPastBucketsLocked(const int64_t dumpTimeNs) {
+ mProto->clear();
+}
+
void EventMetricProducer::onDumpReportLocked(const int64_t dumpTimeNs,
const bool include_current_partial_bucket,
ProtoOutputStream* protoOutput) {
diff --git a/cmds/statsd/src/metrics/EventMetricProducer.h b/cmds/statsd/src/metrics/EventMetricProducer.h
index 5c29174..23302c4 100644
--- a/cmds/statsd/src/metrics/EventMetricProducer.h
+++ b/cmds/statsd/src/metrics/EventMetricProducer.h
@@ -49,6 +49,7 @@
void onDumpReportLocked(const int64_t dumpTimeNs,
const bool include_current_partial_bucket,
android::util::ProtoOutputStream* protoOutput) override;
+ void clearPastBucketsLocked(const int64_t dumpTimeNs) override;
// Internal interface to handle condition change.
void onConditionChangedLocked(const bool conditionMet, const int64_t eventTime) override;
diff --git a/cmds/statsd/src/metrics/GaugeMetricProducer.cpp b/cmds/statsd/src/metrics/GaugeMetricProducer.cpp
index 1270856..005cb71 100644
--- a/cmds/statsd/src/metrics/GaugeMetricProducer.cpp
+++ b/cmds/statsd/src/metrics/GaugeMetricProducer.cpp
@@ -160,6 +160,12 @@
}
}
+void GaugeMetricProducer::clearPastBucketsLocked(const int64_t dumpTimeNs) {
+ flushIfNeededLocked(dumpTimeNs);
+ mPastBuckets.clear();
+ mSkippedBuckets.clear();
+}
+
void GaugeMetricProducer::onDumpReportLocked(const int64_t dumpTimeNs,
const bool include_current_partial_bucket,
ProtoOutputStream* protoOutput) {
diff --git a/cmds/statsd/src/metrics/GaugeMetricProducer.h b/cmds/statsd/src/metrics/GaugeMetricProducer.h
index 71d5912..8af2f36 100644
--- a/cmds/statsd/src/metrics/GaugeMetricProducer.h
+++ b/cmds/statsd/src/metrics/GaugeMetricProducer.h
@@ -91,6 +91,7 @@
void onDumpReportLocked(const int64_t dumpTimeNs,
const bool include_current_partial_bucket,
android::util::ProtoOutputStream* protoOutput) override;
+ void clearPastBucketsLocked(const int64_t dumpTimeNs) override;
// for testing
GaugeMetricProducer(const ConfigKey& key, const GaugeMetric& gaugeMetric,
diff --git a/cmds/statsd/src/metrics/MetricProducer.h b/cmds/statsd/src/metrics/MetricProducer.h
index 532ecbf..4239649 100644
--- a/cmds/statsd/src/metrics/MetricProducer.h
+++ b/cmds/statsd/src/metrics/MetricProducer.h
@@ -119,6 +119,11 @@
return onDumpReportLocked(dumpTimeNs, include_current_partial_bucket, protoOutput);
}
+ void clearPastBuckets(const int64_t dumpTimeNs) {
+ std::lock_guard<std::mutex> lock(mMutex);
+ return clearPastBucketsLocked(dumpTimeNs);
+ }
+
void dumpStates(FILE* out, bool verbose) const {
std::lock_guard<std::mutex> lock(mMutex);
dumpStatesLocked(out, verbose);
@@ -177,6 +182,7 @@
virtual void onDumpReportLocked(const int64_t dumpTimeNs,
const bool include_current_partial_bucket,
android::util::ProtoOutputStream* protoOutput) = 0;
+ virtual void clearPastBucketsLocked(const int64_t dumpTimeNs) = 0;
virtual size_t byteSizeLocked() const = 0;
virtual void dumpStatesLocked(FILE* out, bool verbose) const = 0;
diff --git a/cmds/statsd/src/metrics/MetricsManager.cpp b/cmds/statsd/src/metrics/MetricsManager.cpp
index 47a1a86..0d3aebf 100644
--- a/cmds/statsd/src/metrics/MetricsManager.cpp
+++ b/cmds/statsd/src/metrics/MetricsManager.cpp
@@ -201,6 +201,8 @@
protoOutput->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED | FIELD_ID_METRICS);
producer->onDumpReport(dumpTimeStampNs, include_current_partial_bucket, protoOutput);
protoOutput->end(token);
+ } else {
+ producer->clearPastBuckets(dumpTimeStampNs);
}
}
for (const auto& annotation : mAnnotations) {
diff --git a/cmds/statsd/src/metrics/ValueMetricProducer.cpp b/cmds/statsd/src/metrics/ValueMetricProducer.cpp
index 27fd78f..506cf38 100644
--- a/cmds/statsd/src/metrics/ValueMetricProducer.cpp
+++ b/cmds/statsd/src/metrics/ValueMetricProducer.cpp
@@ -151,6 +151,12 @@
mPastBuckets.clear();
}
+void ValueMetricProducer::clearPastBucketsLocked(const int64_t dumpTimeNs) {
+ flushIfNeededLocked(dumpTimeNs);
+ mPastBuckets.clear();
+ mSkippedBuckets.clear();
+}
+
void ValueMetricProducer::onDumpReportLocked(const int64_t dumpTimeNs,
const bool include_current_partial_bucket,
ProtoOutputStream* protoOutput) {
diff --git a/cmds/statsd/src/metrics/ValueMetricProducer.h b/cmds/statsd/src/metrics/ValueMetricProducer.h
index 8df30d3..64604c2 100644
--- a/cmds/statsd/src/metrics/ValueMetricProducer.h
+++ b/cmds/statsd/src/metrics/ValueMetricProducer.h
@@ -89,6 +89,7 @@
void onDumpReportLocked(const int64_t dumpTimeNs,
const bool include_current_partial_bucket,
android::util::ProtoOutputStream* protoOutput) override;
+ void clearPastBucketsLocked(const int64_t dumpTimeNs) override;
// Internal interface to handle condition change.
void onConditionChangedLocked(const bool conditionMet, const int64_t eventTime) override;
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index c5b8019..725f240 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -5102,6 +5102,10 @@
savedBundle.getBoolean(EXTRA_SHOW_CHRONOMETER));
publicExtras.putBoolean(EXTRA_CHRONOMETER_COUNT_DOWN,
savedBundle.getBoolean(EXTRA_CHRONOMETER_COUNT_DOWN));
+ String appName = savedBundle.getString(EXTRA_SUBSTITUTE_APP_NAME);
+ if (appName != null) {
+ publicExtras.putString(EXTRA_SUBSTITUTE_APP_NAME, appName);
+ }
mN.extras = publicExtras;
RemoteViews view;
if (ambient) {
diff --git a/core/java/android/hardware/radio/RadioMetadata.java b/core/java/android/hardware/radio/RadioMetadata.java
index 6e51060..baa7a50 100644
--- a/core/java/android/hardware/radio/RadioMetadata.java
+++ b/core/java/android/hardware/radio/RadioMetadata.java
@@ -269,6 +269,29 @@
mBundle = in.readBundle();
}
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder("RadioMetadata[");
+
+ final String removePrefix = "android.hardware.radio.metadata";
+
+ boolean first = true;
+ for (String key : mBundle.keySet()) {
+ if (first) first = false;
+ else sb.append(", ");
+
+ String keyDisp = key;
+ if (key.startsWith(removePrefix)) keyDisp = key.substring(removePrefix.length());
+
+ sb.append(keyDisp);
+ sb.append('=');
+ sb.append(mBundle.get(key));
+ }
+
+ sb.append("]");
+ return sb.toString();
+ }
+
/**
* Returns {@code true} if the given key is contained in the meta data
*
diff --git a/core/java/com/android/internal/policy/DividerSnapAlgorithm.java b/core/java/com/android/internal/policy/DividerSnapAlgorithm.java
index 3af3e2a..a3c7a9e 100644
--- a/core/java/com/android/internal/policy/DividerSnapAlgorithm.java
+++ b/core/java/com/android/internal/policy/DividerSnapAlgorithm.java
@@ -344,7 +344,7 @@
if (dockedSide == DOCKED_LEFT) {
position += mInsets.left;
} else if (dockedSide == DOCKED_RIGHT) {
- position = mDisplayWidth - position - mInsets.right;
+ position = mDisplayWidth - position - mInsets.right - mDividerSize;
}
}
mTargets.add(new SnapTarget(position, position, SnapTarget.FLAG_NONE));
diff --git a/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CaptivePortalLoginActivity.java b/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CaptivePortalLoginActivity.java
index 7479d9aa..b1933373 100644
--- a/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CaptivePortalLoginActivity.java
+++ b/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CaptivePortalLoginActivity.java
@@ -111,13 +111,11 @@
mWebView.setWebViewClient(mWebViewClient);
mWebView.setWebChromeClient(new MyWebChromeClient());
- mNetwork = getNetworkForCaptivePortal();
- if (mNetwork == null) {
+ final Network network = getNetworkForCaptivePortal();
+ if (network == null) {
requestNetworkForCaptivePortal();
} else {
- mCm.bindProcessToNetwork(mNetwork);
- mCm.setProcessDefaultNetworkForHostResolution(
- ResolvUtil.getNetworkWithUseLocalNameserversFlag(mNetwork));
+ setNetwork(network);
// Start initial page load so WebView finishes loading proxy settings.
// Actual load of mUrl is initiated by MyWebViewClient.
mWebView.loadData("", "text/html", null);
@@ -159,6 +157,15 @@
super.onDestroy();
}
+ private void setNetwork(Network network) {
+ if (network != null) {
+ mCm.bindProcessToNetwork(network);
+ mCm.setProcessDefaultNetworkForHostResolution(
+ ResolvUtil.getNetworkWithUseLocalNameserversFlag(network));
+ }
+ mNetwork = network;
+ }
+
// Find WebView's proxy BroadcastReceiver and prompt it to read proxy system properties.
private void setWebViewProxy() {
LoadedApk loadedApk = getApplication().mLoadedApk;
@@ -235,6 +242,7 @@
private void testForCaptivePortal() {
mTestingThread = new Thread(new Runnable() {
public void run() {
+ final Network network = ResolvUtil.makeNetworkWithPrivateDnsBypass(mNetwork);
// Give time for captive portal to open.
try {
Thread.sleep(1000);
@@ -245,7 +253,7 @@
int httpResponseCode = 500;
int oldTag = TrafficStats.getAndSetThreadStatsTag(TrafficStats.TAG_SYSTEM_PROBE);
try {
- urlConnection = (HttpURLConnection) mNetwork.openConnection(
+ urlConnection = (HttpURLConnection) network.openConnection(
new URL(mCm.getCaptivePortalServerUrl()));
urlConnection.setInstanceFollowRedirects(false);
urlConnection.setConnectTimeout(SOCKET_TIMEOUT_MS);
@@ -292,8 +300,7 @@
@Override
public void onAvailable(Network network) {
if (DBG) logd("Network available: " + network);
- mCm.bindProcessToNetwork(network);
- mNetwork = network;
+ setNetwork(network);
runOnUiThreadIfNotFinishing(() -> {
if (mReload) {
mWebView.reload();
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/WindowManagerWrapper.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/WindowManagerWrapper.java
index 07b980e..ed2f831 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/WindowManagerWrapper.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/WindowManagerWrapper.java
@@ -26,6 +26,10 @@
import android.view.WindowManager;
import android.view.WindowManagerGlobal;
+import static android.view.WindowManagerPolicyConstants.NAV_BAR_RIGHT;
+import static android.view.WindowManagerPolicyConstants.NAV_BAR_BOTTOM;
+import static android.view.WindowManagerPolicyConstants.NAV_BAR_LEFT;
+
import com.android.systemui.shared.recents.view.AppTransitionAnimationSpecsFuture;
import com.android.systemui.shared.recents.view.RecentsTransition;
@@ -58,6 +62,11 @@
public static final int TRANSIT_KEYGUARD_OCCLUDE = WindowManager.TRANSIT_KEYGUARD_OCCLUDE;
public static final int TRANSIT_KEYGUARD_UNOCCLUDE = WindowManager.TRANSIT_KEYGUARD_UNOCCLUDE;
+ public static final int NAV_BAR_POS_INVALID = -1;
+ public static final int NAV_BAR_POS_LEFT = NAV_BAR_LEFT;
+ public static final int NAV_BAR_POS_RIGHT = NAV_BAR_RIGHT;
+ public static final int NAV_BAR_POS_BOTTOM = NAV_BAR_BOTTOM;
+
public static final int ACTIVITY_TYPE_STANDARD = WindowConfiguration.ACTIVITY_TYPE_STANDARD;
public static final int WINDOWING_MODE_UNDEFINED = WindowConfiguration.WINDOWING_MODE_UNDEFINED;
@@ -141,4 +150,20 @@
Log.w(TAG, "Failed to set recents visibility");
}
}
+
+ /**
+ * @return The side of the screen where navigation bar is positioned.
+ * @see #NAV_BAR_POS_RIGHT
+ * @see #NAV_BAR_POS_LEFT
+ * @see #NAV_BAR_POS_BOTTOM
+ * @see #NAV_BAR_POS_INVALID
+ */
+ public int getNavBarPosition() {
+ try {
+ return WindowManagerGlobal.getWindowManagerService().getNavBarPosition();
+ } catch (RemoteException e) {
+ Log.w(TAG, "Failed to get nav bar position");
+ }
+ return NAV_BAR_POS_INVALID;
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java
index 1149ad1..79fea9f 100644
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java
+++ b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java
@@ -21,6 +21,8 @@
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
import static android.view.PointerIcon.TYPE_HORIZONTAL_DOUBLE_ARROW;
import static android.view.PointerIcon.TYPE_VERTICAL_DOUBLE_ARROW;
+import static android.view.WindowManager.DOCKED_LEFT;
+import static android.view.WindowManager.DOCKED_RIGHT;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
@@ -364,14 +366,7 @@
if (mStableInsets.isEmpty()) {
SystemServicesProxy.getInstance(mContext).getStableInsets(mStableInsets);
}
- int position = (int) (mState.mRatioPositionBeforeMinimized *
- (isHorizontalDivision() ? mDisplayHeight : mDisplayWidth));
- mSnapAlgorithm = null;
- initializeSnapAlgorithm();
-
- // Set the snap target before minimized but do not save until divider is attached and not
- // minimized because it does not know its minimized state yet.
- mSnapTargetBeforeMinimized = mSnapAlgorithm.calculateNonDismissingSnapTarget(position);
+ repositionSnapTargetBeforeMinimized();
}
public WindowManagerProxy getWindowManagerProxy() {
@@ -878,9 +873,36 @@
}
public void notifyDockSideChanged(int newDockSide) {
+ int oldDockSide = mDockSide;
mDockSide = newDockSide;
mMinimizedShadow.setDockSide(mDockSide);
requestLayout();
+
+ // Update the snap position to the new docked side with correct insets
+ SystemServicesProxy.getInstance(mContext).getStableInsets(mStableInsets);
+ mMinimizedSnapAlgorithm = null;
+ initializeSnapAlgorithm();
+
+ if (oldDockSide == DOCKED_LEFT && mDockSide == DOCKED_RIGHT
+ || oldDockSide == DOCKED_RIGHT && mDockSide == DOCKED_LEFT) {
+ repositionSnapTargetBeforeMinimized();
+ }
+
+ // Landscape to seascape rotation requires minimized to resize docked app correctly
+ if (mHomeStackResizable && mDockedStackMinimized) {
+ resizeStack(mMinimizedSnapAlgorithm.getMiddleTarget());
+ }
+ }
+
+ private void repositionSnapTargetBeforeMinimized() {
+ int position = (int) (mState.mRatioPositionBeforeMinimized *
+ (isHorizontalDivision() ? mDisplayHeight : mDisplayWidth));
+ mSnapAlgorithm = null;
+ initializeSnapAlgorithm();
+
+ // Set the snap target before minimized but do not save until divider is attached and not
+ // minimized because it does not know its minimized state yet.
+ mSnapTargetBeforeMinimized = mSnapAlgorithm.calculateNonDismissingSnapTarget(position);
}
private void updateDisplayInfo() {
@@ -962,6 +984,12 @@
if (mHomeStackResizable && mIsInMinimizeInteraction) {
calculateBoundsForPosition(mSnapTargetBeforeMinimized.position, mDockSide,
mDockedTaskRect);
+
+ // Move a right-docked-app to line up with the divider while dragging it
+ if (mDockSide == DOCKED_RIGHT) {
+ mDockedTaskRect.offset(Math.max(position, mStableInsets.left - mDividerSize)
+ - mDockedTaskRect.left + mDividerSize, 0);
+ }
calculateBoundsForPosition(mSnapTargetBeforeMinimized.position,
DockedDividerUtils.invertDockSide(mDockSide), mOtherTaskRect);
mWindowManagerProxy.resizeDockedStack(mDockedRect, mDockedTaskRect, mDockedTaskRect,
@@ -976,6 +1004,12 @@
calculateBoundsForPosition(isHorizontalDivision() ? mDisplayHeight : mDisplayWidth,
mDockSide, mDockedTaskRect);
}
+
+ // Move a docked app if from the right in position with the divider up to insets
+ if (mDockSide == DOCKED_RIGHT) {
+ mDockedTaskRect.offset(Math.max(position,
+ mStableInsets.left) - mDockedTaskRect.left, 0);
+ }
calculateBoundsForPosition(taskPosition, DockedDividerUtils.invertDockSide(mDockSide),
mOtherTaskRect);
mWindowManagerProxy.resizeDockedStack(mDockedRect, mDockedTaskRect, null,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
index 1d640880..ff0adb6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -24,6 +24,8 @@
import static com.android.systemui.keyguard.WakefulnessLifecycle.WAKEFULNESS_ASLEEP;
import static com.android.systemui.keyguard.WakefulnessLifecycle.WAKEFULNESS_AWAKE;
import static com.android.systemui.keyguard.WakefulnessLifecycle.WAKEFULNESS_WAKING;
+import static com.android.systemui.shared.system.WindowManagerWrapper.NAV_BAR_POS_LEFT;
+import static com.android.systemui.shared.system.WindowManagerWrapper.NAV_BAR_POS_INVALID;
import static com.android.systemui.statusbar.NotificationLockscreenUserManager
.NOTIFICATION_UNLOCKED_BY_WORK_CHALLENGE_ACTION;
import static com.android.systemui.statusbar.NotificationLockscreenUserManager.PERMISSION_SELF;
@@ -178,6 +180,7 @@
import com.android.systemui.recents.events.activity.AppTransitionFinishedEvent;
import com.android.systemui.recents.events.activity.UndockingTaskEvent;
import com.android.systemui.recents.misc.SystemServicesProxy;
+import com.android.systemui.shared.system.WindowManagerWrapper;
import com.android.systemui.stackdivider.Divider;
import com.android.systemui.stackdivider.WindowManagerProxy;
import com.android.systemui.statusbar.ActivatableNotificationView;
@@ -207,14 +210,12 @@
import com.android.systemui.statusbar.NotificationViewHierarchyManager;
import com.android.systemui.statusbar.RemoteInputController;
import com.android.systemui.statusbar.ScrimView;
-import com.android.systemui.statusbar.SignalClusterView;
import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.statusbar.VibratorHelper;
import com.android.systemui.statusbar.notification.AboveShelfObserver;
import com.android.systemui.statusbar.notification.ActivityLaunchAnimator;
import com.android.systemui.statusbar.notification.VisualStabilityManager;
import com.android.systemui.statusbar.phone.UnlockMethodCache.OnUnlockMethodChangedListener;
-import com.android.systemui.statusbar.phone.KeyguardDismissUtil;
import com.android.systemui.statusbar.policy.BatteryController;
import com.android.systemui.statusbar.policy.BatteryController.BatteryStateChangeCallback;
import com.android.systemui.statusbar.policy.BrightnessMirrorController;
@@ -1339,8 +1340,15 @@
}
int dockSide = WindowManagerProxy.getInstance().getDockSide();
if (dockSide == WindowManager.DOCKED_INVALID) {
- return mRecents.splitPrimaryTask(NavigationBarGestureHelper.DRAG_MODE_NONE,
- ActivityManager.SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT, null, metricsDockAction);
+ final int navbarPos = WindowManagerWrapper.getInstance().getNavBarPosition();
+ if (navbarPos == NAV_BAR_POS_INVALID) {
+ return false;
+ }
+ int createMode = navbarPos == NAV_BAR_POS_LEFT
+ ? ActivityManager.SPLIT_SCREEN_CREATE_MODE_BOTTOM_OR_RIGHT
+ : ActivityManager.SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT;
+ return mRecents.splitPrimaryTask(NavigationBarGestureHelper.DRAG_MODE_NONE, createMode,
+ null, metricsDockAction);
} else {
Divider divider = getComponent(Divider.class);
if (divider != null && divider.isMinimized() && !divider.isHomeStackResizable()) {
@@ -1896,6 +1904,13 @@
}
}
+ if (!panelsEnabled()) {
+ if (DEBUG) {
+ Log.d(TAG, "No peeking: disabled panel : " + sbn.getKey());
+ }
+ return false;
+ }
+
if (sbn.getNotification().fullScreenIntent != null) {
if (mAccessibilityManager.isTouchExplorationEnabled()) {
if (DEBUG) Log.d(TAG, "No peeking: accessible fullscreen: " + sbn.getKey());
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
index d3cb5a6..37e0005 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
@@ -443,6 +443,30 @@
}
@Test
+ public void testPeek_disabledStatusBar() {
+ Notification n = new Notification.Builder(getContext(), "a").build();
+ StatusBarNotification sbn = new StatusBarNotification("a", "a", 0, "a", 0, 0, n,
+ UserHandle.of(0), null, 0);
+ NotificationData.Entry entry = new NotificationData.Entry(sbn);
+ mStatusBar.disable(StatusBarManager.DISABLE_EXPAND, 0, false /* animate */);
+
+ assertFalse("The panel shouldn't allow peek while disabled",
+ mStatusBar.shouldPeek(entry, sbn));
+ }
+
+ @Test
+ public void testPeek_disabledNotificationShade() {
+ Notification n = new Notification.Builder(getContext(), "a").build();
+ StatusBarNotification sbn = new StatusBarNotification("a", "a", 0, "a", 0, 0, n,
+ UserHandle.of(0), null, 0);
+ NotificationData.Entry entry = new NotificationData.Entry(sbn);
+ mStatusBar.disable(0, StatusBarManager.DISABLE2_NOTIFICATION_SHADE, false /* animate */);
+
+ assertFalse("The panel shouldn't allow peek while notitifcation shade disabled",
+ mStatusBar.shouldPeek(entry, sbn));
+ }
+
+ @Test
public void testLogHidden() {
try {
mStatusBar.handleVisibleToUserChanged(false);
diff --git a/services/core/java/com/android/server/EventLogTags.logtags b/services/core/java/com/android/server/EventLogTags.logtags
index 2465ba2..d869734 100644
--- a/services/core/java/com/android/server/EventLogTags.logtags
+++ b/services/core/java/com/android/server/EventLogTags.logtags
@@ -33,10 +33,11 @@
# It logs the time remaining before the device would've normally gone to sleep without the request.
2731 power_soft_sleep_requested (savedwaketimems|2)
# Power save state has changed. See BatterySaverController.java for the details.
-2739 battery_saver_mode (prevOffOrOn|1|5),(nowOffOrOn|1|5),(interactive|1|5),(features|3|5)
+2739 battery_saver_mode (prevOffOrOn|1|5),(nowOffOrOn|1|5),(interactive|1|5),(features|3|5),(reason|1|5)
27390 battery_saving_stats (batterySaver|1|5),(interactive|1|5),(doze|1|5),(delta_duration|2|3),(delta_battery_drain|1|1),(delta_battery_drain_percent|1|6),(total_duration|2|3),(total_battery_drain|1|1),(total_battery_drain_percent|1|6)
# Note when the user activity timeout has been overriden by ActivityManagerService
27391 user_activity_timeout_override (override|2|3)
+27392 battery_saver_setting (threshold|1)
#
# Leave IDs through 2740 for more power logs (2730 used by battery_discharge above)
diff --git a/services/core/java/com/android/server/content/ContentService.java b/services/core/java/com/android/server/content/ContentService.java
index e840a29..03d8f39 100644
--- a/services/core/java/com/android/server/content/ContentService.java
+++ b/services/core/java/com/android/server/content/ContentService.java
@@ -1279,7 +1279,9 @@
case Process.SYSTEM_UID:
break; // Okay
default:
- throw new SecurityException("Invalid extras specified.");
+ final String msg = "Invalid extras specified.";
+ Log.w(TAG, msg + " requestsync -f/-F needs to run on 'adb shell'");
+ throw new SecurityException(msg);
}
}
}
diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java
index 06137cd..3b35d02 100644
--- a/services/core/java/com/android/server/display/DisplayPowerController.java
+++ b/services/core/java/com/android/server/display/DisplayPowerController.java
@@ -774,14 +774,8 @@
brightness = mScreenBrightnessForVr;
}
- boolean setBrightnessToOverride = false;
if (brightness < 0 && mPowerRequest.screenBrightnessOverride > 0) {
brightness = mPowerRequest.screenBrightnessOverride;
- // If there's a screen brightness override, we want to reset the brightness to it
- // whenever the user changes it, to communicate that these changes aren't taking
- // effect. However, for a nicer user experience, we don't do it here, but rather after
- // the temporary brightness has been taken into account.
- setBrightnessToOverride = true;
}
final boolean autoBrightnessEnabledInDoze =
@@ -804,12 +798,6 @@
brightnessIsTemporary = true;
}
- // Reset the brightness to the screen brightness override to communicate to the user that
- // her changes aren't taking effect.
- if (setBrightnessToOverride && !brightnessIsTemporary) {
- putScreenBrightnessSetting(brightness);
- }
-
final boolean autoBrightnessAdjustmentChanged = updateAutoBrightnessAdjustment();
if (autoBrightnessAdjustmentChanged) {
mTemporaryAutoBrightnessAdjustment = Float.NaN;
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index 1d5b1a3..18f3434 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -234,6 +234,7 @@
import android.util.proto.ProtoOutputStream;
import android.view.Display;
import android.view.DisplayCutout;
+import android.view.DisplayInfo;
import android.view.Gravity;
import android.view.HapticFeedbackConstants;
import android.view.IApplicationToken;
@@ -7191,14 +7192,35 @@
}
@Override
- public boolean isDockSideAllowed(int dockSide) {
+ public boolean isDockSideAllowed(int dockSide, int originalDockSide, int displayWidth,
+ int displayHeight, int displayRotation) {
+ final int barPosition = navigationBarPosition(displayWidth, displayHeight, displayRotation);
+ return isDockSideAllowed(dockSide, originalDockSide, barPosition, mNavigationBarCanMove);
+ }
- // We do not allow all dock sides at which the navigation bar touches the docked stack.
- if (!mNavigationBarCanMove) {
- return dockSide == DOCKED_TOP || dockSide == DOCKED_LEFT || dockSide == DOCKED_RIGHT;
- } else {
- return dockSide == DOCKED_TOP || dockSide == DOCKED_LEFT;
+ @VisibleForTesting
+ static boolean isDockSideAllowed(int dockSide, int originalDockSide,
+ int navBarPosition, boolean navigationBarCanMove) {
+ if (dockSide == DOCKED_TOP) {
+ return true;
}
+
+ if (navigationBarCanMove) {
+ // Only allow the dockside opposite to the nav bar position in landscape
+ return dockSide == DOCKED_LEFT && navBarPosition == NAV_BAR_RIGHT
+ || dockSide == DOCKED_RIGHT && navBarPosition == NAV_BAR_LEFT;
+ }
+
+ // Side is the same as original side
+ if (dockSide == originalDockSide) {
+ return true;
+ }
+
+ // Only if original docked side was top in portrait will allow left for landscape
+ if (dockSide == DOCKED_LEFT && originalDockSide == DOCKED_TOP) {
+ return true;
+ }
+ return false;
}
void sendCloseSystemWindows() {
diff --git a/services/core/java/com/android/server/policy/WindowManagerPolicy.java b/services/core/java/com/android/server/policy/WindowManagerPolicy.java
index ccbf502..8690a83 100644
--- a/services/core/java/com/android/server/policy/WindowManagerPolicy.java
+++ b/services/core/java/com/android/server/policy/WindowManagerPolicy.java
@@ -1706,11 +1706,19 @@
DisplayCutout displayCutout, Rect outInsets);
/**
+ * @param displayRotation the current display rotation
+ * @param displayWidth the current display width
+ * @param displayHeight the current display height
+ * @param dockSide the dockside asking if allowed
+ * @param originalDockSide the side that was original docked to in split screen
* @return True if a specified {@param dockSide} is allowed on the current device, or false
* otherwise. It is guaranteed that at least one dock side for a particular orientation
* is allowed, so for example, if DOCKED_RIGHT is not allowed, DOCKED_LEFT is allowed.
+ * If navigation bar is movable then the docked side would bias towards the
+ * {@param originalDockSide}.
*/
- public boolean isDockSideAllowed(int dockSide);
+ public boolean isDockSideAllowed(int dockSide, int originalDockSide, int displayWidth,
+ int displayHeight, int displayRotation);
/**
* Called when the configuration has changed, and it's safe to load new values from resources.
diff --git a/services/core/java/com/android/server/power/batterysaver/BatterySaverController.java b/services/core/java/com/android/server/power/batterysaver/BatterySaverController.java
index c527533..cb84cf3 100644
--- a/services/core/java/com/android/server/power/batterysaver/BatterySaverController.java
+++ b/services/core/java/com/android/server/power/batterysaver/BatterySaverController.java
@@ -90,6 +90,16 @@
*/
private final Plugin[] mPlugins;
+ public static final int REASON_AUTOMATIC_ON = 0;
+ public static final int REASON_AUTOMATIC_OFF = 1;
+ public static final int REASON_MANUAL_ON = 2;
+ public static final int REASON_MANUAL_OFF = 3;
+ public static final int REASON_STICKY_RESTORE = 4;
+ public static final int REASON_INTERACTIVE_CHANGED = 5;
+ public static final int REASON_POLICY_CHANGED = 6;
+ public static final int REASON_PLUGGED_IN = 7;
+ public static final int REASON_SETTING_CHANGED = 8;
+
/**
* Plugin interface. All methods are guaranteed to be called on the same (handler) thread.
*/
@@ -113,7 +123,8 @@
return; // No need to send it if not enabled.
}
// Don't send the broadcast, because we never did so in this case.
- mHandler.postStateChanged(/*sendBroadcast=*/ false);
+ mHandler.postStateChanged(/*sendBroadcast=*/ false,
+ REASON_INTERACTIVE_CHANGED);
break;
case Intent.ACTION_BATTERY_CHANGED:
synchronized (mLock) {
@@ -184,7 +195,7 @@
if (!isEnabled()) {
return; // No need to send it if not enabled.
}
- mHandler.postStateChanged(/*sendBroadcast=*/ true);
+ mHandler.postStateChanged(/*sendBroadcast=*/ true, REASON_POLICY_CHANGED);
}
private class MyHandler extends Handler {
@@ -199,9 +210,9 @@
super(looper);
}
- public void postStateChanged(boolean sendBroadcast) {
+ public void postStateChanged(boolean sendBroadcast, int reason) {
obtainMessage(MSG_STATE_CHANGED, sendBroadcast ?
- ARG_SEND_BROADCAST : ARG_DONT_SEND_BROADCAST, 0).sendToTarget();
+ ARG_SEND_BROADCAST : ARG_DONT_SEND_BROADCAST, reason).sendToTarget();
}
public void postSystemReady() {
@@ -212,7 +223,9 @@
public void dispatchMessage(Message msg) {
switch (msg.what) {
case MSG_STATE_CHANGED:
- handleBatterySaverStateChanged(msg.arg1 == ARG_SEND_BROADCAST);
+ handleBatterySaverStateChanged(
+ msg.arg1 == ARG_SEND_BROADCAST,
+ msg.arg2);
break;
case MSG_SYSTEM_READY:
@@ -227,14 +240,14 @@
/**
* Called by {@link PowerManagerService} to update the battery saver stete.
*/
- public void enableBatterySaver(boolean enable) {
+ public void enableBatterySaver(boolean enable, int reason) {
synchronized (mLock) {
if (mEnabled == enable) {
return;
}
mEnabled = enable;
- mHandler.postStateChanged(/*sendBroadcast=*/ true);
+ mHandler.postStateChanged(/*sendBroadcast=*/ true, reason);
}
}
@@ -275,7 +288,7 @@
* - When battery saver is on the interactive state changes.
* - When battery saver is on the battery saver policy changes.
*/
- void handleBatterySaverStateChanged(boolean sendBroadcast) {
+ void handleBatterySaverStateChanged(boolean sendBroadcast, int reason) {
final LowPowerModeListener[] listeners;
final boolean enabled;
@@ -287,7 +300,8 @@
mPreviouslyEnabled ? 1 : 0, // Previously off or on.
mEnabled ? 1 : 0, // Now off or on.
isInteractive ? 1 : 0, // Device interactive state.
- mEnabled ? mBatterySaverPolicy.toEventLogString() : "");
+ mEnabled ? mBatterySaverPolicy.toEventLogString() : "",
+ reason);
mPreviouslyEnabled = mEnabled;
listeners = mListeners.toArray(new LowPowerModeListener[mListeners.size()]);
diff --git a/services/core/java/com/android/server/power/batterysaver/BatterySaverStateMachine.java b/services/core/java/com/android/server/power/batterysaver/BatterySaverStateMachine.java
index 2860521..b9f31b1 100644
--- a/services/core/java/com/android/server/power/batterysaver/BatterySaverStateMachine.java
+++ b/services/core/java/com/android/server/power/batterysaver/BatterySaverStateMachine.java
@@ -18,6 +18,7 @@
import android.content.ContentResolver;
import android.content.Context;
import android.database.ContentObserver;
+import android.os.Handler;
import android.os.UserHandle;
import android.provider.Settings;
import android.provider.Settings.Global;
@@ -27,6 +28,7 @@
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.os.BackgroundThread;
+import com.android.server.EventLogTags;
import com.android.server.power.BatterySaverPolicy;
import com.android.server.power.BatterySaverStateMachineProto;
@@ -95,6 +97,18 @@
@GuardedBy("mLock")
private boolean mBatterySaverSnoozing;
+ /**
+ * Last reason passed to {@link #enableBatterySaverLocked}.
+ */
+ @GuardedBy("mLock")
+ private int mLastChangedIntReason;
+
+ /**
+ * Last reason passed to {@link #enableBatterySaverLocked}.
+ */
+ @GuardedBy("mLock")
+ private String mLastChangedStrReason;
+
private final ContentObserver mSettingsObserver = new ContentObserver(null) {
@Override
public void onChange(boolean selfChange) {
@@ -149,11 +163,25 @@
});
}
+ /**
+ * Run a {@link Runnable} on a background handler.
+ */
@VisibleForTesting
void runOnBgThread(Runnable r) {
BackgroundThread.getHandler().post(r);
}
+ /**
+ * Run a {@link Runnable} on a background handler, but lazily. If the same {@link Runnable},
+ * it'll be first removed before a new one is posted.
+ */
+ @VisibleForTesting
+ void runOnBgThreadLazy(Runnable r, int delayMillis) {
+ final Handler h = BackgroundThread.getHandler();
+ h.removeCallbacks(r);
+ h.postDelayed(r, delayMillis);
+ }
+
void refreshSettingsLocked() {
final ContentResolver cr = mContext.getContentResolver();
@@ -199,14 +227,23 @@
mSettingBatterySaverEnabledSticky = batterySaverEnabledSticky;
mSettingBatterySaverTriggerThreshold = batterySaverTriggerThreshold;
+ if (thresholdChanged) {
+ // To avoid spamming the event log, we throttle logging here.
+ runOnBgThreadLazy(mThresholdChangeLogger, 2000);
+ }
+
if (enabledChanged) {
final String reason = batterySaverEnabled
? "Global.low_power changed to 1" : "Global.low_power changed to 0";
enableBatterySaverLocked(/*enable=*/ batterySaverEnabled, /*manual=*/ true,
- reason);
+ BatterySaverController.REASON_SETTING_CHANGED, reason);
}
}
+ private final Runnable mThresholdChangeLogger = () -> {
+ EventLogTags.writeBatterySaverSetting(mSettingBatterySaverTriggerThreshold);
+ };
+
/**
* {@link com.android.server.power.PowerManagerService} calls it when battery state changes.
*
@@ -257,18 +294,26 @@
}
if (mIsPowered) {
updateSnoozingLocked(false, "Plugged in");
- enableBatterySaverLocked(/*enable=*/ false, /*manual=*/ false, "Plugged in");
+ enableBatterySaverLocked(/*enable=*/ false, /*manual=*/ false,
+ BatterySaverController.REASON_PLUGGED_IN,
+ "Plugged in");
} else if (mSettingBatterySaverEnabledSticky) {
// Re-enable BS.
- enableBatterySaverLocked(/*enable=*/ true, /*manual=*/ true, "Sticky restore");
+ enableBatterySaverLocked(/*enable=*/ true, /*manual=*/ true,
+ BatterySaverController.REASON_STICKY_RESTORE,
+ "Sticky restore");
} else if (mIsBatteryLevelLow) {
if (!mBatterySaverSnoozing && isAutoBatterySaverConfigured()) {
- enableBatterySaverLocked(/*enable=*/ true, /*manual=*/ false, "Auto ON");
+ enableBatterySaverLocked(/*enable=*/ true, /*manual=*/ false,
+ BatterySaverController.REASON_AUTOMATIC_ON,
+ "Auto ON");
}
} else { // Battery not low
- enableBatterySaverLocked(/*enable=*/ false, /*manual=*/ false, "Auto OFF");
+ enableBatterySaverLocked(/*enable=*/ false, /*manual=*/ false,
+ BatterySaverController.REASON_AUTOMATIC_OFF,
+ "Auto OFF");
}
}
@@ -284,6 +329,8 @@
}
synchronized (mLock) {
enableBatterySaverLocked(/*enable=*/ enabled, /*manual=*/ true,
+ (enabled ? BatterySaverController.REASON_MANUAL_ON
+ : BatterySaverController.REASON_MANUAL_OFF),
(enabled ? "Manual ON" : "Manual OFF"));
}
}
@@ -292,10 +339,11 @@
* Actually enable / disable battery saver. Write the new state to the global settings
* and propagate it to {@link #mBatterySaverController}.
*/
- private void enableBatterySaverLocked(boolean enable, boolean manual, String reason) {
+ private void enableBatterySaverLocked(boolean enable, boolean manual, int intReason,
+ String strReason) {
if (DEBUG) {
Slog.d(TAG, "enableBatterySaver: enable=" + enable + " manual=" + manual
- + " reason=" + reason);
+ + " reason=" + strReason + "(" + intReason + ")");
}
final boolean wasEnabled = mBatterySaverController.isEnabled();
@@ -309,6 +357,8 @@
if (DEBUG) Slog.d(TAG, "Can't enable: isPowered");
return;
}
+ mLastChangedIntReason = intReason;
+ mLastChangedStrReason = strReason;
if (manual) {
if (enable) {
@@ -330,12 +380,12 @@
mSettingBatterySaverEnabledSticky = enable;
putGlobalSetting(Global.LOW_POWER_MODE_STICKY, enable ? 1 : 0);
}
- mBatterySaverController.enableBatterySaver(enable);
+ mBatterySaverController.enableBatterySaver(enable, intReason);
if (DEBUG) {
Slog.d(TAG, "Battery saver: Enabled=" + enable
+ " manual=" + manual
- + " reason=" + reason);
+ + " reason=" + strReason + "(" + intReason + ")");
}
}
@@ -365,6 +415,11 @@
pw.print(" Enabled=");
pw.println(mBatterySaverController.isEnabled());
+ pw.print(" mLastChangedIntReason=");
+ pw.println(mLastChangedIntReason);
+ pw.print(" mLastChangedStrReason=");
+ pw.println(mLastChangedStrReason);
+
pw.print(" mBootCompleted=");
pw.println(mBootCompleted);
pw.print(" mSettingsLoaded=");
diff --git a/services/core/java/com/android/server/wm/DockedStackDividerController.java b/services/core/java/com/android/server/wm/DockedStackDividerController.java
index 2cd2ef1..c8baced 100644
--- a/services/core/java/com/android/server/wm/DockedStackDividerController.java
+++ b/services/core/java/com/android/server/wm/DockedStackDividerController.java
@@ -170,7 +170,7 @@
final int orientation = mTmpRect2.width() <= mTmpRect2.height()
? ORIENTATION_PORTRAIT
: ORIENTATION_LANDSCAPE;
- final int dockSide = TaskStack.getDockSideUnchecked(mTmpRect, mTmpRect2, orientation);
+ final int dockSide = getDockSide(mTmpRect, mTmpRect2, orientation);
final int position = DockedDividerUtils.calculatePositionForBounds(mTmpRect, dockSide,
getContentWidth());
@@ -191,6 +191,39 @@
return (int) (minWidth / mDisplayContent.getDisplayMetrics().density);
}
+ /**
+ * Get the current docked side. Determined by its location of {@param bounds} within
+ * {@param displayRect} but if both are the same, it will try to dock to each side and determine
+ * if allowed in its respected {@param orientation}.
+ *
+ * @param bounds bounds of the docked task to get which side is docked
+ * @param displayRect bounds of the display that contains the docked task
+ * @param orientation the origination of device
+ * @return current docked side
+ */
+ int getDockSide(Rect bounds, Rect displayRect, int orientation) {
+ if (orientation == Configuration.ORIENTATION_PORTRAIT) {
+ // Portrait mode, docked either at the top or the bottom.
+ final int diff = (displayRect.bottom - bounds.bottom) - (bounds.top - displayRect.top);
+ if (diff > 0) {
+ return DOCKED_TOP;
+ } else if (diff < 0) {
+ return DOCKED_BOTTOM;
+ }
+ return canPrimaryStackDockTo(DOCKED_TOP) ? DOCKED_TOP : DOCKED_BOTTOM;
+ } else if (orientation == Configuration.ORIENTATION_LANDSCAPE) {
+ // Landscape mode, docked either on the left or on the right.
+ final int diff = (displayRect.right - bounds.right) - (bounds.left - displayRect.left);
+ if (diff > 0) {
+ return DOCKED_LEFT;
+ } else if (diff < 0) {
+ return DOCKED_RIGHT;
+ }
+ return canPrimaryStackDockTo(DOCKED_LEFT) ? DOCKED_LEFT : DOCKED_RIGHT;
+ }
+ return DOCKED_INVALID;
+ }
+
void getHomeStackBoundsInDockedMode(Rect outBounds) {
final DisplayInfo di = mDisplayContent.getDisplayInfo();
mService.mPolicy.getStableInsetsLw(di.rotation, di.logicalWidth, di.logicalHeight,
@@ -203,10 +236,20 @@
outBounds.set(0, mTaskHeightInMinimizedMode + dividerSize + mTmpRect.top,
di.logicalWidth, di.logicalHeight);
} else {
- // In landscape append the left position with the statusbar height to match the
+ // In landscape also inset the left/right side with the statusbar height to match the
// minimized size height in portrait mode.
- outBounds.set(mTaskHeightInMinimizedMode + dividerSize + mTmpRect.left + mTmpRect.top,
- 0, di.logicalWidth, di.logicalHeight);
+ final TaskStack stack = mDisplayContent.getSplitScreenPrimaryStackIgnoringVisibility();
+ final int primaryTaskWidth = mTaskHeightInMinimizedMode + dividerSize + mTmpRect.top;
+ int left = mTmpRect.left;
+ int right = di.logicalWidth - mTmpRect.right;
+ if (stack != null) {
+ if (stack.getDockSide() == DOCKED_LEFT) {
+ left += primaryTaskWidth;
+ } else if (stack.getDockSide() == DOCKED_RIGHT) {
+ right -= primaryTaskWidth;
+ }
+ }
+ outBounds.set(left, 0, right, di.logicalHeight);
}
}
@@ -420,21 +463,9 @@
* @return true if the side provided is valid
*/
boolean canPrimaryStackDockTo(int dockSide) {
- if (mService.mPolicy.isDockSideAllowed(dockSide)) {
- // Side is the same as original side
- if (dockSide == mOriginalDockedSide) {
- return true;
- }
- // Special rule that the top in portrait is always valid
- if (dockSide == DOCKED_TOP) {
- return true;
- }
- // Only if original docked side was top in portrait will allow left side for landscape
- if (dockSide == DOCKED_LEFT && mOriginalDockedSide == DOCKED_TOP) {
- return true;
- }
- }
- return false;
+ final DisplayInfo di = mDisplayContent.getDisplayInfo();
+ return mService.mPolicy.isDockSideAllowed(dockSide, mOriginalDockedSide, di.logicalWidth,
+ di.logicalHeight, di.rotation);
}
void notifyDockedStackExistsChanged(boolean exists) {
diff --git a/services/core/java/com/android/server/wm/TaskStack.java b/services/core/java/com/android/server/wm/TaskStack.java
index 018765d..891ee2e 100644
--- a/services/core/java/com/android/server/wm/TaskStack.java
+++ b/services/core/java/com/android/server/wm/TaskStack.java
@@ -1462,27 +1462,7 @@
}
dc.getBounds(mTmpRect);
final int orientation = dc.getConfiguration().orientation;
- return getDockSideUnchecked(bounds, mTmpRect, orientation);
- }
-
- static int getDockSideUnchecked(Rect bounds, Rect displayRect, int orientation) {
- if (orientation == Configuration.ORIENTATION_PORTRAIT) {
- // Portrait mode, docked either at the top or the bottom.
- if (bounds.top - displayRect.top <= displayRect.bottom - bounds.bottom) {
- return DOCKED_TOP;
- } else {
- return DOCKED_BOTTOM;
- }
- } else if (orientation == Configuration.ORIENTATION_LANDSCAPE) {
- // Landscape mode, docked either on the left or on the right.
- if (bounds.left - displayRect.left <= displayRect.right - bounds.right) {
- return DOCKED_LEFT;
- } else {
- return DOCKED_RIGHT;
- }
- } else {
- return DOCKED_INVALID;
- }
+ return dc.getDockedDividerController().getDockSide(bounds, mTmpRect, orientation);
}
boolean hasTaskForUser(int userId) {
diff --git a/services/tests/servicestests/src/com/android/server/policy/PhoneWindowManagerTest.java b/services/tests/servicestests/src/com/android/server/policy/PhoneWindowManagerTest.java
index 64637f4..30665b5 100644
--- a/services/tests/servicestests/src/com/android/server/policy/PhoneWindowManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/policy/PhoneWindowManagerTest.java
@@ -28,12 +28,19 @@
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
+import static android.view.WindowManager.DOCKED_BOTTOM;
+import static android.view.WindowManager.DOCKED_LEFT;
+import static android.view.WindowManager.DOCKED_RIGHT;
+import static android.view.WindowManager.DOCKED_TOP;
+import static com.android.server.policy.WindowManagerPolicy.NAV_BAR_LEFT;
import static com.android.server.policy.WindowManagerPolicy.NAV_BAR_BOTTOM;
import static com.android.server.policy.WindowManagerPolicy.NAV_BAR_RIGHT;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
import android.graphics.PixelFormat;
import android.platform.test.annotations.Presubmit;
@@ -194,4 +201,53 @@
PhoneWindowManager.updateLightNavigationBarLw(0, opaqueDarkNavBar,
opaqueDarkNavBar, imeDrawLightNavBar, imeDrawLightNavBar));
}
+
+ @Test
+ public void testIsDockSideAllowedDockTop() throws Exception {
+ // Docked top is always allowed
+ assertTrue(PhoneWindowManager.isDockSideAllowed(DOCKED_TOP, DOCKED_LEFT, NAV_BAR_BOTTOM,
+ true /* navigationBarCanMove */));
+ assertTrue(PhoneWindowManager.isDockSideAllowed(DOCKED_TOP, DOCKED_LEFT, NAV_BAR_BOTTOM,
+ false /* navigationBarCanMove */));
+ }
+
+ @Test
+ public void testIsDockSideAllowedDockBottom() throws Exception {
+ // Cannot dock bottom
+ assertFalse(PhoneWindowManager.isDockSideAllowed(DOCKED_BOTTOM, DOCKED_LEFT, NAV_BAR_BOTTOM,
+ true /* navigationBarCanMove */));
+ }
+
+ @Test
+ public void testIsDockSideAllowedNavigationBarMovable() throws Exception {
+ assertFalse(PhoneWindowManager.isDockSideAllowed(DOCKED_LEFT, DOCKED_LEFT, NAV_BAR_BOTTOM,
+ true /* navigationBarCanMove */));
+ assertFalse(PhoneWindowManager.isDockSideAllowed(DOCKED_LEFT, DOCKED_LEFT, NAV_BAR_LEFT,
+ true /* navigationBarCanMove */));
+ assertTrue(PhoneWindowManager.isDockSideAllowed(DOCKED_LEFT, DOCKED_LEFT, NAV_BAR_RIGHT,
+ true /* navigationBarCanMove */));
+ assertFalse(PhoneWindowManager.isDockSideAllowed(DOCKED_RIGHT, DOCKED_LEFT, NAV_BAR_BOTTOM,
+ true /* navigationBarCanMove */));
+ assertFalse(PhoneWindowManager.isDockSideAllowed(DOCKED_RIGHT, DOCKED_LEFT, NAV_BAR_RIGHT,
+ true /* navigationBarCanMove */));
+ assertTrue(PhoneWindowManager.isDockSideAllowed(DOCKED_RIGHT, DOCKED_LEFT, NAV_BAR_LEFT,
+ true /* navigationBarCanMove */));
+ }
+
+ @Test
+ public void testIsDockSideAllowedNavigationBarNotMovable() throws Exception {
+ // Navigation bar is not movable such as tablets
+ assertTrue(PhoneWindowManager.isDockSideAllowed(DOCKED_LEFT, DOCKED_LEFT, NAV_BAR_BOTTOM,
+ false /* navigationBarCanMove */));
+ assertTrue(PhoneWindowManager.isDockSideAllowed(DOCKED_LEFT, DOCKED_TOP, NAV_BAR_BOTTOM,
+ false /* navigationBarCanMove */));
+ assertFalse(PhoneWindowManager.isDockSideAllowed(DOCKED_LEFT, DOCKED_RIGHT, NAV_BAR_BOTTOM,
+ false /* navigationBarCanMove */));
+ assertFalse(PhoneWindowManager.isDockSideAllowed(DOCKED_RIGHT, DOCKED_LEFT, NAV_BAR_BOTTOM,
+ false /* navigationBarCanMove */));
+ assertFalse(PhoneWindowManager.isDockSideAllowed(DOCKED_RIGHT, DOCKED_TOP, NAV_BAR_BOTTOM,
+ false /* navigationBarCanMove */));
+ assertTrue(PhoneWindowManager.isDockSideAllowed(DOCKED_RIGHT, DOCKED_RIGHT, NAV_BAR_BOTTOM,
+ false /* navigationBarCanMove */));
+ }
}
diff --git a/services/tests/servicestests/src/com/android/server/power/batterysaver/BatterySaverStateMachineTest.java b/services/tests/servicestests/src/com/android/server/power/batterysaver/BatterySaverStateMachineTest.java
index 1367f58..62fe6b2 100644
--- a/services/tests/servicestests/src/com/android/server/power/batterysaver/BatterySaverStateMachineTest.java
+++ b/services/tests/servicestests/src/com/android/server/power/batterysaver/BatterySaverStateMachineTest.java
@@ -17,6 +17,7 @@
import static org.junit.Assert.assertEquals;
import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
@@ -144,6 +145,11 @@
void runOnBgThread(Runnable r) {
r.run();
}
+
+ @Override
+ void runOnBgThreadLazy(Runnable r, int delayMillis) {
+ r.run();
+ }
}
@Before
@@ -153,7 +159,7 @@
mMockBatterySaverController = mock(BatterySaverController.class);
doAnswer((inv) -> mDevice.batterySaverEnabled = inv.getArgument(0))
- .when(mMockBatterySaverController).enableBatterySaver(anyBoolean());
+ .when(mMockBatterySaverController).enableBatterySaver(anyBoolean(), anyInt());
when(mMockBatterySaverController.isEnabled())
.thenAnswer((inv) -> mDevice.batterySaverEnabled);
diff --git a/services/tests/servicestests/src/com/android/server/wm/TestWindowManagerPolicy.java b/services/tests/servicestests/src/com/android/server/wm/TestWindowManagerPolicy.java
index 1c2d538..013c672 100644
--- a/services/tests/servicestests/src/com/android/server/wm/TestWindowManagerPolicy.java
+++ b/services/tests/servicestests/src/com/android/server/wm/TestWindowManagerPolicy.java
@@ -552,7 +552,8 @@
}
@Override
- public boolean isDockSideAllowed(int dockSide) {
+ public boolean isDockSideAllowed(int dockSide, int originalDockSide, int displayWidth,
+ int displayHeight, int displayRotation) {
return false;
}