Merge "Add FSI view binder and wm config" into tm-qpr-dev

This commit is contained in:
Lyn Han
2022-12-24 04:01:06 +00:00
committed by Android (Google) Code Review
3 changed files with 181 additions and 0 deletions

View File

@@ -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

View File

@@ -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)
}
}

View File

@@ -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
}
}
}