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