Merge changes from topic "dialog-width" into sc-v2-dev
* changes: Make all SystemUIDialog's the same configurable width (1/2) Synchronize dialog launch animations Animate the internet dialog launch.
This commit is contained in:
committed by
Android (Google) Code Review
commit
a5088b1302
@@ -21,11 +21,16 @@ import android.content.Context
|
|||||||
import android.graphics.Color
|
import android.graphics.Color
|
||||||
import android.os.Looper
|
import android.os.Looper
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
|
import android.view.GhostView
|
||||||
import android.view.Gravity
|
import android.view.Gravity
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import android.view.ViewTreeObserver
|
import android.view.ViewTreeObserver.OnPreDrawListener
|
||||||
|
import android.view.WindowInsets
|
||||||
import android.view.WindowManager
|
import android.view.WindowManager
|
||||||
|
import android.view.WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR
|
||||||
|
import android.view.WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
|
||||||
|
import android.view.WindowManagerPolicyConstants
|
||||||
import android.widget.FrameLayout
|
import android.widget.FrameLayout
|
||||||
|
|
||||||
private const val TAG = "DialogLaunchAnimator"
|
private const val TAG = "DialogLaunchAnimator"
|
||||||
@@ -221,10 +226,12 @@ private class DialogLaunchAnimation(
|
|||||||
private var isDismissing = false
|
private var isDismissing = false
|
||||||
|
|
||||||
private var dismissRequested = false
|
private var dismissRequested = false
|
||||||
private var drawHostDialog = false
|
|
||||||
var ignoreNextCallToHide = false
|
var ignoreNextCallToHide = false
|
||||||
var exitAnimationDisabled = false
|
var exitAnimationDisabled = false
|
||||||
|
|
||||||
|
private var isTouchSurfaceGhostDrawn = false
|
||||||
|
private var isOriginalDialogViewLaidOut = false
|
||||||
|
|
||||||
fun start() {
|
fun start() {
|
||||||
// Show the host (fullscreen) dialog, to which we will add the stolen dialog view.
|
// Show the host (fullscreen) dialog, to which we will add the stolen dialog view.
|
||||||
hostDialog.show()
|
hostDialog.show()
|
||||||
@@ -252,19 +259,76 @@ private class DialogLaunchAnimation(
|
|||||||
WindowManager.LayoutParams.MATCH_PARENT
|
WindowManager.LayoutParams.MATCH_PARENT
|
||||||
)
|
)
|
||||||
|
|
||||||
// Prevent the host dialog from drawing until the animation starts.
|
// If we are using gesture navigation, then we can overlay the navigation/task bars with
|
||||||
hostDialogRoot.viewTreeObserver.addOnPreDrawListener(
|
// the host dialog.
|
||||||
object : ViewTreeObserver.OnPreDrawListener {
|
val navigationMode = context.resources.getInteger(
|
||||||
override fun onPreDraw(): Boolean {
|
com.android.internal.R.integer.config_navBarInteractionMode)
|
||||||
if (drawHostDialog) {
|
if (navigationMode == WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL) {
|
||||||
hostDialogRoot.viewTreeObserver.removeOnPreDrawListener(this)
|
window.attributes.fitInsetsTypes = window.attributes.fitInsetsTypes and
|
||||||
return true
|
WindowInsets.Type.navigationBars().inv()
|
||||||
}
|
window.addFlags(FLAG_LAYOUT_IN_SCREEN or FLAG_LAYOUT_INSET_DECOR)
|
||||||
|
window.setDecorFitsSystemWindows(false)
|
||||||
|
}
|
||||||
|
|
||||||
return false
|
// Disable the dim. We will enable it once we start the animation.
|
||||||
}
|
window.clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND)
|
||||||
|
|
||||||
|
// Add a temporary touch surface ghost as soon as the window is ready to draw. This
|
||||||
|
// temporary ghost will be drawn together with the touch surface, but in the host dialog
|
||||||
|
// window. Once it is drawn, we will make the touch surface invisible, and then start the
|
||||||
|
// animation. We do all this synchronization to avoid flicker that would occur if we made
|
||||||
|
// the touch surface invisible too early (before its ghost is drawn), leading to one or more
|
||||||
|
// frames with a hole instead of the touch surface (or its ghost).
|
||||||
|
hostDialogRoot.viewTreeObserver.addOnPreDrawListener(object : OnPreDrawListener {
|
||||||
|
override fun onPreDraw(): Boolean {
|
||||||
|
hostDialogRoot.viewTreeObserver.removeOnPreDrawListener(this)
|
||||||
|
addTemporaryTouchSurfaceGhost()
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
)
|
})
|
||||||
|
hostDialogRoot.invalidate()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun addTemporaryTouchSurfaceGhost() {
|
||||||
|
// Create a ghost of the touch surface (which will make the touch surface invisible) and add
|
||||||
|
// it to the host dialog. We will wait for this ghost to be drawn before starting the
|
||||||
|
// animation.
|
||||||
|
val ghost = GhostView.addGhost(touchSurface, hostDialogRoot)
|
||||||
|
|
||||||
|
// The ghost of the touch surface was just created, so the touch surface was made invisible.
|
||||||
|
// We make it visible again until the ghost is actually drawn.
|
||||||
|
touchSurface.visibility = View.VISIBLE
|
||||||
|
|
||||||
|
// Wait for the ghost to be drawn before continuing.
|
||||||
|
ghost.viewTreeObserver.addOnPreDrawListener(object : OnPreDrawListener {
|
||||||
|
override fun onPreDraw(): Boolean {
|
||||||
|
ghost.viewTreeObserver.removeOnPreDrawListener(this)
|
||||||
|
onTouchSurfaceGhostDrawn()
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
ghost.invalidate()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun onTouchSurfaceGhostDrawn() {
|
||||||
|
// Make the touch surface invisible and make sure that it stays invisible as long as the
|
||||||
|
// dialog is shown or animating.
|
||||||
|
touchSurface.visibility = View.INVISIBLE
|
||||||
|
if (touchSurface is LaunchableView) {
|
||||||
|
touchSurface.setShouldBlockVisibilityChanges(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add a pre draw listener to (maybe) start the animation once the touch surface is
|
||||||
|
// actually invisible.
|
||||||
|
touchSurface.viewTreeObserver.addOnPreDrawListener(object : OnPreDrawListener {
|
||||||
|
override fun onPreDraw(): Boolean {
|
||||||
|
touchSurface.viewTreeObserver.removeOnPreDrawListener(this)
|
||||||
|
isTouchSurfaceGhostDrawn = true
|
||||||
|
maybeStartLaunchAnimation()
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
touchSurface.invalidate()
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Get the content view of [originalDialog] and pass it to [then]. */
|
/** Get the content view of [originalDialog] and pass it to [then]. */
|
||||||
@@ -276,7 +340,7 @@ private class DialogLaunchAnimation(
|
|||||||
?: throw IllegalStateException("Dialog does not have any android.R.id.content view")
|
?: throw IllegalStateException("Dialog does not have any android.R.id.content view")
|
||||||
|
|
||||||
androidContent.viewTreeObserver.addOnPreDrawListener(
|
androidContent.viewTreeObserver.addOnPreDrawListener(
|
||||||
object : ViewTreeObserver.OnPreDrawListener {
|
object : OnPreDrawListener {
|
||||||
override fun onPreDraw(): Boolean {
|
override fun onPreDraw(): Boolean {
|
||||||
if (androidContent.childCount == 1) {
|
if (androidContent.childCount == 1) {
|
||||||
androidContent.viewTreeObserver.removeOnPreDrawListener(this)
|
androidContent.viewTreeObserver.removeOnPreDrawListener(this)
|
||||||
@@ -354,32 +418,47 @@ private class DialogLaunchAnimation(
|
|||||||
oldBottom: Int
|
oldBottom: Int
|
||||||
) {
|
) {
|
||||||
dialogView.removeOnLayoutChangeListener(this)
|
dialogView.removeOnLayoutChangeListener(this)
|
||||||
startAnimation(
|
|
||||||
isLaunching = true,
|
|
||||||
onLaunchAnimationStart = { drawHostDialog = true },
|
|
||||||
onLaunchAnimationEnd = {
|
|
||||||
touchSurface.setTag(R.id.launch_animation_running, null)
|
|
||||||
|
|
||||||
// We hide the touch surface when the dialog is showing. We will make this
|
isOriginalDialogViewLaidOut = true
|
||||||
// view visible again when dismissing the dialog.
|
maybeStartLaunchAnimation()
|
||||||
// TODO(b/193634619): Provide an easy way for views to check if they should
|
|
||||||
// be hidden because of a dialog launch so that they don't override this
|
|
||||||
// visibility when updating/refreshing itself.
|
|
||||||
touchSurface.visibility = View.INVISIBLE
|
|
||||||
|
|
||||||
isLaunching = false
|
|
||||||
|
|
||||||
// dismiss was called during the animation, dismiss again now to actually
|
|
||||||
// dismiss.
|
|
||||||
if (dismissRequested) {
|
|
||||||
hostDialog.dismiss()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun maybeStartLaunchAnimation() {
|
||||||
|
if (!isTouchSurfaceGhostDrawn || !isOriginalDialogViewLaidOut) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Show the background dim.
|
||||||
|
hostDialog.window.addFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND)
|
||||||
|
|
||||||
|
startAnimation(
|
||||||
|
isLaunching = true,
|
||||||
|
onLaunchAnimationStart = {
|
||||||
|
// Remove the temporary ghost. Another ghost (that ghosts only the touch surface
|
||||||
|
// content, and not its background) will be added right after this and will be
|
||||||
|
// animated.
|
||||||
|
GhostView.removeGhost(touchSurface)
|
||||||
|
},
|
||||||
|
onLaunchAnimationEnd = {
|
||||||
|
touchSurface.setTag(R.id.launch_animation_running, null)
|
||||||
|
|
||||||
|
// We hide the touch surface when the dialog is showing. We will make this
|
||||||
|
// view visible again when dismissing the dialog.
|
||||||
|
touchSurface.visibility = View.INVISIBLE
|
||||||
|
|
||||||
|
isLaunching = false
|
||||||
|
|
||||||
|
// dismiss was called during the animation, dismiss again now to actually
|
||||||
|
// dismiss.
|
||||||
|
if (dismissRequested) {
|
||||||
|
hostDialog.dismiss()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
private fun onHostDialogDismissed(actualDismiss: () -> Unit) {
|
private fun onHostDialogDismissed(actualDismiss: () -> Unit) {
|
||||||
if (Looper.myLooper() != Looper.getMainLooper()) {
|
if (Looper.myLooper() != Looper.getMainLooper()) {
|
||||||
context.mainExecutor.execute { onHostDialogDismissed(actualDismiss) }
|
context.mainExecutor.execute { onHostDialogDismissed(actualDismiss) }
|
||||||
@@ -417,6 +496,11 @@ private class DialogLaunchAnimation(
|
|||||||
if (!shouldAnimateDialogIntoView()) {
|
if (!shouldAnimateDialogIntoView()) {
|
||||||
Log.i(TAG, "Skipping animation of dialog into the touch surface")
|
Log.i(TAG, "Skipping animation of dialog into the touch surface")
|
||||||
|
|
||||||
|
// Make sure we allow the touch surface to change its visibility again.
|
||||||
|
if (touchSurface is LaunchableView) {
|
||||||
|
touchSurface.setShouldBlockVisibilityChanges(false)
|
||||||
|
}
|
||||||
|
|
||||||
// If the view is invisible it's probably because of us, so we make it visible again.
|
// If the view is invisible it's probably because of us, so we make it visible again.
|
||||||
if (touchSurface.visibility == View.INVISIBLE) {
|
if (touchSurface.visibility == View.INVISIBLE) {
|
||||||
touchSurface.visibility = View.VISIBLE
|
touchSurface.visibility = View.VISIBLE
|
||||||
@@ -434,10 +518,33 @@ private class DialogLaunchAnimation(
|
|||||||
hostDialog.window.clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND)
|
hostDialog.window.clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND)
|
||||||
},
|
},
|
||||||
onLaunchAnimationEnd = {
|
onLaunchAnimationEnd = {
|
||||||
|
// Make sure we allow the touch surface to change its visibility again.
|
||||||
|
if (touchSurface is LaunchableView) {
|
||||||
|
touchSurface.setShouldBlockVisibilityChanges(false)
|
||||||
|
}
|
||||||
|
|
||||||
touchSurface.visibility = View.VISIBLE
|
touchSurface.visibility = View.VISIBLE
|
||||||
originalDialogView!!.visibility = View.INVISIBLE
|
originalDialogView!!.visibility = View.INVISIBLE
|
||||||
dismissDialogs(true /* instantDismiss */)
|
|
||||||
onDialogDismissed(this@DialogLaunchAnimation)
|
// The animated ghost was just removed. We create a temporary ghost that will be
|
||||||
|
// removed only once we draw the touch surface, to avoid flickering that would
|
||||||
|
// happen when removing the ghost too early (before the touch surface is drawn).
|
||||||
|
GhostView.addGhost(touchSurface, hostDialogRoot)
|
||||||
|
|
||||||
|
touchSurface.viewTreeObserver.addOnPreDrawListener(object : OnPreDrawListener {
|
||||||
|
override fun onPreDraw(): Boolean {
|
||||||
|
touchSurface.viewTreeObserver.removeOnPreDrawListener(this)
|
||||||
|
|
||||||
|
// Now that the touch surface was drawn, we can remove the temporary ghost
|
||||||
|
// and instantly dismiss the dialog.
|
||||||
|
GhostView.removeGhost(touchSurface)
|
||||||
|
dismissDialogs(true /* instantDismiss */)
|
||||||
|
onDialogDismissed(this@DialogLaunchAnimation)
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
touchSurface.invalidate()
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -472,10 +579,13 @@ private class DialogLaunchAnimation(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onLaunchAnimationStart(isExpandingFullyAbove: Boolean) {
|
override fun onLaunchAnimationStart(isExpandingFullyAbove: Boolean) {
|
||||||
|
// During launch, onLaunchAnimationStart will be used to remove the temporary touch
|
||||||
|
// surface ghost so it is important to call this before calling
|
||||||
|
// onLaunchAnimationStart on the controller (which will create its own ghost).
|
||||||
|
onLaunchAnimationStart()
|
||||||
|
|
||||||
startViewController.onLaunchAnimationStart(isExpandingFullyAbove)
|
startViewController.onLaunchAnimationStart(isExpandingFullyAbove)
|
||||||
endViewController.onLaunchAnimationStart(isExpandingFullyAbove)
|
endViewController.onLaunchAnimationStart(isExpandingFullyAbove)
|
||||||
|
|
||||||
onLaunchAnimationStart()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onLaunchAnimationEnd(isExpandingFullyAbove: Boolean) {
|
override fun onLaunchAnimationEnd(isExpandingFullyAbove: Boolean) {
|
||||||
|
|||||||
@@ -0,0 +1,30 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2021 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.animation
|
||||||
|
|
||||||
|
/** A view that can expand/launch into an app or a dialog. */
|
||||||
|
interface LaunchableView {
|
||||||
|
/**
|
||||||
|
* Set whether this view should block/prevent all visibility changes. This ensures that this
|
||||||
|
* view remains invisible during the launch animation given that it is ghosted and already drawn
|
||||||
|
* somewhere else.
|
||||||
|
*
|
||||||
|
* Note that when this is set to true, both the [normal][android.view.View.setVisibility] and
|
||||||
|
* [transition][android.view.View.setTransitionVisibility] visibility changes must be blocked.
|
||||||
|
*/
|
||||||
|
fun setShouldBlockVisibilityChanges(block: Boolean)
|
||||||
|
}
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
<?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.
|
|
||||||
-->
|
|
||||||
|
|
||||||
<inset xmlns:android="http://schemas.android.com/apk/res/android">
|
|
||||||
<shape android:shape="rectangle">
|
|
||||||
<corners android:radius="8dp" />
|
|
||||||
<solid android:color="?android:attr/colorBackground" />
|
|
||||||
</shape>
|
|
||||||
</inset>
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<!-- Copyright (C) 2021 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.
|
|
||||||
-->
|
|
||||||
<inset xmlns:android="http://schemas.android.com/apk/res/android">
|
|
||||||
<shape android:shape="rectangle">
|
|
||||||
<corners
|
|
||||||
android:topLeftRadius="@dimen/internet_dialog_corner_radius"
|
|
||||||
android:topRightRadius="@dimen/internet_dialog_corner_radius"
|
|
||||||
android:bottomLeftRadius="@dimen/internet_dialog_corner_radius"
|
|
||||||
android:bottomRightRadius="@dimen/internet_dialog_corner_radius"/>
|
|
||||||
<solid android:color="?android:attr/colorBackground" />
|
|
||||||
</shape>
|
|
||||||
</inset>
|
|
||||||
@@ -20,8 +20,7 @@
|
|||||||
xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
|
xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
|
||||||
android:id="@+id/internet_connectivity_dialog"
|
android:id="@+id/internet_connectivity_dialog"
|
||||||
android:layout_width="@dimen/large_dialog_width"
|
android:layout_width="@dimen/large_dialog_width"
|
||||||
android:layout_height="@dimen/internet_dialog_list_max_height"
|
android:layout_height="wrap_content"
|
||||||
android:background="@drawable/internet_dialog_rounded_top_corner_background"
|
|
||||||
android:orientation="vertical">
|
android:orientation="vertical">
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
|
|||||||
@@ -105,5 +105,5 @@
|
|||||||
<dimen name="qs_detail_margin_top">0dp</dimen>
|
<dimen name="qs_detail_margin_top">0dp</dimen>
|
||||||
|
|
||||||
<!-- The width of large/content heavy dialogs (e.g. Internet, Media output, etc) -->
|
<!-- The width of large/content heavy dialogs (e.g. Internet, Media output, etc) -->
|
||||||
<dimen name="large_dialog_width">624dp</dimen>
|
<dimen name="large_dialog_width">504dp</dimen>
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
@@ -1602,7 +1602,6 @@
|
|||||||
|
|
||||||
<!-- Internet panel related dimensions -->
|
<!-- Internet panel related dimensions -->
|
||||||
<dimen name="internet_dialog_list_margin">12dp</dimen>
|
<dimen name="internet_dialog_list_margin">12dp</dimen>
|
||||||
<dimen name="internet_dialog_list_max_height">662dp</dimen>
|
|
||||||
|
|
||||||
<!-- The width of large/content heavy dialogs (e.g. Internet, Media output, etc) -->
|
<!-- The width of large/content heavy dialogs (e.g. Internet, Media output, etc) -->
|
||||||
<dimen name="large_dialog_width">@dimen/match_parent</dimen>
|
<dimen name="large_dialog_width">@dimen/match_parent</dimen>
|
||||||
|
|||||||
@@ -956,10 +956,6 @@
|
|||||||
<item name="android:textColor">?android:attr/textColorPrimary</item>
|
<item name="android:textColor">?android:attr/textColorPrimary</item>
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<style name="Theme.SystemUI.Dialog.Internet">
|
|
||||||
<item name="android:windowBackground">@drawable/internet_dialog_background</item>
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<style name="MainSwitch.Settingslib" parent="@android:style/Theme.DeviceDefault">
|
<style name="MainSwitch.Settingslib" parent="@android:style/Theme.DeviceDefault">
|
||||||
<item name="android:switchMinWidth">@dimen/settingslib_min_switch_width</item>
|
<item name="android:switchMinWidth">@dimen/settingslib_min_switch_width</item>
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -104,8 +104,6 @@ public abstract class MediaOutputBaseDialog extends SystemUIDialog implements
|
|||||||
lp.setFitInsetsIgnoringVisibility(true);
|
lp.setFitInsetsIgnoringVisibility(true);
|
||||||
window.setAttributes(lp);
|
window.setAttributes(lp);
|
||||||
window.setContentView(mDialogView);
|
window.setContentView(mDialogView);
|
||||||
window.setLayout(mContext.getResources().getDimensionPixelSize(R.dimen.large_dialog_width),
|
|
||||||
ViewGroup.LayoutParams.WRAP_CONTENT);
|
|
||||||
|
|
||||||
mHeaderTitle = mDialogView.requireViewById(R.id.header_title);
|
mHeaderTitle = mDialogView.requireViewById(R.id.header_title);
|
||||||
mHeaderSubtitle = mDialogView.requireViewById(R.id.header_subtitle);
|
mHeaderSubtitle = mDialogView.requireViewById(R.id.header_subtitle);
|
||||||
|
|||||||
@@ -24,7 +24,6 @@ import android.view.Gravity
|
|||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import android.view.ViewGroup.LayoutParams.WRAP_CONTENT
|
|
||||||
import android.view.WindowInsets
|
import android.view.WindowInsets
|
||||||
import android.widget.ImageView
|
import android.widget.ImageView
|
||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
@@ -65,7 +64,6 @@ class PrivacyDialog(
|
|||||||
window?.apply {
|
window?.apply {
|
||||||
attributes.fitInsetsTypes = attributes.fitInsetsTypes or WindowInsets.Type.statusBars()
|
attributes.fitInsetsTypes = attributes.fitInsetsTypes or WindowInsets.Type.statusBars()
|
||||||
attributes.receiveInsetsIgnoringZOrder = true
|
attributes.receiveInsetsIgnoringZOrder = true
|
||||||
setLayout(context.resources.getDimensionPixelSize(R.dimen.qs_panel_width), WRAP_CONTENT)
|
|
||||||
setGravity(Gravity.TOP or Gravity.CENTER_HORIZONTAL)
|
setGravity(Gravity.TOP or Gravity.CENTER_HORIZONTAL)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ import androidx.annotation.VisibleForTesting
|
|||||||
import com.android.settingslib.Utils
|
import com.android.settingslib.Utils
|
||||||
import com.android.systemui.FontSizeUtils
|
import com.android.systemui.FontSizeUtils
|
||||||
import com.android.systemui.R
|
import com.android.systemui.R
|
||||||
|
import com.android.systemui.animation.LaunchableView
|
||||||
import com.android.systemui.plugins.qs.QSIconView
|
import com.android.systemui.plugins.qs.QSIconView
|
||||||
import com.android.systemui.plugins.qs.QSTile
|
import com.android.systemui.plugins.qs.QSTile
|
||||||
import com.android.systemui.plugins.qs.QSTile.BooleanState
|
import com.android.systemui.plugins.qs.QSTile.BooleanState
|
||||||
@@ -54,7 +55,7 @@ open class QSTileViewImpl @JvmOverloads constructor(
|
|||||||
context: Context,
|
context: Context,
|
||||||
private val _icon: QSIconView,
|
private val _icon: QSIconView,
|
||||||
private val collapsed: Boolean = false
|
private val collapsed: Boolean = false
|
||||||
) : QSTileView(context), HeightOverrideable {
|
) : QSTileView(context), HeightOverrideable, LaunchableView {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private const val INVALID = -1
|
private const val INVALID = -1
|
||||||
@@ -130,6 +131,8 @@ open class QSTileViewImpl @JvmOverloads constructor(
|
|||||||
private var lastStateDescription: CharSequence? = null
|
private var lastStateDescription: CharSequence? = null
|
||||||
private var tileState = false
|
private var tileState = false
|
||||||
private var lastState = INVALID
|
private var lastState = INVALID
|
||||||
|
private var blockVisibilityChanges = false
|
||||||
|
private var lastVisibility = View.VISIBLE
|
||||||
|
|
||||||
private val locInScreen = IntArray(2)
|
private val locInScreen = IntArray(2)
|
||||||
|
|
||||||
@@ -319,6 +322,36 @@ open class QSTileViewImpl @JvmOverloads constructor(
|
|||||||
return sideView
|
return sideView
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun setShouldBlockVisibilityChanges(block: Boolean) {
|
||||||
|
blockVisibilityChanges = block
|
||||||
|
|
||||||
|
if (block) {
|
||||||
|
lastVisibility = visibility
|
||||||
|
} else {
|
||||||
|
visibility = lastVisibility
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun setVisibility(visibility: Int) {
|
||||||
|
if (blockVisibilityChanges) {
|
||||||
|
lastVisibility = visibility
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
super.setVisibility(visibility)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun setTransitionVisibility(visibility: Int) {
|
||||||
|
if (blockVisibilityChanges) {
|
||||||
|
// View.setTransitionVisibility just sets the visibility flag, so we don't have to save
|
||||||
|
// the transition visibility separately from the normal visibility.
|
||||||
|
lastVisibility = visibility
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
super.setTransitionVisibility(visibility)
|
||||||
|
}
|
||||||
|
|
||||||
// Accessibility
|
// Accessibility
|
||||||
|
|
||||||
override fun onInitializeAccessibilityEvent(event: AccessibilityEvent) {
|
override fun onInitializeAccessibilityEvent(event: AccessibilityEvent) {
|
||||||
@@ -484,7 +517,7 @@ open class QSTileViewImpl @JvmOverloads constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun setColor(color: Int) {
|
private fun setColor(color: Int) {
|
||||||
colorBackgroundDrawable.setTint(color)
|
colorBackgroundDrawable.mutate().setTint(color)
|
||||||
paintColor = color
|
paintColor = color
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -124,7 +124,7 @@ public class InternetTile extends QSTileImpl<SignalState> {
|
|||||||
protected void handleClick(@Nullable View view) {
|
protected void handleClick(@Nullable View view) {
|
||||||
mHandler.post(() -> mInternetDialogFactory.create(true,
|
mHandler.post(() -> mInternetDialogFactory.create(true,
|
||||||
mAccessPointController.canConfigMobileData(),
|
mAccessPointController.canConfigMobileData(),
|
||||||
mAccessPointController.canConfigWifi()));
|
mAccessPointController.canConfigWifi(), view));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -15,14 +15,10 @@
|
|||||||
*/
|
*/
|
||||||
package com.android.systemui.qs.tiles.dialog;
|
package com.android.systemui.qs.tiles.dialog;
|
||||||
|
|
||||||
import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS;
|
|
||||||
|
|
||||||
import static com.android.systemui.Prefs.Key.QS_HAS_TURNED_OFF_MOBILE_DATA;
|
import static com.android.systemui.Prefs.Key.QS_HAS_TURNED_OFF_MOBILE_DATA;
|
||||||
|
|
||||||
import android.app.AlertDialog;
|
import android.app.AlertDialog;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.graphics.Color;
|
|
||||||
import android.graphics.drawable.ColorDrawable;
|
|
||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
||||||
import android.net.Network;
|
import android.net.Network;
|
||||||
import android.net.NetworkCapabilities;
|
import android.net.NetworkCapabilities;
|
||||||
@@ -41,10 +37,7 @@ import android.util.Log;
|
|||||||
import android.view.Gravity;
|
import android.view.Gravity;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
|
||||||
import android.view.ViewTreeObserver;
|
|
||||||
import android.view.Window;
|
import android.view.Window;
|
||||||
import android.view.WindowInsets;
|
|
||||||
import android.view.WindowManager;
|
import android.view.WindowManager;
|
||||||
import android.widget.FrameLayout;
|
import android.widget.FrameLayout;
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
@@ -130,7 +123,6 @@ public class InternetDialog extends SystemUIDialog implements
|
|||||||
private Switch mWiFiToggle;
|
private Switch mWiFiToggle;
|
||||||
private FrameLayout mDoneLayout;
|
private FrameLayout mDoneLayout;
|
||||||
private Drawable mBackgroundOn;
|
private Drawable mBackgroundOn;
|
||||||
private int mListMaxHeight;
|
|
||||||
private int mDefaultDataSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
|
private int mDefaultDataSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
|
||||||
private boolean mCanConfigMobileData;
|
private boolean mCanConfigMobileData;
|
||||||
|
|
||||||
@@ -149,20 +141,11 @@ public class InternetDialog extends SystemUIDialog implements
|
|||||||
mInternetDialogSubTitle.setText(getSubtitleText());
|
mInternetDialogSubTitle.setText(getSubtitleText());
|
||||||
};
|
};
|
||||||
|
|
||||||
private final ViewTreeObserver.OnGlobalLayoutListener mInternetListLayoutListener = () -> {
|
|
||||||
// Set max height for list
|
|
||||||
if (mInternetDialogLayout.getHeight() > mListMaxHeight) {
|
|
||||||
ViewGroup.LayoutParams params = mInternetDialogLayout.getLayoutParams();
|
|
||||||
params.height = mListMaxHeight;
|
|
||||||
mInternetDialogLayout.setLayoutParams(params);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
public InternetDialog(Context context, InternetDialogFactory internetDialogFactory,
|
public InternetDialog(Context context, InternetDialogFactory internetDialogFactory,
|
||||||
InternetDialogController internetDialogController, boolean canConfigMobileData,
|
InternetDialogController internetDialogController, boolean canConfigMobileData,
|
||||||
boolean canConfigWifi, boolean aboveStatusBar, UiEventLogger uiEventLogger,
|
boolean canConfigWifi, boolean aboveStatusBar, UiEventLogger uiEventLogger,
|
||||||
@Main Handler handler, @Background Executor executor) {
|
@Main Handler handler, @Background Executor executor) {
|
||||||
super(context, R.style.Theme_SystemUI_Dialog_Internet);
|
super(context);
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
Log.d(TAG, "Init InternetDialog");
|
Log.d(TAG, "Init InternetDialog");
|
||||||
}
|
}
|
||||||
@@ -184,8 +167,6 @@ public class InternetDialog extends SystemUIDialog implements
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
mListMaxHeight = context.getResources().getDimensionPixelSize(
|
|
||||||
R.dimen.internet_dialog_list_max_height);
|
|
||||||
mUiEventLogger = uiEventLogger;
|
mUiEventLogger = uiEventLogger;
|
||||||
mAdapter = new InternetAdapter(mInternetDialogController);
|
mAdapter = new InternetAdapter(mInternetDialogController);
|
||||||
if (!aboveStatusBar) {
|
if (!aboveStatusBar) {
|
||||||
@@ -203,21 +184,9 @@ public class InternetDialog extends SystemUIDialog implements
|
|||||||
mDialogView = LayoutInflater.from(mContext).inflate(R.layout.internet_connectivity_dialog,
|
mDialogView = LayoutInflater.from(mContext).inflate(R.layout.internet_connectivity_dialog,
|
||||||
null);
|
null);
|
||||||
final Window window = getWindow();
|
final Window window = getWindow();
|
||||||
final WindowManager.LayoutParams layoutParams = window.getAttributes();
|
|
||||||
layoutParams.gravity = Gravity.BOTTOM;
|
|
||||||
// Move down the dialog to overlay the navigation bar.
|
|
||||||
layoutParams.setFitInsetsTypes(
|
|
||||||
layoutParams.getFitInsetsTypes() & ~WindowInsets.Type.navigationBars());
|
|
||||||
layoutParams.setFitInsetsSides(WindowInsets.Side.all());
|
|
||||||
layoutParams.setFitInsetsIgnoringVisibility(true);
|
|
||||||
window.setAttributes(layoutParams);
|
|
||||||
window.setContentView(mDialogView);
|
window.setContentView(mDialogView);
|
||||||
//Only fix the width for large screen or tablet.
|
|
||||||
window.setLayout(mContext.getResources().getDimensionPixelSize(
|
|
||||||
R.dimen.large_dialog_width), ViewGroup.LayoutParams.WRAP_CONTENT);
|
|
||||||
window.setWindowAnimations(R.style.Animation_InternetDialog);
|
window.setWindowAnimations(R.style.Animation_InternetDialog);
|
||||||
window.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
|
|
||||||
window.addFlags(FLAG_LAYOUT_NO_LIMITS);
|
|
||||||
|
|
||||||
mInternetDialogLayout = mDialogView.requireViewById(R.id.internet_connectivity_dialog);
|
mInternetDialogLayout = mDialogView.requireViewById(R.id.internet_connectivity_dialog);
|
||||||
mInternetDialogTitle = mDialogView.requireViewById(R.id.internet_dialog_title);
|
mInternetDialogTitle = mDialogView.requireViewById(R.id.internet_dialog_title);
|
||||||
@@ -244,8 +213,6 @@ public class InternetDialog extends SystemUIDialog implements
|
|||||||
mMobileDataToggle = mDialogView.requireViewById(R.id.mobile_toggle);
|
mMobileDataToggle = mDialogView.requireViewById(R.id.mobile_toggle);
|
||||||
mWiFiToggle = mDialogView.requireViewById(R.id.wifi_toggle);
|
mWiFiToggle = mDialogView.requireViewById(R.id.wifi_toggle);
|
||||||
mBackgroundOn = mContext.getDrawable(R.drawable.settingslib_switch_bar_bg_on);
|
mBackgroundOn = mContext.getDrawable(R.drawable.settingslib_switch_bar_bg_on);
|
||||||
mInternetDialogLayout.getViewTreeObserver().addOnGlobalLayoutListener(
|
|
||||||
mInternetListLayoutListener);
|
|
||||||
mInternetDialogTitle.setText(getDialogTitleText());
|
mInternetDialogTitle.setText(getDialogTitleText());
|
||||||
mInternetDialogTitle.setGravity(Gravity.START | Gravity.CENTER_VERTICAL);
|
mInternetDialogTitle.setGravity(Gravity.START | Gravity.CENTER_VERTICAL);
|
||||||
|
|
||||||
|
|||||||
@@ -71,6 +71,7 @@ import com.android.settingslib.mobile.TelephonyIcons;
|
|||||||
import com.android.settingslib.net.SignalStrengthUtil;
|
import com.android.settingslib.net.SignalStrengthUtil;
|
||||||
import com.android.settingslib.wifi.WifiUtils;
|
import com.android.settingslib.wifi.WifiUtils;
|
||||||
import com.android.systemui.R;
|
import com.android.systemui.R;
|
||||||
|
import com.android.systemui.animation.DialogLaunchAnimator;
|
||||||
import com.android.systemui.broadcast.BroadcastDispatcher;
|
import com.android.systemui.broadcast.BroadcastDispatcher;
|
||||||
import com.android.systemui.dagger.qualifiers.Background;
|
import com.android.systemui.dagger.qualifiers.Background;
|
||||||
import com.android.systemui.dagger.qualifiers.Main;
|
import com.android.systemui.dagger.qualifiers.Main;
|
||||||
@@ -152,6 +153,7 @@ public class InternetDialogController implements WifiEntry.DisconnectCallback,
|
|||||||
private ToastFactory mToastFactory;
|
private ToastFactory mToastFactory;
|
||||||
private SignalDrawable mSignalDrawable;
|
private SignalDrawable mSignalDrawable;
|
||||||
private LocationController mLocationController;
|
private LocationController mLocationController;
|
||||||
|
private DialogLaunchAnimator mDialogLaunchAnimator;
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
static final float TOAST_PARAMS_HORIZONTAL_WEIGHT = 1.0f;
|
static final float TOAST_PARAMS_HORIZONTAL_WEIGHT = 1.0f;
|
||||||
@@ -202,7 +204,8 @@ public class InternetDialogController implements WifiEntry.DisconnectCallback,
|
|||||||
WindowManager windowManager, ToastFactory toastFactory,
|
WindowManager windowManager, ToastFactory toastFactory,
|
||||||
@Background Handler workerHandler,
|
@Background Handler workerHandler,
|
||||||
CarrierConfigTracker carrierConfigTracker,
|
CarrierConfigTracker carrierConfigTracker,
|
||||||
LocationController locationController) {
|
LocationController locationController,
|
||||||
|
DialogLaunchAnimator dialogLaunchAnimator) {
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
Log.d(TAG, "Init InternetDialogController");
|
Log.d(TAG, "Init InternetDialogController");
|
||||||
}
|
}
|
||||||
@@ -231,6 +234,7 @@ public class InternetDialogController implements WifiEntry.DisconnectCallback,
|
|||||||
mToastFactory = toastFactory;
|
mToastFactory = toastFactory;
|
||||||
mSignalDrawable = new SignalDrawable(mContext);
|
mSignalDrawable = new SignalDrawable(mContext);
|
||||||
mLocationController = locationController;
|
mLocationController = locationController;
|
||||||
|
mDialogLaunchAnimator = dialogLaunchAnimator;
|
||||||
}
|
}
|
||||||
|
|
||||||
void onStart(@NonNull InternetDialogCallback callback, boolean canConfigWifi) {
|
void onStart(@NonNull InternetDialogCallback callback, boolean canConfigWifi) {
|
||||||
@@ -596,20 +600,32 @@ public class InternetDialogController implements WifiEntry.DisconnectCallback,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void launchNetworkSetting() {
|
void launchNetworkSetting() {
|
||||||
|
// Dismissing a dialog into its touch surface and starting an activity at the same time
|
||||||
|
// looks bad, so let's make sure the dialog just fades out quickly.
|
||||||
|
mDialogLaunchAnimator.disableAllCurrentDialogsExitAnimations();
|
||||||
mCallback.dismissDialog();
|
mCallback.dismissDialog();
|
||||||
|
|
||||||
mActivityStarter.postStartActivityDismissingKeyguard(getSettingsIntent(), 0);
|
mActivityStarter.postStartActivityDismissingKeyguard(getSettingsIntent(), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void launchWifiNetworkDetailsSetting(String key) {
|
void launchWifiNetworkDetailsSetting(String key) {
|
||||||
Intent intent = getWifiDetailsSettingsIntent(key);
|
Intent intent = getWifiDetailsSettingsIntent(key);
|
||||||
if (intent != null) {
|
if (intent != null) {
|
||||||
|
// Dismissing a dialog into its touch surface and starting an activity at the same time
|
||||||
|
// looks bad, so let's make sure the dialog just fades out quickly.
|
||||||
|
mDialogLaunchAnimator.disableAllCurrentDialogsExitAnimations();
|
||||||
mCallback.dismissDialog();
|
mCallback.dismissDialog();
|
||||||
|
|
||||||
mActivityStarter.postStartActivityDismissingKeyguard(intent, 0);
|
mActivityStarter.postStartActivityDismissingKeyguard(intent, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void launchWifiScanningSetting() {
|
void launchWifiScanningSetting() {
|
||||||
|
// Dismissing a dialog into its touch surface and starting an activity at the same time
|
||||||
|
// looks bad, so let's make sure the dialog just fades out quickly.
|
||||||
|
mDialogLaunchAnimator.disableAllCurrentDialogsExitAnimations();
|
||||||
mCallback.dismissDialog();
|
mCallback.dismissDialog();
|
||||||
|
|
||||||
final Intent intent = new Intent(ACTION_WIFI_SCANNING_SETTINGS);
|
final Intent intent = new Intent(ACTION_WIFI_SCANNING_SETTINGS);
|
||||||
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||||
mActivityStarter.postStartActivityDismissingKeyguard(intent, 0);
|
mActivityStarter.postStartActivityDismissingKeyguard(intent, 0);
|
||||||
|
|||||||
@@ -18,9 +18,11 @@ package com.android.systemui.qs.tiles.dialog
|
|||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.os.Handler
|
import android.os.Handler
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
|
import android.view.View
|
||||||
import com.android.internal.logging.UiEventLogger
|
import com.android.internal.logging.UiEventLogger
|
||||||
|
import com.android.systemui.animation.DialogLaunchAnimator
|
||||||
import com.android.systemui.dagger.SysUISingleton
|
import com.android.systemui.dagger.SysUISingleton
|
||||||
import com.android.systemui.dagger.qualifiers.Background;
|
import com.android.systemui.dagger.qualifiers.Background
|
||||||
import com.android.systemui.dagger.qualifiers.Main
|
import com.android.systemui.dagger.qualifiers.Main
|
||||||
import java.util.concurrent.Executor
|
import java.util.concurrent.Executor
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
@@ -37,14 +39,20 @@ class InternetDialogFactory @Inject constructor(
|
|||||||
@Background private val executor: Executor,
|
@Background private val executor: Executor,
|
||||||
private val internetDialogController: InternetDialogController,
|
private val internetDialogController: InternetDialogController,
|
||||||
private val context: Context,
|
private val context: Context,
|
||||||
private val uiEventLogger: UiEventLogger
|
private val uiEventLogger: UiEventLogger,
|
||||||
|
private val dialogLaunchAnimator: DialogLaunchAnimator
|
||||||
) {
|
) {
|
||||||
companion object {
|
companion object {
|
||||||
var internetDialog: InternetDialog? = null
|
var internetDialog: InternetDialog? = null
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Creates a [InternetDialog]. */
|
/** Creates a [InternetDialog]. The dialog will be animated from [view] if it is not null. */
|
||||||
fun create(aboveStatusBar: Boolean, canConfigMobileData: Boolean, canConfigWifi: Boolean) {
|
fun create(
|
||||||
|
aboveStatusBar: Boolean,
|
||||||
|
canConfigMobileData: Boolean,
|
||||||
|
canConfigWifi: Boolean,
|
||||||
|
view: View?
|
||||||
|
) {
|
||||||
if (internetDialog != null) {
|
if (internetDialog != null) {
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
Log.d(TAG, "InternetDialog is showing, do not create it twice.")
|
Log.d(TAG, "InternetDialog is showing, do not create it twice.")
|
||||||
@@ -54,7 +62,11 @@ class InternetDialogFactory @Inject constructor(
|
|||||||
internetDialog = InternetDialog(context, this, internetDialogController,
|
internetDialog = InternetDialog(context, this, internetDialogController,
|
||||||
canConfigMobileData, canConfigWifi, aboveStatusBar, uiEventLogger, handler,
|
canConfigMobileData, canConfigWifi, aboveStatusBar, uiEventLogger, handler,
|
||||||
executor)
|
executor)
|
||||||
internetDialog?.show()
|
if (view != null) {
|
||||||
|
dialogLaunchAnimator.showFromView(internetDialog!!, view)
|
||||||
|
} else {
|
||||||
|
internetDialog?.show()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -71,10 +71,6 @@ class UserDialog(
|
|||||||
setType(WindowManager.LayoutParams.TYPE_STATUS_BAR_SUB_PANEL)
|
setType(WindowManager.LayoutParams.TYPE_STATUS_BAR_SUB_PANEL)
|
||||||
attributes.fitInsetsTypes = attributes.fitInsetsTypes or WindowInsets.Type.statusBars()
|
attributes.fitInsetsTypes = attributes.fitInsetsTypes or WindowInsets.Type.statusBars()
|
||||||
attributes.receiveInsetsIgnoringZOrder = true
|
attributes.receiveInsetsIgnoringZOrder = true
|
||||||
setLayout(
|
|
||||||
context.resources.getDimensionPixelSize(R.dimen.notification_panel_width),
|
|
||||||
ViewGroup.LayoutParams.WRAP_CONTENT
|
|
||||||
)
|
|
||||||
setGravity(Gravity.CENTER)
|
setGravity(Gravity.CENTER)
|
||||||
}
|
}
|
||||||
setContentView(R.layout.qs_user_dialog_content)
|
setContentView(R.layout.qs_user_dialog_content)
|
||||||
|
|||||||
@@ -811,7 +811,8 @@ public class NetworkControllerImpl extends BroadcastReceiver
|
|||||||
break;
|
break;
|
||||||
case Settings.Panel.ACTION_INTERNET_CONNECTIVITY:
|
case Settings.Panel.ACTION_INTERNET_CONNECTIVITY:
|
||||||
mMainHandler.post(() -> mInternetDialogFactory.create(true,
|
mMainHandler.post(() -> mInternetDialogFactory.create(true,
|
||||||
mAccessPoints.canConfigMobileData(), mAccessPoints.canConfigWifi()));
|
mAccessPoints.canConfigMobileData(), mAccessPoints.canConfigWifi(),
|
||||||
|
null /* view */));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
int subId = intent.getIntExtra(SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX,
|
int subId = intent.getIntExtra(SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX,
|
||||||
|
|||||||
@@ -22,7 +22,11 @@ import android.content.BroadcastReceiver;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.IntentFilter;
|
import android.content.IntentFilter;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.os.SystemProperties;
|
||||||
import android.os.UserHandle;
|
import android.os.UserHandle;
|
||||||
|
import android.util.TypedValue;
|
||||||
|
import android.view.ViewGroup;
|
||||||
import android.view.Window;
|
import android.view.Window;
|
||||||
import android.view.WindowInsets.Type;
|
import android.view.WindowInsets.Type;
|
||||||
import android.view.WindowManager;
|
import android.view.WindowManager;
|
||||||
@@ -45,6 +49,10 @@ import java.util.Set;
|
|||||||
* and dismisses itself when it receives the broadcast.
|
* and dismisses itself when it receives the broadcast.
|
||||||
*/
|
*/
|
||||||
public class SystemUIDialog extends AlertDialog implements ListenableDialog {
|
public class SystemUIDialog extends AlertDialog implements ListenableDialog {
|
||||||
|
// TODO(b/203389579): Remove this once the dialog width on large screens has been agreed on.
|
||||||
|
private static final String FLAG_TABLET_DIALOG_WIDTH =
|
||||||
|
"persist.systemui.flag_tablet_dialog_width";
|
||||||
|
|
||||||
private final Context mContext;
|
private final Context mContext;
|
||||||
private final DismissReceiver mDismissReceiver;
|
private final DismissReceiver mDismissReceiver;
|
||||||
private final Set<DialogListener> mDialogListeners = new LinkedHashSet<>();
|
private final Set<DialogListener> mDialogListeners = new LinkedHashSet<>();
|
||||||
@@ -65,6 +73,41 @@ public class SystemUIDialog extends AlertDialog implements ListenableDialog {
|
|||||||
mDismissReceiver = new DismissReceiver(this);
|
mDismissReceiver = new DismissReceiver(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
|
// Set the dialog window size.
|
||||||
|
getWindow().setLayout(getDialogWidth(), ViewGroup.LayoutParams.WRAP_CONTENT);
|
||||||
|
}
|
||||||
|
|
||||||
|
private int getDialogWidth() {
|
||||||
|
boolean isOnTablet =
|
||||||
|
mContext.getResources().getConfiguration().smallestScreenWidthDp >= 600;
|
||||||
|
if (!isOnTablet) {
|
||||||
|
return ViewGroup.LayoutParams.MATCH_PARENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
int flagValue = SystemProperties.getInt(FLAG_TABLET_DIALOG_WIDTH, 0);
|
||||||
|
if (flagValue == -1) {
|
||||||
|
// The width of bottom sheets (624dp).
|
||||||
|
return Math.round(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 624,
|
||||||
|
mContext.getResources().getDisplayMetrics()));
|
||||||
|
} else if (flagValue == -2) {
|
||||||
|
// The suggested small width for all dialogs (348dp)
|
||||||
|
return Math.round(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 348,
|
||||||
|
mContext.getResources().getDisplayMetrics()));
|
||||||
|
} else if (flagValue > 0) {
|
||||||
|
// Any given width.
|
||||||
|
return Math.round(
|
||||||
|
TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, flagValue,
|
||||||
|
mContext.getResources().getDisplayMetrics()));
|
||||||
|
} else {
|
||||||
|
// By default we use the same width as the notification shade in portrait mode (504dp).
|
||||||
|
return mContext.getResources().getDimensionPixelSize(R.dimen.large_dialog_width);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onStart() {
|
protected void onStart() {
|
||||||
super.onStart();
|
super.onStart();
|
||||||
|
|||||||
@@ -45,6 +45,7 @@ import com.android.keyguard.KeyguardUpdateMonitor;
|
|||||||
import com.android.settingslib.wifi.WifiUtils;
|
import com.android.settingslib.wifi.WifiUtils;
|
||||||
import com.android.systemui.R;
|
import com.android.systemui.R;
|
||||||
import com.android.systemui.SysuiTestCase;
|
import com.android.systemui.SysuiTestCase;
|
||||||
|
import com.android.systemui.animation.DialogLaunchAnimator;
|
||||||
import com.android.systemui.broadcast.BroadcastDispatcher;
|
import com.android.systemui.broadcast.BroadcastDispatcher;
|
||||||
import com.android.systemui.dagger.qualifiers.Main;
|
import com.android.systemui.dagger.qualifiers.Main;
|
||||||
import com.android.systemui.plugins.ActivityStarter;
|
import com.android.systemui.plugins.ActivityStarter;
|
||||||
@@ -138,6 +139,8 @@ public class InternetDialogControllerTest extends SysuiTestCase {
|
|||||||
private CarrierConfigTracker mCarrierConfigTracker;
|
private CarrierConfigTracker mCarrierConfigTracker;
|
||||||
@Mock
|
@Mock
|
||||||
private LocationController mLocationController;
|
private LocationController mLocationController;
|
||||||
|
@Mock
|
||||||
|
private DialogLaunchAnimator mDialogLaunchAnimator;
|
||||||
|
|
||||||
private TestableResources mTestableResources;
|
private TestableResources mTestableResources;
|
||||||
private MockInternetDialogController mInternetDialogController;
|
private MockInternetDialogController mInternetDialogController;
|
||||||
@@ -174,7 +177,7 @@ public class InternetDialogControllerTest extends SysuiTestCase {
|
|||||||
mock(ConnectivityManager.class), mHandler, mExecutor, mBroadcastDispatcher,
|
mock(ConnectivityManager.class), mHandler, mExecutor, mBroadcastDispatcher,
|
||||||
mock(KeyguardUpdateMonitor.class), mGlobalSettings, mKeyguardStateController,
|
mock(KeyguardUpdateMonitor.class), mGlobalSettings, mKeyguardStateController,
|
||||||
mWindowManager, mToastFactory, mWorkerHandler, mCarrierConfigTracker,
|
mWindowManager, mToastFactory, mWorkerHandler, mCarrierConfigTracker,
|
||||||
mLocationController);
|
mLocationController, mDialogLaunchAnimator);
|
||||||
mSubscriptionManager.addOnSubscriptionsChangedListener(mExecutor,
|
mSubscriptionManager.addOnSubscriptionsChangedListener(mExecutor,
|
||||||
mInternetDialogController.mOnSubscriptionsChangedListener);
|
mInternetDialogController.mOnSubscriptionsChangedListener);
|
||||||
mInternetDialogController.onStart(mInternetDialogCallback, true);
|
mInternetDialogController.onStart(mInternetDialogCallback, true);
|
||||||
@@ -654,12 +657,13 @@ public class InternetDialogControllerTest extends SysuiTestCase {
|
|||||||
KeyguardStateController keyguardStateController, WindowManager windowManager,
|
KeyguardStateController keyguardStateController, WindowManager windowManager,
|
||||||
ToastFactory toastFactory, Handler workerHandler,
|
ToastFactory toastFactory, Handler workerHandler,
|
||||||
CarrierConfigTracker carrierConfigTracker,
|
CarrierConfigTracker carrierConfigTracker,
|
||||||
LocationController locationController) {
|
LocationController locationController,
|
||||||
|
DialogLaunchAnimator dialogLaunchAnimator) {
|
||||||
super(context, uiEventLogger, starter, accessPointController, subscriptionManager,
|
super(context, uiEventLogger, starter, accessPointController, subscriptionManager,
|
||||||
telephonyManager, wifiManager, connectivityManager, handler, mainExecutor,
|
telephonyManager, wifiManager, connectivityManager, handler, mainExecutor,
|
||||||
broadcastDispatcher, keyguardUpdateMonitor, globalSettings,
|
broadcastDispatcher, keyguardUpdateMonitor, globalSettings,
|
||||||
keyguardStateController, windowManager, toastFactory, workerHandler,
|
keyguardStateController, windowManager, toastFactory, workerHandler,
|
||||||
carrierConfigTracker, locationController);
|
carrierConfigTracker, locationController, dialogLaunchAnimator);
|
||||||
mGlobalSettings = globalSettings;
|
mGlobalSettings = globalSettings;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user