Loading src/com/android/settings/homepage/contextualcards/ContextualCardLookupTable.java +41 −14 Original line number Diff line number Diff line Loading @@ -16,43 +16,57 @@ package com.android.settings.homepage.contextualcards; import android.util.Log; import androidx.annotation.VisibleForTesting; import com.android.settings.homepage.contextualcards.ContextualCard.CardType; import com.android.settings.homepage.contextualcards.conditional.ConditionContextualCardController; import com.android.settings.homepage.contextualcards.conditional.ConditionContextualCardRenderer; import com.android.settings.homepage.contextualcards.slices.SliceContextualCardController; import com.android.settings.homepage.contextualcards.slices.SliceContextualCardRenderer; import java.util.Comparator; import java.util.List; import java.util.Set; import java.util.TreeSet; import java.util.stream.Collectors; public class ContextualCardLookupTable { private static final String TAG = "ContextualCardLookup"; static class ControllerRendererMapping implements Comparable<ControllerRendererMapping> { @CardType private final int mCardType; private final Class<? extends ContextualCardController> mControllerClass; private final Class<? extends ContextualCardRenderer> mRendererClass; final int mCardType; final int mViewType; final Class<? extends ContextualCardController> mControllerClass; final Class<? extends ContextualCardRenderer> mRendererClass; private ControllerRendererMapping(@CardType int cardType, ControllerRendererMapping(@CardType int cardType, int viewType, Class<? extends ContextualCardController> controllerClass, Class<? extends ContextualCardRenderer> rendererClass) { mCardType = cardType; mViewType = viewType; mControllerClass = controllerClass; mRendererClass = rendererClass; } @Override public int compareTo(ControllerRendererMapping other) { return Integer.compare(this.mCardType, other.mCardType); return Comparator.comparingInt((ControllerRendererMapping mapping) -> mapping.mCardType) .thenComparingInt(mapping -> mapping.mViewType) .compare(this, other); } } private static final Set<ControllerRendererMapping> LOOKUP_TABLE = @VisibleForTesting static final Set<ControllerRendererMapping> LOOKUP_TABLE = new TreeSet<ControllerRendererMapping>() {{ add(new ControllerRendererMapping(CardType.CONDITIONAL, ConditionContextualCardRenderer.VIEW_TYPE, ConditionContextualCardController.class, ConditionContextualCardRenderer.class)); add(new ControllerRendererMapping(CardType.SLICE, SliceContextualCardRenderer.VIEW_TYPE, SliceContextualCardController.class, SliceContextualCardRenderer.class)); }}; Loading @@ -67,14 +81,27 @@ public class ContextualCardLookupTable { return null; } //TODO(b/112578070): Implement multi renderer cases. public static Class<? extends ContextualCardRenderer> getCardRendererClasses( public static Class<? extends ContextualCardRenderer> getCardRendererClassByCardType( @CardType int cardType) { for (ControllerRendererMapping mapping : LOOKUP_TABLE) { if (mapping.mCardType == cardType) { return mapping.mRendererClass; } return LOOKUP_TABLE.stream() .filter(m -> m.mCardType == cardType) .findFirst() .map(mapping -> mapping.mRendererClass) .orElse(null); } public static Class<? extends ContextualCardRenderer> getCardRendererClassByViewType( int viewType) throws IllegalStateException { List<ControllerRendererMapping> validMappings = LOOKUP_TABLE.stream() .filter(m -> m.mViewType == viewType).collect(Collectors.toList()); if (validMappings == null || validMappings.isEmpty()) { Log.w(TAG, "No matching mapping"); return null; } if (validMappings.size() != 1) { throw new IllegalStateException("Have duplicate VIEW_TYPE in lookup table."); } return validMappings.get(0).mRendererClass; } } src/com/android/settings/homepage/contextualcards/ContextualCardRenderer.java +2 −2 Original line number Diff line number Diff line Loading @@ -26,9 +26,9 @@ import androidx.recyclerview.widget.RecyclerView; public interface ContextualCardRenderer { /** * The layout type of the controller. * The layout type of the renderer. */ int getViewType(); int getViewType(boolean isHalfWidth); /** * When {@link ContextualCardsAdapter} calls {@link ContextualCardsAdapter#onCreateViewHolder}, Loading src/com/android/settings/homepage/contextualcards/ContextualCardsAdapter.java +11 −11 Original line number Diff line number Diff line Loading @@ -61,26 +61,26 @@ public class ContextualCardsAdapter extends RecyclerView.Adapter<RecyclerView.Vi @Override public int getItemViewType(int position) { return mContextualCards.get(position).getCardType(); final ContextualCard card = mContextualCards.get(position); final ContextualCardRenderer renderer = mControllerRendererPool.getRendererByCardType( mContext, mLifecycleOwner, card.getCardType()); return renderer.getViewType(card.isHalfWidth()); } @Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int cardType) { final ContextualCardRenderer renderer = mControllerRendererPool.getRenderer(mContext, mLifecycleOwner, cardType); final int viewType = renderer.getViewType(); public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { final ContextualCardRenderer renderer = mControllerRendererPool.getRendererByViewType( mContext, mLifecycleOwner, viewType); final View view = LayoutInflater.from(parent.getContext()).inflate(viewType, parent, false); return renderer.createViewHolder(view); } @Override public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { final int cardType = mContextualCards.get(position).getCardType(); final ContextualCardRenderer renderer = mControllerRendererPool.getRenderer(mContext, mLifecycleOwner, cardType); renderer.bindView(holder, mContextualCards.get(position)); final ContextualCard card = mContextualCards.get(position); final ContextualCardRenderer renderer = mControllerRendererPool.getRendererByCardType( mContext, mLifecycleOwner, card.getCardType()); renderer.bindView(holder, card); } @Override Loading src/com/android/settings/homepage/contextualcards/ControllerRendererPool.java +24 −4 Original line number Diff line number Diff line Loading @@ -16,12 +16,14 @@ package com.android.settings.homepage.contextualcards; import android.annotation.NonNull; import android.content.Context; import android.util.Log; import androidx.collection.ArraySet; import androidx.lifecycle.LifecycleOwner; import com.android.internal.annotations.VisibleForTesting; import com.android.settings.homepage.contextualcards.conditional.ConditionContextualCardController; import com.android.settings.homepage.contextualcards.conditional.ConditionContextualCardRenderer; import com.android.settings.homepage.contextualcards.slices.SliceContextualCardController; Loading Loading @@ -63,14 +65,32 @@ public class ControllerRendererPool { return (T) controller; } public Set<ContextualCardController> getControllers() { @VisibleForTesting Set<ContextualCardController> getControllers() { return mControllers; } public ContextualCardRenderer getRenderer(Context context, LifecycleOwner lifecycleOwner, @ContextualCard.CardType int cardType) { @VisibleForTesting Set<ContextualCardRenderer> getRenderers() { return mRenderers; } public ContextualCardRenderer getRendererByViewType(Context context, LifecycleOwner lifecycleOwner, int viewType) { final Class<? extends ContextualCardRenderer> clz = ContextualCardLookupTable.getCardRendererClassByViewType(viewType); return getRenderer(context, lifecycleOwner, clz); } public ContextualCardRenderer getRendererByCardType(Context context, LifecycleOwner lifecycleOwner, @ContextualCard.CardType int cardType) { final Class<? extends ContextualCardRenderer> clz = ContextualCardLookupTable.getCardRendererClasses(cardType); ContextualCardLookupTable.getCardRendererClassByCardType(cardType); return getRenderer(context, lifecycleOwner, clz); } private ContextualCardRenderer getRenderer(Context context, LifecycleOwner lifecycleOwner, @NonNull Class<? extends ContextualCardRenderer> clz) { for (ContextualCardRenderer renderer : mRenderers) { if (renderer.getClass() == clz) { Log.d(TAG, "Renderer is already there."); Loading src/com/android/settings/homepage/contextualcards/conditional/ConditionContextualCardRenderer.java +3 −2 Original line number Diff line number Diff line Loading @@ -37,6 +37,7 @@ import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; * Card renderer for {@link ConditionalContextualCard}. */ public class ConditionContextualCardRenderer implements ContextualCardRenderer { public static final int VIEW_TYPE = R.layout.homepage_condition_tile; private final Context mContext; private final ControllerRendererPool mControllerRendererPool; Loading @@ -48,8 +49,8 @@ public class ConditionContextualCardRenderer implements ContextualCardRenderer { } @Override public int getViewType() { return R.layout.homepage_condition_tile; public int getViewType(boolean isHalfWidth) { return VIEW_TYPE; } @Override Loading Loading
src/com/android/settings/homepage/contextualcards/ContextualCardLookupTable.java +41 −14 Original line number Diff line number Diff line Loading @@ -16,43 +16,57 @@ package com.android.settings.homepage.contextualcards; import android.util.Log; import androidx.annotation.VisibleForTesting; import com.android.settings.homepage.contextualcards.ContextualCard.CardType; import com.android.settings.homepage.contextualcards.conditional.ConditionContextualCardController; import com.android.settings.homepage.contextualcards.conditional.ConditionContextualCardRenderer; import com.android.settings.homepage.contextualcards.slices.SliceContextualCardController; import com.android.settings.homepage.contextualcards.slices.SliceContextualCardRenderer; import java.util.Comparator; import java.util.List; import java.util.Set; import java.util.TreeSet; import java.util.stream.Collectors; public class ContextualCardLookupTable { private static final String TAG = "ContextualCardLookup"; static class ControllerRendererMapping implements Comparable<ControllerRendererMapping> { @CardType private final int mCardType; private final Class<? extends ContextualCardController> mControllerClass; private final Class<? extends ContextualCardRenderer> mRendererClass; final int mCardType; final int mViewType; final Class<? extends ContextualCardController> mControllerClass; final Class<? extends ContextualCardRenderer> mRendererClass; private ControllerRendererMapping(@CardType int cardType, ControllerRendererMapping(@CardType int cardType, int viewType, Class<? extends ContextualCardController> controllerClass, Class<? extends ContextualCardRenderer> rendererClass) { mCardType = cardType; mViewType = viewType; mControllerClass = controllerClass; mRendererClass = rendererClass; } @Override public int compareTo(ControllerRendererMapping other) { return Integer.compare(this.mCardType, other.mCardType); return Comparator.comparingInt((ControllerRendererMapping mapping) -> mapping.mCardType) .thenComparingInt(mapping -> mapping.mViewType) .compare(this, other); } } private static final Set<ControllerRendererMapping> LOOKUP_TABLE = @VisibleForTesting static final Set<ControllerRendererMapping> LOOKUP_TABLE = new TreeSet<ControllerRendererMapping>() {{ add(new ControllerRendererMapping(CardType.CONDITIONAL, ConditionContextualCardRenderer.VIEW_TYPE, ConditionContextualCardController.class, ConditionContextualCardRenderer.class)); add(new ControllerRendererMapping(CardType.SLICE, SliceContextualCardRenderer.VIEW_TYPE, SliceContextualCardController.class, SliceContextualCardRenderer.class)); }}; Loading @@ -67,14 +81,27 @@ public class ContextualCardLookupTable { return null; } //TODO(b/112578070): Implement multi renderer cases. public static Class<? extends ContextualCardRenderer> getCardRendererClasses( public static Class<? extends ContextualCardRenderer> getCardRendererClassByCardType( @CardType int cardType) { for (ControllerRendererMapping mapping : LOOKUP_TABLE) { if (mapping.mCardType == cardType) { return mapping.mRendererClass; } return LOOKUP_TABLE.stream() .filter(m -> m.mCardType == cardType) .findFirst() .map(mapping -> mapping.mRendererClass) .orElse(null); } public static Class<? extends ContextualCardRenderer> getCardRendererClassByViewType( int viewType) throws IllegalStateException { List<ControllerRendererMapping> validMappings = LOOKUP_TABLE.stream() .filter(m -> m.mViewType == viewType).collect(Collectors.toList()); if (validMappings == null || validMappings.isEmpty()) { Log.w(TAG, "No matching mapping"); return null; } if (validMappings.size() != 1) { throw new IllegalStateException("Have duplicate VIEW_TYPE in lookup table."); } return validMappings.get(0).mRendererClass; } }
src/com/android/settings/homepage/contextualcards/ContextualCardRenderer.java +2 −2 Original line number Diff line number Diff line Loading @@ -26,9 +26,9 @@ import androidx.recyclerview.widget.RecyclerView; public interface ContextualCardRenderer { /** * The layout type of the controller. * The layout type of the renderer. */ int getViewType(); int getViewType(boolean isHalfWidth); /** * When {@link ContextualCardsAdapter} calls {@link ContextualCardsAdapter#onCreateViewHolder}, Loading
src/com/android/settings/homepage/contextualcards/ContextualCardsAdapter.java +11 −11 Original line number Diff line number Diff line Loading @@ -61,26 +61,26 @@ public class ContextualCardsAdapter extends RecyclerView.Adapter<RecyclerView.Vi @Override public int getItemViewType(int position) { return mContextualCards.get(position).getCardType(); final ContextualCard card = mContextualCards.get(position); final ContextualCardRenderer renderer = mControllerRendererPool.getRendererByCardType( mContext, mLifecycleOwner, card.getCardType()); return renderer.getViewType(card.isHalfWidth()); } @Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int cardType) { final ContextualCardRenderer renderer = mControllerRendererPool.getRenderer(mContext, mLifecycleOwner, cardType); final int viewType = renderer.getViewType(); public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { final ContextualCardRenderer renderer = mControllerRendererPool.getRendererByViewType( mContext, mLifecycleOwner, viewType); final View view = LayoutInflater.from(parent.getContext()).inflate(viewType, parent, false); return renderer.createViewHolder(view); } @Override public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { final int cardType = mContextualCards.get(position).getCardType(); final ContextualCardRenderer renderer = mControllerRendererPool.getRenderer(mContext, mLifecycleOwner, cardType); renderer.bindView(holder, mContextualCards.get(position)); final ContextualCard card = mContextualCards.get(position); final ContextualCardRenderer renderer = mControllerRendererPool.getRendererByCardType( mContext, mLifecycleOwner, card.getCardType()); renderer.bindView(holder, card); } @Override Loading
src/com/android/settings/homepage/contextualcards/ControllerRendererPool.java +24 −4 Original line number Diff line number Diff line Loading @@ -16,12 +16,14 @@ package com.android.settings.homepage.contextualcards; import android.annotation.NonNull; import android.content.Context; import android.util.Log; import androidx.collection.ArraySet; import androidx.lifecycle.LifecycleOwner; import com.android.internal.annotations.VisibleForTesting; import com.android.settings.homepage.contextualcards.conditional.ConditionContextualCardController; import com.android.settings.homepage.contextualcards.conditional.ConditionContextualCardRenderer; import com.android.settings.homepage.contextualcards.slices.SliceContextualCardController; Loading Loading @@ -63,14 +65,32 @@ public class ControllerRendererPool { return (T) controller; } public Set<ContextualCardController> getControllers() { @VisibleForTesting Set<ContextualCardController> getControllers() { return mControllers; } public ContextualCardRenderer getRenderer(Context context, LifecycleOwner lifecycleOwner, @ContextualCard.CardType int cardType) { @VisibleForTesting Set<ContextualCardRenderer> getRenderers() { return mRenderers; } public ContextualCardRenderer getRendererByViewType(Context context, LifecycleOwner lifecycleOwner, int viewType) { final Class<? extends ContextualCardRenderer> clz = ContextualCardLookupTable.getCardRendererClassByViewType(viewType); return getRenderer(context, lifecycleOwner, clz); } public ContextualCardRenderer getRendererByCardType(Context context, LifecycleOwner lifecycleOwner, @ContextualCard.CardType int cardType) { final Class<? extends ContextualCardRenderer> clz = ContextualCardLookupTable.getCardRendererClasses(cardType); ContextualCardLookupTable.getCardRendererClassByCardType(cardType); return getRenderer(context, lifecycleOwner, clz); } private ContextualCardRenderer getRenderer(Context context, LifecycleOwner lifecycleOwner, @NonNull Class<? extends ContextualCardRenderer> clz) { for (ContextualCardRenderer renderer : mRenderers) { if (renderer.getClass() == clz) { Log.d(TAG, "Renderer is already there."); Loading
src/com/android/settings/homepage/contextualcards/conditional/ConditionContextualCardRenderer.java +3 −2 Original line number Diff line number Diff line Loading @@ -37,6 +37,7 @@ import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; * Card renderer for {@link ConditionalContextualCard}. */ public class ConditionContextualCardRenderer implements ContextualCardRenderer { public static final int VIEW_TYPE = R.layout.homepage_condition_tile; private final Context mContext; private final ControllerRendererPool mControllerRendererPool; Loading @@ -48,8 +49,8 @@ public class ConditionContextualCardRenderer implements ContextualCardRenderer { } @Override public int getViewType() { return R.layout.homepage_condition_tile; public int getViewType(boolean isHalfWidth) { return VIEW_TYPE; } @Override Loading