Merge "Add FSI view binder and wm config" into tm-qpr-dev
This commit is contained in:
@@ -43,6 +43,7 @@ import com.android.systemui.shortcut.ShortcutKeyDispatcher
|
|||||||
import com.android.systemui.statusbar.notification.fsi.FsiChromeRepo
|
import com.android.systemui.statusbar.notification.fsi.FsiChromeRepo
|
||||||
import com.android.systemui.statusbar.notification.InstantAppNotifier
|
import com.android.systemui.statusbar.notification.InstantAppNotifier
|
||||||
import com.android.systemui.statusbar.notification.fsi.FsiChromeViewModelFactory
|
import com.android.systemui.statusbar.notification.fsi.FsiChromeViewModelFactory
|
||||||
|
import com.android.systemui.statusbar.notification.fsi.FsiChromeViewBinder
|
||||||
import com.android.systemui.statusbar.phone.KeyguardLiftController
|
import com.android.systemui.statusbar.phone.KeyguardLiftController
|
||||||
import com.android.systemui.stylus.StylusUsiPowerStartable
|
import com.android.systemui.stylus.StylusUsiPowerStartable
|
||||||
import com.android.systemui.temporarydisplay.chipbar.ChipbarCoordinator
|
import com.android.systemui.temporarydisplay.chipbar.ChipbarCoordinator
|
||||||
@@ -93,6 +94,12 @@ abstract class SystemUICoreStartableModule {
|
|||||||
@ClassKey(FsiChromeViewModelFactory::class)
|
@ClassKey(FsiChromeViewModelFactory::class)
|
||||||
abstract fun bindFSIChromeWindowViewModel(sysui: FsiChromeViewModelFactory): CoreStartable
|
abstract fun bindFSIChromeWindowViewModel(sysui: FsiChromeViewModelFactory): CoreStartable
|
||||||
|
|
||||||
|
/** Inject into FsiChromeWindowBinder. */
|
||||||
|
@Binds
|
||||||
|
@IntoMap
|
||||||
|
@ClassKey(FsiChromeViewBinder::class)
|
||||||
|
abstract fun bindFsiChromeWindowBinder(sysui: FsiChromeViewBinder): CoreStartable
|
||||||
|
|
||||||
/** Inject into GarbageMonitor.Service. */
|
/** Inject into GarbageMonitor.Service. */
|
||||||
@Binds
|
@Binds
|
||||||
@IntoMap
|
@IntoMap
|
||||||
|
|||||||
@@ -0,0 +1,99 @@
|
|||||||
|
package com.android.systemui.statusbar.notification.fsi
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.WindowManager
|
||||||
|
import com.android.systemui.CoreStartable
|
||||||
|
import com.android.systemui.R
|
||||||
|
import com.android.systemui.dagger.SysUISingleton
|
||||||
|
import com.android.systemui.dagger.qualifiers.Application
|
||||||
|
import com.android.systemui.dagger.qualifiers.Main
|
||||||
|
import com.android.systemui.statusbar.notification.fsi.FsiDebug.Companion.log
|
||||||
|
import com.android.systemui.statusbar.phone.CentralSurfaces
|
||||||
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
import java.util.concurrent.Executor
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
@SysUISingleton
|
||||||
|
class FsiChromeViewBinder
|
||||||
|
@Inject
|
||||||
|
constructor(
|
||||||
|
val context: Context,
|
||||||
|
val windowManager: WindowManager,
|
||||||
|
val viewModelFactory: FsiChromeViewModelFactory,
|
||||||
|
val layoutInflater: LayoutInflater,
|
||||||
|
val centralSurfaces: CentralSurfaces,
|
||||||
|
@Main val mainExecutor: Executor,
|
||||||
|
@Application val scope: CoroutineScope,
|
||||||
|
) : CoreStartable {
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private const val classTag = "FsiChromeViewBinder"
|
||||||
|
}
|
||||||
|
|
||||||
|
private val fsiChromeView =
|
||||||
|
layoutInflater.inflate(R.layout.fsi_chrome_view, null /* root */, false /* attachToRoot */)
|
||||||
|
as FsiChromeView
|
||||||
|
|
||||||
|
var addedToWindowManager = false
|
||||||
|
var cornerRadius: Int = context.resources.getDimensionPixelSize(
|
||||||
|
R.dimen.notification_corner_radius)
|
||||||
|
|
||||||
|
override fun start() {
|
||||||
|
val methodTag = "start"
|
||||||
|
log("$classTag $methodTag ")
|
||||||
|
|
||||||
|
scope.launch {
|
||||||
|
log("$classTag $methodTag launch ")
|
||||||
|
viewModelFactory.viewModelFlow.collect { vm -> updateForViewModel(vm) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun updateForViewModel(vm: FsiChromeViewModel?) {
|
||||||
|
val methodTag = "updateForViewModel"
|
||||||
|
|
||||||
|
if (vm == null) {
|
||||||
|
log("$classTag $methodTag viewModel is null, removing from window manager")
|
||||||
|
|
||||||
|
if (addedToWindowManager) {
|
||||||
|
windowManager.removeView(fsiChromeView)
|
||||||
|
addedToWindowManager = false
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
bindViewModel(vm, windowManager)
|
||||||
|
|
||||||
|
if (addedToWindowManager) {
|
||||||
|
log("$classTag $methodTag already addedToWindowManager")
|
||||||
|
} else {
|
||||||
|
windowManager.addView(fsiChromeView, FsiTaskViewConfig.getWmLayoutParams("PackageName"))
|
||||||
|
addedToWindowManager = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun bindViewModel(
|
||||||
|
vm: FsiChromeViewModel,
|
||||||
|
windowManager: WindowManager,
|
||||||
|
) {
|
||||||
|
log("$classTag bindViewModel")
|
||||||
|
|
||||||
|
fsiChromeView.appIconImageView.setImageDrawable(vm.appIcon)
|
||||||
|
fsiChromeView.appNameTextView.text = vm.appName
|
||||||
|
|
||||||
|
fsiChromeView.dismissButton.setOnClickListener { vm.onDismiss() }
|
||||||
|
fsiChromeView.fullscreenButton.setOnClickListener { vm.onFullscreen() }
|
||||||
|
|
||||||
|
vm.taskView.cornerRadius = cornerRadius.toFloat()
|
||||||
|
vm.taskView.startActivity(
|
||||||
|
vm.fsi,
|
||||||
|
FsiTaskViewConfig.getFillInIntent(),
|
||||||
|
FsiTaskViewConfig.getActivityOptions(context, windowManager),
|
||||||
|
FsiTaskViewConfig.getLaunchBounds(windowManager)
|
||||||
|
)
|
||||||
|
|
||||||
|
log("$classTag bindViewModel started taskview activity")
|
||||||
|
fsiChromeView.addView(vm.taskView)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,75 @@
|
|||||||
|
package com.android.systemui.statusbar.notification.fsi
|
||||||
|
|
||||||
|
import android.app.ActivityOptions
|
||||||
|
import android.content.Context
|
||||||
|
import android.content.Intent
|
||||||
|
import android.graphics.PixelFormat
|
||||||
|
import android.graphics.Rect
|
||||||
|
import android.os.Binder
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import android.view.WindowManager
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Config for adding the FsiChromeView window to WindowManager and starting the FSI activity.
|
||||||
|
*/
|
||||||
|
class FsiTaskViewConfig {
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
|
||||||
|
private const val classTag = "FsiTaskViewConfig"
|
||||||
|
|
||||||
|
fun getWmLayoutParams(packageName: String): WindowManager.LayoutParams {
|
||||||
|
val params: WindowManager.LayoutParams?
|
||||||
|
params =
|
||||||
|
WindowManager.LayoutParams(
|
||||||
|
ViewGroup.LayoutParams.MATCH_PARENT,
|
||||||
|
ViewGroup.LayoutParams.MATCH_PARENT,
|
||||||
|
WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL,
|
||||||
|
WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE or
|
||||||
|
WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED or
|
||||||
|
WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER,
|
||||||
|
PixelFormat.TRANSLUCENT
|
||||||
|
)
|
||||||
|
params.setTrustedOverlay()
|
||||||
|
params.fitInsetsTypes = 0
|
||||||
|
params.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE
|
||||||
|
params.token = Binder()
|
||||||
|
params.packageName = packageName
|
||||||
|
params.layoutInDisplayCutoutMode =
|
||||||
|
WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS
|
||||||
|
params.privateFlags =
|
||||||
|
params.privateFlags or WindowManager.LayoutParams.SYSTEM_FLAG_SHOW_FOR_ALL_USERS
|
||||||
|
return params
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getFillInIntent(): Intent {
|
||||||
|
val fillInIntent = Intent()
|
||||||
|
fillInIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT)
|
||||||
|
fillInIntent.addFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK)
|
||||||
|
// FLAG_ACTIVITY_NEW_TASK is auto-applied because
|
||||||
|
// we're starting the FSI activity from a non-Activity context
|
||||||
|
return fillInIntent
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getLaunchBounds(windowManager: WindowManager): Rect {
|
||||||
|
// TODO(b/243421660) check this works for non-resizeable activity
|
||||||
|
return Rect()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getActivityOptions(context: Context, windowManager: WindowManager): ActivityOptions {
|
||||||
|
// Custom options so there is no activity transition animation
|
||||||
|
val options =
|
||||||
|
ActivityOptions.makeCustomAnimation(context, 0 /* enterResId */, 0 /* exitResId */)
|
||||||
|
|
||||||
|
options.taskAlwaysOnTop = true
|
||||||
|
|
||||||
|
options.pendingIntentLaunchFlags =
|
||||||
|
Intent.FLAG_ACTIVITY_NEW_DOCUMENT or
|
||||||
|
Intent.FLAG_ACTIVITY_MULTIPLE_TASK or
|
||||||
|
Intent.FLAG_ACTIVITY_NEW_TASK
|
||||||
|
|
||||||
|
options.launchBounds = getLaunchBounds(windowManager)
|
||||||
|
return options
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user