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.util.Log;
20 
21 import androidx.annotation.LayoutRes;
22 import androidx.annotation.VisibleForTesting;
23 
24 import com.android.settings.homepage.contextualcards.ContextualCard.CardType;
25 import com.android.settings.homepage.contextualcards.conditional.ConditionContextualCardController;
26 import com.android.settings.homepage.contextualcards.conditional.ConditionContextualCardRenderer;
27 import com.android.settings.homepage.contextualcards.conditional.ConditionFooterContextualCardRenderer;
28 import com.android.settings.homepage.contextualcards.conditional.ConditionHeaderContextualCardRenderer;
29 import com.android.settings.homepage.contextualcards.legacysuggestion.LegacySuggestionContextualCardController;
30 import com.android.settings.homepage.contextualcards.legacysuggestion.LegacySuggestionContextualCardRenderer;
31 import com.android.settings.homepage.contextualcards.slices.SliceContextualCardController;
32 import com.android.settings.homepage.contextualcards.slices.SliceContextualCardRenderer;
33 
34 import java.util.Comparator;
35 import java.util.List;
36 import java.util.Set;
37 import java.util.stream.Collectors;
38 
39 public class ContextualCardLookupTable {
40     private static final String TAG = "ContextualCardLookup";
41 
42     static class ControllerRendererMapping implements Comparable<ControllerRendererMapping> {
43         @CardType
44         final int mCardType;
45         final int mViewType;
46         final Class<? extends ContextualCardController> mControllerClass;
47         final Class<? extends ContextualCardRenderer> mRendererClass;
48 
ControllerRendererMapping(@ardType int cardType, @LayoutRes int viewType, Class<? extends ContextualCardController> controllerClass, Class<? extends ContextualCardRenderer> rendererClass)49         ControllerRendererMapping(@CardType int cardType, @LayoutRes int viewType,
50                 Class<? extends ContextualCardController> controllerClass,
51                 Class<? extends ContextualCardRenderer> rendererClass) {
52             mCardType = cardType;
53             mViewType = viewType;
54             mControllerClass = controllerClass;
55             mRendererClass = rendererClass;
56         }
57 
58         @Override
compareTo(ControllerRendererMapping other)59         public int compareTo(ControllerRendererMapping other) {
60             return Comparator.comparingInt((ControllerRendererMapping mapping) -> mapping.mCardType)
61                     .thenComparingInt(mapping -> mapping.mViewType)
62                     .compare(this, other);
63         }
64     }
65 
66     @VisibleForTesting
67     static final Set<ControllerRendererMapping> LOOKUP_TABLE = Set.of(
68             new ControllerRendererMapping(CardType.CONDITIONAL,
69                     ConditionContextualCardRenderer.VIEW_TYPE_HALF_WIDTH,
70                     ConditionContextualCardController.class,
71                     ConditionContextualCardRenderer.class),
72             new ControllerRendererMapping(CardType.CONDITIONAL,
73                     ConditionContextualCardRenderer.VIEW_TYPE_FULL_WIDTH,
74                     ConditionContextualCardController.class,
75                     ConditionContextualCardRenderer.class),
76             new ControllerRendererMapping(CardType.LEGACY_SUGGESTION,
77                     LegacySuggestionContextualCardRenderer.VIEW_TYPE,
78                     LegacySuggestionContextualCardController.class,
79                     LegacySuggestionContextualCardRenderer.class),
80             new ControllerRendererMapping(CardType.SLICE,
81                     SliceContextualCardRenderer.VIEW_TYPE_FULL_WIDTH,
82                     SliceContextualCardController.class,
83                     SliceContextualCardRenderer.class),
84             new ControllerRendererMapping(CardType.SLICE,
85                     SliceContextualCardRenderer.VIEW_TYPE_HALF_WIDTH,
86                     SliceContextualCardController.class,
87                     SliceContextualCardRenderer.class),
88             new ControllerRendererMapping(CardType.SLICE,
89                     SliceContextualCardRenderer.VIEW_TYPE_STICKY,
90                     SliceContextualCardController.class,
91                     SliceContextualCardRenderer.class),
92             new ControllerRendererMapping(CardType.CONDITIONAL_FOOTER,
93                     ConditionFooterContextualCardRenderer.VIEW_TYPE,
94                     ConditionContextualCardController.class,
95                     ConditionFooterContextualCardRenderer.class),
96             new ControllerRendererMapping(CardType.CONDITIONAL_HEADER,
97                     ConditionHeaderContextualCardRenderer.VIEW_TYPE,
98                     ConditionContextualCardController.class,
99                     ConditionHeaderContextualCardRenderer.class));
100 
getCardControllerClass( @ardType int cardType)101     public static Class<? extends ContextualCardController> getCardControllerClass(
102             @CardType int cardType) {
103         for (ControllerRendererMapping mapping : LOOKUP_TABLE) {
104             if (mapping.mCardType == cardType) {
105                 return mapping.mControllerClass;
106             }
107         }
108         return null;
109     }
110 
getCardRendererClassByViewType( int viewType)111     public static Class<? extends ContextualCardRenderer> getCardRendererClassByViewType(
112             int viewType) throws IllegalStateException {
113         List<ControllerRendererMapping> validMappings = LOOKUP_TABLE.stream()
114                 .filter(m -> m.mViewType == viewType).collect(Collectors.toList());
115         if (validMappings == null || validMappings.isEmpty()) {
116             Log.w(TAG, "No matching mapping");
117             return null;
118         }
119         if (validMappings.size() != 1) {
120             throw new IllegalStateException("Have duplicate VIEW_TYPE in lookup table.");
121         }
122 
123         return validMappings.get(0).mRendererClass;
124     }
125 }
126