Change to use new suggestion/condition UI.
Change to always use the new UI that combines the suggestion and conditions, and remove all codes relating to the old UI. Fix: 37645754 Fix: 62621808 Test: make RunSettingsRoboTests Merged-In: I3421a9e5182f6606843392d6fae8b9f07c5f2e46 Change-Id: I5ef169a563166520dad0ac44f6780da814e2f1f7
This commit is contained in:
@@ -1,128 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<!--
|
|
||||||
Copyright (C) 2015 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.
|
|
||||||
-->
|
|
||||||
|
|
||||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:clipChildren="false"
|
|
||||||
android:clipToPadding="false">
|
|
||||||
<LinearLayout
|
|
||||||
android:id="@+id/content"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:orientation="vertical"
|
|
||||||
android:background="?android:attr/colorAccent"
|
|
||||||
android:elevation="2dp"
|
|
||||||
android:clickable="true"
|
|
||||||
android:focusable="true">
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:id="@+id/collapsed_group"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="56dp"
|
|
||||||
android:background="?android:attr/selectableItemBackground"
|
|
||||||
android:orientation="horizontal"
|
|
||||||
android:gravity="center">
|
|
||||||
|
|
||||||
<ImageView
|
|
||||||
android:id="@android:id/icon"
|
|
||||||
android:layout_width="24dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginStart="16dp"
|
|
||||||
android:layout_marginEnd="32dp"
|
|
||||||
android:tint="?android:attr/textColorPrimaryInverse" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@android:id/title"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_weight="1"
|
|
||||||
android:textAppearance="?android:attr/textAppearanceMedium"
|
|
||||||
android:textColor="?android:attr/textColorPrimaryInverse" />
|
|
||||||
|
|
||||||
<ImageView
|
|
||||||
android:id="@+id/expand_indicator"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:padding="16dp"
|
|
||||||
android:tint="?android:attr/textColorPrimaryInverse"/>
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:id="@+id/detail_group"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:paddingStart="72dp"
|
|
||||||
android:visibility="gone"
|
|
||||||
android:orientation="vertical">
|
|
||||||
|
|
||||||
<!-- TODO: Don't set alpha here, and do proper themeing that
|
|
||||||
handles night mode -->
|
|
||||||
<TextView
|
|
||||||
android:id="@android:id/summary"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
|
|
||||||
android:paddingBottom="16dp"
|
|
||||||
android:textAppearance="?android:attr/textAppearanceListItemSecondary"
|
|
||||||
android:alpha=".7"
|
|
||||||
android:textColor="?android:attr/textColorPrimaryInverse" />
|
|
||||||
|
|
||||||
<!-- TODO: Better background -->
|
|
||||||
<View
|
|
||||||
android:id="@+id/divider"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height=".25dp"
|
|
||||||
android:background="@android:color/white" />
|
|
||||||
|
|
||||||
<com.android.internal.widget.ButtonBarLayout
|
|
||||||
android:id="@+id/buttonBar"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:paddingTop="8dp"
|
|
||||||
android:paddingBottom="8dp"
|
|
||||||
style="?android:attr/buttonBarStyle"
|
|
||||||
android:paddingEnd="?android:attr/listPreferredItemPaddingEnd">
|
|
||||||
|
|
||||||
<Button
|
|
||||||
android:id="@+id/first_action"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_weight="1"
|
|
||||||
android:paddingStart="0dp"
|
|
||||||
android:alpha=".8"
|
|
||||||
android:textAlignment="viewStart"
|
|
||||||
android:textColor="?android:attr/textColorPrimaryInverse"
|
|
||||||
style="?android:attr/buttonBarButtonStyle" />
|
|
||||||
|
|
||||||
<Button
|
|
||||||
android:id="@+id/second_action"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_weight="1"
|
|
||||||
android:alpha=".8"
|
|
||||||
android:textAlignment="viewStart"
|
|
||||||
android:textColor="?android:attr/textColorPrimaryInverse"
|
|
||||||
style="?android:attr/buttonBarButtonStyle" />
|
|
||||||
|
|
||||||
</com.android.internal.widget.ButtonBarLayout>
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
</FrameLayout>
|
|
@@ -1,52 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<!--
|
|
||||||
Copyright (C) 2016 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.
|
|
||||||
-->
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="@dimen/dashboard_category_height"
|
|
||||||
android:clickable="true"
|
|
||||||
android:focusable="true"
|
|
||||||
android:background="@drawable/selectable_card_grey"
|
|
||||||
android:gravity="center_vertical"
|
|
||||||
android:paddingTop="4dp">
|
|
||||||
<ImageView
|
|
||||||
android:id="@android:id/icon"
|
|
||||||
android:layout_width="@dimen/dashboard_tile_image_size"
|
|
||||||
android:layout_height="@dimen/dashboard_tile_image_size"
|
|
||||||
android:layout_marginStart="@dimen/dashboard_tile_image_margin"
|
|
||||||
android:layout_marginEnd="@dimen/dashboard_tile_image_margin"
|
|
||||||
android:src="@drawable/ic_expand_more"/>
|
|
||||||
<TextView
|
|
||||||
android:id="@android:id/title"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:singleLine="true"
|
|
||||||
android:textAppearance="@style/TextAppearance.SuggestionTitle"
|
|
||||||
android:textColor="?android:attr/colorAccent"
|
|
||||||
android:ellipsize="marquee"
|
|
||||||
android:fadingEdge="horizontal"/>
|
|
||||||
<TextView
|
|
||||||
android:id="@android:id/summary"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_weight="1"
|
|
||||||
android:gravity="end"
|
|
||||||
android:paddingEnd="18dp"
|
|
||||||
android:textAppearance="@style/TextAppearance.SuggestionTitle"
|
|
||||||
android:textColor="?android:attr/colorAccent"/>
|
|
||||||
</LinearLayout>
|
|
@@ -1,58 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<!-- Copyright (C) 2016 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.
|
|
||||||
-->
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:background="@drawable/selectable_card_grey"
|
|
||||||
android:clickable="true"
|
|
||||||
android:focusable="true"
|
|
||||||
android:gravity="center_vertical"
|
|
||||||
android:minHeight="@dimen/dashboard_tile_minimum_height">
|
|
||||||
|
|
||||||
<ImageView
|
|
||||||
android:id="@android:id/icon"
|
|
||||||
android:layout_width="@dimen/dashboard_tile_image_size"
|
|
||||||
android:layout_height="@dimen/dashboard_tile_image_size"
|
|
||||||
android:layout_marginStart="@dimen/dashboard_tile_image_margin"
|
|
||||||
android:layout_marginEnd="@dimen/dashboard_tile_image_margin"
|
|
||||||
android:scaleType="centerInside"/>
|
|
||||||
|
|
||||||
<RelativeLayout
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_weight="1">
|
|
||||||
|
|
||||||
<TextView android:id="@android:id/title"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:singleLine="true"
|
|
||||||
android:textAppearance="@style/TextAppearance.TileTitle"
|
|
||||||
android:ellipsize="marquee"
|
|
||||||
android:fadingEdge="horizontal"/>
|
|
||||||
|
|
||||||
<TextView android:id="@android:id/summary"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_below="@android:id/title"
|
|
||||||
android:layout_alignStart="@android:id/title"
|
|
||||||
android:textAppearance="@style/TextAppearance.Small"
|
|
||||||
android:textColor="?android:attr/textColorSecondary"/>
|
|
||||||
|
|
||||||
</RelativeLayout>
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
@@ -18,9 +18,7 @@
|
|||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_margin="8dp"
|
android:background="@android:color/white"
|
||||||
android:background="@drawable/selectable_card"
|
|
||||||
android:clickable="true"
|
android:clickable="true"
|
||||||
android:elevation="2dp"
|
|
||||||
android:focusable="true"
|
android:focusable="true"
|
||||||
android:minHeight="@dimen/dashboard_tile_minimum_height" />
|
android:minHeight="@dimen/dashboard_tile_minimum_height" />
|
||||||
|
@@ -15,7 +15,6 @@
|
|||||||
*/
|
*/
|
||||||
package com.android.settings.dashboard;
|
package com.android.settings.dashboard;
|
||||||
|
|
||||||
import android.annotation.ColorInt;
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.res.TypedArray;
|
import android.content.res.TypedArray;
|
||||||
@@ -40,12 +39,10 @@ import android.widget.TextView;
|
|||||||
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
||||||
import com.android.settings.R;
|
import com.android.settings.R;
|
||||||
import com.android.settings.R.id;
|
import com.android.settings.R.id;
|
||||||
import com.android.settings.SettingsActivity;
|
|
||||||
import com.android.settings.core.instrumentation.MetricsFeatureProvider;
|
import com.android.settings.core.instrumentation.MetricsFeatureProvider;
|
||||||
import com.android.settings.dashboard.DashboardData.SuggestionConditionHeaderData;
|
import com.android.settings.dashboard.DashboardData.SuggestionConditionHeaderData;
|
||||||
import com.android.settings.dashboard.conditional.Condition;
|
import com.android.settings.dashboard.conditional.Condition;
|
||||||
import com.android.settings.dashboard.conditional.ConditionAdapter;
|
import com.android.settings.dashboard.conditional.ConditionAdapter;
|
||||||
import com.android.settings.dashboard.conditional.ConditionAdapterUtils;
|
|
||||||
import com.android.settings.dashboard.suggestions.SuggestionAdapter;
|
import com.android.settings.dashboard.suggestions.SuggestionAdapter;
|
||||||
import com.android.settings.dashboard.suggestions.SuggestionDismissController;
|
import com.android.settings.dashboard.suggestions.SuggestionDismissController;
|
||||||
import com.android.settings.dashboard.suggestions.SuggestionFeatureProvider;
|
import com.android.settings.dashboard.suggestions.SuggestionFeatureProvider;
|
||||||
@@ -63,7 +60,6 @@ public class DashboardAdapter extends RecyclerView.Adapter<DashboardAdapter.Dash
|
|||||||
public static final String TAG = "DashboardAdapter";
|
public static final String TAG = "DashboardAdapter";
|
||||||
private static final String STATE_SUGGESTION_LIST = "suggestion_list";
|
private static final String STATE_SUGGESTION_LIST = "suggestion_list";
|
||||||
private static final String STATE_CATEGORY_LIST = "category_list";
|
private static final String STATE_CATEGORY_LIST = "category_list";
|
||||||
private static final String STATE_SUGGESTION_MODE = "suggestion_mode";
|
|
||||||
private static final String STATE_SUGGESTIONS_SHOWN_LOGGED = "suggestions_shown_logged";
|
private static final String STATE_SUGGESTIONS_SHOWN_LOGGED = "suggestions_shown_logged";
|
||||||
private static final String STATE_SUGGESTION_CONDITION_MODE = "suggestion_condition_mode";
|
private static final String STATE_SUGGESTION_CONDITION_MODE = "suggestion_condition_mode";
|
||||||
|
|
||||||
@@ -77,7 +73,6 @@ public class DashboardAdapter extends RecyclerView.Adapter<DashboardAdapter.Dash
|
|||||||
private final SuggestionFeatureProvider mSuggestionFeatureProvider;
|
private final SuggestionFeatureProvider mSuggestionFeatureProvider;
|
||||||
private final ArrayList<String> mSuggestionsShownLogged;
|
private final ArrayList<String> mSuggestionsShownLogged;
|
||||||
private boolean mFirstFrameDrawn;
|
private boolean mFirstFrameDrawn;
|
||||||
private boolean mCombineSuggestionAndCondition;
|
|
||||||
private RecyclerView mRecyclerView;
|
private RecyclerView mRecyclerView;
|
||||||
private SuggestionParser mSuggestionParser;
|
private SuggestionParser mSuggestionParser;
|
||||||
private SuggestionAdapter mSuggestionAdapter;
|
private SuggestionAdapter mSuggestionAdapter;
|
||||||
@@ -99,46 +94,20 @@ public class DashboardAdapter extends RecyclerView.Adapter<DashboardAdapter.Dash
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
if (mCombineSuggestionAndCondition) {
|
|
||||||
Condition condition = (Condition) v.getTag();
|
Condition condition = (Condition) v.getTag();
|
||||||
//TODO: get rid of setTag/getTag
|
//TODO: get rid of setTag/getTag
|
||||||
mMetricsFeatureProvider.action(mContext,
|
mMetricsFeatureProvider.action(mContext,
|
||||||
MetricsEvent.ACTION_SETTINGS_CONDITION_CLICK,
|
MetricsEvent.ACTION_SETTINGS_CONDITION_CLICK,
|
||||||
condition.getMetricsConstant());
|
condition.getMetricsConstant());
|
||||||
condition.onPrimaryClick();
|
condition.onPrimaryClick();
|
||||||
} else {
|
|
||||||
Condition expandedCondition = mDashboardData.getExpandedCondition();
|
|
||||||
|
|
||||||
//TODO: get rid of setTag/getTag
|
|
||||||
if (v.getTag() == expandedCondition) {
|
|
||||||
mMetricsFeatureProvider.action(mContext,
|
|
||||||
MetricsEvent.ACTION_SETTINGS_CONDITION_CLICK,
|
|
||||||
expandedCondition.getMetricsConstant());
|
|
||||||
expandedCondition.onPrimaryClick();
|
|
||||||
} else {
|
|
||||||
expandedCondition = (Condition) v.getTag();
|
|
||||||
mMetricsFeatureProvider.action(mContext,
|
|
||||||
MetricsEvent.ACTION_SETTINGS_CONDITION_EXPAND,
|
|
||||||
expandedCondition.getMetricsConstant());
|
|
||||||
|
|
||||||
updateExpandedCondition(expandedCondition);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
public DashboardAdapter(Context context, Bundle savedInstanceState,
|
|
||||||
List<Condition> conditions) {
|
|
||||||
this(context, savedInstanceState, conditions, null, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
public DashboardAdapter(Context context, Bundle savedInstanceState,
|
public DashboardAdapter(Context context, Bundle savedInstanceState,
|
||||||
List<Condition> conditions, SuggestionParser suggestionParser,
|
List<Condition> conditions, SuggestionParser suggestionParser,
|
||||||
SuggestionDismissController.Callback callback) {
|
SuggestionDismissController.Callback callback) {
|
||||||
List<Tile> suggestions = null;
|
List<Tile> suggestions = null;
|
||||||
List<DashboardCategory> categories = null;
|
List<DashboardCategory> categories = null;
|
||||||
int suggestionMode = DashboardData.SUGGESTION_MODE_DEFAULT;
|
|
||||||
int suggestionConditionMode = DashboardData.HEADER_MODE_DEFAULT;
|
int suggestionConditionMode = DashboardData.HEADER_MODE_DEFAULT;
|
||||||
|
|
||||||
mContext = context;
|
mContext = context;
|
||||||
@@ -146,7 +115,6 @@ public class DashboardAdapter extends RecyclerView.Adapter<DashboardAdapter.Dash
|
|||||||
mMetricsFeatureProvider = factory.getMetricsFeatureProvider();
|
mMetricsFeatureProvider = factory.getMetricsFeatureProvider();
|
||||||
mDashboardFeatureProvider = factory.getDashboardFeatureProvider(context);
|
mDashboardFeatureProvider = factory.getDashboardFeatureProvider(context);
|
||||||
mSuggestionFeatureProvider = factory.getSuggestionFeatureProvider(context);
|
mSuggestionFeatureProvider = factory.getSuggestionFeatureProvider(context);
|
||||||
mCombineSuggestionAndCondition = mDashboardFeatureProvider.combineSuggestionAndCondition();
|
|
||||||
mCache = new IconCache(context);
|
mCache = new IconCache(context);
|
||||||
mSuggestionParser = suggestionParser;
|
mSuggestionParser = suggestionParser;
|
||||||
mCallback = callback;
|
mCallback = callback;
|
||||||
@@ -158,8 +126,6 @@ public class DashboardAdapter extends RecyclerView.Adapter<DashboardAdapter.Dash
|
|||||||
categories = savedInstanceState.getParcelableArrayList(STATE_CATEGORY_LIST);
|
categories = savedInstanceState.getParcelableArrayList(STATE_CATEGORY_LIST);
|
||||||
suggestionConditionMode = savedInstanceState.getInt(
|
suggestionConditionMode = savedInstanceState.getInt(
|
||||||
STATE_SUGGESTION_CONDITION_MODE, suggestionConditionMode);
|
STATE_SUGGESTION_CONDITION_MODE, suggestionConditionMode);
|
||||||
suggestionMode = savedInstanceState.getInt(
|
|
||||||
STATE_SUGGESTION_MODE, DashboardData.SUGGESTION_MODE_DEFAULT);
|
|
||||||
mSuggestionsShownLogged = savedInstanceState.getStringArrayList(
|
mSuggestionsShownLogged = savedInstanceState.getStringArrayList(
|
||||||
STATE_SUGGESTIONS_SHOWN_LOGGED);
|
STATE_SUGGESTIONS_SHOWN_LOGGED);
|
||||||
} else {
|
} else {
|
||||||
@@ -170,8 +136,6 @@ public class DashboardAdapter extends RecyclerView.Adapter<DashboardAdapter.Dash
|
|||||||
.setConditions(conditions)
|
.setConditions(conditions)
|
||||||
.setSuggestions(suggestions)
|
.setSuggestions(suggestions)
|
||||||
.setCategories(categories)
|
.setCategories(categories)
|
||||||
.setSuggestionMode(suggestionMode)
|
|
||||||
.setCombineSuggestionAndCondition(mCombineSuggestionAndCondition)
|
|
||||||
.setSuggestionConditionMode(suggestionConditionMode)
|
.setSuggestionConditionMode(suggestionConditionMode)
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
@@ -213,7 +177,6 @@ public class DashboardAdapter extends RecyclerView.Adapter<DashboardAdapter.Dash
|
|||||||
.build();
|
.build();
|
||||||
notifyDashboardDataChanged(prevData);
|
notifyDashboardDataChanged(prevData);
|
||||||
List<Tile> shownSuggestions = null;
|
List<Tile> shownSuggestions = null;
|
||||||
if (mCombineSuggestionAndCondition) {
|
|
||||||
final int mode = mDashboardData.getSuggestionConditionMode();
|
final int mode = mDashboardData.getSuggestionConditionMode();
|
||||||
if (mode == DashboardData.HEADER_MODE_DEFAULT) {
|
if (mode == DashboardData.HEADER_MODE_DEFAULT) {
|
||||||
shownSuggestions = suggestions.subList(0,
|
shownSuggestions = suggestions.subList(0,
|
||||||
@@ -221,17 +184,6 @@ public class DashboardAdapter extends RecyclerView.Adapter<DashboardAdapter.Dash
|
|||||||
} else if (mode != DashboardData.HEADER_MODE_COLLAPSED) {
|
} else if (mode != DashboardData.HEADER_MODE_COLLAPSED) {
|
||||||
shownSuggestions = suggestions;
|
shownSuggestions = suggestions;
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
switch (mDashboardData.getSuggestionMode()) {
|
|
||||||
case DashboardData.SUGGESTION_MODE_DEFAULT:
|
|
||||||
shownSuggestions = suggestions.subList(0,
|
|
||||||
Math.min(suggestions.size(), DashboardData.DEFAULT_SUGGESTION_COUNT));
|
|
||||||
break;
|
|
||||||
case DashboardData.SUGGESTION_MODE_EXPANDED:
|
|
||||||
shownSuggestions = suggestions;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (shownSuggestions != null) {
|
if (shownSuggestions != null) {
|
||||||
for (Tile suggestion : shownSuggestions) {
|
for (Tile suggestion : shownSuggestions) {
|
||||||
final String identifier = mSuggestionFeatureProvider.getSuggestionIdentifier(
|
final String identifier = mSuggestionFeatureProvider.getSuggestionIdentifier(
|
||||||
@@ -255,16 +207,9 @@ public class DashboardAdapter extends RecyclerView.Adapter<DashboardAdapter.Dash
|
|||||||
public void setConditions(List<Condition> conditions) {
|
public void setConditions(List<Condition> conditions) {
|
||||||
final DashboardData prevData = mDashboardData;
|
final DashboardData prevData = mDashboardData;
|
||||||
Log.d(TAG, "adapter setConditions called");
|
Log.d(TAG, "adapter setConditions called");
|
||||||
if (mCombineSuggestionAndCondition) {
|
|
||||||
mDashboardData = new DashboardData.Builder(prevData)
|
mDashboardData = new DashboardData.Builder(prevData)
|
||||||
.setConditions(conditions)
|
.setConditions(conditions)
|
||||||
.build();
|
.build();
|
||||||
} else {
|
|
||||||
mDashboardData = new DashboardData.Builder(prevData)
|
|
||||||
.setConditions(conditions)
|
|
||||||
.setExpandedCondition(null)
|
|
||||||
.build();
|
|
||||||
}
|
|
||||||
notifyDashboardDataChanged(prevData);
|
notifyDashboardDataChanged(prevData);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -317,44 +262,6 @@ public class DashboardAdapter extends RecyclerView.Adapter<DashboardAdapter.Dash
|
|||||||
holder.itemView.setTag(tile);
|
holder.itemView.setTag(tile);
|
||||||
holder.itemView.setOnClickListener(mTileClickListener);
|
holder.itemView.setOnClickListener(mTileClickListener);
|
||||||
break;
|
break;
|
||||||
case R.layout.suggestion_header:
|
|
||||||
onBindSuggestionHeader(holder, (DashboardData.SuggestionHeaderData)
|
|
||||||
mDashboardData.getItemEntityByPosition(position));
|
|
||||||
break;
|
|
||||||
case R.layout.suggestion_tile:
|
|
||||||
case R.layout.suggestion_tile_card:
|
|
||||||
final Tile suggestion = (Tile) mDashboardData.getItemEntityByPosition(position);
|
|
||||||
final String suggestionId = mSuggestionFeatureProvider.getSuggestionIdentifier(
|
|
||||||
mContext, suggestion);
|
|
||||||
// This is for cases when a suggestion is dismissed and the next one comes to view
|
|
||||||
if (!mSuggestionsShownLogged.contains(suggestionId)) {
|
|
||||||
mMetricsFeatureProvider.action(
|
|
||||||
mContext, MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION, suggestionId);
|
|
||||||
mSuggestionsShownLogged.add(suggestionId);
|
|
||||||
}
|
|
||||||
onBindTile(holder, suggestion);
|
|
||||||
View clickHandler = holder.itemView;
|
|
||||||
// If a view with @android:id/primary is defined, use that as the click handler
|
|
||||||
// instead.
|
|
||||||
final View primaryAction = holder.itemView.findViewById(android.R.id.primary);
|
|
||||||
if (primaryAction != null) {
|
|
||||||
clickHandler = primaryAction;
|
|
||||||
// set the item view to disabled to remove any touch effects
|
|
||||||
holder.itemView.setEnabled(false);
|
|
||||||
}
|
|
||||||
clickHandler.setOnClickListener(v -> {
|
|
||||||
mMetricsFeatureProvider.action(mContext,
|
|
||||||
MetricsEvent.ACTION_SETTINGS_SUGGESTION, suggestionId);
|
|
||||||
((SettingsActivity) mContext).startSuggestion(suggestion.intent);
|
|
||||||
});
|
|
||||||
break;
|
|
||||||
case R.layout.condition_card:
|
|
||||||
final boolean isExpanded = mDashboardData.getItemEntityByPosition(position)
|
|
||||||
== mDashboardData.getExpandedCondition();
|
|
||||||
ConditionAdapterUtils.bindViews(
|
|
||||||
(Condition) mDashboardData.getItemEntityByPosition(position),
|
|
||||||
holder, isExpanded, mConditionClickListener, v -> onExpandClick(v));
|
|
||||||
break;
|
|
||||||
case R.layout.suggestion_condition_container:
|
case R.layout.suggestion_condition_container:
|
||||||
onBindConditionAndSuggestion(
|
onBindConditionAndSuggestion(
|
||||||
(SuggestionAndConditionContainerHolder) holder, position);
|
(SuggestionAndConditionContainerHolder) holder, position);
|
||||||
@@ -434,35 +341,13 @@ public class DashboardAdapter extends RecyclerView.Adapter<DashboardAdapter.Dash
|
|||||||
mSuggestionsShownLogged.clear();
|
mSuggestionsShownLogged.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
// condition card is always expanded in new suggestion/condition UI.
|
|
||||||
// TODO: Remove when completely move to new suggestion/condition UI
|
|
||||||
@Deprecated
|
|
||||||
public void onExpandClick(View v) {
|
|
||||||
Condition expandedCondition = mDashboardData.getExpandedCondition();
|
|
||||||
if (v.getTag() == expandedCondition) {
|
|
||||||
mMetricsFeatureProvider.action(mContext,
|
|
||||||
MetricsEvent.ACTION_SETTINGS_CONDITION_COLLAPSE,
|
|
||||||
expandedCondition.getMetricsConstant());
|
|
||||||
expandedCondition = null;
|
|
||||||
} else {
|
|
||||||
expandedCondition = (Condition) v.getTag();
|
|
||||||
mMetricsFeatureProvider.action(mContext, MetricsEvent.ACTION_SETTINGS_CONDITION_EXPAND,
|
|
||||||
expandedCondition.getMetricsConstant());
|
|
||||||
}
|
|
||||||
|
|
||||||
updateExpandedCondition(expandedCondition);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Object getItem(long itemId) {
|
public Object getItem(long itemId) {
|
||||||
return mDashboardData.getItemEntityById(itemId);
|
return mDashboardData.getItemEntityById(itemId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Tile getSuggestion(int position) {
|
public Tile getSuggestion(int position) {
|
||||||
if (mCombineSuggestionAndCondition) {
|
|
||||||
return mSuggestionAdapter.getSuggestion(position);
|
return mSuggestionAdapter.getSuggestion(position);
|
||||||
}
|
}
|
||||||
return (Tile) getItem(getItemId(position));
|
|
||||||
}
|
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
void notifyDashboardDataChanged(DashboardData prevData) {
|
void notifyDashboardDataChanged(DashboardData prevData) {
|
||||||
@@ -476,56 +361,6 @@ public class DashboardAdapter extends RecyclerView.Adapter<DashboardAdapter.Dash
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateExpandedCondition(Condition condition) {
|
|
||||||
final DashboardData prevData = mDashboardData;
|
|
||||||
mDashboardData = new DashboardData.Builder(prevData)
|
|
||||||
.setExpandedCondition(condition)
|
|
||||||
.build();
|
|
||||||
notifyDashboardDataChanged(prevData);
|
|
||||||
}
|
|
||||||
|
|
||||||
@VisibleForTesting
|
|
||||||
void onBindSuggestionHeader(final DashboardItemHolder holder, DashboardData
|
|
||||||
.SuggestionHeaderData data) {
|
|
||||||
final boolean moreSuggestions = data.hasMoreSuggestions;
|
|
||||||
final int undisplayedSuggestionCount = data.undisplayedSuggestionCount;
|
|
||||||
|
|
||||||
holder.icon.setImageResource(moreSuggestions ? R.drawable.ic_expand_more
|
|
||||||
: R.drawable.ic_expand_less);
|
|
||||||
holder.title.setText(mContext.getString(R.string.suggestions_title, data.suggestionSize));
|
|
||||||
String summaryContentDescription;
|
|
||||||
if (moreSuggestions) {
|
|
||||||
summaryContentDescription = mContext.getResources().getQuantityString(
|
|
||||||
R.plurals.settings_suggestion_header_summary_hidden_items,
|
|
||||||
undisplayedSuggestionCount, undisplayedSuggestionCount);
|
|
||||||
} else {
|
|
||||||
summaryContentDescription = mContext.getString(R.string.condition_expand_hide);
|
|
||||||
}
|
|
||||||
holder.summary.setContentDescription(summaryContentDescription);
|
|
||||||
|
|
||||||
if (undisplayedSuggestionCount == 0) {
|
|
||||||
holder.summary.setText(null);
|
|
||||||
} else {
|
|
||||||
holder.summary.setText(
|
|
||||||
mContext.getString(R.string.suggestions_summary, undisplayedSuggestionCount));
|
|
||||||
}
|
|
||||||
holder.itemView.setOnClickListener(v -> {
|
|
||||||
final int suggestionMode;
|
|
||||||
if (moreSuggestions) {
|
|
||||||
suggestionMode = DashboardData.SUGGESTION_MODE_EXPANDED;
|
|
||||||
logSuggestions();
|
|
||||||
} else {
|
|
||||||
suggestionMode = DashboardData.SUGGESTION_MODE_COLLAPSED;
|
|
||||||
}
|
|
||||||
|
|
||||||
DashboardData prevData = mDashboardData;
|
|
||||||
mDashboardData = new DashboardData.Builder(prevData)
|
|
||||||
.setSuggestionMode(suggestionMode)
|
|
||||||
.build();
|
|
||||||
notifyDashboardDataChanged(prevData);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private void logSuggestions() {
|
private void logSuggestions() {
|
||||||
for (Tile suggestion : mDashboardData.getSuggestions()) {
|
for (Tile suggestion : mDashboardData.getSuggestions()) {
|
||||||
final String suggestionId = mSuggestionFeatureProvider.getSuggestionIdentifier(
|
final String suggestionId = mSuggestionFeatureProvider.getSuggestionIdentifier(
|
||||||
@@ -550,7 +385,8 @@ public class DashboardAdapter extends RecyclerView.Adapter<DashboardAdapter.Dash
|
|||||||
holder.itemView.setOnClickListener(null);
|
holder.itemView.setOnClickListener(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onBindSuggestionConditionHeader(final SuggestionAndConditionHeaderHolder holder,
|
@VisibleForTesting
|
||||||
|
void onBindSuggestionConditionHeader(final SuggestionAndConditionHeaderHolder holder,
|
||||||
SuggestionConditionHeaderData data) {
|
SuggestionConditionHeaderData data) {
|
||||||
final int curMode = mDashboardData.getSuggestionConditionMode();
|
final int curMode = mDashboardData.getSuggestionConditionMode();
|
||||||
final int nextMode = data.hiddenSuggestionCount > 0 && data.conditionCount > 0
|
final int nextMode = data.hiddenSuggestionCount > 0 && data.conditionCount > 0
|
||||||
@@ -632,24 +468,23 @@ public class DashboardAdapter extends RecyclerView.Adapter<DashboardAdapter.Dash
|
|||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
void onBindConditionAndSuggestion(final SuggestionAndConditionContainerHolder holder,
|
void onBindConditionAndSuggestion(final SuggestionAndConditionContainerHolder holder,
|
||||||
int position) {
|
int position) {
|
||||||
RecyclerView.Adapter<DashboardItemHolder> adapter;
|
|
||||||
// If there is suggestions to show, it will be at position 1
|
// If there is suggestions to show, it will be at position 1
|
||||||
// position 0 is suggestion header.
|
// position 0 is suggestion header.
|
||||||
if (position == (SUGGESTION_CONDITION_HEADER_POSITION + 1)
|
if (position == (SUGGESTION_CONDITION_HEADER_POSITION + 1)
|
||||||
&& mDashboardData.getSuggestions() != null) {
|
&& mDashboardData.getSuggestions() != null) {
|
||||||
mSuggestionAdapter = new SuggestionAdapter(mContext, (List<Tile>)
|
mSuggestionAdapter = new SuggestionAdapter(mContext, (List<Tile>)
|
||||||
mDashboardData.getItemEntityByPosition(position), mSuggestionsShownLogged);
|
mDashboardData.getItemEntityByPosition(position), mSuggestionsShownLogged);
|
||||||
adapter = mSuggestionAdapter;
|
|
||||||
mSuggestionDismissHandler = new SuggestionDismissController(mContext,
|
mSuggestionDismissHandler = new SuggestionDismissController(mContext,
|
||||||
holder.data, mSuggestionParser, mCallback);
|
holder.data, mSuggestionParser, mCallback);
|
||||||
|
holder.data.setAdapter(mSuggestionAdapter);
|
||||||
} else {
|
} else {
|
||||||
ConditionAdapterUtils.addDismiss(holder.data);
|
ConditionAdapter adapter = new ConditionAdapter(mContext,
|
||||||
adapter = new ConditionAdapter(mContext,
|
|
||||||
(List<Condition>) mDashboardData.getItemEntityByPosition(position),
|
(List<Condition>) mDashboardData.getItemEntityByPosition(position),
|
||||||
mDashboardData.getSuggestionConditionMode());
|
mDashboardData.getSuggestionConditionMode());
|
||||||
|
adapter.addDismissHandling(holder.data);
|
||||||
|
holder.data.setAdapter(adapter);
|
||||||
}
|
}
|
||||||
holder.data.setLayoutManager(new LinearLayoutManager(mContext));
|
holder.data.setLayoutManager(new LinearLayoutManager(mContext));
|
||||||
holder.data.setAdapter(adapter);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onBindTile(DashboardItemHolder holder, Tile tile) {
|
private void onBindTile(DashboardItemHolder holder, Tile tile) {
|
||||||
@@ -682,7 +517,6 @@ public class DashboardAdapter extends RecyclerView.Adapter<DashboardAdapter.Dash
|
|||||||
if (categories != null) {
|
if (categories != null) {
|
||||||
outState.putParcelableArrayList(STATE_CATEGORY_LIST, new ArrayList<>(categories));
|
outState.putParcelableArrayList(STATE_CATEGORY_LIST, new ArrayList<>(categories));
|
||||||
}
|
}
|
||||||
outState.putInt(STATE_SUGGESTION_MODE, mDashboardData.getSuggestionMode());
|
|
||||||
outState.putStringArrayList(STATE_SUGGESTIONS_SHOWN_LOGGED, mSuggestionsShownLogged);
|
outState.putStringArrayList(STATE_SUGGESTIONS_SHOWN_LOGGED, mSuggestionsShownLogged);
|
||||||
outState.putInt(STATE_SUGGESTION_CONDITION_MODE,
|
outState.putInt(STATE_SUGGESTION_CONDITION_MODE,
|
||||||
mDashboardData.getSuggestionConditionMode());
|
mDashboardData.getSuggestionConditionMode());
|
||||||
|
@@ -17,8 +17,6 @@ package com.android.settings.dashboard;
|
|||||||
|
|
||||||
import android.annotation.IntDef;
|
import android.annotation.IntDef;
|
||||||
import android.graphics.drawable.Icon;
|
import android.graphics.drawable.Icon;
|
||||||
import android.support.annotation.Nullable;
|
|
||||||
import android.support.annotation.VisibleForTesting;
|
|
||||||
import android.support.v7.util.DiffUtil;
|
import android.support.v7.util.DiffUtil;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
|
|
||||||
@@ -31,7 +29,6 @@ import java.lang.annotation.Retention;
|
|||||||
import java.lang.annotation.RetentionPolicy;
|
import java.lang.annotation.RetentionPolicy;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Description about data list used in the DashboardAdapter. In the data list each item can be
|
* Description about data list used in the DashboardAdapter. In the data list each item can be
|
||||||
@@ -40,13 +37,6 @@ import java.util.Objects;
|
|||||||
* ItemsData has inner class Item, which represents the Item in data list.
|
* ItemsData has inner class Item, which represents the Item in data list.
|
||||||
*/
|
*/
|
||||||
public class DashboardData {
|
public class DashboardData {
|
||||||
@Deprecated
|
|
||||||
public static final int SUGGESTION_MODE_DEFAULT = 0;
|
|
||||||
@Deprecated
|
|
||||||
public static final int SUGGESTION_MODE_COLLAPSED = 1;
|
|
||||||
@Deprecated
|
|
||||||
public static final int SUGGESTION_MODE_EXPANDED = 2;
|
|
||||||
|
|
||||||
public static final int HEADER_MODE_DEFAULT = 0;
|
public static final int HEADER_MODE_DEFAULT = 0;
|
||||||
public static final int HEADER_MODE_SUGGESTION_EXPANDED = 1;
|
public static final int HEADER_MODE_SUGGESTION_EXPANDED = 1;
|
||||||
public static final int HEADER_MODE_FULLY_EXPANDED = 2;
|
public static final int HEADER_MODE_FULLY_EXPANDED = 2;
|
||||||
@@ -62,29 +52,20 @@ public class DashboardData {
|
|||||||
// id namespace for different type of items.
|
// id namespace for different type of items.
|
||||||
private static final int NS_SPACER = 0;
|
private static final int NS_SPACER = 0;
|
||||||
private static final int NS_ITEMS = 2000;
|
private static final int NS_ITEMS = 2000;
|
||||||
private static final int NS_CONDITION = 3000;
|
private static final int NS_SUGGESTION_CONDITION = 3000;
|
||||||
private static final int NS_SUGGESTION_CONDITION = 4000;
|
|
||||||
|
|
||||||
private final List<Item> mItems;
|
private final List<Item> mItems;
|
||||||
private final List<DashboardCategory> mCategories;
|
private final List<DashboardCategory> mCategories;
|
||||||
private final List<Condition> mConditions;
|
private final List<Condition> mConditions;
|
||||||
private final List<Tile> mSuggestions;
|
private final List<Tile> mSuggestions;
|
||||||
@Deprecated
|
|
||||||
private final int mSuggestionMode;
|
|
||||||
@Deprecated
|
|
||||||
private final Condition mExpandedCondition;
|
|
||||||
private final @HeaderMode int mSuggestionConditionMode;
|
private final @HeaderMode int mSuggestionConditionMode;
|
||||||
private int mId;
|
private int mId;
|
||||||
private boolean mCombineSuggestionAndCondition;
|
|
||||||
|
|
||||||
private DashboardData(Builder builder) {
|
private DashboardData(Builder builder) {
|
||||||
mCategories = builder.mCategories;
|
mCategories = builder.mCategories;
|
||||||
mConditions = builder.mConditions;
|
mConditions = builder.mConditions;
|
||||||
mSuggestions = builder.mSuggestions;
|
mSuggestions = builder.mSuggestions;
|
||||||
mSuggestionMode = builder.mSuggestionMode;
|
|
||||||
mExpandedCondition = builder.mExpandedCondition;
|
|
||||||
mSuggestionConditionMode = builder.mSuggestionConditionMode;
|
mSuggestionConditionMode = builder.mSuggestionConditionMode;
|
||||||
mCombineSuggestionAndCondition = builder.mCombineSuggestionAndCondition;
|
|
||||||
|
|
||||||
mItems = new ArrayList<>();
|
mItems = new ArrayList<>();
|
||||||
mId = 0;
|
mId = 0;
|
||||||
@@ -133,19 +114,10 @@ public class DashboardData {
|
|||||||
return mSuggestions;
|
return mSuggestions;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getSuggestionMode() {
|
|
||||||
return mSuggestionMode;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getSuggestionConditionMode() {
|
public int getSuggestionConditionMode() {
|
||||||
return mSuggestionConditionMode;
|
return mSuggestionConditionMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
public Condition getExpandedCondition() {
|
|
||||||
return mExpandedCondition;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Find the position of the object in mItems list, using the equals method to compare
|
* Find the position of the object in mItems list, using the equals method to compare
|
||||||
*
|
*
|
||||||
@@ -192,10 +164,10 @@ public class DashboardData {
|
|||||||
/**
|
/**
|
||||||
* Get the count of suggestions to display
|
* Get the count of suggestions to display
|
||||||
*
|
*
|
||||||
* The displayable count mainly depends on the {@link #mSuggestionMode}
|
* The displayable count mainly depends on the {@link #mSuggestionConditionMode}
|
||||||
* and the size of suggestions list.
|
* and the size of suggestions list.
|
||||||
*
|
*
|
||||||
* When in default mode, displayable count couldn't larger than
|
* When in default mode, displayable count couldn't be larger than
|
||||||
* {@link #DEFAULT_SUGGESTION_COUNT}.
|
* {@link #DEFAULT_SUGGESTION_COUNT}.
|
||||||
*
|
*
|
||||||
* When in expanded mode, display all the suggestions.
|
* When in expanded mode, display all the suggestions.
|
||||||
@@ -204,7 +176,6 @@ public class DashboardData {
|
|||||||
*/
|
*/
|
||||||
public int getDisplayableSuggestionCount() {
|
public int getDisplayableSuggestionCount() {
|
||||||
final int suggestionSize = sizeOf(mSuggestions);
|
final int suggestionSize = sizeOf(mSuggestions);
|
||||||
if (mCombineSuggestionAndCondition) {
|
|
||||||
if (mSuggestionConditionMode == HEADER_MODE_COLLAPSED) {
|
if (mSuggestionConditionMode == HEADER_MODE_COLLAPSED) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -213,25 +184,12 @@ public class DashboardData {
|
|||||||
}
|
}
|
||||||
return suggestionSize;
|
return suggestionSize;
|
||||||
}
|
}
|
||||||
if (mSuggestionMode == SUGGESTION_MODE_DEFAULT) {
|
|
||||||
return Math.min(DEFAULT_SUGGESTION_COUNT, suggestionSize);
|
|
||||||
}
|
|
||||||
if (mSuggestionMode == SUGGESTION_MODE_EXPANDED) {
|
|
||||||
return suggestionSize;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean hasMoreSuggestions() {
|
public boolean hasMoreSuggestions() {
|
||||||
if (mCombineSuggestionAndCondition) {
|
|
||||||
return mSuggestionConditionMode == HEADER_MODE_COLLAPSED && mSuggestions.size() > 0
|
return mSuggestionConditionMode == HEADER_MODE_COLLAPSED && mSuggestions.size() > 0
|
||||||
|| mSuggestionConditionMode == HEADER_MODE_DEFAULT
|
|| mSuggestionConditionMode == HEADER_MODE_DEFAULT
|
||||||
&& mSuggestions.size() > DEFAULT_SUGGESTION_COUNT;
|
&& mSuggestions.size() > DEFAULT_SUGGESTION_COUNT;
|
||||||
}
|
}
|
||||||
return mSuggestionMode == SUGGESTION_MODE_COLLAPSED
|
|
||||||
|| (mSuggestionMode == SUGGESTION_MODE_DEFAULT
|
|
||||||
&& mSuggestions.size() > DEFAULT_SUGGESTION_COUNT);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void resetCount() {
|
private void resetCount() {
|
||||||
mId = 0;
|
mId = 0;
|
||||||
@@ -251,59 +209,17 @@ public class DashboardData {
|
|||||||
*/
|
*/
|
||||||
private void countItem(Object object, int type, boolean add, int nameSpace) {
|
private void countItem(Object object, int type, boolean add, int nameSpace) {
|
||||||
if (add) {
|
if (add) {
|
||||||
if (mCombineSuggestionAndCondition) {
|
|
||||||
mItems.add(new Item(object, type, mId + nameSpace));
|
mItems.add(new Item(object, type, mId + nameSpace));
|
||||||
} else {
|
|
||||||
mItems.add(new Item(object, type, mId + nameSpace, object == mExpandedCondition));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
mId++;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A special count item method for just suggestions. Id is calculated using suggestion hash
|
|
||||||
* instead of the position of suggestion in list. This is a more stable id than countItem.
|
|
||||||
*/
|
|
||||||
private void countSuggestion(Tile tile, boolean add) {
|
|
||||||
if (add) {
|
|
||||||
mItems.add(new Item(
|
|
||||||
tile,
|
|
||||||
tile.remoteViews != null
|
|
||||||
? R.layout.suggestion_tile_card
|
|
||||||
: R.layout.suggestion_tile,
|
|
||||||
Objects.hash(tile.title),
|
|
||||||
false));
|
|
||||||
}
|
}
|
||||||
mId++;
|
mId++;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Build the mItems list using mConditions, mSuggestions, mCategories data
|
* Build the mItems list using mConditions, mSuggestions, mCategories data
|
||||||
* and mIsShowingAll, mSuggestionMode flag.
|
* and mIsShowingAll, mSuggestionConditionMode flag.
|
||||||
*/
|
*/
|
||||||
private void buildItemsData() {
|
private void buildItemsData() {
|
||||||
final boolean hasSuggestions = sizeOf(mSuggestions) > 0;
|
final boolean hasSuggestions = sizeOf(mSuggestions) > 0;
|
||||||
if (!mCombineSuggestionAndCondition) {
|
|
||||||
boolean hasConditions = false;
|
|
||||||
for (int i = 0; mConditions != null && i < mConditions.size(); i++) {
|
|
||||||
boolean shouldShow = mConditions.get(i).shouldShow();
|
|
||||||
hasConditions |= shouldShow;
|
|
||||||
countItem(mConditions.get(i), R.layout.condition_card, shouldShow, NS_CONDITION);
|
|
||||||
}
|
|
||||||
|
|
||||||
resetCount();
|
|
||||||
countItem(null, R.layout.dashboard_spacer, hasConditions && hasSuggestions, NS_SPACER);
|
|
||||||
countItem(buildSuggestionHeaderData(), R.layout.suggestion_header, hasSuggestions,
|
|
||||||
NS_SPACER);
|
|
||||||
|
|
||||||
resetCount();
|
|
||||||
if (mSuggestions != null) {
|
|
||||||
int maxSuggestions = getDisplayableSuggestionCount();
|
|
||||||
for (int i = 0; i < mSuggestions.size(); i++) {
|
|
||||||
countSuggestion(mSuggestions.get(i), i < maxSuggestions);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
final List<Condition> conditions = getConditionsToShow(mConditions);
|
final List<Condition> conditions = getConditionsToShow(mConditions);
|
||||||
final boolean hasConditions = sizeOf(conditions) > 0;
|
final boolean hasConditions = sizeOf(conditions) > 0;
|
||||||
|
|
||||||
@@ -349,7 +265,6 @@ public class DashboardData {
|
|||||||
mSuggestionConditionMode == HEADER_MODE_FULLY_EXPANDED
|
mSuggestionConditionMode == HEADER_MODE_FULLY_EXPANDED
|
||||||
|| hasSuggestions && !hasConditions && hiddenSuggestion == 0,
|
|| hasSuggestions && !hasConditions && hiddenSuggestion == 0,
|
||||||
NS_SUGGESTION_CONDITION);
|
NS_SUGGESTION_CONDITION);
|
||||||
}
|
|
||||||
|
|
||||||
resetCount();
|
resetCount();
|
||||||
for (int i = 0; mCategories != null && i < mCategories.size(); i++) {
|
for (int i = 0; mCategories != null && i < mCategories.size(); i++) {
|
||||||
@@ -367,21 +282,6 @@ public class DashboardData {
|
|||||||
return list == null ? 0 : list.size();
|
return list == null ? 0 : list.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
private SuggestionHeaderData buildSuggestionHeaderData() {
|
|
||||||
SuggestionHeaderData data;
|
|
||||||
if (mSuggestions == null) {
|
|
||||||
data = new SuggestionHeaderData();
|
|
||||||
} else {
|
|
||||||
final boolean hasMoreSuggestions = hasMoreSuggestions();
|
|
||||||
final int suggestionSize = mSuggestions.size();
|
|
||||||
final int undisplayedSuggestionCount = suggestionSize - getDisplayableSuggestionCount();
|
|
||||||
data = new SuggestionHeaderData(hasMoreSuggestions, suggestionSize,
|
|
||||||
undisplayedSuggestionCount);
|
|
||||||
}
|
|
||||||
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
private List<Condition> getConditionsToShow(List<Condition> conditions) {
|
private List<Condition> getConditionsToShow(List<Condition> conditions) {
|
||||||
if (conditions == null) {
|
if (conditions == null) {
|
||||||
return null;
|
return null;
|
||||||
@@ -411,20 +311,14 @@ public class DashboardData {
|
|||||||
/**
|
/**
|
||||||
* Builder used to build the ItemsData
|
* Builder used to build the ItemsData
|
||||||
* <p>
|
* <p>
|
||||||
* {@link #mExpandedCondition}, {@link #mSuggestionConditionMode} and {@link #mSuggestionMode}
|
* {@link #mSuggestionConditionMode} have default value while others are not.
|
||||||
* have default value while others are not.
|
|
||||||
*/
|
*/
|
||||||
public static class Builder {
|
public static class Builder {
|
||||||
@Deprecated
|
|
||||||
private int mSuggestionMode = SUGGESTION_MODE_DEFAULT;
|
|
||||||
@Deprecated
|
|
||||||
private Condition mExpandedCondition = null;
|
|
||||||
private @HeaderMode int mSuggestionConditionMode = HEADER_MODE_DEFAULT;
|
private @HeaderMode int mSuggestionConditionMode = HEADER_MODE_DEFAULT;
|
||||||
|
|
||||||
private List<DashboardCategory> mCategories;
|
private List<DashboardCategory> mCategories;
|
||||||
private List<Condition> mConditions;
|
private List<Condition> mConditions;
|
||||||
private List<Tile> mSuggestions;
|
private List<Tile> mSuggestions;
|
||||||
private boolean mCombineSuggestionAndCondition;
|
|
||||||
|
|
||||||
public Builder() {
|
public Builder() {
|
||||||
}
|
}
|
||||||
@@ -433,10 +327,7 @@ public class DashboardData {
|
|||||||
mCategories = dashboardData.mCategories;
|
mCategories = dashboardData.mCategories;
|
||||||
mConditions = dashboardData.mConditions;
|
mConditions = dashboardData.mConditions;
|
||||||
mSuggestions = dashboardData.mSuggestions;
|
mSuggestions = dashboardData.mSuggestions;
|
||||||
mSuggestionMode = dashboardData.mSuggestionMode;
|
|
||||||
mExpandedCondition = dashboardData.mExpandedCondition;
|
|
||||||
mSuggestionConditionMode = dashboardData.mSuggestionConditionMode;
|
mSuggestionConditionMode = dashboardData.mSuggestionConditionMode;
|
||||||
mCombineSuggestionAndCondition = dashboardData.mCombineSuggestionAndCondition;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Builder setCategories(List<DashboardCategory> categories) {
|
public Builder setCategories(List<DashboardCategory> categories) {
|
||||||
@@ -454,27 +345,11 @@ public class DashboardData {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Builder setSuggestionMode(int suggestionMode) {
|
|
||||||
this.mSuggestionMode = suggestionMode;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
public Builder setExpandedCondition(Condition expandedCondition) {
|
|
||||||
this.mExpandedCondition = expandedCondition;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Builder setSuggestionConditionMode(@HeaderMode int mode) {
|
public Builder setSuggestionConditionMode(@HeaderMode int mode) {
|
||||||
this.mSuggestionConditionMode = mode;
|
this.mSuggestionConditionMode = mode;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Builder setCombineSuggestionAndCondition(boolean combine) {
|
|
||||||
this.mCombineSuggestionAndCondition = combine;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public DashboardData build() {
|
public DashboardData build() {
|
||||||
return new DashboardData(this);
|
return new DashboardData(this);
|
||||||
}
|
}
|
||||||
@@ -513,16 +388,6 @@ public class DashboardData {
|
|||||||
return mOldItems.get(oldItemPosition).equals(mNewItems.get(newItemPosition));
|
return mOldItems.get(oldItemPosition).equals(mNewItems.get(newItemPosition));
|
||||||
}
|
}
|
||||||
|
|
||||||
// not needed in combined UI
|
|
||||||
@Deprecated
|
|
||||||
@Nullable
|
|
||||||
@Override
|
|
||||||
public Object getChangePayload(int oldItemPosition, int newItemPosition) {
|
|
||||||
if (mOldItems.get(oldItemPosition).type == Item.TYPE_CONDITION_CARD) {
|
|
||||||
return "condition"; // return anything but null to mark the payload
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -532,24 +397,17 @@ public class DashboardData {
|
|||||||
// valid types in field type
|
// valid types in field type
|
||||||
private static final int TYPE_DASHBOARD_CATEGORY = R.layout.dashboard_category;
|
private static final int TYPE_DASHBOARD_CATEGORY = R.layout.dashboard_category;
|
||||||
private static final int TYPE_DASHBOARD_TILE = R.layout.dashboard_tile;
|
private static final int TYPE_DASHBOARD_TILE = R.layout.dashboard_tile;
|
||||||
@Deprecated
|
|
||||||
private static final int TYPE_SUGGESTION_HEADER = R.layout.suggestion_header;
|
|
||||||
@Deprecated
|
|
||||||
private static final int TYPE_SUGGESTION_TILE = R.layout.suggestion_tile;
|
|
||||||
private static final int TYPE_SUGGESTION_CONDITION_CONTAINER =
|
private static final int TYPE_SUGGESTION_CONDITION_CONTAINER =
|
||||||
R.layout.suggestion_condition_container;
|
R.layout.suggestion_condition_container;
|
||||||
private static final int TYPE_SUGGESTION_CONDITION_HEADER =
|
private static final int TYPE_SUGGESTION_CONDITION_HEADER =
|
||||||
R.layout.suggestion_condition_header;
|
R.layout.suggestion_condition_header;
|
||||||
@Deprecated
|
|
||||||
private static final int TYPE_CONDITION_CARD = R.layout.condition_card;
|
|
||||||
private static final int TYPE_SUGGESTION_CONDITION_FOOTER =
|
private static final int TYPE_SUGGESTION_CONDITION_FOOTER =
|
||||||
R.layout.suggestion_condition_footer;
|
R.layout.suggestion_condition_footer;
|
||||||
private static final int TYPE_DASHBOARD_SPACER = R.layout.dashboard_spacer;
|
private static final int TYPE_DASHBOARD_SPACER = R.layout.dashboard_spacer;
|
||||||
|
|
||||||
@IntDef({TYPE_DASHBOARD_CATEGORY, TYPE_DASHBOARD_TILE, TYPE_SUGGESTION_HEADER,
|
@IntDef({TYPE_DASHBOARD_CATEGORY, TYPE_DASHBOARD_TILE, TYPE_SUGGESTION_CONDITION_CONTAINER,
|
||||||
TYPE_SUGGESTION_TILE, TYPE_SUGGESTION_CONDITION_CONTAINER,
|
TYPE_SUGGESTION_CONDITION_HEADER, TYPE_SUGGESTION_CONDITION_FOOTER,
|
||||||
TYPE_SUGGESTION_CONDITION_HEADER, TYPE_CONDITION_CARD,
|
TYPE_DASHBOARD_SPACER})
|
||||||
TYPE_SUGGESTION_CONDITION_FOOTER, TYPE_DASHBOARD_SPACER})
|
|
||||||
@Retention(RetentionPolicy.SOURCE)
|
@Retention(RetentionPolicy.SOURCE)
|
||||||
public @interface ItemTypes{}
|
public @interface ItemTypes{}
|
||||||
|
|
||||||
@@ -571,23 +429,10 @@ public class DashboardData {
|
|||||||
*/
|
*/
|
||||||
public final int id;
|
public final int id;
|
||||||
|
|
||||||
/**
|
public Item(Object entity, @ItemTypes int type, int id) {
|
||||||
* To store whether the condition is expanded, useless when {@link #type} is not
|
|
||||||
* {@link #TYPE_CONDITION_CARD}
|
|
||||||
*/
|
|
||||||
@Deprecated
|
|
||||||
public final boolean conditionExpanded;
|
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
public Item(Object entity, @ItemTypes int type, int id, boolean conditionExpanded) {
|
|
||||||
this.entity = entity;
|
this.entity = entity;
|
||||||
this.type = type;
|
this.type = type;
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.conditionExpanded = conditionExpanded;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Item(Object entity, @ItemTypes int type, int id) {
|
|
||||||
this(entity, type, id, false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -622,12 +467,6 @@ public class DashboardData {
|
|||||||
// Only check title and summary for dashboard tile
|
// Only check title and summary for dashboard tile
|
||||||
return TextUtils.equals(localTile.title, targetTile.title)
|
return TextUtils.equals(localTile.title, targetTile.title)
|
||||||
&& TextUtils.equals(localTile.summary, targetTile.summary);
|
&& TextUtils.equals(localTile.summary, targetTile.summary);
|
||||||
case TYPE_CONDITION_CARD:
|
|
||||||
// First check conditionExpanded for quick return
|
|
||||||
if (conditionExpanded != targetItem.conditionExpanded) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// After that, go to default to do final check
|
|
||||||
default:
|
default:
|
||||||
return entity == null ? targetItem.entity == null
|
return entity == null ? targetItem.entity == null
|
||||||
: entity.equals(targetItem.entity);
|
: entity.equals(targetItem.entity);
|
||||||
@@ -635,46 +474,6 @@ public class DashboardData {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* This class contains the data needed to build the header. The data can also be
|
|
||||||
* used to check the diff in DiffUtil.Callback
|
|
||||||
*/
|
|
||||||
public static class SuggestionHeaderData {
|
|
||||||
public final boolean hasMoreSuggestions;
|
|
||||||
public final int suggestionSize;
|
|
||||||
public final int undisplayedSuggestionCount;
|
|
||||||
|
|
||||||
public SuggestionHeaderData(boolean moreSuggestions, int suggestionSize, int
|
|
||||||
undisplayedSuggestionCount) {
|
|
||||||
this.hasMoreSuggestions = moreSuggestions;
|
|
||||||
this.suggestionSize = suggestionSize;
|
|
||||||
this.undisplayedSuggestionCount = undisplayedSuggestionCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
public SuggestionHeaderData() {
|
|
||||||
hasMoreSuggestions = false;
|
|
||||||
suggestionSize = 0;
|
|
||||||
undisplayedSuggestionCount = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object obj) {
|
|
||||||
if (this == obj) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(obj instanceof SuggestionHeaderData)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
SuggestionHeaderData targetData = (SuggestionHeaderData) obj;
|
|
||||||
|
|
||||||
return hasMoreSuggestions == targetData.hasMoreSuggestions
|
|
||||||
&& suggestionSize == targetData.suggestionSize
|
|
||||||
&& undisplayedSuggestionCount == targetData.undisplayedSuggestionCount;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class contains the data needed to build the suggestion/condition header. The data can
|
* This class contains the data needed to build the suggestion/condition header. The data can
|
||||||
* also be used to check the diff in DiffUtil.Callback
|
* also be used to check the diff in DiffUtil.Callback
|
||||||
|
@@ -43,21 +43,16 @@ public class DashboardDecorator extends RecyclerView.ItemDecoration {
|
|||||||
for (int i = 1; i < childCount; i++) {
|
for (int i = 1; i < childCount; i++) {
|
||||||
final View child = parent.getChildAt(i);
|
final View child = parent.getChildAt(i);
|
||||||
final ViewHolder holder = parent.getChildViewHolder(child);
|
final ViewHolder holder = parent.getChildViewHolder(child);
|
||||||
if (holder.getItemViewType() == R.layout.dashboard_category) {
|
if (holder.getItemViewType() == R.layout.dashboard_category
|
||||||
if (parent.getChildViewHolder(parent.getChildAt(i - 1)).getItemViewType()
|
&& parent.getChildViewHolder(parent.getChildAt(i - 1)).getItemViewType()
|
||||||
!= R.layout.dashboard_tile) {
|
== R.layout.dashboard_tile) {
|
||||||
continue;
|
|
||||||
}
|
|
||||||
} else if (holder.getItemViewType() != R.layout.condition_card) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
int top = getChildTop(child);
|
int top = getChildTop(child);
|
||||||
mDivider.setBounds(child.getLeft(), top, child.getRight(),
|
mDivider.setBounds(child.getLeft(), top, child.getRight(),
|
||||||
top + mDivider.getIntrinsicHeight());
|
top + mDivider.getIntrinsicHeight());
|
||||||
mDivider.draw(c);
|
mDivider.draw(c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private int getChildTop(View child) {
|
private int getChildTop(View child) {
|
||||||
final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child
|
final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child
|
||||||
|
@@ -95,9 +95,4 @@ public interface DashboardFeatureProvider {
|
|||||||
*/
|
*/
|
||||||
void openTileIntent(Activity activity, Tile tile);
|
void openTileIntent(Activity activity, Tile tile);
|
||||||
|
|
||||||
/**
|
|
||||||
* Whether or not we should use new UI that combines the settings suggestions and conditions.
|
|
||||||
*/
|
|
||||||
boolean combineSuggestionAndCondition();
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -206,11 +206,6 @@ public class DashboardFeatureProviderImpl implements DashboardFeatureProvider {
|
|||||||
launchIntentOrSelectProfile(activity, tile, intent, MetricsEvent.DASHBOARD_SUMMARY);
|
launchIntentOrSelectProfile(activity, tile, intent, MetricsEvent.DASHBOARD_SUMMARY);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean combineSuggestionAndCondition() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void launchIntentOrSelectProfile(Activity activity, Tile tile, Intent intent,
|
private void launchIntentOrSelectProfile(Activity activity, Tile tile, Intent intent,
|
||||||
int sourceMetricCategory) {
|
int sourceMetricCategory) {
|
||||||
if (!isIntentResolvable(intent)) {
|
if (!isIntentResolvable(intent)) {
|
||||||
|
@@ -32,7 +32,6 @@ import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
|||||||
import com.android.settings.R;
|
import com.android.settings.R;
|
||||||
import com.android.settings.core.InstrumentedFragment;
|
import com.android.settings.core.InstrumentedFragment;
|
||||||
import com.android.settings.dashboard.conditional.Condition;
|
import com.android.settings.dashboard.conditional.Condition;
|
||||||
import com.android.settings.dashboard.conditional.ConditionAdapterUtils;
|
|
||||||
import com.android.settings.dashboard.conditional.ConditionManager;
|
import com.android.settings.dashboard.conditional.ConditionManager;
|
||||||
import com.android.settings.dashboard.conditional.ConditionManager.ConditionListener;
|
import com.android.settings.dashboard.conditional.ConditionManager.ConditionListener;
|
||||||
import com.android.settings.dashboard.conditional.FocusRecyclerView;
|
import com.android.settings.dashboard.conditional.FocusRecyclerView;
|
||||||
@@ -75,7 +74,6 @@ public class DashboardSummary extends InstrumentedFragment
|
|||||||
private DashboardFeatureProvider mDashboardFeatureProvider;
|
private DashboardFeatureProvider mDashboardFeatureProvider;
|
||||||
private SuggestionFeatureProvider mSuggestionFeatureProvider;
|
private SuggestionFeatureProvider mSuggestionFeatureProvider;
|
||||||
private boolean isOnCategoriesChangedCalled;
|
private boolean isOnCategoriesChangedCalled;
|
||||||
private SuggestionDismissController mSuggestionDismissHandler;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getMetricsCategory() {
|
public int getMetricsCategory() {
|
||||||
@@ -198,11 +196,6 @@ public class DashboardSummary extends InstrumentedFragment
|
|||||||
mAdapter = new DashboardAdapter(getContext(), bundle, mConditionManager.getConditions(),
|
mAdapter = new DashboardAdapter(getContext(), bundle, mConditionManager.getConditions(),
|
||||||
mSuggestionParser, this /* SuggestionDismissController.Callback */);
|
mSuggestionParser, this /* SuggestionDismissController.Callback */);
|
||||||
mDashboard.setAdapter(mAdapter);
|
mDashboard.setAdapter(mAdapter);
|
||||||
if (!mDashboardFeatureProvider.combineSuggestionAndCondition()) {
|
|
||||||
mSuggestionDismissHandler = new SuggestionDismissController(
|
|
||||||
getContext(), mDashboard, mSuggestionParser, this);
|
|
||||||
ConditionAdapterUtils.addDismiss(mDashboard);
|
|
||||||
}
|
|
||||||
mDashboard.setItemAnimator(new DashboardItemAnimator());
|
mDashboard.setItemAnimator(new DashboardItemAnimator());
|
||||||
mSummaryLoader.setSummaryConsumer(mAdapter);
|
mSummaryLoader.setSummaryConsumer(mAdapter);
|
||||||
if (DEBUG_TIMING) {
|
if (DEBUG_TIMING) {
|
||||||
|
@@ -17,16 +17,23 @@ package com.android.settings.dashboard.conditional;
|
|||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.support.v7.widget.RecyclerView;
|
import android.support.v7.widget.RecyclerView;
|
||||||
|
import android.support.v7.widget.helper.ItemTouchHelper;
|
||||||
|
import android.util.Log;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.Button;
|
||||||
|
|
||||||
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
||||||
import com.android.settings.R;
|
import com.android.settings.R;
|
||||||
import com.android.settings.core.instrumentation.MetricsFeatureProvider;
|
import com.android.settings.core.instrumentation.MetricsFeatureProvider;
|
||||||
|
import com.android.settings.dashboard.DashboardAdapter;
|
||||||
import com.android.settings.dashboard.DashboardAdapter.DashboardItemHolder;
|
import com.android.settings.dashboard.DashboardAdapter.DashboardItemHolder;
|
||||||
import com.android.settings.dashboard.DashboardData;
|
import com.android.settings.dashboard.DashboardData;
|
||||||
import com.android.settings.dashboard.DashboardData.HeaderMode;
|
import com.android.settings.dashboard.DashboardData.HeaderMode;
|
||||||
import com.android.settings.overlay.FeatureFactory;
|
import com.android.settings.overlay.FeatureFactory;
|
||||||
|
import com.android.settingslib.WirelessUtils;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
@@ -77,8 +84,7 @@ public class ConditionAdapter extends RecyclerView.Adapter<DashboardItemHolder>
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onBindViewHolder(DashboardItemHolder holder, int position) {
|
public void onBindViewHolder(DashboardItemHolder holder, int position) {
|
||||||
// TODO: merge methods from ConditionAdapterUtils into this class
|
bindViews(mConditions.get(position), holder,
|
||||||
ConditionAdapterUtils.bindViews(mConditions.get(position), holder,
|
|
||||||
position == mConditions.size() - 1, mConditionClickListener);
|
position == mConditions.size() - 1, mConditionClickListener);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -100,4 +106,78 @@ public class ConditionAdapter extends RecyclerView.Adapter<DashboardItemHolder>
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void addDismissHandling(final RecyclerView recyclerView) {
|
||||||
|
ItemTouchHelper.SimpleCallback callback = new ItemTouchHelper.SimpleCallback(0,
|
||||||
|
ItemTouchHelper.START | ItemTouchHelper.END) {
|
||||||
|
@Override
|
||||||
|
public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder,
|
||||||
|
RecyclerView.ViewHolder target) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getSwipeDirs(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
|
||||||
|
return viewHolder.getItemViewType() == R.layout.condition_tile_new_ui
|
||||||
|
? super.getSwipeDirs(recyclerView, viewHolder) : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
|
||||||
|
Object item = getItem(viewHolder.getItemId());
|
||||||
|
((Condition) item).silence();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
ItemTouchHelper itemTouchHelper = new ItemTouchHelper(callback);
|
||||||
|
itemTouchHelper.attachToRecyclerView(recyclerView);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void bindViews(final Condition condition,
|
||||||
|
DashboardAdapter.DashboardItemHolder view, boolean isLastItem,
|
||||||
|
View.OnClickListener onClickListener) {
|
||||||
|
if (condition instanceof AirplaneModeCondition) {
|
||||||
|
Log.d(TAG, "Airplane mode condition has been bound with "
|
||||||
|
+ "isActive=" + condition.isActive() + ". Airplane mode is currently " +
|
||||||
|
WirelessUtils.isAirplaneModeOn(condition.mManager.getContext()));
|
||||||
|
}
|
||||||
|
View card = view.itemView.findViewById(R.id.content);
|
||||||
|
card.setTag(condition);
|
||||||
|
card.setOnClickListener(onClickListener);
|
||||||
|
view.icon.setImageIcon(condition.getIcon());
|
||||||
|
view.title.setText(condition.getTitle());
|
||||||
|
|
||||||
|
CharSequence[] actions = condition.getActions();
|
||||||
|
final boolean hasButtons = actions.length > 0;
|
||||||
|
setViewVisibility(view.itemView, R.id.buttonBar, hasButtons);
|
||||||
|
|
||||||
|
view.summary.setText(condition.getSummary());
|
||||||
|
for (int i = 0; i < 2; i++) {
|
||||||
|
Button button = (Button) view.itemView.findViewById(i == 0
|
||||||
|
? R.id.first_action : R.id.second_action);
|
||||||
|
if (actions.length > i) {
|
||||||
|
button.setVisibility(View.VISIBLE);
|
||||||
|
button.setText(actions[i]);
|
||||||
|
final int index = i;
|
||||||
|
button.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
Context context = v.getContext();
|
||||||
|
FeatureFactory.getFactory(context).getMetricsFeatureProvider()
|
||||||
|
.action(context, MetricsEvent.ACTION_SETTINGS_CONDITION_BUTTON,
|
||||||
|
condition.getMetricsConstant());
|
||||||
|
condition.onActionClick(index);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
button.setVisibility(View.GONE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
setViewVisibility(view.itemView, R.id.divider, !isLastItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setViewVisibility(View containerView, int viewId, boolean visible) {
|
||||||
|
View view = containerView.findViewById(viewId);
|
||||||
|
if (view != null) {
|
||||||
|
view.setVisibility(visible ? View.VISIBLE : View.GONE);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,179 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2015 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.dashboard.conditional;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.support.v7.widget.RecyclerView;
|
|
||||||
import android.support.v7.widget.helper.ItemTouchHelper;
|
|
||||||
import android.util.Log;
|
|
||||||
import android.view.View;
|
|
||||||
import android.widget.Button;
|
|
||||||
import android.widget.ImageView;
|
|
||||||
|
|
||||||
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
|
||||||
import com.android.settings.R;
|
|
||||||
import com.android.settings.dashboard.DashboardAdapter;
|
|
||||||
import com.android.settings.overlay.FeatureFactory;
|
|
||||||
import com.android.settingslib.WirelessUtils;
|
|
||||||
|
|
||||||
public class ConditionAdapterUtils {
|
|
||||||
private static final String TAG = "ConditionAdapterUtils";
|
|
||||||
|
|
||||||
public static void addDismiss(final RecyclerView recyclerView) {
|
|
||||||
ItemTouchHelper.SimpleCallback callback = new ItemTouchHelper.SimpleCallback(0,
|
|
||||||
ItemTouchHelper.START | ItemTouchHelper.END) {
|
|
||||||
@Override
|
|
||||||
public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder,
|
|
||||||
RecyclerView.ViewHolder target) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getSwipeDirs(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
|
|
||||||
return viewHolder.getItemViewType() == R.layout.condition_card
|
|
||||||
|| viewHolder.getItemViewType() == R.layout.condition_tile_new_ui
|
|
||||||
? super.getSwipeDirs(recyclerView, viewHolder) : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
|
|
||||||
Object item;
|
|
||||||
if (viewHolder.getItemViewType() == R.layout.condition_card) {
|
|
||||||
DashboardAdapter adapter = (DashboardAdapter) recyclerView.getAdapter();
|
|
||||||
item = adapter.getItem(viewHolder.getItemId());
|
|
||||||
} else {
|
|
||||||
ConditionAdapter adapter = (ConditionAdapter) recyclerView.getAdapter();
|
|
||||||
item = adapter.getItem(viewHolder.getItemId());
|
|
||||||
}
|
|
||||||
((Condition) item).silence();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
ItemTouchHelper itemTouchHelper = new ItemTouchHelper(callback);
|
|
||||||
itemTouchHelper.attachToRecyclerView(recyclerView);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
public static void bindViews(final Condition condition,
|
|
||||||
DashboardAdapter.DashboardItemHolder view, boolean isExpanded,
|
|
||||||
View.OnClickListener onClickListener, View.OnClickListener onExpandListener) {
|
|
||||||
if (condition instanceof AirplaneModeCondition) {
|
|
||||||
Log.d(TAG, "Airplane mode condition has been bound with "
|
|
||||||
+ "isActive=" + condition.isActive() + ". Airplane mode is currently " +
|
|
||||||
WirelessUtils.isAirplaneModeOn(condition.mManager.getContext()));
|
|
||||||
}
|
|
||||||
View card = view.itemView.findViewById(R.id.content);
|
|
||||||
card.setTag(condition);
|
|
||||||
card.setOnClickListener(onClickListener);
|
|
||||||
view.icon.setImageIcon(condition.getIcon());
|
|
||||||
view.title.setText(condition.getTitle());
|
|
||||||
final View collapsedGroup = view.itemView.findViewById(R.id.collapsed_group);
|
|
||||||
collapsedGroup.setTag(condition);
|
|
||||||
final ImageView expand = (ImageView) view.itemView.findViewById(R.id.expand_indicator);
|
|
||||||
expand.setImageResource(isExpanded ? R.drawable.ic_expand_less : R.drawable.ic_expand_more);
|
|
||||||
expand.setContentDescription(expand.getContext().getString(isExpanded
|
|
||||||
? R.string.condition_expand_hide : R.string.condition_expand_show));
|
|
||||||
collapsedGroup.setOnClickListener(onExpandListener);
|
|
||||||
|
|
||||||
View detailGroup = view.itemView.findViewById(R.id.detail_group);
|
|
||||||
CharSequence[] actions = condition.getActions();
|
|
||||||
if (isExpanded != (detailGroup.getVisibility() == View.VISIBLE)) {
|
|
||||||
if (isExpanded) {
|
|
||||||
final boolean hasButtons = actions.length > 0;
|
|
||||||
setViewVisibility(detailGroup, R.id.divider, hasButtons);
|
|
||||||
setViewVisibility(detailGroup, R.id.buttonBar, hasButtons);
|
|
||||||
|
|
||||||
detailGroup.setVisibility(View.VISIBLE);
|
|
||||||
} else {
|
|
||||||
detailGroup.setVisibility(View.GONE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isExpanded) {
|
|
||||||
view.summary.setText(condition.getSummary());
|
|
||||||
for (int i = 0; i < 2; i++) {
|
|
||||||
Button button = (Button) detailGroup.findViewById(i == 0
|
|
||||||
? R.id.first_action : R.id.second_action);
|
|
||||||
if (actions.length > i) {
|
|
||||||
button.setVisibility(View.VISIBLE);
|
|
||||||
button.setText(actions[i]);
|
|
||||||
final int index = i;
|
|
||||||
button.setOnClickListener(new View.OnClickListener() {
|
|
||||||
@Override
|
|
||||||
public void onClick(View v) {
|
|
||||||
Context context = v.getContext();
|
|
||||||
FeatureFactory.getFactory(context).getMetricsFeatureProvider()
|
|
||||||
.action(context, MetricsEvent.ACTION_SETTINGS_CONDITION_BUTTON,
|
|
||||||
condition.getMetricsConstant());
|
|
||||||
condition.onActionClick(index);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
button.setVisibility(View.GONE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void bindViews(final Condition condition,
|
|
||||||
DashboardAdapter.DashboardItemHolder view, boolean isLastItem,
|
|
||||||
View.OnClickListener onClickListener) {
|
|
||||||
if (condition instanceof AirplaneModeCondition) {
|
|
||||||
Log.d(TAG, "Airplane mode condition has been bound with "
|
|
||||||
+ "isActive=" + condition.isActive() + ". Airplane mode is currently " +
|
|
||||||
WirelessUtils.isAirplaneModeOn(condition.mManager.getContext()));
|
|
||||||
}
|
|
||||||
View card = view.itemView.findViewById(R.id.content);
|
|
||||||
card.setTag(condition);
|
|
||||||
card.setOnClickListener(onClickListener);
|
|
||||||
view.icon.setImageIcon(condition.getIcon());
|
|
||||||
view.title.setText(condition.getTitle());
|
|
||||||
|
|
||||||
CharSequence[] actions = condition.getActions();
|
|
||||||
final boolean hasButtons = actions.length > 0;
|
|
||||||
setViewVisibility(view.itemView, R.id.buttonBar, hasButtons);
|
|
||||||
|
|
||||||
view.summary.setText(condition.getSummary());
|
|
||||||
for (int i = 0; i < 2; i++) {
|
|
||||||
Button button = (Button) view.itemView.findViewById(i == 0
|
|
||||||
? R.id.first_action : R.id.second_action);
|
|
||||||
if (actions.length > i) {
|
|
||||||
button.setVisibility(View.VISIBLE);
|
|
||||||
button.setText(actions[i]);
|
|
||||||
final int index = i;
|
|
||||||
button.setOnClickListener(new View.OnClickListener() {
|
|
||||||
@Override
|
|
||||||
public void onClick(View v) {
|
|
||||||
Context context = v.getContext();
|
|
||||||
FeatureFactory.getFactory(context).getMetricsFeatureProvider()
|
|
||||||
.action(context, MetricsEvent.ACTION_SETTINGS_CONDITION_BUTTON,
|
|
||||||
condition.getMetricsConstant());
|
|
||||||
condition.onActionClick(index);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
button.setVisibility(View.GONE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
setViewVisibility(view.itemView, R.id.divider, !isLastItem);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void setViewVisibility(View containerView, int viewId, boolean visible) {
|
|
||||||
View view = containerView.findViewById(viewId);
|
|
||||||
if (view != null) {
|
|
||||||
view.setVisibility(visible ? View.VISIBLE : View.GONE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -23,7 +23,6 @@ import android.view.View;
|
|||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
||||||
import com.android.settings.R;
|
import com.android.settings.R;
|
||||||
import com.android.settings.R.layout;
|
|
||||||
import com.android.settings.SettingsActivity;
|
import com.android.settings.SettingsActivity;
|
||||||
import com.android.settings.core.instrumentation.MetricsFeatureProvider;
|
import com.android.settings.core.instrumentation.MetricsFeatureProvider;
|
||||||
import com.android.settings.dashboard.DashboardAdapter.DashboardItemHolder;
|
import com.android.settings.dashboard.DashboardAdapter.DashboardItemHolder;
|
||||||
@@ -114,7 +113,10 @@ public class SuggestionAdapter extends RecyclerView.Adapter<DashboardItemHolder>
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getItemViewType(int position) {
|
public int getItemViewType(int position) {
|
||||||
return layout.suggestion_tile_new_ui;
|
Tile suggestion = getSuggestion(position);
|
||||||
|
return suggestion.remoteViews != null
|
||||||
|
? R.layout.suggestion_tile_card
|
||||||
|
: R.layout.suggestion_tile_new_ui;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@@ -66,8 +66,7 @@ public class SuggestionDismissController extends ItemTouchHelper.SimpleCallback
|
|||||||
@Override
|
@Override
|
||||||
public int getSwipeDirs(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
|
public int getSwipeDirs(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
|
||||||
final int layoutId = viewHolder.getItemViewType();
|
final int layoutId = viewHolder.getItemViewType();
|
||||||
if (layoutId == R.layout.suggestion_tile
|
if (layoutId == R.layout.suggestion_tile_new_ui
|
||||||
|| layoutId == R.layout.suggestion_tile_new_ui
|
|
||||||
|| layoutId == R.layout.suggestion_tile_card) {
|
|| layoutId == R.layout.suggestion_tile_card) {
|
||||||
// Only return swipe direction for suggestion tiles. All other types are not swipeable.
|
// Only return swipe direction for suggestion tiles. All other types are not swipeable.
|
||||||
return super.getSwipeDirs(recyclerView, viewHolder);
|
return super.getSwipeDirs(recyclerView, viewHolder);
|
||||||
|
@@ -1,74 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2016 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.conditional;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.view.LayoutInflater;
|
|
||||||
import android.view.View;
|
|
||||||
import android.widget.LinearLayout;
|
|
||||||
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
|
||||||
import com.android.settings.TestConfig;
|
|
||||||
import com.android.settings.dashboard.DashboardAdapter;
|
|
||||||
import com.android.settings.dashboard.conditional.Condition;
|
|
||||||
import com.android.settings.dashboard.conditional.ConditionAdapterUtils;
|
|
||||||
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;
|
|
||||||
import com.android.settings.R;
|
|
||||||
|
|
||||||
import static com.google.common.truth.Truth.assertThat;
|
|
||||||
import static org.mockito.Mockito.when;
|
|
||||||
|
|
||||||
// Not needed in new UI as the view is always expanded
|
|
||||||
@Deprecated
|
|
||||||
@RunWith(SettingsRobolectricTestRunner.class)
|
|
||||||
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
|
|
||||||
public class ConditionAdapterUtilsTest{
|
|
||||||
@Mock
|
|
||||||
private Condition mCondition;
|
|
||||||
private DashboardAdapter.DashboardItemHolder mViewHolder;
|
|
||||||
private Context mContext;
|
|
||||||
|
|
||||||
@Before
|
|
||||||
public void setUp() {
|
|
||||||
MockitoAnnotations.initMocks(this);
|
|
||||||
mContext = RuntimeEnvironment.application;
|
|
||||||
final CharSequence[] actions = new CharSequence[2];
|
|
||||||
when(mCondition.getActions()).thenReturn(actions);
|
|
||||||
|
|
||||||
final View view = LayoutInflater.from(mContext).inflate(R.layout.condition_card, new
|
|
||||||
LinearLayout(mContext), true);
|
|
||||||
mViewHolder = new DashboardAdapter.DashboardItemHolder(view);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testBindView_isExpanded_returnVisible() {
|
|
||||||
ConditionAdapterUtils.bindViews(mCondition, mViewHolder, true, null, null);
|
|
||||||
assertThat(mViewHolder.itemView.findViewById(R.id.detail_group).getVisibility())
|
|
||||||
.isEqualTo(View.VISIBLE);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testBindView_isNotExpanded_returnGone() {
|
|
||||||
ConditionAdapterUtils.bindViews(mCondition, mViewHolder, false, null, null);
|
|
||||||
assertThat(mViewHolder.itemView.findViewById(R.id.detail_group).getVisibility())
|
|
||||||
.isEqualTo(View.GONE);
|
|
||||||
}
|
|
||||||
}
|
|
@@ -38,15 +38,10 @@ import android.graphics.drawable.ColorDrawable;
|
|||||||
import android.graphics.drawable.Icon;
|
import android.graphics.drawable.Icon;
|
||||||
import android.support.v7.widget.RecyclerView;
|
import android.support.v7.widget.RecyclerView;
|
||||||
import android.util.DisplayMetrics;
|
import android.util.DisplayMetrics;
|
||||||
import android.view.ContextThemeWrapper;
|
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
|
||||||
import android.widget.Button;
|
|
||||||
import android.widget.FrameLayout;
|
|
||||||
import android.widget.LinearLayout;
|
import android.widget.LinearLayout;
|
||||||
import android.widget.RemoteViews;
|
import android.widget.RelativeLayout;
|
||||||
import android.widget.TextView;
|
|
||||||
|
|
||||||
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
||||||
import com.android.settings.R;
|
import com.android.settings.R;
|
||||||
@@ -71,7 +66,6 @@ import org.mockito.Mock;
|
|||||||
import org.mockito.MockitoAnnotations;
|
import org.mockito.MockitoAnnotations;
|
||||||
import org.robolectric.RuntimeEnvironment;
|
import org.robolectric.RuntimeEnvironment;
|
||||||
import org.robolectric.annotation.Config;
|
import org.robolectric.annotation.Config;
|
||||||
import org.robolectric.shadows.ShadowApplication;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
@@ -101,8 +95,8 @@ public class DashboardAdapterTest {
|
|||||||
private ArgumentCaptor<String> mActionPackageCaptor = ArgumentCaptor.forClass(String.class);
|
private ArgumentCaptor<String> mActionPackageCaptor = ArgumentCaptor.forClass(String.class);
|
||||||
private FakeFeatureFactory mFactory;
|
private FakeFeatureFactory mFactory;
|
||||||
private DashboardAdapter mDashboardAdapter;
|
private DashboardAdapter mDashboardAdapter;
|
||||||
private DashboardAdapter.DashboardItemHolder mSuggestionHolder;
|
private DashboardAdapter.SuggestionAndConditionHeaderHolder mSuggestionHolder;
|
||||||
private DashboardData.SuggestionHeaderData mSuggestionHeaderData;
|
private DashboardData.SuggestionConditionHeaderData mSuggestionHeaderData;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() {
|
public void setUp() {
|
||||||
@@ -121,8 +115,10 @@ public class DashboardAdapterTest {
|
|||||||
when(mResources.getQuantityString(any(int.class), any(int.class), any()))
|
when(mResources.getQuantityString(any(int.class), any(int.class), any()))
|
||||||
.thenReturn("");
|
.thenReturn("");
|
||||||
|
|
||||||
mDashboardAdapter = new DashboardAdapter(mContext, null, null);
|
List<Condition> conditions = new ArrayList<>();
|
||||||
mSuggestionHeaderData = new DashboardData.SuggestionHeaderData(true, 1, 0);
|
conditions.add(mCondition);
|
||||||
|
mDashboardAdapter = new DashboardAdapter(mContext, null, conditions, null, null);
|
||||||
|
mSuggestionHeaderData = new DashboardData.SuggestionConditionHeaderData(conditions, 1);
|
||||||
when(mView.getTag()).thenReturn(mCondition);
|
when(mView.getTag()).thenReturn(mCondition);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -161,8 +157,7 @@ public class DashboardAdapterTest {
|
|||||||
@Test
|
@Test
|
||||||
public void testSuggestionsLogs_Expanded() {
|
public void testSuggestionsLogs_Expanded() {
|
||||||
setupSuggestions(makeSuggestions("pkg1", "pkg2", "pkg3"));
|
setupSuggestions(makeSuggestions("pkg1", "pkg2", "pkg3"));
|
||||||
mDashboardAdapter.onBindSuggestionHeader(
|
mDashboardAdapter.onBindSuggestionConditionHeader(mSuggestionHolder, mSuggestionHeaderData);
|
||||||
mSuggestionHolder, mSuggestionHeaderData);
|
|
||||||
mSuggestionHolder.itemView.callOnClick();
|
mSuggestionHolder.itemView.callOnClick();
|
||||||
verify(mFactory.metricsFeatureProvider, times(3)).action(
|
verify(mFactory.metricsFeatureProvider, times(3)).action(
|
||||||
any(Context.class), mActionCategoryCaptor.capture(),
|
any(Context.class), mActionCategoryCaptor.capture(),
|
||||||
@@ -180,8 +175,7 @@ public class DashboardAdapterTest {
|
|||||||
@Test
|
@Test
|
||||||
public void testSuggestionsLogs_ExpandedAndPaused() {
|
public void testSuggestionsLogs_ExpandedAndPaused() {
|
||||||
setupSuggestions(makeSuggestions("pkg1", "pkg2", "pkg3"));
|
setupSuggestions(makeSuggestions("pkg1", "pkg2", "pkg3"));
|
||||||
mDashboardAdapter.onBindSuggestionHeader(
|
mDashboardAdapter.onBindSuggestionConditionHeader(mSuggestionHolder, mSuggestionHeaderData);
|
||||||
mSuggestionHolder, mSuggestionHeaderData);
|
|
||||||
mSuggestionHolder.itemView.callOnClick();
|
mSuggestionHolder.itemView.callOnClick();
|
||||||
mDashboardAdapter.onPause();
|
mDashboardAdapter.onPause();
|
||||||
verify(mFactory.metricsFeatureProvider, times(6)).action(
|
verify(mFactory.metricsFeatureProvider, times(6)).action(
|
||||||
@@ -204,8 +198,7 @@ public class DashboardAdapterTest {
|
|||||||
public void testSuggestionsLogs_ExpandedAfterPause() {
|
public void testSuggestionsLogs_ExpandedAfterPause() {
|
||||||
setupSuggestions(makeSuggestions("pkg1", "pkg2", "pkg3"));
|
setupSuggestions(makeSuggestions("pkg1", "pkg2", "pkg3"));
|
||||||
mDashboardAdapter.onPause();
|
mDashboardAdapter.onPause();
|
||||||
mDashboardAdapter.onBindSuggestionHeader(
|
mDashboardAdapter.onBindSuggestionConditionHeader(mSuggestionHolder, mSuggestionHeaderData);
|
||||||
mSuggestionHolder, mSuggestionHeaderData);
|
|
||||||
mSuggestionHolder.itemView.callOnClick();
|
mSuggestionHolder.itemView.callOnClick();
|
||||||
verify(mFactory.metricsFeatureProvider, times(7)).action(
|
verify(mFactory.metricsFeatureProvider, times(7)).action(
|
||||||
any(Context.class), mActionCategoryCaptor.capture(),
|
any(Context.class), mActionCategoryCaptor.capture(),
|
||||||
@@ -229,8 +222,7 @@ public class DashboardAdapterTest {
|
|||||||
public void testSuggestionsLogs_ExpandedAfterPauseAndPausedAgain() {
|
public void testSuggestionsLogs_ExpandedAfterPauseAndPausedAgain() {
|
||||||
setupSuggestions(makeSuggestions("pkg1", "pkg2", "pkg3"));
|
setupSuggestions(makeSuggestions("pkg1", "pkg2", "pkg3"));
|
||||||
mDashboardAdapter.onPause();
|
mDashboardAdapter.onPause();
|
||||||
mDashboardAdapter.onBindSuggestionHeader(
|
mDashboardAdapter.onBindSuggestionConditionHeader(mSuggestionHolder, mSuggestionHeaderData);
|
||||||
mSuggestionHolder, mSuggestionHeaderData);
|
|
||||||
mSuggestionHolder.itemView.callOnClick();
|
mSuggestionHolder.itemView.callOnClick();
|
||||||
mDashboardAdapter.onPause();
|
mDashboardAdapter.onPause();
|
||||||
verify(mFactory.metricsFeatureProvider, times(10)).action(
|
verify(mFactory.metricsFeatureProvider, times(10)).action(
|
||||||
@@ -257,8 +249,7 @@ public class DashboardAdapterTest {
|
|||||||
@Test
|
@Test
|
||||||
public void testSuggestionsLogs_ExpandedWithLessThanDefaultShown() {
|
public void testSuggestionsLogs_ExpandedWithLessThanDefaultShown() {
|
||||||
setupSuggestions(makeSuggestions("pkg1"));
|
setupSuggestions(makeSuggestions("pkg1"));
|
||||||
mDashboardAdapter.onBindSuggestionHeader(
|
mDashboardAdapter.onBindSuggestionConditionHeader(mSuggestionHolder, mSuggestionHeaderData);
|
||||||
mSuggestionHolder, mSuggestionHeaderData);
|
|
||||||
mSuggestionHolder.itemView.callOnClick();
|
mSuggestionHolder.itemView.callOnClick();
|
||||||
verify(mFactory.metricsFeatureProvider, times(1)).action(
|
verify(mFactory.metricsFeatureProvider, times(1)).action(
|
||||||
any(Context.class), mActionCategoryCaptor.capture(),
|
any(Context.class), mActionCategoryCaptor.capture(),
|
||||||
@@ -274,8 +265,7 @@ public class DashboardAdapterTest {
|
|||||||
@Test
|
@Test
|
||||||
public void testSuggestionsLogs_ExpandedWithLessThanDefaultShownAndPaused() {
|
public void testSuggestionsLogs_ExpandedWithLessThanDefaultShownAndPaused() {
|
||||||
setupSuggestions(makeSuggestions("pkg1"));
|
setupSuggestions(makeSuggestions("pkg1"));
|
||||||
mDashboardAdapter.onBindSuggestionHeader(
|
mDashboardAdapter.onBindSuggestionConditionHeader(mSuggestionHolder, mSuggestionHeaderData);
|
||||||
mSuggestionHolder, mSuggestionHeaderData);
|
|
||||||
mSuggestionHolder.itemView.callOnClick();
|
mSuggestionHolder.itemView.callOnClick();
|
||||||
mDashboardAdapter.onPause();
|
mDashboardAdapter.onPause();
|
||||||
verify(mFactory.metricsFeatureProvider, times(2)).action(
|
verify(mFactory.metricsFeatureProvider, times(2)).action(
|
||||||
@@ -294,8 +284,7 @@ public class DashboardAdapterTest {
|
|||||||
public void testSuggestionsLogs_ExpandedWithLessThanDefaultShownAfterPause() {
|
public void testSuggestionsLogs_ExpandedWithLessThanDefaultShownAfterPause() {
|
||||||
setupSuggestions(makeSuggestions("pkg1"));
|
setupSuggestions(makeSuggestions("pkg1"));
|
||||||
mDashboardAdapter.onPause();
|
mDashboardAdapter.onPause();
|
||||||
mDashboardAdapter.onBindSuggestionHeader(
|
mDashboardAdapter.onBindSuggestionConditionHeader(mSuggestionHolder, mSuggestionHeaderData);
|
||||||
mSuggestionHolder, mSuggestionHeaderData);
|
|
||||||
mSuggestionHolder.itemView.callOnClick();
|
mSuggestionHolder.itemView.callOnClick();
|
||||||
verify(mFactory.metricsFeatureProvider, times(3)).action(
|
verify(mFactory.metricsFeatureProvider, times(3)).action(
|
||||||
any(Context.class), mActionCategoryCaptor.capture(),
|
any(Context.class), mActionCategoryCaptor.capture(),
|
||||||
@@ -314,8 +303,7 @@ public class DashboardAdapterTest {
|
|||||||
public void testSuggestionsLogs_ExpandedWithLessThanDefaultShownAfterPauseAndPausedAgain() {
|
public void testSuggestionsLogs_ExpandedWithLessThanDefaultShownAfterPauseAndPausedAgain() {
|
||||||
setupSuggestions(makeSuggestions("pkg1"));
|
setupSuggestions(makeSuggestions("pkg1"));
|
||||||
mDashboardAdapter.onPause();
|
mDashboardAdapter.onPause();
|
||||||
mDashboardAdapter.onBindSuggestionHeader(
|
mDashboardAdapter.onBindSuggestionConditionHeader(mSuggestionHolder, mSuggestionHeaderData);
|
||||||
mSuggestionHolder, mSuggestionHeaderData);
|
|
||||||
mSuggestionHolder.itemView.callOnClick();
|
mSuggestionHolder.itemView.callOnClick();
|
||||||
mDashboardAdapter.onPause();
|
mDashboardAdapter.onPause();
|
||||||
verify(mFactory.metricsFeatureProvider, times(4)).action(
|
verify(mFactory.metricsFeatureProvider, times(4)).action(
|
||||||
@@ -333,81 +321,9 @@ public class DashboardAdapterTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBindViewHolder_inflateRemoteView() {
|
public void testSuggestioDismissed_notOnlySuggestion_doNothing() {
|
||||||
List<Tile> packages = makeSuggestions("pkg1");
|
final DashboardAdapter adapter =
|
||||||
RemoteViews remoteViews = mock(RemoteViews.class);
|
spy(new DashboardAdapter(mContext, null, null, null, null));
|
||||||
TextView textView = new TextView(RuntimeEnvironment.application);
|
|
||||||
doReturn(textView).when(remoteViews).apply(any(Context.class), any(ViewGroup.class));
|
|
||||||
packages.get(0).remoteViews = remoteViews;
|
|
||||||
mDashboardAdapter.setCategoriesAndSuggestions(Collections.emptyList(), packages);
|
|
||||||
mSuggestionHolder = mDashboardAdapter.onCreateViewHolder(
|
|
||||||
new FrameLayout(RuntimeEnvironment.application),
|
|
||||||
R.layout.suggestion_tile_card);
|
|
||||||
|
|
||||||
mDashboardAdapter.onBindViewHolder(mSuggestionHolder, 1);
|
|
||||||
assertThat(textView.getParent()).isSameAs(mSuggestionHolder.itemView);
|
|
||||||
mSuggestionHolder.itemView.performClick();
|
|
||||||
|
|
||||||
verify(mContext).startSuggestion(any(Intent.class));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testBindViewHolder_primaryViewHandlesClick() {
|
|
||||||
Context context =
|
|
||||||
new ContextThemeWrapper(RuntimeEnvironment.application, R.style.Theme_Settings);
|
|
||||||
|
|
||||||
List<Tile> packages = makeSuggestions("pkg1");
|
|
||||||
RemoteViews remoteViews = mock(RemoteViews.class);
|
|
||||||
FrameLayout layout = new FrameLayout(context);
|
|
||||||
Button primary = new Button(context);
|
|
||||||
primary.setId(android.R.id.primary);
|
|
||||||
layout.addView(primary);
|
|
||||||
doReturn(layout).when(remoteViews).apply(any(Context.class), any(ViewGroup.class));
|
|
||||||
packages.get(0).remoteViews = remoteViews;
|
|
||||||
mDashboardAdapter.setCategoriesAndSuggestions(Collections.emptyList(), packages);
|
|
||||||
mSuggestionHolder = mDashboardAdapter.onCreateViewHolder(
|
|
||||||
new FrameLayout(context),
|
|
||||||
R.layout.suggestion_tile_card);
|
|
||||||
|
|
||||||
mDashboardAdapter.onBindViewHolder(mSuggestionHolder, 1);
|
|
||||||
|
|
||||||
mSuggestionHolder.itemView.performClick();
|
|
||||||
assertThat(ShadowApplication.getInstance().getNextStartedActivity()).isNull();
|
|
||||||
verify(mContext, never()).startSuggestion(any(Intent.class));
|
|
||||||
|
|
||||||
primary.performClick();
|
|
||||||
|
|
||||||
verify(mContext).startSuggestion(any(Intent.class));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testBindViewHolder_viewsClearedOnRebind() {
|
|
||||||
Context context =
|
|
||||||
new ContextThemeWrapper(RuntimeEnvironment.application, R.style.Theme_Settings);
|
|
||||||
|
|
||||||
List<Tile> packages = makeSuggestions("pkg1");
|
|
||||||
RemoteViews remoteViews = mock(RemoteViews.class);
|
|
||||||
FrameLayout layout = new FrameLayout(context);
|
|
||||||
Button primary = new Button(context);
|
|
||||||
primary.setId(android.R.id.primary);
|
|
||||||
layout.addView(primary);
|
|
||||||
doReturn(layout).when(remoteViews).apply(any(Context.class), any(ViewGroup.class));
|
|
||||||
packages.get(0).remoteViews = remoteViews;
|
|
||||||
mDashboardAdapter.setCategoriesAndSuggestions(Collections.emptyList(), packages);
|
|
||||||
mSuggestionHolder = mDashboardAdapter.onCreateViewHolder(
|
|
||||||
new FrameLayout(context),
|
|
||||||
R.layout.suggestion_tile_card);
|
|
||||||
|
|
||||||
mDashboardAdapter.onBindViewHolder(mSuggestionHolder, 1);
|
|
||||||
mDashboardAdapter.onBindViewHolder(mSuggestionHolder, 1);
|
|
||||||
|
|
||||||
ViewGroup itemView = (ViewGroup) mSuggestionHolder.itemView;
|
|
||||||
assertThat(itemView.getChildCount()).isEqualTo(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testSuggestionDismissed_notOnlySuggestion_doNothing() {
|
|
||||||
final DashboardAdapter adapter = spy(new DashboardAdapter(mContext, null, null));
|
|
||||||
adapter.setCategoriesAndSuggestions(
|
adapter.setCategoriesAndSuggestions(
|
||||||
new ArrayList<>(), makeSuggestions("pkg1", "pkg2", "pkg3"));
|
new ArrayList<>(), makeSuggestions("pkg1", "pkg2", "pkg3"));
|
||||||
final DashboardData dashboardData = adapter.mDashboardData;
|
final DashboardData dashboardData = adapter.mDashboardData;
|
||||||
@@ -420,8 +336,9 @@ public class DashboardAdapterTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSuggestionDismissed_onlySuggestion_updateDashboardData() {
|
public void testSuggestioDismissed_onlySuggestion_updateDashboardData() {
|
||||||
DashboardAdapter adapter = spy(new DashboardAdapter(mContext, null, null));
|
DashboardAdapter adapter =
|
||||||
|
spy(new DashboardAdapter(mContext, null, null, null, null));
|
||||||
adapter.setCategoriesAndSuggestions(new ArrayList<>(), makeSuggestions("pkg1"));
|
adapter.setCategoriesAndSuggestions(new ArrayList<>(), makeSuggestions("pkg1"));
|
||||||
final DashboardData dashboardData = adapter.mDashboardData;
|
final DashboardData dashboardData = adapter.mDashboardData;
|
||||||
reset(adapter); // clear interactions tracking
|
reset(adapter); // clear interactions tracking
|
||||||
@@ -450,8 +367,7 @@ public class DashboardAdapterTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBindConditionAndSuggestion_shouldSetSuggestionAdapterAndNoCrash() {
|
public void testBindConditionAndSuggestion_shouldSetSuggestionAdapterAndNoCrash() {
|
||||||
when(mFactory.dashboardFeatureProvider.combineSuggestionAndCondition()).thenReturn(true);
|
mDashboardAdapter = new DashboardAdapter(mContext, null, null, null, null);
|
||||||
mDashboardAdapter = new DashboardAdapter(mContext, null, null);
|
|
||||||
final List<Tile> suggestions = makeSuggestions("pkg1");
|
final List<Tile> suggestions = makeSuggestions("pkg1");
|
||||||
final List<DashboardCategory> categories = new ArrayList<>();
|
final List<DashboardCategory> categories = new ArrayList<>();
|
||||||
final DashboardCategory category = mock(DashboardCategory.class);
|
final DashboardCategory category = mock(DashboardCategory.class);
|
||||||
@@ -489,8 +405,9 @@ public class DashboardAdapterTest {
|
|||||||
|
|
||||||
private void setupSuggestions(List<Tile> suggestions) {
|
private void setupSuggestions(List<Tile> suggestions) {
|
||||||
mDashboardAdapter.setCategoriesAndSuggestions(new ArrayList<>(), suggestions);
|
mDashboardAdapter.setCategoriesAndSuggestions(new ArrayList<>(), suggestions);
|
||||||
mSuggestionHolder = mDashboardAdapter.onCreateViewHolder(
|
final Context context = RuntimeEnvironment.application;
|
||||||
new FrameLayout(RuntimeEnvironment.application),
|
mSuggestionHolder = new DashboardAdapter.SuggestionAndConditionHeaderHolder(
|
||||||
mDashboardAdapter.getItemViewType(1));
|
LayoutInflater.from(context).inflate(
|
||||||
|
R.layout.suggestion_condition_header, new RelativeLayout(context), true));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -94,7 +94,6 @@ public class DashboardDataTest {
|
|||||||
.setCategories(categories)
|
.setCategories(categories)
|
||||||
.setSuggestions(suggestions)
|
.setSuggestions(suggestions)
|
||||||
.setSuggestionConditionMode(DashboardData.HEADER_MODE_FULLY_EXPANDED)
|
.setSuggestionConditionMode(DashboardData.HEADER_MODE_FULLY_EXPANDED)
|
||||||
.setCombineSuggestionAndCondition(true)
|
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
mDashboardDataWithTwoConditions = new DashboardData.Builder()
|
mDashboardDataWithTwoConditions = new DashboardData.Builder()
|
||||||
@@ -102,7 +101,6 @@ public class DashboardDataTest {
|
|||||||
.setCategories(categories)
|
.setCategories(categories)
|
||||||
.setSuggestions(suggestions)
|
.setSuggestions(suggestions)
|
||||||
.setSuggestionConditionMode(DashboardData.HEADER_MODE_FULLY_EXPANDED)
|
.setSuggestionConditionMode(DashboardData.HEADER_MODE_FULLY_EXPANDED)
|
||||||
.setCombineSuggestionAndCondition(true)
|
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
mDashboardDataWithNoItems = new DashboardData.Builder()
|
mDashboardDataWithNoItems = new DashboardData.Builder()
|
||||||
@@ -127,9 +125,7 @@ public class DashboardDataTest {
|
|||||||
.isEqualTo(expectedSize);
|
.isEqualTo(expectedSize);
|
||||||
for (int i = 0; i < expectedSize; i++) {
|
for (int i = 0; i < expectedSize; i++) {
|
||||||
final Object item = mDashboardDataWithOneConditions.getItemEntityByPosition(i);
|
final Object item = mDashboardDataWithOneConditions.getItemEntityByPosition(i);
|
||||||
if (item instanceof DashboardData.SuggestionHeaderData
|
if (item instanceof List) {
|
||||||
|| item instanceof List) {
|
|
||||||
// SuggestionHeaderData is created inside when build, we can only use isEqualTo
|
|
||||||
assertThat(item).isEqualTo(expectedObjects[i]);
|
assertThat(item).isEqualTo(expectedObjects[i]);
|
||||||
} else if (item instanceof DashboardData.SuggestionConditionHeaderData) {
|
} else if (item instanceof DashboardData.SuggestionConditionHeaderData) {
|
||||||
DashboardData.SuggestionConditionHeaderData i1 =
|
DashboardData.SuggestionConditionHeaderData i1 =
|
||||||
|
@@ -38,7 +38,6 @@ import org.robolectric.RuntimeEnvironment;
|
|||||||
import org.robolectric.annotation.Config;
|
import org.robolectric.annotation.Config;
|
||||||
|
|
||||||
import static com.google.common.truth.Truth.assertThat;
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
import static org.mockito.Mockito.mock;
|
|
||||||
import static org.mockito.Mockito.verify;
|
import static org.mockito.Mockito.verify;
|
||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
@@ -15,16 +15,26 @@
|
|||||||
*/
|
*/
|
||||||
package com.android.settings.dashboard.suggestions;
|
package com.android.settings.dashboard.suggestions;
|
||||||
|
|
||||||
|
import android.content.ComponentName;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
import android.graphics.drawable.Icon;
|
import android.graphics.drawable.Icon;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
import android.view.ContextThemeWrapper;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.Button;
|
||||||
|
import android.widget.FrameLayout;
|
||||||
import android.widget.LinearLayout;
|
import android.widget.LinearLayout;
|
||||||
|
import android.widget.RemoteViews;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
import com.android.settings.R;
|
import com.android.settings.R;
|
||||||
|
import com.android.settings.SettingsActivity;
|
||||||
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||||
import com.android.settings.TestConfig;
|
import com.android.settings.TestConfig;
|
||||||
import com.android.settings.dashboard.DashboardAdapter;
|
import com.android.settings.dashboard.DashboardAdapter;
|
||||||
|
import com.android.settings.testutils.FakeFeatureFactory;
|
||||||
import com.android.settingslib.drawer.Tile;
|
import com.android.settingslib.drawer.Tile;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@@ -33,15 +43,20 @@ import java.util.List;
|
|||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
|
import org.mockito.Answers;
|
||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
import org.mockito.MockitoAnnotations;
|
import org.mockito.MockitoAnnotations;
|
||||||
import org.robolectric.RuntimeEnvironment;
|
import org.robolectric.RuntimeEnvironment;
|
||||||
import org.robolectric.annotation.Config;
|
import org.robolectric.annotation.Config;
|
||||||
|
import org.robolectric.shadows.ShadowApplication;
|
||||||
|
|
||||||
import static com.google.common.truth.Truth.assertThat;
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
import static org.mockito.Mockito.any;
|
import static org.mockito.Mockito.any;
|
||||||
|
import static org.mockito.Mockito.doReturn;
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
|
import static org.mockito.Mockito.never;
|
||||||
import static org.mockito.Mockito.spy;
|
import static org.mockito.Mockito.spy;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
import static org.mockito.Mockito.verify;
|
import static org.mockito.Mockito.verify;
|
||||||
|
|
||||||
@RunWith(SettingsRobolectricTestRunner.class)
|
@RunWith(SettingsRobolectricTestRunner.class)
|
||||||
@@ -51,9 +66,12 @@ public class SuggestionAdapterTest {
|
|||||||
private Tile mSuggestion1;
|
private Tile mSuggestion1;
|
||||||
@Mock
|
@Mock
|
||||||
private Tile mSuggestion2;
|
private Tile mSuggestion2;
|
||||||
|
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
|
||||||
|
private SettingsActivity mActivity;
|
||||||
|
|
||||||
private Context mContext;
|
private Context mContext;
|
||||||
private SuggestionAdapter mSuggestionAdapter;
|
private SuggestionAdapter mSuggestionAdapter;
|
||||||
|
private DashboardAdapter.DashboardItemHolder mSuggestionHolder;
|
||||||
private List<Tile> mOneSuggestion;
|
private List<Tile> mOneSuggestion;
|
||||||
private List<Tile> mTwoSuggestions;
|
private List<Tile> mTwoSuggestions;
|
||||||
|
|
||||||
@@ -61,6 +79,8 @@ public class SuggestionAdapterTest {
|
|||||||
public void setUp() {
|
public void setUp() {
|
||||||
MockitoAnnotations.initMocks(this);
|
MockitoAnnotations.initMocks(this);
|
||||||
mContext = RuntimeEnvironment.application;
|
mContext = RuntimeEnvironment.application;
|
||||||
|
FakeFeatureFactory.setupForTest(mActivity);
|
||||||
|
|
||||||
mSuggestion1.title = "Test Suggestion 1";
|
mSuggestion1.title = "Test Suggestion 1";
|
||||||
mSuggestion1.icon = mock(Icon.class);
|
mSuggestion1.icon = mock(Icon.class);
|
||||||
mSuggestion2.title = "Test Suggestion 2";
|
mSuggestion2.title = "Test Suggestion 2";
|
||||||
@@ -92,13 +112,96 @@ public class SuggestionAdapterTest {
|
|||||||
public void onBindViewHolder_shouldSetListener() {
|
public void onBindViewHolder_shouldSetListener() {
|
||||||
final View view = spy(LayoutInflater.from(mContext).inflate(
|
final View view = spy(LayoutInflater.from(mContext).inflate(
|
||||||
R.layout.suggestion_tile_new_ui, new LinearLayout(mContext), true));
|
R.layout.suggestion_tile_new_ui, new LinearLayout(mContext), true));
|
||||||
final DashboardAdapter.DashboardItemHolder viewHolder =
|
mSuggestionHolder = new DashboardAdapter.DashboardItemHolder(view);
|
||||||
new DashboardAdapter.DashboardItemHolder(view);
|
|
||||||
mSuggestionAdapter = new SuggestionAdapter(mContext, mOneSuggestion, new ArrayList<>());
|
mSuggestionAdapter = new SuggestionAdapter(mContext, mOneSuggestion, new ArrayList<>());
|
||||||
|
|
||||||
mSuggestionAdapter.onBindViewHolder(viewHolder, 0);
|
mSuggestionAdapter.onBindViewHolder(mSuggestionHolder, 0);
|
||||||
|
|
||||||
verify(view).setOnClickListener(any(View.OnClickListener.class));
|
verify(view).setOnClickListener(any(View.OnClickListener.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void onBindViewHolder_shouldInflateRemoteView() {
|
||||||
|
List<Tile> packages = makeSuggestions("pkg1");
|
||||||
|
RemoteViews remoteViews = mock(RemoteViews.class);
|
||||||
|
TextView textView = new TextView(RuntimeEnvironment.application);
|
||||||
|
doReturn(textView).when(remoteViews).apply(any(Context.class), any(ViewGroup.class));
|
||||||
|
packages.get(0).remoteViews = remoteViews;
|
||||||
|
setupSuggestions(mActivity, packages);
|
||||||
|
|
||||||
|
mSuggestionAdapter.onBindViewHolder(mSuggestionHolder, 0);
|
||||||
|
|
||||||
|
assertThat(textView.getParent()).isSameAs(mSuggestionHolder.itemView);
|
||||||
|
mSuggestionHolder.itemView.performClick();
|
||||||
|
|
||||||
|
verify(mActivity).startSuggestion(any(Intent.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void onBindViewHolder_primaryViewShouldHandleClick() {
|
||||||
|
Context context =
|
||||||
|
new ContextThemeWrapper(RuntimeEnvironment.application, R.style.Theme_Settings);
|
||||||
|
|
||||||
|
List<Tile> packages = makeSuggestions("pkg1");
|
||||||
|
RemoteViews remoteViews = mock(RemoteViews.class);
|
||||||
|
FrameLayout layout = new FrameLayout(context);
|
||||||
|
Button primary = new Button(context);
|
||||||
|
primary.setId(android.R.id.primary);
|
||||||
|
layout.addView(primary);
|
||||||
|
doReturn(layout).when(remoteViews).apply(any(Context.class), any(ViewGroup.class));
|
||||||
|
packages.get(0).remoteViews = remoteViews;
|
||||||
|
setupSuggestions(mActivity, packages);
|
||||||
|
|
||||||
|
mSuggestionAdapter.onBindViewHolder(mSuggestionHolder, 0);
|
||||||
|
mSuggestionHolder.itemView.performClick();
|
||||||
|
|
||||||
|
assertThat(ShadowApplication.getInstance().getNextStartedActivity()).isNull();
|
||||||
|
verify(mActivity, never()).startSuggestion(any(Intent.class));
|
||||||
|
|
||||||
|
primary.performClick();
|
||||||
|
|
||||||
|
verify(mActivity).startSuggestion(any(Intent.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void onBindViewHolder_viewsShouldClearOnRebind() {
|
||||||
|
Context context =
|
||||||
|
new ContextThemeWrapper(RuntimeEnvironment.application, R.style.Theme_Settings);
|
||||||
|
|
||||||
|
List<Tile> packages = makeSuggestions("pkg1");
|
||||||
|
RemoteViews remoteViews = mock(RemoteViews.class);
|
||||||
|
FrameLayout layout = new FrameLayout(context);
|
||||||
|
Button primary = new Button(context);
|
||||||
|
primary.setId(android.R.id.primary);
|
||||||
|
layout.addView(primary);
|
||||||
|
doReturn(layout).when(remoteViews).apply(any(Context.class), any(ViewGroup.class));
|
||||||
|
packages.get(0).remoteViews = remoteViews;
|
||||||
|
setupSuggestions(mActivity, packages);
|
||||||
|
|
||||||
|
mSuggestionAdapter.onBindViewHolder(mSuggestionHolder, 0);
|
||||||
|
mSuggestionAdapter.onBindViewHolder(mSuggestionHolder, 0);
|
||||||
|
|
||||||
|
ViewGroup itemView = (ViewGroup) mSuggestionHolder.itemView;
|
||||||
|
assertThat(itemView.getChildCount()).isEqualTo(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setupSuggestions(Context context, List<Tile> suggestions) {
|
||||||
|
mSuggestionAdapter = new SuggestionAdapter(context, suggestions, new ArrayList<>());
|
||||||
|
mSuggestionHolder = mSuggestionAdapter.onCreateViewHolder(
|
||||||
|
new FrameLayout(RuntimeEnvironment.application),
|
||||||
|
mSuggestionAdapter.getItemViewType(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<Tile> makeSuggestions(String... pkgNames) {
|
||||||
|
final List<Tile> suggestions = new ArrayList<>();
|
||||||
|
for (String pkgName : pkgNames) {
|
||||||
|
Tile suggestion = new Tile();
|
||||||
|
suggestion.intent = new Intent("action");
|
||||||
|
suggestion.intent.setComponent(new ComponentName(pkgName, "cls"));
|
||||||
|
suggestions.add(suggestion);
|
||||||
|
suggestion.icon = mock(Icon.class);
|
||||||
|
}
|
||||||
|
return suggestions;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -80,7 +80,7 @@ public class SuggestionDismissControllerTest {
|
|||||||
@Test
|
@Test
|
||||||
public void getSwipeDirs_isSuggestionTile_shouldReturnDirection() {
|
public void getSwipeDirs_isSuggestionTile_shouldReturnDirection() {
|
||||||
final RecyclerView.ViewHolder vh = mock(RecyclerView.ViewHolder.class);
|
final RecyclerView.ViewHolder vh = mock(RecyclerView.ViewHolder.class);
|
||||||
when(vh.getItemViewType()).thenReturn(R.layout.suggestion_tile);
|
when(vh.getItemViewType()).thenReturn(R.layout.suggestion_tile_new_ui);
|
||||||
|
|
||||||
assertThat(mController.getSwipeDirs(mRecyclerView, vh))
|
assertThat(mController.getSwipeDirs(mRecyclerView, vh))
|
||||||
.isEqualTo(ItemTouchHelper.START | ItemTouchHelper.END);
|
.isEqualTo(ItemTouchHelper.START | ItemTouchHelper.END);
|
||||||
@@ -98,7 +98,7 @@ public class SuggestionDismissControllerTest {
|
|||||||
@Test
|
@Test
|
||||||
public void getSwipeDirs_isNotSuggestionTile_shouldReturn0() {
|
public void getSwipeDirs_isNotSuggestionTile_shouldReturn0() {
|
||||||
final RecyclerView.ViewHolder vh = mock(RecyclerView.ViewHolder.class);
|
final RecyclerView.ViewHolder vh = mock(RecyclerView.ViewHolder.class);
|
||||||
when(vh.getItemViewType()).thenReturn(R.layout.condition_card);
|
when(vh.getItemViewType()).thenReturn(R.layout.condition_tile_new_ui);
|
||||||
|
|
||||||
assertThat(mController.getSwipeDirs(mRecyclerView, vh))
|
assertThat(mController.getSwipeDirs(mRecyclerView, vh))
|
||||||
.isEqualTo(0);
|
.isEqualTo(0);
|
||||||
|
Reference in New Issue
Block a user