1 /* 2 * Copyright (C) 2019 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.management 18 19 import android.app.ActivityOptions 20 import android.content.ComponentName 21 import android.content.Intent 22 import android.os.Bundle 23 import android.view.LayoutInflater 24 import android.view.View 25 import android.view.ViewGroup 26 import android.view.ViewStub 27 import android.widget.Button 28 import android.widget.TextView 29 import androidx.recyclerview.widget.LinearLayoutManager 30 import androidx.recyclerview.widget.RecyclerView 31 import androidx.recyclerview.widget.RecyclerView.AdapterDataObserver 32 import com.android.systemui.R 33 import com.android.systemui.broadcast.BroadcastDispatcher 34 import com.android.systemui.controls.controller.ControlsController 35 import com.android.systemui.dagger.qualifiers.Background 36 import com.android.systemui.dagger.qualifiers.Main 37 import com.android.systemui.globalactions.GlobalActionsComponent 38 import com.android.systemui.settings.CurrentUserTracker 39 import com.android.systemui.util.LifecycleActivity 40 import java.util.concurrent.Executor 41 import javax.inject.Inject 42 43 /** 44 * Activity to select an application to favorite the [Control] provided by them. 45 */ 46 class ControlsProviderSelectorActivity @Inject constructor( 47 @Main private val executor: Executor, 48 @Background private val backExecutor: Executor, 49 private val listingController: ControlsListingController, 50 private val controlsController: ControlsController, 51 private val globalActionsComponent: GlobalActionsComponent, 52 broadcastDispatcher: BroadcastDispatcher 53 ) : LifecycleActivity() { 54 55 companion object { 56 private const val TAG = "ControlsProviderSelectorActivity" 57 } 58 59 private lateinit var recyclerView: RecyclerView 60 private val currentUserTracker = object : CurrentUserTracker(broadcastDispatcher) { 61 private val startingUser = listingController.currentUserId 62 onUserSwitchednull63 override fun onUserSwitched(newUserId: Int) { 64 if (newUserId != startingUser) { 65 stopTracking() 66 finish() 67 } 68 } 69 } 70 onCreatenull71 override fun onCreate(savedInstanceState: Bundle?) { 72 super.onCreate(savedInstanceState) 73 74 setContentView(R.layout.controls_management) 75 76 getLifecycle().addObserver( 77 ControlsAnimations.observerForAnimations( 78 requireViewById<ViewGroup>(R.id.controls_management_root), 79 window, 80 intent 81 ) 82 ) 83 84 requireViewById<ViewStub>(R.id.stub).apply { 85 layoutResource = R.layout.controls_management_apps 86 inflate() 87 } 88 89 recyclerView = requireViewById(R.id.list) 90 recyclerView.layoutManager = LinearLayoutManager(applicationContext) 91 92 requireViewById<TextView>(R.id.title).apply { 93 text = resources.getText(R.string.controls_providers_title) 94 } 95 96 requireViewById<Button>(R.id.other_apps).apply { 97 visibility = View.VISIBLE 98 setText(com.android.internal.R.string.cancel) 99 setOnClickListener { 100 onBackPressed() 101 } 102 } 103 requireViewById<View>(R.id.done).visibility = View.GONE 104 } 105 onBackPressednull106 override fun onBackPressed() { 107 globalActionsComponent.handleShowGlobalActionsMenu() 108 animateExitAndFinish() 109 } 110 onStartnull111 override fun onStart() { 112 super.onStart() 113 currentUserTracker.startTracking() 114 115 recyclerView.alpha = 0.0f 116 recyclerView.adapter = AppAdapter( 117 backExecutor, 118 executor, 119 lifecycle, 120 listingController, 121 LayoutInflater.from(this), 122 ::launchFavoritingActivity, 123 FavoritesRenderer(resources, controlsController::countFavoritesForComponent), 124 resources).apply { 125 registerAdapterDataObserver(object : RecyclerView.AdapterDataObserver() { 126 var hasAnimated = false 127 override fun onChanged() { 128 if (!hasAnimated) { 129 hasAnimated = true 130 ControlsAnimations.enterAnimation(recyclerView).start() 131 } 132 } 133 }) 134 } 135 } 136 onStopnull137 override fun onStop() { 138 super.onStop() 139 currentUserTracker.stopTracking() 140 } 141 142 /** 143 * Launch the [ControlsFavoritingActivity] for the specified component. 144 * @param component a component name for a [ControlsProviderService] 145 */ launchFavoritingActivitynull146 fun launchFavoritingActivity(component: ComponentName?) { 147 executor.execute { 148 component?.let { 149 val intent = Intent(applicationContext, ControlsFavoritingActivity::class.java) 150 .apply { 151 putExtra(ControlsFavoritingActivity.EXTRA_APP, 152 listingController.getAppLabel(it)) 153 putExtra(Intent.EXTRA_COMPONENT_NAME, it) 154 putExtra(ControlsFavoritingActivity.EXTRA_FROM_PROVIDER_SELECTOR, true) 155 } 156 startActivity(intent, ActivityOptions.makeSceneTransitionAnimation(this).toBundle()) 157 } 158 } 159 } 160 onDestroynull161 override fun onDestroy() { 162 currentUserTracker.stopTracking() 163 super.onDestroy() 164 } 165 animateExitAndFinishnull166 private fun animateExitAndFinish() { 167 val rootView = requireViewById<ViewGroup>(R.id.controls_management_root) 168 ControlsAnimations.exitAnimation( 169 rootView, 170 object : Runnable { 171 override fun run() { 172 finish() 173 } 174 } 175 ).start() 176 } 177 } 178