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