• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022 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.mediaprojection.appselector
18 
19 import android.app.Activity
20 import android.content.ComponentName
21 import android.content.Context
22 import android.os.UserHandle
23 import com.android.launcher3.icons.IconFactory
24 import com.android.systemui.dagger.qualifiers.Application
25 import com.android.systemui.media.MediaProjectionAppSelectorActivity
26 import com.android.systemui.media.MediaProjectionAppSelectorActivity.Companion.EXTRA_HOST_APP_USER_HANDLE
27 import com.android.systemui.media.MediaProjectionPermissionActivity
28 import com.android.systemui.mediaprojection.appselector.data.ActivityTaskManagerLabelLoader
29 import com.android.systemui.mediaprojection.appselector.data.ActivityTaskManagerThumbnailLoader
30 import com.android.systemui.mediaprojection.appselector.data.AppIconLoader
31 import com.android.systemui.mediaprojection.appselector.data.IconLoaderLibAppIconLoader
32 import com.android.systemui.mediaprojection.appselector.data.RecentTaskLabelLoader
33 import com.android.systemui.mediaprojection.appselector.data.RecentTaskListProvider
34 import com.android.systemui.mediaprojection.appselector.data.RecentTaskThumbnailLoader
35 import com.android.systemui.mediaprojection.appselector.data.ShellRecentTaskListProvider
36 import com.android.systemui.mediaprojection.appselector.view.MediaProjectionRecentsViewController
37 import com.android.systemui.mediaprojection.appselector.view.TaskPreviewSizeProvider
38 import com.android.systemui.mediaprojection.devicepolicy.MediaProjectionDevicePolicyModule
39 import com.android.systemui.mediaprojection.devicepolicy.PersonalProfile
40 import com.android.systemui.statusbar.phone.ConfigurationControllerImpl
41 import com.android.systemui.statusbar.policy.ConfigurationController
42 import dagger.Binds
43 import dagger.BindsInstance
44 import dagger.Module
45 import dagger.Provides
46 import dagger.Subcomponent
47 import dagger.multibindings.ClassKey
48 import dagger.multibindings.IntoMap
49 import javax.inject.Qualifier
50 import javax.inject.Scope
51 import kotlinx.coroutines.CoroutineScope
52 import kotlinx.coroutines.SupervisorJob
53 
54 @Qualifier @Retention(AnnotationRetention.BINARY) annotation class MediaProjectionAppSelector
55 
56 @Qualifier @Retention(AnnotationRetention.BINARY) annotation class HostUserHandle
57 
58 @Retention(AnnotationRetention.RUNTIME) @Scope annotation class MediaProjectionAppSelectorScope
59 
60 @Module(
61     subcomponents = [MediaProjectionAppSelectorComponent::class],
62     includes = [MediaProjectionDevicePolicyModule::class]
63 )
64 interface MediaProjectionModule {
65     @Binds
66     @IntoMap
67     @ClassKey(MediaProjectionAppSelectorActivity::class)
provideMediaProjectionAppSelectorActivitynull68     fun provideMediaProjectionAppSelectorActivity(
69         activity: MediaProjectionAppSelectorActivity
70     ): Activity
71 
72     @Binds
73     @IntoMap
74     @ClassKey(MediaProjectionPermissionActivity::class)
75     fun bindsMediaProjectionPermissionActivity(impl: MediaProjectionPermissionActivity): Activity
76 }
77 
78 /**
79  * Scoped values for [MediaProjectionAppSelectorComponent]. We create a scope for the activity so
80  * certain dependencies like [TaskPreviewSizeProvider] could be reused.
81  */
82 @Module
83 interface MediaProjectionAppSelectorModule {
84 
85     @Binds
86     @MediaProjectionAppSelectorScope
87     fun bindRecentTaskThumbnailLoader(
88         impl: ActivityTaskManagerThumbnailLoader
89     ): RecentTaskThumbnailLoader
90 
91     @Binds
92     @MediaProjectionAppSelectorScope
93     fun bindRecentTaskLabelLoader(impl: ActivityTaskManagerLabelLoader): RecentTaskLabelLoader
94 
95     @Binds
96     @MediaProjectionAppSelectorScope
97     fun bindRecentTaskListProvider(impl: ShellRecentTaskListProvider): RecentTaskListProvider
98 
99     @Binds
100     @MediaProjectionAppSelectorScope
101     fun bindAppIconLoader(impl: IconLoaderLibAppIconLoader): AppIconLoader
102 
103     companion object {
104         @Provides
105         @MediaProjectionAppSelector
106         @MediaProjectionAppSelectorScope
107         fun provideAppSelectorComponentName(context: Context): ComponentName =
108             ComponentName(context, MediaProjectionAppSelectorActivity::class.java)
109 
110         @Provides
111         @MediaProjectionAppSelector
112         @MediaProjectionAppSelectorScope
113         fun provideCallerPackageName(activity: MediaProjectionAppSelectorActivity): String? =
114             activity.callingPackage
115 
116         @Provides
117         @MediaProjectionAppSelector
118         @MediaProjectionAppSelectorScope
119         fun bindConfigurationController(
120             activity: MediaProjectionAppSelectorActivity
121         ): ConfigurationController = ConfigurationControllerImpl(activity)
122 
123         @Provides
124         @HostUserHandle
125         @MediaProjectionAppSelectorScope
126         fun hostUserHandle(activity: MediaProjectionAppSelectorActivity): UserHandle {
127             val extras =
128                 activity.intent.extras
129                     ?: error("MediaProjectionAppSelectorActivity should be launched with extras")
130             return extras.getParcelable(EXTRA_HOST_APP_USER_HANDLE)
131                 ?: error(
132                     "MediaProjectionAppSelectorActivity should be provided with " +
133                         "$EXTRA_HOST_APP_USER_HANDLE extra"
134                 )
135         }
136 
137         @Provides fun bindIconFactory(context: Context): IconFactory = IconFactory.obtain(context)
138 
139         @Provides
140         @MediaProjectionAppSelector
141         @MediaProjectionAppSelectorScope
142         fun provideCoroutineScope(@Application applicationScope: CoroutineScope): CoroutineScope =
143             CoroutineScope(applicationScope.coroutineContext + SupervisorJob())
144     }
145 }
146 
147 @Subcomponent(modules = [MediaProjectionAppSelectorModule::class])
148 @MediaProjectionAppSelectorScope
149 interface MediaProjectionAppSelectorComponent {
150 
151     /** Generates [MediaProjectionAppSelectorComponent]. */
152     @Subcomponent.Factory
153     interface Factory {
154         /** Create a factory to inject the activity into the graph */
createnull155         fun create(
156             @BindsInstance activity: MediaProjectionAppSelectorActivity,
157             @BindsInstance view: MediaProjectionAppSelectorView,
158             @BindsInstance resultHandler: MediaProjectionAppSelectorResultHandler,
159         ): MediaProjectionAppSelectorComponent
160     }
161 
162     val controller: MediaProjectionAppSelectorController
163     val recentsViewController: MediaProjectionRecentsViewController
164     val emptyStateProvider: MediaProjectionBlockerEmptyStateProvider
165     @get:HostUserHandle val hostUserHandle: UserHandle
166     @get:PersonalProfile val personalProfileUserHandle: UserHandle
167 
168     @MediaProjectionAppSelector val configurationController: ConfigurationController
169 }
170