• 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.complication;
18 
19 import static com.android.systemui.complication.dagger.DreamMediaEntryComplicationComponent.DreamMediaEntryModule.DREAM_MEDIA_ENTRY_VIEW;
20 import static com.android.systemui.complication.dagger.RegisteredComplicationsModule.DREAM_MEDIA_ENTRY_LAYOUT_PARAMS;
21 import static com.android.systemui.flags.Flags.DREAM_MEDIA_TAP_TO_OPEN;
22 
23 import android.app.PendingIntent;
24 import android.util.Log;
25 import android.view.View;
26 
27 import com.android.systemui.ActivityIntentHelper;
28 import com.android.systemui.complication.dagger.DreamMediaEntryComplicationComponent;
29 import com.android.systemui.dreams.DreamOverlayStateController;
30 import com.android.systemui.flags.FeatureFlags;
31 import com.android.systemui.media.controls.ui.MediaCarouselController;
32 import com.android.systemui.media.dream.MediaDreamComplication;
33 import com.android.systemui.plugins.ActivityStarter;
34 import com.android.systemui.statusbar.NotificationLockscreenUserManager;
35 import com.android.systemui.statusbar.policy.KeyguardStateController;
36 import com.android.systemui.util.ViewController;
37 
38 import javax.inject.Inject;
39 import javax.inject.Named;
40 
41 /**
42  * A dream complication that shows a media entry chip to launch media control view.
43  */
44 public class DreamMediaEntryComplication implements Complication {
45     private final DreamMediaEntryComplicationComponent.Factory mComponentFactory;
46 
47     @Inject
DreamMediaEntryComplication( DreamMediaEntryComplicationComponent.Factory componentFactory)48     public DreamMediaEntryComplication(
49             DreamMediaEntryComplicationComponent.Factory componentFactory) {
50         mComponentFactory = componentFactory;
51     }
52 
53     @Override
createView(ComplicationViewModel model)54     public ViewHolder createView(ComplicationViewModel model) {
55         return mComponentFactory.create().getViewHolder();
56     }
57 
58     @Override
getRequiredTypeAvailability()59     public int getRequiredTypeAvailability() {
60         return COMPLICATION_TYPE_MEDIA_ENTRY;
61     }
62 
63     /**
64      * Contains values/logic associated with the dream complication view.
65      */
66     public static class DreamMediaEntryViewHolder implements ViewHolder {
67         private final View mView;
68         private final ComplicationLayoutParams mLayoutParams;
69         private final DreamMediaEntryViewController mViewController;
70 
71         @Inject
DreamMediaEntryViewHolder( DreamMediaEntryViewController dreamMediaEntryViewController, @Named(DREAM_MEDIA_ENTRY_VIEW) View view, @Named(DREAM_MEDIA_ENTRY_LAYOUT_PARAMS) ComplicationLayoutParams layoutParams )72         DreamMediaEntryViewHolder(
73                 DreamMediaEntryViewController dreamMediaEntryViewController,
74                 @Named(DREAM_MEDIA_ENTRY_VIEW) View view,
75                 @Named(DREAM_MEDIA_ENTRY_LAYOUT_PARAMS) ComplicationLayoutParams layoutParams
76         ) {
77             mView = view;
78             mLayoutParams = layoutParams;
79             mViewController = dreamMediaEntryViewController;
80             mViewController.init();
81         }
82 
83         @Override
getView()84         public View getView() {
85             return mView;
86         }
87 
88         @Override
getLayoutParams()89         public ComplicationLayoutParams getLayoutParams() {
90             return mLayoutParams;
91         }
92     }
93 
94     /**
95      * Controls behavior of the dream complication.
96      */
97     static class DreamMediaEntryViewController extends ViewController<View> {
98         private static final String TAG = "DreamMediaEntryVwCtrl";
99         private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
100 
101         private final DreamOverlayStateController mDreamOverlayStateController;
102         private final MediaDreamComplication mMediaComplication;
103         private final MediaCarouselController mMediaCarouselController;
104 
105         private final ActivityStarter mActivityStarter;
106         private final ActivityIntentHelper mActivityIntentHelper;
107         private final KeyguardStateController mKeyguardStateController;
108         private final NotificationLockscreenUserManager mLockscreenUserManager;
109 
110         private final FeatureFlags mFeatureFlags;
111         private boolean mIsTapToOpenEnabled;
112 
113         private boolean mMediaComplicationAdded;
114 
115         @Inject
DreamMediaEntryViewController( @amedDREAM_MEDIA_ENTRY_VIEW) View view, DreamOverlayStateController dreamOverlayStateController, MediaDreamComplication mediaComplication, MediaCarouselController mediaCarouselController, ActivityStarter activityStarter, ActivityIntentHelper activityIntentHelper, KeyguardStateController keyguardStateController, NotificationLockscreenUserManager lockscreenUserManager, FeatureFlags featureFlags)116         DreamMediaEntryViewController(
117                 @Named(DREAM_MEDIA_ENTRY_VIEW) View view,
118                 DreamOverlayStateController dreamOverlayStateController,
119                 MediaDreamComplication mediaComplication,
120                 MediaCarouselController mediaCarouselController,
121                 ActivityStarter activityStarter,
122                 ActivityIntentHelper activityIntentHelper,
123                 KeyguardStateController keyguardStateController,
124                 NotificationLockscreenUserManager lockscreenUserManager,
125                 FeatureFlags featureFlags) {
126             super(view);
127             mDreamOverlayStateController = dreamOverlayStateController;
128             mMediaComplication = mediaComplication;
129             mMediaCarouselController = mediaCarouselController;
130             mActivityStarter = activityStarter;
131             mActivityIntentHelper = activityIntentHelper;
132             mKeyguardStateController = keyguardStateController;
133             mLockscreenUserManager = lockscreenUserManager;
134             mFeatureFlags = featureFlags;
135             mView.setOnClickListener(this::onClickMediaEntry);
136         }
137 
138         @Override
onViewAttached()139         protected void onViewAttached() {
140             mIsTapToOpenEnabled = mFeatureFlags.isEnabled(DREAM_MEDIA_TAP_TO_OPEN);
141         }
142 
143         @Override
onViewDetached()144         protected void onViewDetached() {
145             removeMediaComplication();
146         }
147 
onClickMediaEntry(View v)148         private void onClickMediaEntry(View v) {
149             if (DEBUG) Log.d(TAG, "media entry complication tapped");
150 
151             if (mIsTapToOpenEnabled) {
152                 final PendingIntent clickIntent =
153                         mMediaCarouselController.getCurrentVisibleMediaContentIntent();
154 
155                 if (clickIntent == null) {
156                     return;
157                 }
158 
159                 // See StatusBarNotificationActivityStarter#onNotificationClicked
160                 final boolean showOverLockscreen = mKeyguardStateController.isShowing()
161                         && mActivityIntentHelper.wouldShowOverLockscreen(clickIntent.getIntent(),
162                         mLockscreenUserManager.getCurrentUserId());
163 
164                 if (showOverLockscreen) {
165                     mActivityStarter.startActivity(clickIntent.getIntent(),
166                             /* dismissShade */ true,
167                             /* animationController */ null,
168                             /* showOverLockscreenWhenLocked */ true);
169                 } else {
170                     mActivityStarter.postStartActivityDismissingKeyguard(clickIntent, null);
171                 }
172 
173                 return;
174             }
175 
176             if (!mMediaComplicationAdded) {
177                 addMediaComplication();
178             } else {
179                 removeMediaComplication();
180             }
181         }
182 
addMediaComplication()183         private void addMediaComplication() {
184             mView.setSelected(true);
185             mDreamOverlayStateController.addComplication(mMediaComplication);
186             mMediaComplicationAdded = true;
187         }
188 
removeMediaComplication()189         private void removeMediaComplication() {
190             mView.setSelected(false);
191             mDreamOverlayStateController.removeComplication(mMediaComplication);
192             mMediaComplicationAdded = false;
193         }
194     }
195 }
196