1 /* 2 * Copyright (C) 2021 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.systemui.controls.ui 18 19 import android.content.BroadcastReceiver 20 import android.content.Context 21 import android.content.Intent 22 import android.content.IntentFilter 23 import android.os.Bundle 24 import android.view.View 25 import android.view.ViewGroup 26 import android.view.WindowInsets 27 import android.view.WindowInsets.Type 28 29 import com.android.systemui.R 30 import com.android.systemui.broadcast.BroadcastDispatcher 31 import com.android.systemui.controls.management.ControlsAnimations 32 import com.android.systemui.util.LifecycleActivity 33 import javax.inject.Inject 34 35 /** 36 * Displays Device Controls inside an activity. This activity is available to be displayed over the 37 * lockscreen if the user has allowed it via 38 * [android.provider.Settings.Secure.LOCKSCREEN_SHOW_CONTROLS]. This activity will be 39 * destroyed on SCREEN_OFF events, due to issues with occluded activities over lockscreen as well as 40 * user expectations for the activity to not continue running. 41 */ 42 class ControlsActivity @Inject constructor( 43 private val uiController: ControlsUiController, 44 private val broadcastDispatcher: BroadcastDispatcher 45 ) : LifecycleActivity() { 46 47 private lateinit var parent: ViewGroup 48 private lateinit var broadcastReceiver: BroadcastReceiver 49 50 override fun onCreate(savedInstanceState: Bundle?) { 51 super.onCreate(savedInstanceState) 52 53 setContentView(R.layout.controls_fullscreen) 54 55 getLifecycle().addObserver( 56 ControlsAnimations.observerForAnimations( 57 requireViewById<ViewGroup>(R.id.control_detail_root), 58 window, 59 intent 60 ) 61 ) 62 63 requireViewById<ViewGroup>(R.id.control_detail_root).apply { 64 setOnApplyWindowInsetsListener { 65 v: View, insets: WindowInsets -> 66 v.apply { 67 val l = getPaddingLeft() 68 val t = getPaddingTop() 69 val r = getPaddingRight() 70 setPadding(l, t, r, insets.getInsets(Type.systemBars()).bottom) 71 } 72 73 WindowInsets.CONSUMED 74 } 75 } 76 77 initBroadcastReceiver() 78 } 79 80 override fun onResume() { 81 super.onResume() 82 83 parent = requireViewById<ViewGroup>(R.id.global_actions_controls) 84 parent.alpha = 0f 85 uiController.show(parent, { finish() }, this) 86 87 ControlsAnimations.enterAnimation(parent).start() 88 } 89 90 override fun onBackPressed() { 91 finish() 92 } 93 94 override fun onPause() { 95 super.onPause() 96 97 uiController.hide() 98 } 99 100 override fun onDestroy() { 101 super.onDestroy() 102 103 broadcastDispatcher.unregisterReceiver(broadcastReceiver) 104 } 105 106 private fun initBroadcastReceiver() { 107 broadcastReceiver = object : BroadcastReceiver() { 108 override fun onReceive(context: Context, intent: Intent) { 109 val action = intent.getAction() 110 if (Intent.ACTION_SCREEN_OFF.equals(action)) { 111 finish() 112 } 113 } 114 } 115 116 val filter = IntentFilter() 117 filter.addAction(Intent.ACTION_SCREEN_OFF) 118 broadcastDispatcher.registerReceiver(broadcastReceiver, filter) 119 } 120 } 121