1 /*
2  * Copyright (C) 2018 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.settings.homepage.contextualcards;
18 
19 import android.annotation.NonNull;
20 import android.content.Context;
21 import android.util.Log;
22 
23 import androidx.collection.ArraySet;
24 import androidx.lifecycle.LifecycleOwner;
25 
26 import com.android.internal.annotations.VisibleForTesting;
27 import com.android.settings.homepage.contextualcards.conditional.ConditionContextualCardController;
28 import com.android.settings.homepage.contextualcards.conditional.ConditionContextualCardRenderer;
29 import com.android.settings.homepage.contextualcards.conditional.ConditionFooterContextualCardRenderer;
30 import com.android.settings.homepage.contextualcards.conditional.ConditionHeaderContextualCardRenderer;
31 import com.android.settings.homepage.contextualcards.legacysuggestion.LegacySuggestionContextualCardController;
32 import com.android.settings.homepage.contextualcards.legacysuggestion.LegacySuggestionContextualCardRenderer;
33 import com.android.settings.homepage.contextualcards.slices.SliceContextualCardController;
34 import com.android.settings.homepage.contextualcards.slices.SliceContextualCardRenderer;
35 
36 import java.util.Set;
37 
38 /**
39  * This is a fragment scoped singleton holding a set of {@link ContextualCardController} and
40  * {@link ContextualCardRenderer}.
41  */
42 public class ControllerRendererPool {
43 
44     private static final String TAG = "ControllerRendererPool";
45 
46     private final Set<ContextualCardController> mControllers;
47     private final Set<ContextualCardRenderer> mRenderers;
48 
ControllerRendererPool()49     public ControllerRendererPool() {
50         mControllers = new ArraySet<>();
51         mRenderers = new ArraySet<>();
52     }
53 
getController(Context context, @ContextualCard.CardType int cardType)54     public <T extends ContextualCardController> T getController(Context context,
55             @ContextualCard.CardType int cardType) {
56         final Class<? extends ContextualCardController> clz =
57                 ContextualCardLookupTable.getCardControllerClass(cardType);
58         for (ContextualCardController controller : mControllers) {
59             if (controller.getClass() == clz) {
60                 Log.d(TAG, "Controller is already there.");
61                 return (T) controller;
62             }
63         }
64 
65         final ContextualCardController controller = createCardController(context, clz);
66         if (controller != null) {
67             mControllers.add(controller);
68         }
69         return (T) controller;
70     }
71 
72     @VisibleForTesting
getControllers()73     Set<ContextualCardController> getControllers() {
74         return mControllers;
75     }
76 
77     @VisibleForTesting
getRenderers()78     Set<ContextualCardRenderer> getRenderers() {
79         return mRenderers;
80     }
81 
getRendererByViewType(Context context, LifecycleOwner lifecycleOwner, int viewType)82     public ContextualCardRenderer getRendererByViewType(Context context,
83             LifecycleOwner lifecycleOwner, int viewType) {
84         final Class<? extends ContextualCardRenderer> clz =
85                 ContextualCardLookupTable.getCardRendererClassByViewType(viewType);
86         return getRenderer(context, lifecycleOwner, clz);
87     }
88 
getRenderer(Context context, LifecycleOwner lifecycleOwner, @NonNull Class<? extends ContextualCardRenderer> clz)89     private ContextualCardRenderer getRenderer(Context context, LifecycleOwner lifecycleOwner,
90             @NonNull Class<? extends ContextualCardRenderer> clz) {
91         for (ContextualCardRenderer renderer : mRenderers) {
92             if (renderer.getClass() == clz) {
93                 Log.d(TAG, "Renderer is already there.");
94                 return renderer;
95             }
96         }
97 
98         final ContextualCardRenderer renderer = createCardRenderer(context, lifecycleOwner, clz);
99         if (renderer != null) {
100             mRenderers.add(renderer);
101         }
102         return renderer;
103     }
104 
createCardController(Context context, Class<? extends ContextualCardController> clz)105     private ContextualCardController createCardController(Context context,
106             Class<? extends ContextualCardController> clz) {
107         if (ConditionContextualCardController.class == clz) {
108             return new ConditionContextualCardController(context);
109         } else if (SliceContextualCardController.class == clz) {
110             return new SliceContextualCardController(context);
111         } else if (LegacySuggestionContextualCardController.class == clz) {
112             return new LegacySuggestionContextualCardController(context);
113         }
114         return null;
115     }
116 
createCardRenderer(Context context, LifecycleOwner lifecycleOwner, Class<?> clz)117     private ContextualCardRenderer createCardRenderer(Context context,
118             LifecycleOwner lifecycleOwner, Class<?> clz) {
119         if (ConditionContextualCardRenderer.class == clz) {
120             return new ConditionContextualCardRenderer(context, this /* controllerRendererPool */);
121         } else if (SliceContextualCardRenderer.class == clz) {
122             return new SliceContextualCardRenderer(context, lifecycleOwner,
123                     this /* controllerRendererPool */);
124         } else if (LegacySuggestionContextualCardRenderer.class == clz) {
125             return new LegacySuggestionContextualCardRenderer(context,
126                     this /* controllerRendererPool */);
127         } else if (ConditionFooterContextualCardRenderer.class == clz) {
128             return new ConditionFooterContextualCardRenderer(context,
129                     this /*controllerRendererPool*/);
130         } else if (ConditionHeaderContextualCardRenderer.class == clz) {
131             return new ConditionHeaderContextualCardRenderer(context,
132                     this /*controllerRendererPool*/);
133         }
134         return null;
135     }
136 }
137