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.media.dream;
18 
19 import static com.android.systemui.flags.Flags.DREAM_MEDIA_COMPLICATION;
20 
21 import android.util.Log;
22 
23 import androidx.annotation.NonNull;
24 import androidx.annotation.Nullable;
25 
26 import com.android.systemui.CoreStartable;
27 import com.android.systemui.complication.DreamMediaEntryComplication;
28 import com.android.systemui.dreams.DreamOverlayStateController;
29 import com.android.systemui.flags.FeatureFlags;
30 import com.android.systemui.media.controls.models.player.MediaData;
31 import com.android.systemui.media.controls.models.recommendation.SmartspaceMediaData;
32 import com.android.systemui.media.controls.pipeline.MediaDataManager;
33 
34 import javax.inject.Inject;
35 
36 /**
37  * {@link MediaDreamSentinel} is responsible for tracking media state and registering/unregistering
38  * the media complication as appropriate
39  */
40 public class MediaDreamSentinel implements CoreStartable {
41     private static final String TAG = "MediaDreamSentinel";
42     private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
43 
44     private final MediaDataManager.Listener mListener = new MediaDataManager.Listener() {
45         private boolean mAdded;
46         @Override
47         public void onSmartspaceMediaDataRemoved(@NonNull String key, boolean immediately) {
48         }
49 
50         @Override
51         public void onMediaDataRemoved(@NonNull String key) {
52             final boolean hasActiveMedia = mMediaDataManager.hasActiveMedia();
53             if (DEBUG) {
54                 Log.d(TAG, "onMediaDataRemoved(" + key + "), mAdded=" + mAdded + ", hasActiveMedia="
55                         + hasActiveMedia);
56             }
57 
58             if (!mAdded) {
59                 return;
60             }
61 
62             if (hasActiveMedia) {
63                 return;
64             }
65 
66             mAdded = false;
67             mDreamOverlayStateController.removeComplication(mMediaEntryComplication);
68         }
69 
70         @Override
71         public void onSmartspaceMediaDataLoaded(@NonNull String key,
72                 @NonNull SmartspaceMediaData data, boolean shouldPrioritize) {
73         }
74 
75         @Override
76         public void onMediaDataLoaded(@NonNull String key, @Nullable String oldKey,
77                 @NonNull MediaData data, boolean immediately, int receivedSmartspaceCardLatency,
78                 boolean isSsReactivated) {
79             if (!mFeatureFlags.isEnabled(DREAM_MEDIA_COMPLICATION)) {
80                 return;
81             }
82 
83             final boolean hasActiveMedia = mMediaDataManager.hasActiveMedia();
84             if (DEBUG) {
85                 Log.d(TAG, "onMediaDataLoaded(" + key + "), mAdded=" + mAdded + ", hasActiveMedia="
86                         + hasActiveMedia);
87             }
88 
89             // Media data can become inactive without triggering onMediaDataRemoved.
90             if (mAdded && !hasActiveMedia) {
91                 mAdded = false;
92                 mDreamOverlayStateController.removeComplication(mMediaEntryComplication);
93                 return;
94             }
95 
96             if (mAdded) {
97                 return;
98             }
99 
100             if (!hasActiveMedia) {
101                 return;
102             }
103 
104             mAdded = true;
105             mDreamOverlayStateController.addComplication(mMediaEntryComplication);
106         }
107     };
108 
109     private final MediaDataManager mMediaDataManager;
110     private final DreamOverlayStateController mDreamOverlayStateController;
111     private final DreamMediaEntryComplication mMediaEntryComplication;
112     private final FeatureFlags mFeatureFlags;
113 
114     @Inject
MediaDreamSentinel(MediaDataManager mediaDataManager, DreamOverlayStateController dreamOverlayStateController, DreamMediaEntryComplication mediaEntryComplication, FeatureFlags featureFlags)115     public MediaDreamSentinel(MediaDataManager mediaDataManager,
116             DreamOverlayStateController dreamOverlayStateController,
117             DreamMediaEntryComplication mediaEntryComplication,
118             FeatureFlags featureFlags) {
119         mMediaDataManager = mediaDataManager;
120         mDreamOverlayStateController = dreamOverlayStateController;
121         mMediaEntryComplication = mediaEntryComplication;
122         mFeatureFlags = featureFlags;
123     }
124 
125     @Override
start()126     public void start() {
127         mMediaDataManager.addListener(mListener);
128     }
129 }
130