• 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 androidx.lifecycle.DefaultLifecycleObserver
24 import com.android.launcher3.icons.IconFactory
25 import com.android.systemui.coroutines.newTracingContext
26 import com.android.systemui.dagger.qualifiers.Application
27 import com.android.systemui.mediaprojection.appselector.data.ActivityTaskManagerLabelLoader
28 import com.android.systemui.mediaprojection.appselector.data.ActivityTaskManagerThumbnailLoader
29 import com.android.systemui.mediaprojection.appselector.data.BasicAppIconLoader
30 import com.android.systemui.mediaprojection.appselector.data.BasicPackageManagerAppIconLoader
31 import com.android.systemui.mediaprojection.appselector.data.RecentTaskLabelLoader
32 import com.android.systemui.mediaprojection.appselector.data.RecentTaskListProvider
33 import com.android.systemui.mediaprojection.appselector.data.RecentTaskThumbnailLoader
34 import com.android.systemui.mediaprojection.appselector.data.ShellRecentTaskListProvider
35 import com.android.systemui.mediaprojection.appselector.view.MediaProjectionRecentsViewController
36 import com.android.systemui.mediaprojection.appselector.view.TaskPreviewSizeProvider
37 import com.android.systemui.mediaprojection.appselector.view.WindowMetricsProvider
38 import com.android.systemui.mediaprojection.appselector.view.WindowMetricsProviderImpl
39 import com.android.systemui.mediaprojection.devicepolicy.MediaProjectionDevicePolicyModule
40 import com.android.systemui.mediaprojection.devicepolicy.PersonalProfile
41 import com.android.systemui.mediaprojection.permission.MediaProjectionPermissionActivity
42 import com.android.systemui.statusbar.phone.ConfigurationControllerImpl
43 import com.android.systemui.statusbar.policy.ConfigurationController
44 import dagger.Binds
45 import dagger.BindsInstance
46 import dagger.Module
47 import dagger.Provides
48 import dagger.Subcomponent
49 import dagger.multibindings.ClassKey
50 import dagger.multibindings.IntoMap
51 import dagger.multibindings.IntoSet
52 import javax.inject.Qualifier
53 import javax.inject.Scope
54 import kotlinx.coroutines.CoroutineScope
55 import kotlinx.coroutines.SupervisorJob
56 
57 @Qualifier @Retention(AnnotationRetention.BINARY) annotation class MediaProjectionAppSelector
58 
59 @Qualifier @Retention(AnnotationRetention.BINARY) annotation class HostUserHandle
60 
61 @Qualifier @Retention(AnnotationRetention.BINARY) annotation class HostUid
62 
63 @Retention(AnnotationRetention.RUNTIME) @Scope annotation class MediaProjectionAppSelectorScope
64 
65 @Module(
66     subcomponents = [MediaProjectionAppSelectorComponent::class],
67     includes = [MediaProjectionDevicePolicyModule::class]
68 )
69 interface MediaProjectionActivitiesModule {
70     @Binds
71     @IntoMap
72     @ClassKey(MediaProjectionAppSelectorActivity::class)
provideMediaProjectionAppSelectorActivitynull73     fun provideMediaProjectionAppSelectorActivity(
74         activity: MediaProjectionAppSelectorActivity
75     ): Activity
76 
77     @Binds
78     @IntoMap
79     @ClassKey(MediaProjectionPermissionActivity::class)
80     fun bindsMediaProjectionPermissionActivity(impl: MediaProjectionPermissionActivity): Activity
81 }
82 
83 /**
84  * Scoped values for [MediaProjectionAppSelectorComponent]. We create a scope for the activity so
85  * certain dependencies like [TaskPreviewSizeProvider] could be reused.
86  */
87 @Module
88 interface MediaProjectionAppSelectorModule {
89 
90     @Binds
91     @MediaProjectionAppSelectorScope
92     fun bindRecentTaskThumbnailLoader(
93         impl: ActivityTaskManagerThumbnailLoader
94     ): RecentTaskThumbnailLoader
95 
96     @Binds
97     @MediaProjectionAppSelectorScope
98     fun bindRecentTaskLabelLoader(impl: ActivityTaskManagerLabelLoader): RecentTaskLabelLoader
99 
100     @Binds
101     @MediaProjectionAppSelectorScope
102     fun bindRecentTaskListProvider(impl: ShellRecentTaskListProvider): RecentTaskListProvider
103 
104     @Binds
105     @MediaProjectionAppSelectorScope
106     fun bindAppIconLoader(impl: BasicPackageManagerAppIconLoader): BasicAppIconLoader
107 
108     @Binds
109     @IntoSet
110     fun taskPreviewSizeProviderAsLifecycleObserver(
111         impl: TaskPreviewSizeProvider
112     ): DefaultLifecycleObserver
113 
114     @Binds fun windowMetricsProvider(impl: WindowMetricsProviderImpl): WindowMetricsProvider
115 
116     companion object {
117         @Provides
118         @MediaProjectionAppSelector
119         @MediaProjectionAppSelectorScope
120         fun provideAppSelectorComponentName(context: Context): ComponentName =
121             ComponentName(context, MediaProjectionAppSelectorActivity::class.java)
122 
123         @Provides
124         @MediaProjectionAppSelector
125         @MediaProjectionAppSelectorScope
126         fun bindConfigurationController(
127             context: Context,
128             configurationControlleFactory: ConfigurationControllerImpl.Factory
129         ): ConfigurationController = configurationControlleFactory.create(context)
130 
131         @Provides fun bindIconFactory(context: Context): IconFactory = IconFactory.obtain(context)
132 
133         @Provides
134         @MediaProjectionAppSelector
135         @MediaProjectionAppSelectorScope
136         fun provideCoroutineScope(@Application applicationScope: CoroutineScope): CoroutineScope =
137             CoroutineScope(
138                 applicationScope.coroutineContext +
139                     SupervisorJob() +
140                     newTracingContext("MediaProjectionAppSelectorScope")
141             )
142     }
143 }
144 
145 @Subcomponent(modules = [MediaProjectionAppSelectorModule::class])
146 @MediaProjectionAppSelectorScope
147 interface MediaProjectionAppSelectorComponent {
148 
149     /** Generates [MediaProjectionAppSelectorComponent]. */
150     @Subcomponent.Factory
151     interface Factory {
152         /** Create a factory to inject the activity into the graph */
createnull153         fun create(
154             @BindsInstance @HostUserHandle hostUserHandle: UserHandle,
155             @BindsInstance @HostUid hostUid: Int,
156             @BindsInstance @MediaProjectionAppSelector callingPackage: String?,
157             @BindsInstance view: MediaProjectionAppSelectorView,
158             @BindsInstance resultHandler: MediaProjectionAppSelectorResultHandler,
159             // Whether the app selector is starting for the first time. False when it is re-starting
160             // due to a config change.
161             @BindsInstance @MediaProjectionAppSelector isFirstStart: Boolean,
162         ): MediaProjectionAppSelectorComponent
163     }
164 
165     val controller: MediaProjectionAppSelectorController
166     val recentsViewController: MediaProjectionRecentsViewController
167     val emptyStateProvider: MediaProjectionBlockerEmptyStateProvider
168     @get:HostUserHandle val hostUserHandle: UserHandle
169     @get:PersonalProfile val personalProfileUserHandle: UserHandle
170 
171     @MediaProjectionAppSelector val configurationController: ConfigurationController
172     val lifecycleObservers: Set<DefaultLifecycleObserver>
173 }
174