Loading suggestions via legacy SuggestionService sometimes
When legacy_suggestion flag is turned on, load Suggestions from SuggestionService instead of contextual homepage, because contextual homepage infrastructure might not be availble on all devices. Bug: 118842099 Test: robo Change-Id: I91710c005e11be5a9b3dd39ceff670106e7f80c3
This commit is contained in:
@@ -32,8 +32,8 @@
|
|||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
android:id="@android:id/icon"
|
android:id="@android:id/icon"
|
||||||
android:layout_width="@dimen/suggestion_card_icon_size"
|
android:layout_width="@dimen/homepage_card_icon_size"
|
||||||
android:layout_height="@dimen/suggestion_card_icon_size"
|
android:layout_height="@dimen/homepage_card_icon_size"
|
||||||
android:tint="?android:attr/colorAccent"/>
|
android:tint="?android:attr/colorAccent"/>
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
|
@@ -32,8 +32,8 @@
|
|||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
android:id="@android:id/icon"
|
android:id="@android:id/icon"
|
||||||
android:layout_width="@dimen/suggestion_card_icon_size"
|
android:layout_width="@dimen/homepage_card_icon_size"
|
||||||
android:layout_height="@dimen/suggestion_card_icon_size"
|
android:layout_height="@dimen/homepage_card_icon_size"
|
||||||
android:tint="?android:attr/colorAccent"/>
|
android:tint="?android:attr/colorAccent"/>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
|
70
res/layout/homepage_suggestion_tile.xml
Normal file
70
res/layout/homepage_suggestion_tile.xml
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!--
|
||||||
|
Copyright (C) 2018 The Android Open Source Project
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<androidx.cardview.widget.CardView
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:id="@+id/suggestion_card"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
style="@style/ContextualCardStyle">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:minHeight="112dp"
|
||||||
|
android:paddingBottom="8dp"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<RelativeLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@android:id/icon"
|
||||||
|
android:layout_width="@dimen/homepage_card_icon_size"
|
||||||
|
android:layout_height="@dimen/homepage_card_icon_size"
|
||||||
|
style="@style/SuggestionCardIcon"
|
||||||
|
android:layout_marginTop="16dp"
|
||||||
|
android:layout_marginBottom="6dp"/>
|
||||||
|
|
||||||
|
</RelativeLayout>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@android:id/title"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
style="@style/SuggestionCardText"
|
||||||
|
android:layout_marginStart="12dp"
|
||||||
|
android:layout_marginEnd="12dp"
|
||||||
|
android:singleLine="true"
|
||||||
|
android:textAppearance="@style/TextAppearance.SuggestionTitle"
|
||||||
|
android:fadingEdge="horizontal"/>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@android:id/summary"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
style="@style/SuggestionCardText"
|
||||||
|
android:layout_marginStart="12dp"
|
||||||
|
android:layout_marginEnd="12dp"
|
||||||
|
android:singleLine="true"
|
||||||
|
android:textAppearance="@style/TextAppearance.SuggestionSummary"/>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</androidx.cardview.widget.CardView>
|
@@ -134,6 +134,12 @@
|
|||||||
have distinct intensity levels -->
|
have distinct intensity levels -->
|
||||||
<bool name="config_vibration_supports_multiple_intensities">false</bool>
|
<bool name="config_vibration_supports_multiple_intensities">false</bool>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Whether or not the homepage should be powered by legacy suggestion (versus contextual cards)
|
||||||
|
Default to true as not all devices support contextual cards.
|
||||||
|
-->
|
||||||
|
<bool name="config_use_legacy_suggestion">true</bool>
|
||||||
|
|
||||||
<!-- Whether or not TopLevelSettings should force rounded icon for injected tiles -->
|
<!-- Whether or not TopLevelSettings should force rounded icon for injected tiles -->
|
||||||
<bool name="config_force_rounded_icon_TopLevelSettings">true</bool>
|
<bool name="config_force_rounded_icon_TopLevelSettings">true</bool>
|
||||||
|
|
||||||
|
@@ -303,17 +303,6 @@
|
|||||||
<dimen name="suggestion_condition_header_padding_expanded">5dp</dimen>
|
<dimen name="suggestion_condition_header_padding_expanded">5dp</dimen>
|
||||||
<dimen name="condition_header_height">36dp</dimen>
|
<dimen name="condition_header_height">36dp</dimen>
|
||||||
|
|
||||||
<!-- Suggestion cards size and padding -->
|
|
||||||
<dimen name="suggestion_card_icon_size">24dp</dimen>
|
|
||||||
<dimen name="suggestion_card_outer_margin">14dp</dimen>
|
|
||||||
<dimen name="suggestion_card_inner_margin">12dp</dimen>
|
|
||||||
<dimen name="suggestion_card_padding_bottom_one_card">16dp</dimen>
|
|
||||||
<dimen name="suggestion_card_corner_radius">2dp</dimen>
|
|
||||||
<dimen name="suggestion_card_icon_side_margin">12dp</dimen>
|
|
||||||
<dimen name="suggestion_card_button_side_margin">8dp</dimen>
|
|
||||||
<dimen name="suggestion_card_button_top_margin">16dp</dimen>
|
|
||||||
<dimen name="suggestion_card_button_bottom_margin">18dp</dimen>
|
|
||||||
|
|
||||||
<!-- Condition cards size and padding -->
|
<!-- Condition cards size and padding -->
|
||||||
<dimen name="condition_card_elevation">2dp</dimen>
|
<dimen name="condition_card_elevation">2dp</dimen>
|
||||||
|
|
||||||
@@ -331,6 +320,7 @@
|
|||||||
<dimen name="homepage_bottombar_fab_cradle">68dp</dimen>
|
<dimen name="homepage_bottombar_fab_cradle">68dp</dimen>
|
||||||
|
|
||||||
<!-- Homepage cards size and padding -->
|
<!-- Homepage cards size and padding -->
|
||||||
|
<dimen name="homepage_card_icon_size">24dp</dimen>
|
||||||
<dimen name="homepage_card_corner_radius">8dp</dimen>
|
<dimen name="homepage_card_corner_radius">8dp</dimen>
|
||||||
<dimen name="homepage_card_elevation">2dp</dimen>
|
<dimen name="homepage_card_elevation">2dp</dimen>
|
||||||
<dimen name="homepage_card_vertical_margin">4dp</dimen>
|
<dimen name="homepage_card_vertical_margin">4dp</dimen>
|
||||||
|
@@ -350,16 +350,8 @@
|
|||||||
<style name="SuggestionCardIcon">
|
<style name="SuggestionCardIcon">
|
||||||
<item name="android:layout_centerHorizontal">false</item>
|
<item name="android:layout_centerHorizontal">false</item>
|
||||||
<item name="android:layout_alignParentStart">true</item>
|
<item name="android:layout_alignParentStart">true</item>
|
||||||
<item name="android:layout_marginStart">@dimen/suggestion_card_icon_side_margin</item>
|
<item name="android:layout_marginStart">12dp</item>
|
||||||
<item name="android:layout_marginEnd">@dimen/suggestion_card_icon_side_margin</item>
|
<item name="android:layout_marginEnd">12dp</item>
|
||||||
</style>
|
|
||||||
|
|
||||||
<style name="SuggestionCardButton">
|
|
||||||
<item name="android:layout_gravity">start</item>
|
|
||||||
<item name="android:layout_marginStart">@dimen/suggestion_card_button_side_margin</item>
|
|
||||||
<item name="android:layout_marginEnd">@dimen/suggestion_card_button_side_margin</item>
|
|
||||||
<item name="android:layout_marginTop">@dimen/suggestion_card_button_top_margin</item>
|
|
||||||
<item name="android:layout_marginBottom">@dimen/suggestion_card_button_bottom_margin</item>
|
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<style name="FingerprintLayoutTheme">
|
<style name="FingerprintLayoutTheme">
|
||||||
|
@@ -33,12 +33,12 @@ public class ContextualCard {
|
|||||||
/**
|
/**
|
||||||
* Flags indicating the type of the ContextualCard.
|
* Flags indicating the type of the ContextualCard.
|
||||||
*/
|
*/
|
||||||
@IntDef({CardType.DEFAULT, CardType.SLICE, CardType.SUGGESTION, CardType.CONDITIONAL})
|
@IntDef({CardType.DEFAULT, CardType.SLICE, CardType.LEGACY_SUGGESTION, CardType.CONDITIONAL})
|
||||||
@Retention(RetentionPolicy.SOURCE)
|
@Retention(RetentionPolicy.SOURCE)
|
||||||
public @interface CardType {
|
public @interface CardType {
|
||||||
int DEFAULT = 0;
|
int DEFAULT = 0;
|
||||||
int SLICE = 1;
|
int SLICE = 1;
|
||||||
int SUGGESTION = 2;
|
int LEGACY_SUGGESTION = 2;
|
||||||
int CONDITIONAL = 3;
|
int CONDITIONAL = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -18,11 +18,16 @@ package com.android.settings.homepage.contextualcards;
|
|||||||
|
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
|
import androidx.annotation.LayoutRes;
|
||||||
import androidx.annotation.VisibleForTesting;
|
import androidx.annotation.VisibleForTesting;
|
||||||
|
|
||||||
import com.android.settings.homepage.contextualcards.ContextualCard.CardType;
|
import com.android.settings.homepage.contextualcards.ContextualCard.CardType;
|
||||||
import com.android.settings.homepage.contextualcards.conditional.ConditionContextualCardController;
|
import com.android.settings.homepage.contextualcards.conditional.ConditionContextualCardController;
|
||||||
import com.android.settings.homepage.contextualcards.conditional.ConditionContextualCardRenderer;
|
import com.android.settings.homepage.contextualcards.conditional.ConditionContextualCardRenderer;
|
||||||
|
import com.android.settings.homepage.contextualcards.legacysuggestion
|
||||||
|
.LegacySuggestionContextualCardController;
|
||||||
|
import com.android.settings.homepage.contextualcards.legacysuggestion
|
||||||
|
.LegacySuggestionContextualCardRenderer;
|
||||||
import com.android.settings.homepage.contextualcards.slices.SliceContextualCardController;
|
import com.android.settings.homepage.contextualcards.slices.SliceContextualCardController;
|
||||||
import com.android.settings.homepage.contextualcards.slices.SliceContextualCardRenderer;
|
import com.android.settings.homepage.contextualcards.slices.SliceContextualCardRenderer;
|
||||||
|
|
||||||
@@ -34,6 +39,7 @@ import java.util.stream.Collectors;
|
|||||||
|
|
||||||
public class ContextualCardLookupTable {
|
public class ContextualCardLookupTable {
|
||||||
private static final String TAG = "ContextualCardLookup";
|
private static final String TAG = "ContextualCardLookup";
|
||||||
|
|
||||||
static class ControllerRendererMapping implements Comparable<ControllerRendererMapping> {
|
static class ControllerRendererMapping implements Comparable<ControllerRendererMapping> {
|
||||||
@CardType
|
@CardType
|
||||||
final int mCardType;
|
final int mCardType;
|
||||||
@@ -41,7 +47,7 @@ public class ContextualCardLookupTable {
|
|||||||
final Class<? extends ContextualCardController> mControllerClass;
|
final Class<? extends ContextualCardController> mControllerClass;
|
||||||
final Class<? extends ContextualCardRenderer> mRendererClass;
|
final Class<? extends ContextualCardRenderer> mRendererClass;
|
||||||
|
|
||||||
ControllerRendererMapping(@CardType int cardType, int viewType,
|
ControllerRendererMapping(@CardType int cardType, @LayoutRes int viewType,
|
||||||
Class<? extends ContextualCardController> controllerClass,
|
Class<? extends ContextualCardController> controllerClass,
|
||||||
Class<? extends ContextualCardRenderer> rendererClass) {
|
Class<? extends ContextualCardRenderer> rendererClass) {
|
||||||
mCardType = cardType;
|
mCardType = cardType;
|
||||||
@@ -69,6 +75,10 @@ public class ContextualCardLookupTable {
|
|||||||
ConditionContextualCardRenderer.FULL_WIDTH_VIEW_TYPE,
|
ConditionContextualCardRenderer.FULL_WIDTH_VIEW_TYPE,
|
||||||
ConditionContextualCardController.class,
|
ConditionContextualCardController.class,
|
||||||
ConditionContextualCardRenderer.class));
|
ConditionContextualCardRenderer.class));
|
||||||
|
add(new ControllerRendererMapping(CardType.LEGACY_SUGGESTION,
|
||||||
|
LegacySuggestionContextualCardRenderer.VIEW_TYPE,
|
||||||
|
LegacySuggestionContextualCardController.class,
|
||||||
|
LegacySuggestionContextualCardRenderer.class));
|
||||||
add(new ControllerRendererMapping(CardType.SLICE,
|
add(new ControllerRendererMapping(CardType.SLICE,
|
||||||
SliceContextualCardRenderer.VIEW_TYPE,
|
SliceContextualCardRenderer.VIEW_TYPE,
|
||||||
SliceContextualCardController.class,
|
SliceContextualCardController.class,
|
||||||
|
@@ -16,7 +16,8 @@
|
|||||||
|
|
||||||
package com.android.settings.homepage.contextualcards;
|
package com.android.settings.homepage.contextualcards;
|
||||||
|
|
||||||
import static com.android.settings.homepage.contextualcards.ContextualCardLoader.CARD_CONTENT_LOADER_ID;
|
import static com.android.settings.homepage.contextualcards.ContextualCardLoader
|
||||||
|
.CARD_CONTENT_LOADER_ID;
|
||||||
|
|
||||||
import static java.util.stream.Collectors.groupingBy;
|
import static java.util.stream.Collectors.groupingBy;
|
||||||
|
|
||||||
@@ -57,8 +58,8 @@ public class ContextualCardManager implements ContextualCardLoader.CardContentLo
|
|||||||
|
|
||||||
private static final String TAG = "ContextualCardManager";
|
private static final String TAG = "ContextualCardManager";
|
||||||
//The list for Settings Custom Card
|
//The list for Settings Custom Card
|
||||||
@ContextualCard.CardType
|
private static final int[] SETTINGS_CARDS =
|
||||||
private static final int[] SETTINGS_CARDS = {ContextualCard.CardType.CONDITIONAL};
|
{ContextualCard.CardType.CONDITIONAL, ContextualCard.CardType.LEGACY_SUGGESTION};
|
||||||
|
|
||||||
private final Context mContext;
|
private final Context mContext;
|
||||||
private final ControllerRendererPool mControllerRendererPool;
|
private final ControllerRendererPool mControllerRendererPool;
|
||||||
@@ -68,14 +69,14 @@ public class ContextualCardManager implements ContextualCardLoader.CardContentLo
|
|||||||
|
|
||||||
private ContextualCardUpdateListener mListener;
|
private ContextualCardUpdateListener mListener;
|
||||||
|
|
||||||
public ContextualCardManager(Context context, @NonNull Lifecycle lifecycle) {
|
public ContextualCardManager(Context context, Lifecycle lifecycle) {
|
||||||
mContext = context;
|
mContext = context;
|
||||||
mLifecycle = lifecycle;
|
mLifecycle = lifecycle;
|
||||||
mContextualCards = new ArrayList<>();
|
mContextualCards = new ArrayList<>();
|
||||||
mLifecycleObservers = new ArrayList<>();
|
mLifecycleObservers = new ArrayList<>();
|
||||||
mControllerRendererPool = new ControllerRendererPool();
|
mControllerRendererPool = new ControllerRendererPool();
|
||||||
//for data provided by Settings
|
//for data provided by Settings
|
||||||
for (int cardType : SETTINGS_CARDS) {
|
for (@ContextualCard.CardType int cardType : SETTINGS_CARDS) {
|
||||||
setupController(cardType);
|
setupController(cardType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -94,7 +95,7 @@ public class ContextualCardManager implements ContextualCardLoader.CardContentLo
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setupController(int cardType) {
|
private void setupController(@ContextualCard.CardType int cardType) {
|
||||||
final ContextualCardController controller = mControllerRendererPool.getController(mContext,
|
final ContextualCardController controller = mControllerRendererPool.getController(mContext,
|
||||||
cardType);
|
cardType);
|
||||||
if (controller == null) {
|
if (controller == null) {
|
||||||
|
@@ -18,6 +18,7 @@ package com.android.settings.homepage.contextualcards;
|
|||||||
|
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
|
||||||
|
import androidx.annotation.LayoutRes;
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -28,6 +29,7 @@ public interface ContextualCardRenderer {
|
|||||||
/**
|
/**
|
||||||
* The layout type of the renderer.
|
* The layout type of the renderer.
|
||||||
*/
|
*/
|
||||||
|
@LayoutRes
|
||||||
int getViewType(boolean isHalfWidth);
|
int getViewType(boolean isHalfWidth);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -16,6 +16,8 @@
|
|||||||
|
|
||||||
package com.android.settings.homepage.contextualcards;
|
package com.android.settings.homepage.contextualcards;
|
||||||
|
|
||||||
|
import androidx.annotation.MainThread;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
@@ -31,5 +33,6 @@ public interface ContextualCardUpdateListener {
|
|||||||
* null, which means all cards from corresponding {@link
|
* null, which means all cards from corresponding {@link
|
||||||
* ContextualCard.CardType} are removed.
|
* ContextualCard.CardType} are removed.
|
||||||
*/
|
*/
|
||||||
|
@MainThread
|
||||||
void onContextualCardUpdated(Map<Integer, List<ContextualCard>> cards);
|
void onContextualCardUpdated(Map<Integer, List<ContextualCard>> cards);
|
||||||
}
|
}
|
@@ -26,6 +26,10 @@ import androidx.lifecycle.LifecycleOwner;
|
|||||||
import com.android.internal.annotations.VisibleForTesting;
|
import com.android.internal.annotations.VisibleForTesting;
|
||||||
import com.android.settings.homepage.contextualcards.conditional.ConditionContextualCardController;
|
import com.android.settings.homepage.contextualcards.conditional.ConditionContextualCardController;
|
||||||
import com.android.settings.homepage.contextualcards.conditional.ConditionContextualCardRenderer;
|
import com.android.settings.homepage.contextualcards.conditional.ConditionContextualCardRenderer;
|
||||||
|
import com.android.settings.homepage.contextualcards.legacysuggestion
|
||||||
|
.LegacySuggestionContextualCardController;
|
||||||
|
import com.android.settings.homepage.contextualcards.legacysuggestion
|
||||||
|
.LegacySuggestionContextualCardRenderer;
|
||||||
import com.android.settings.homepage.contextualcards.slices.SliceContextualCardController;
|
import com.android.settings.homepage.contextualcards.slices.SliceContextualCardController;
|
||||||
import com.android.settings.homepage.contextualcards.slices.SliceContextualCardRenderer;
|
import com.android.settings.homepage.contextualcards.slices.SliceContextualCardRenderer;
|
||||||
|
|
||||||
@@ -111,6 +115,8 @@ public class ControllerRendererPool {
|
|||||||
return new ConditionContextualCardController(context);
|
return new ConditionContextualCardController(context);
|
||||||
} else if (SliceContextualCardController.class == clz) {
|
} else if (SliceContextualCardController.class == clz) {
|
||||||
return new SliceContextualCardController();
|
return new SliceContextualCardController();
|
||||||
|
} else if (LegacySuggestionContextualCardController.class == clz) {
|
||||||
|
return new LegacySuggestionContextualCardController(context);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -118,9 +124,12 @@ public class ControllerRendererPool {
|
|||||||
private ContextualCardRenderer createCardRenderer(Context context,
|
private ContextualCardRenderer createCardRenderer(Context context,
|
||||||
LifecycleOwner lifecycleOwner, Class<?> clz) {
|
LifecycleOwner lifecycleOwner, Class<?> clz) {
|
||||||
if (ConditionContextualCardRenderer.class == clz) {
|
if (ConditionContextualCardRenderer.class == clz) {
|
||||||
return new ConditionContextualCardRenderer(context, this /*controllerRendererPool*/);
|
return new ConditionContextualCardRenderer(context, this /* controllerRendererPool */);
|
||||||
} else if (SliceContextualCardRenderer.class == clz) {
|
} else if (SliceContextualCardRenderer.class == clz) {
|
||||||
return new SliceContextualCardRenderer(context, lifecycleOwner);
|
return new SliceContextualCardRenderer(context, lifecycleOwner);
|
||||||
|
} else if (LegacySuggestionContextualCardRenderer.class == clz) {
|
||||||
|
return new LegacySuggestionContextualCardRenderer(context,
|
||||||
|
this /* controllerRendererPool */);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@@ -23,6 +23,7 @@ import android.widget.Button;
|
|||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import androidx.annotation.LayoutRes;
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
import com.android.internal.logging.nano.MetricsProto;
|
import com.android.internal.logging.nano.MetricsProto;
|
||||||
@@ -37,7 +38,9 @@ import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
|
|||||||
* Card renderer for {@link ConditionalContextualCard}.
|
* Card renderer for {@link ConditionalContextualCard}.
|
||||||
*/
|
*/
|
||||||
public class ConditionContextualCardRenderer implements ContextualCardRenderer {
|
public class ConditionContextualCardRenderer implements ContextualCardRenderer {
|
||||||
|
@LayoutRes
|
||||||
public static final int HALF_WIDTH_VIEW_TYPE = R.layout.homepage_condition_half_tile;
|
public static final int HALF_WIDTH_VIEW_TYPE = R.layout.homepage_condition_half_tile;
|
||||||
|
@LayoutRes
|
||||||
public static final int FULL_WIDTH_VIEW_TYPE = R.layout.homepage_condition_full_tile;
|
public static final int FULL_WIDTH_VIEW_TYPE = R.layout.homepage_condition_full_tile;
|
||||||
|
|
||||||
private final Context mContext;
|
private final Context mContext;
|
||||||
|
@@ -0,0 +1,61 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2018 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.android.settings.homepage.contextualcards.legacysuggestion;
|
||||||
|
|
||||||
|
import android.app.PendingIntent;
|
||||||
|
|
||||||
|
import com.android.settings.homepage.contextualcards.ContextualCard;
|
||||||
|
|
||||||
|
public class LegacySuggestionContextualCard extends ContextualCard {
|
||||||
|
|
||||||
|
private final PendingIntent mPendingIntent;
|
||||||
|
|
||||||
|
public LegacySuggestionContextualCard(Builder builder) {
|
||||||
|
super(builder);
|
||||||
|
mPendingIntent = builder.mPendingIntent;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getCardType() {
|
||||||
|
return CardType.LEGACY_SUGGESTION;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PendingIntent getPendingIntent() {
|
||||||
|
return mPendingIntent;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Builder extends ContextualCard.Builder {
|
||||||
|
|
||||||
|
private PendingIntent mPendingIntent;
|
||||||
|
|
||||||
|
public Builder setPendingIntent(PendingIntent pendingIntent) {
|
||||||
|
mPendingIntent = pendingIntent;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Builder setCardType(int cardType) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"Cannot change card type for " + getClass().getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
public LegacySuggestionContextualCard build() {
|
||||||
|
return new LegacySuggestionContextualCard(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -0,0 +1,156 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2018 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.android.settings.homepage.contextualcards.legacysuggestion;
|
||||||
|
|
||||||
|
import android.app.PendingIntent;
|
||||||
|
import android.content.ComponentName;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.service.settings.suggestions.Suggestion;
|
||||||
|
import android.util.ArrayMap;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import androidx.annotation.VisibleForTesting;
|
||||||
|
|
||||||
|
import com.android.settings.R;
|
||||||
|
import com.android.settings.homepage.contextualcards.ContextualCard;
|
||||||
|
import com.android.settings.homepage.contextualcards.ContextualCardController;
|
||||||
|
import com.android.settings.homepage.contextualcards.ContextualCardUpdateListener;
|
||||||
|
import com.android.settings.overlay.FeatureFactory;
|
||||||
|
import com.android.settingslib.core.lifecycle.LifecycleObserver;
|
||||||
|
import com.android.settingslib.core.lifecycle.events.OnStart;
|
||||||
|
import com.android.settingslib.core.lifecycle.events.OnStop;
|
||||||
|
import com.android.settingslib.suggestions.SuggestionController;
|
||||||
|
import com.android.settingslib.suggestions.SuggestionController.ServiceConnectionListener;
|
||||||
|
import com.android.settingslib.utils.ThreadUtils;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class LegacySuggestionContextualCardController implements ContextualCardController,
|
||||||
|
LifecycleObserver, OnStart, OnStop, ServiceConnectionListener {
|
||||||
|
|
||||||
|
private static final String TAG = "LegacySuggestCardCtrl";
|
||||||
|
|
||||||
|
@VisibleForTesting
|
||||||
|
SuggestionController mSuggestionController;
|
||||||
|
|
||||||
|
private ContextualCardUpdateListener mCardUpdateListener;
|
||||||
|
private final Context mContext;
|
||||||
|
|
||||||
|
|
||||||
|
public LegacySuggestionContextualCardController(Context context) {
|
||||||
|
mContext = context;
|
||||||
|
if (!mContext.getResources().getBoolean(R.bool.config_use_legacy_suggestion)) {
|
||||||
|
Log.w(TAG, "Legacy suggestion contextual card disabled, skipping.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
final ComponentName suggestionServiceComponent =
|
||||||
|
FeatureFactory.getFactory(mContext).getSuggestionFeatureProvider(mContext)
|
||||||
|
.getSuggestionServiceComponent();
|
||||||
|
mSuggestionController = new SuggestionController(
|
||||||
|
mContext, suggestionServiceComponent, this /* listener */);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getCardType() {
|
||||||
|
return ContextualCard.CardType.LEGACY_SUGGESTION;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPrimaryClick(ContextualCard card) {
|
||||||
|
try {
|
||||||
|
((LegacySuggestionContextualCard) card).getPendingIntent().send();
|
||||||
|
} catch (PendingIntent.CanceledException e) {
|
||||||
|
Log.w(TAG, "Failed to start suggestion " + card.getTitleText());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onActionClick(ContextualCard card) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setCardUpdateListener(ContextualCardUpdateListener listener) {
|
||||||
|
mCardUpdateListener = listener;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onStart() {
|
||||||
|
if (mSuggestionController == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mSuggestionController.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onStop() {
|
||||||
|
if (mSuggestionController == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mSuggestionController.stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onServiceConnected() {
|
||||||
|
loadSuggestions();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onServiceDisconnected() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void loadSuggestions() {
|
||||||
|
ThreadUtils.postOnBackgroundThread(() -> {
|
||||||
|
if (mSuggestionController == null || mCardUpdateListener == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
final List<Suggestion> suggestions = mSuggestionController.getSuggestions();
|
||||||
|
Log.d(TAG, "Loaded suggests: "
|
||||||
|
+ suggestions == null ? "null" : String.valueOf(suggestions.size()));
|
||||||
|
|
||||||
|
final List<ContextualCard> cards = new ArrayList<>();
|
||||||
|
if (suggestions != null) {
|
||||||
|
// Convert suggestion to ContextualCard
|
||||||
|
for (Suggestion suggestion : suggestions) {
|
||||||
|
final LegacySuggestionContextualCard.Builder cardBuilder =
|
||||||
|
new LegacySuggestionContextualCard.Builder();
|
||||||
|
if (suggestion.getIcon() != null) {
|
||||||
|
cardBuilder.setIconDrawable(suggestion.getIcon().loadDrawable(mContext));
|
||||||
|
}
|
||||||
|
cardBuilder
|
||||||
|
.setPendingIntent(suggestion.getPendingIntent())
|
||||||
|
.setName(suggestion.getId())
|
||||||
|
.setTitleText(suggestion.getTitle().toString())
|
||||||
|
.setSummaryText(suggestion.getSummary().toString());
|
||||||
|
|
||||||
|
cards.add(cardBuilder.build());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update adapter
|
||||||
|
final Map<Integer, List<ContextualCard>> suggestionCards = new ArrayMap<>();
|
||||||
|
suggestionCards.put(ContextualCard.CardType.LEGACY_SUGGESTION, cards);
|
||||||
|
ThreadUtils.postOnMainThread(
|
||||||
|
() -> mCardUpdateListener.onContextualCardUpdated(suggestionCards));
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,81 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2018 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.android.settings.homepage.contextualcards.legacysuggestion;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.view.View;
|
||||||
|
import android.widget.ImageView;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import androidx.annotation.LayoutRes;
|
||||||
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
|
import com.android.settings.R;
|
||||||
|
import com.android.settings.homepage.contextualcards.ContextualCard;
|
||||||
|
import com.android.settings.homepage.contextualcards.ContextualCardRenderer;
|
||||||
|
import com.android.settings.homepage.contextualcards.ControllerRendererPool;
|
||||||
|
|
||||||
|
public class LegacySuggestionContextualCardRenderer implements ContextualCardRenderer {
|
||||||
|
|
||||||
|
@LayoutRes
|
||||||
|
public static final int VIEW_TYPE = R.layout.homepage_suggestion_tile;
|
||||||
|
|
||||||
|
private final Context mContext;
|
||||||
|
private final ControllerRendererPool mControllerRendererPool;
|
||||||
|
|
||||||
|
public LegacySuggestionContextualCardRenderer(Context context,
|
||||||
|
ControllerRendererPool controllerRendererPool) {
|
||||||
|
mContext = context;
|
||||||
|
mControllerRendererPool = controllerRendererPool;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getViewType(boolean isHalfWidth) {
|
||||||
|
return VIEW_TYPE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public RecyclerView.ViewHolder createViewHolder(View view) {
|
||||||
|
return new LegacySuggestionViewHolder(view);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void bindView(RecyclerView.ViewHolder holder, ContextualCard card) {
|
||||||
|
final LegacySuggestionViewHolder vh = (LegacySuggestionViewHolder) holder;
|
||||||
|
vh.icon.setImageDrawable(card.getIconDrawable());
|
||||||
|
vh.title.setText(card.getTitleText());
|
||||||
|
vh.summary.setText(card.getSummaryText());
|
||||||
|
vh.itemView.setOnClickListener(v ->
|
||||||
|
mControllerRendererPool.getController(mContext,
|
||||||
|
card.getCardType()).onPrimaryClick(card));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class LegacySuggestionViewHolder extends RecyclerView.ViewHolder {
|
||||||
|
|
||||||
|
public final ImageView icon;
|
||||||
|
public final TextView title;
|
||||||
|
public final TextView summary;
|
||||||
|
|
||||||
|
public LegacySuggestionViewHolder(View itemView) {
|
||||||
|
super(itemView);
|
||||||
|
icon = itemView.findViewById(android.R.id.icon);
|
||||||
|
title = itemView.findViewById(android.R.id.title);
|
||||||
|
summary = itemView.findViewById(android.R.id.summary);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@@ -62,6 +62,7 @@
|
|||||||
<bool name="config_show_wifi_mac_address">false</bool>
|
<bool name="config_show_wifi_mac_address">false</bool>
|
||||||
<bool name="config_disable_uninstall_update">true</bool>
|
<bool name="config_disable_uninstall_update">true</bool>
|
||||||
<bool name="config_show_device_name">false</bool>
|
<bool name="config_show_device_name">false</bool>
|
||||||
|
<bool name="config_use_legacy_suggestion">false</bool>
|
||||||
|
|
||||||
<!-- Whether or not extra preview panels should be used for screen zoom setting. -->
|
<!-- Whether or not extra preview panels should be used for screen zoom setting. -->
|
||||||
<bool name="config_enable_extra_screen_zoom_preview">false</bool>
|
<bool name="config_enable_extra_screen_zoom_preview">false</bool>
|
||||||
|
@@ -30,7 +30,7 @@ public class ConditionalContextualCardTest {
|
|||||||
@Test(expected = IllegalArgumentException.class)
|
@Test(expected = IllegalArgumentException.class)
|
||||||
public void newInstance_changeCardType_shouldCrash() {
|
public void newInstance_changeCardType_shouldCrash() {
|
||||||
new ConditionalContextualCard.Builder()
|
new ConditionalContextualCard.Builder()
|
||||||
.setCardType(ContextualCard.CardType.SUGGESTION)
|
.setCardType(ContextualCard.CardType.LEGACY_SUGGESTION)
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -0,0 +1,94 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2018 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.android.settings.homepage.contextualcards.legacysuggestion;
|
||||||
|
|
||||||
|
|
||||||
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
|
|
||||||
|
import static org.mockito.Mockito.verify;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
|
||||||
|
import com.android.settings.homepage.contextualcards.ContextualCardUpdateListener;
|
||||||
|
import com.android.settings.testutils.FakeFeatureFactory;
|
||||||
|
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||||
|
import com.android.settings.testutils.shadow.ShadowThreadUtils;
|
||||||
|
import com.android.settingslib.suggestions.SuggestionController;
|
||||||
|
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.MockitoAnnotations;
|
||||||
|
import org.robolectric.RuntimeEnvironment;
|
||||||
|
import org.robolectric.annotation.Config;
|
||||||
|
|
||||||
|
@RunWith(SettingsRobolectricTestRunner.class)
|
||||||
|
@Config(shadows = ShadowThreadUtils.class)
|
||||||
|
public class LegacySuggestionContextualCardControllerTest {
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private SuggestionController mSuggestionController;
|
||||||
|
@Mock
|
||||||
|
private ContextualCardUpdateListener mCardUpdateListener;
|
||||||
|
|
||||||
|
private Context mContext;
|
||||||
|
private LegacySuggestionContextualCardController mController;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() {
|
||||||
|
MockitoAnnotations.initMocks(this);
|
||||||
|
FakeFeatureFactory.setupForTest();
|
||||||
|
mContext = RuntimeEnvironment.application;
|
||||||
|
mController = new LegacySuggestionContextualCardController(mContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void init_configOn_shouldCreateSuggestionController() {
|
||||||
|
final LegacySuggestionContextualCardController controller =
|
||||||
|
new LegacySuggestionContextualCardController(mContext);
|
||||||
|
assertThat(controller.mSuggestionController).isNotNull();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Config(qualifiers = "mcc999")
|
||||||
|
public void init_configOff_shouldNotCreateSuggestionController() {
|
||||||
|
final LegacySuggestionContextualCardController controller =
|
||||||
|
new LegacySuggestionContextualCardController(mContext);
|
||||||
|
|
||||||
|
assertThat(controller.mSuggestionController).isNull();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void goThroughLifecycle_hasSuggestionController_shouldStartStopController() {
|
||||||
|
mController.mSuggestionController = mSuggestionController;
|
||||||
|
mController.onStart();
|
||||||
|
verify(mSuggestionController).start();
|
||||||
|
|
||||||
|
mController.onStop();
|
||||||
|
verify(mSuggestionController).stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void onServiceConnected_shouldLoadSuggestion() {
|
||||||
|
mController.mSuggestionController = mSuggestionController;
|
||||||
|
mController.setCardUpdateListener(mCardUpdateListener);
|
||||||
|
mController.onServiceConnected();
|
||||||
|
|
||||||
|
verify(mSuggestionController).getSuggestions();
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,105 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2018 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.android.settings.homepage.contextualcards.legacysuggestion;
|
||||||
|
|
||||||
|
|
||||||
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
|
|
||||||
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
|
import static org.mockito.Mockito.verify;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
|
||||||
|
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||||
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
|
import com.android.settings.R;
|
||||||
|
import com.android.settings.homepage.contextualcards.ContextualCard;
|
||||||
|
import com.android.settings.homepage.contextualcards.ControllerRendererPool;
|
||||||
|
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||||
|
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.MockitoAnnotations;
|
||||||
|
import org.robolectric.RuntimeEnvironment;
|
||||||
|
|
||||||
|
@RunWith(SettingsRobolectricTestRunner.class)
|
||||||
|
public class LegacySuggestionContextualCardRendererTest {
|
||||||
|
@Mock
|
||||||
|
private ControllerRendererPool mControllerRendererPool;
|
||||||
|
@Mock
|
||||||
|
private LegacySuggestionContextualCardController mController;
|
||||||
|
private Context mContext;
|
||||||
|
private LegacySuggestionContextualCardRenderer mRenderer;
|
||||||
|
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() {
|
||||||
|
MockitoAnnotations.initMocks(this);
|
||||||
|
mContext = RuntimeEnvironment.application;
|
||||||
|
mRenderer = new LegacySuggestionContextualCardRenderer(mContext, mControllerRendererPool);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void bindView_shouldSetListener() {
|
||||||
|
final int viewType = mRenderer.getViewType(true /* isHalfWidth */);
|
||||||
|
final RecyclerView recyclerView = new RecyclerView(mContext);
|
||||||
|
recyclerView.setLayoutManager(new LinearLayoutManager(mContext));
|
||||||
|
final View card = LayoutInflater.from(mContext).inflate(viewType, recyclerView, false);
|
||||||
|
final RecyclerView.ViewHolder viewHolder = mRenderer.createViewHolder(card);
|
||||||
|
|
||||||
|
when(mControllerRendererPool.getController(mContext,
|
||||||
|
ContextualCard.CardType.LEGACY_SUGGESTION)).thenReturn(mController);
|
||||||
|
|
||||||
|
mRenderer.bindView(viewHolder, buildContextualCard());
|
||||||
|
|
||||||
|
assertThat(card).isNotNull();
|
||||||
|
assertThat(card.hasOnClickListeners()).isTrue();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void viewClick_shouldInvokeControllerPrimaryClick() {
|
||||||
|
final int viewType = mRenderer.getViewType(true /* isHalfWidth */);
|
||||||
|
final RecyclerView recyclerView = new RecyclerView(mContext);
|
||||||
|
recyclerView.setLayoutManager(new LinearLayoutManager(mContext));
|
||||||
|
final View card = LayoutInflater.from(mContext).inflate(viewType, recyclerView, false);
|
||||||
|
final RecyclerView.ViewHolder viewHolder = mRenderer.createViewHolder(card);
|
||||||
|
when(mControllerRendererPool.getController(mContext,
|
||||||
|
ContextualCard.CardType.LEGACY_SUGGESTION)).thenReturn(mController);
|
||||||
|
|
||||||
|
mRenderer.bindView(viewHolder, buildContextualCard());
|
||||||
|
|
||||||
|
assertThat(card).isNotNull();
|
||||||
|
card.performClick();
|
||||||
|
|
||||||
|
verify(mController).onPrimaryClick(any(ContextualCard.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
private ContextualCard buildContextualCard() {
|
||||||
|
return new LegacySuggestionContextualCard.Builder()
|
||||||
|
.setName("test_name")
|
||||||
|
.setTitleText("test_title")
|
||||||
|
.setSummaryText("test_summary")
|
||||||
|
.setIconDrawable(mContext.getDrawable(R.drawable.ic_do_not_disturb_on_24dp))
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,55 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2018 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.android.settings.homepage.contextualcards.legacysuggestion;
|
||||||
|
|
||||||
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
|
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
|
|
||||||
|
import android.app.PendingIntent;
|
||||||
|
|
||||||
|
import com.android.settings.homepage.contextualcards.ContextualCard;
|
||||||
|
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
|
||||||
|
@RunWith(SettingsRobolectricTestRunner.class)
|
||||||
|
public class LegacySuggestionContextualCardTest {
|
||||||
|
|
||||||
|
@Test(expected = IllegalArgumentException.class)
|
||||||
|
public void newInstance_changeCardType_shouldCrash() {
|
||||||
|
new LegacySuggestionContextualCard.Builder()
|
||||||
|
.setCardType(ContextualCard.CardType.CONDITIONAL)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getCardType_shouldAlwaysBeSuggestionType() {
|
||||||
|
assertThat(new LegacySuggestionContextualCard.Builder().build().getCardType())
|
||||||
|
.isEqualTo(ContextualCard.CardType.LEGACY_SUGGESTION);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void build_shouldSetPendingIntent() {
|
||||||
|
assertThat(new LegacySuggestionContextualCard.Builder()
|
||||||
|
.setPendingIntent(mock(PendingIntent.class))
|
||||||
|
.build()
|
||||||
|
.getPendingIntent()).isNotNull();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Reference in New Issue
Block a user