Remove condition manager v1 code.
Change-Id: I866c1f7c493c6080ccf766ecfc8e6b00dafeecd9 Fixes: 112485407 Test: robotests
This commit is contained in:
@@ -25,5 +25,4 @@ public class FeatureFlags {
|
|||||||
public static final String AUDIO_SWITCHER_SETTINGS = "settings_audio_switcher";
|
public static final String AUDIO_SWITCHER_SETTINGS = "settings_audio_switcher";
|
||||||
public static final String DYNAMIC_HOMEPAGE = "settings_dynamic_homepage";
|
public static final String DYNAMIC_HOMEPAGE = "settings_dynamic_homepage";
|
||||||
public static final String HEARING_AID_SETTINGS = "settings_bluetooth_hearing_aid";
|
public static final String HEARING_AID_SETTINGS = "settings_bluetooth_hearing_aid";
|
||||||
public static final String CONDITION_MANAGER_V2 = "settings_condition_manager_v2";
|
|
||||||
}
|
}
|
||||||
|
@@ -40,10 +40,9 @@ import com.android.settings.R;
|
|||||||
import com.android.settings.R.id;
|
import com.android.settings.R.id;
|
||||||
import com.android.settings.dashboard.DashboardData.ConditionHeaderData;
|
import com.android.settings.dashboard.DashboardData.ConditionHeaderData;
|
||||||
import com.android.settings.dashboard.suggestions.SuggestionAdapter;
|
import com.android.settings.dashboard.suggestions.SuggestionAdapter;
|
||||||
import com.android.settings.homepage.conditional.Condition;
|
|
||||||
import com.android.settings.homepage.conditional.ConditionAdapter;
|
import com.android.settings.homepage.conditional.ConditionAdapter;
|
||||||
import com.android.settings.homepage.conditional.v2.ConditionManager;
|
import com.android.settings.homepage.conditional.ConditionManager;
|
||||||
import com.android.settings.homepage.conditional.v2.ConditionalCard;
|
import com.android.settings.homepage.conditional.ConditionalCard;
|
||||||
import com.android.settings.overlay.FeatureFactory;
|
import com.android.settings.overlay.FeatureFactory;
|
||||||
import com.android.settings.widget.RoundedHomepageIcon;
|
import com.android.settings.widget.RoundedHomepageIcon;
|
||||||
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
|
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
|
||||||
@@ -88,7 +87,7 @@ public class DashboardAdapter extends RecyclerView.Adapter<DashboardAdapter.Dash
|
|||||||
};
|
};
|
||||||
|
|
||||||
public DashboardAdapter(Context context, Bundle savedInstanceState,
|
public DashboardAdapter(Context context, Bundle savedInstanceState,
|
||||||
List<Condition> conditions, ConditionManager conditionManager,
|
ConditionManager conditionManager,
|
||||||
SuggestionControllerMixinCompat suggestionControllerMixin, Lifecycle lifecycle) {
|
SuggestionControllerMixinCompat suggestionControllerMixin, Lifecycle lifecycle) {
|
||||||
|
|
||||||
DashboardCategory category = null;
|
DashboardCategory category = null;
|
||||||
@@ -116,8 +115,7 @@ public class DashboardAdapter extends RecyclerView.Adapter<DashboardAdapter.Dash
|
|||||||
}
|
}
|
||||||
|
|
||||||
mDashboardData = new DashboardData.Builder()
|
mDashboardData = new DashboardData.Builder()
|
||||||
.setConditions(conditions)
|
.setConditions(
|
||||||
.setConditionsV2(
|
|
||||||
conditionManager == null ? null : conditionManager.getDisplayableCards())
|
conditionManager == null ? null : conditionManager.getDisplayableCards())
|
||||||
.setSuggestions(mSuggestionAdapter.getSuggestions())
|
.setSuggestions(mSuggestionAdapter.getSuggestions())
|
||||||
.setCategory(category)
|
.setCategory(category)
|
||||||
@@ -142,7 +140,7 @@ public class DashboardAdapter extends RecyclerView.Adapter<DashboardAdapter.Dash
|
|||||||
notifyDashboardDataChanged(prevData);
|
notifyDashboardDataChanged(prevData);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setConditions(List<Condition> conditions) {
|
public void setConditions(List<ConditionalCard> conditions) {
|
||||||
final DashboardData prevData = mDashboardData;
|
final DashboardData prevData = mDashboardData;
|
||||||
Log.d(TAG, "adapter setConditions called");
|
Log.d(TAG, "adapter setConditions called");
|
||||||
mDashboardData = new DashboardData.Builder(prevData)
|
mDashboardData = new DashboardData.Builder(prevData)
|
||||||
@@ -151,15 +149,6 @@ public class DashboardAdapter extends RecyclerView.Adapter<DashboardAdapter.Dash
|
|||||||
notifyDashboardDataChanged(prevData);
|
notifyDashboardDataChanged(prevData);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setConditionsV2(List<ConditionalCard> conditions) {
|
|
||||||
final DashboardData prevData = mDashboardData;
|
|
||||||
Log.d(TAG, "adapter setConditions called");
|
|
||||||
mDashboardData = new DashboardData.Builder(prevData)
|
|
||||||
.setConditionsV2(conditions)
|
|
||||||
.build();
|
|
||||||
notifyDashboardDataChanged(prevData);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onSuggestionClosed(Suggestion suggestion) {
|
public void onSuggestionClosed(Suggestion suggestion) {
|
||||||
final List<Suggestion> list = mDashboardData.getSuggestions();
|
final List<Suggestion> list = mDashboardData.getSuggestions();
|
||||||
@@ -301,31 +290,12 @@ public class DashboardAdapter extends RecyclerView.Adapter<DashboardAdapter.Dash
|
|||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
void onBindCondition(final ConditionContainerHolder holder, int position) {
|
void onBindCondition(final ConditionContainerHolder holder, int position) {
|
||||||
final List conditions = (List) mDashboardData.getItemEntityByPosition(position);
|
final List<ConditionalCard> conditions =
|
||||||
final List<Condition> conditionsV1;
|
(List) mDashboardData.getItemEntityByPosition(position);
|
||||||
final List<ConditionalCard> conditionsV2;
|
final ConditionAdapter adapter = new ConditionAdapter(
|
||||||
if (conditions == null || conditions.isEmpty()) {
|
mContext, mConditionManager, conditions,
|
||||||
conditionsV1 = null;
|
mDashboardData.isConditionExpanded());
|
||||||
conditionsV2 = null;
|
holder.data.setAdapter(adapter);
|
||||||
} else if (conditions.get(0) instanceof Condition) {
|
|
||||||
conditionsV1 = conditions;
|
|
||||||
conditionsV2 = null;
|
|
||||||
} else {
|
|
||||||
conditionsV1 = null;
|
|
||||||
conditionsV2 = conditions;
|
|
||||||
}
|
|
||||||
if (conditionsV2 == null) {
|
|
||||||
final ConditionAdapter adapter = new ConditionAdapter(mContext,
|
|
||||||
conditionsV1, mDashboardData.isConditionExpanded());
|
|
||||||
adapter.addDismissHandling(holder.data);
|
|
||||||
holder.data.setAdapter(adapter);
|
|
||||||
} else {
|
|
||||||
final com.android.settings.homepage.conditional.v2.ConditionAdapter adapter =
|
|
||||||
new com.android.settings.homepage.conditional.v2.ConditionAdapter(
|
|
||||||
mContext, mConditionManager, conditionsV2,
|
|
||||||
mDashboardData.isConditionExpanded());
|
|
||||||
holder.data.setAdapter(adapter);
|
|
||||||
}
|
|
||||||
holder.data.setLayoutManager(new LinearLayoutManager(mContext));
|
holder.data.setLayoutManager(new LinearLayoutManager(mContext));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -24,8 +24,7 @@ import androidx.annotation.VisibleForTesting;
|
|||||||
import androidx.recyclerview.widget.DiffUtil;
|
import androidx.recyclerview.widget.DiffUtil;
|
||||||
|
|
||||||
import com.android.settings.R;
|
import com.android.settings.R;
|
||||||
import com.android.settings.homepage.conditional.Condition;
|
import com.android.settings.homepage.conditional.ConditionalCard;
|
||||||
import com.android.settings.homepage.conditional.v2.ConditionalCard;
|
|
||||||
import com.android.settingslib.drawer.DashboardCategory;
|
import com.android.settingslib.drawer.DashboardCategory;
|
||||||
import com.android.settingslib.drawer.Tile;
|
import com.android.settingslib.drawer.Tile;
|
||||||
|
|
||||||
@@ -57,15 +56,13 @@ public class DashboardData {
|
|||||||
|
|
||||||
private final List<Item> mItems;
|
private final List<Item> mItems;
|
||||||
private final DashboardCategory mCategory;
|
private final DashboardCategory mCategory;
|
||||||
private final List<Condition> mConditions;
|
private final List<ConditionalCard> mConditions;
|
||||||
private final List<ConditionalCard> mConditionsV2;
|
|
||||||
private final List<Suggestion> mSuggestions;
|
private final List<Suggestion> mSuggestions;
|
||||||
private final boolean mConditionExpanded;
|
private final boolean mConditionExpanded;
|
||||||
|
|
||||||
private DashboardData(Builder builder) {
|
private DashboardData(Builder builder) {
|
||||||
mCategory = builder.mCategory;
|
mCategory = builder.mCategory;
|
||||||
mConditions = builder.mConditions;
|
mConditions = builder.mConditions;
|
||||||
mConditionsV2 = builder.mConditionsV2;
|
|
||||||
mSuggestions = builder.mSuggestions;
|
mSuggestions = builder.mSuggestions;
|
||||||
mConditionExpanded = builder.mConditionExpanded;
|
mConditionExpanded = builder.mConditionExpanded;
|
||||||
mItems = new ArrayList<>();
|
mItems = new ArrayList<>();
|
||||||
@@ -106,7 +103,7 @@ public class DashboardData {
|
|||||||
return mCategory;
|
return mCategory;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<Condition> getConditions() {
|
public List<ConditionalCard> getConditions() {
|
||||||
return mConditions;
|
return mConditions;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -168,7 +165,8 @@ public class DashboardData {
|
|||||||
/**
|
/**
|
||||||
* Add item into list when {@paramref add} is true.
|
* Add item into list when {@paramref add} is true.
|
||||||
*
|
*
|
||||||
* @param item maybe {@link Condition}, {@link Tile}, {@link DashboardCategory} or null
|
* @param item maybe {@link ConditionalCard}, {@link Tile}, {@link DashboardCategory}
|
||||||
|
* or null
|
||||||
* @param type type of the item, and value is the layout id
|
* @param type type of the item, and value is the layout id
|
||||||
* @param stableId The stable id for this item
|
* @param stableId The stable id for this item
|
||||||
* @param add flag about whether to add item into list
|
* @param add flag about whether to add item into list
|
||||||
@@ -184,11 +182,8 @@ public class DashboardData {
|
|||||||
* and mIsShowingAll, mConditionExpanded flag.
|
* and mIsShowingAll, mConditionExpanded flag.
|
||||||
*/
|
*/
|
||||||
private void buildItemsData() {
|
private void buildItemsData() {
|
||||||
final List<Condition> conditionsV1 = getConditionsToShow(mConditions);
|
final List<ConditionalCard> conditions = mConditions;
|
||||||
final boolean hasConditionsV1 = sizeOf(conditionsV1) > 0;
|
final boolean hasConditions = sizeOf(conditions) > 0;
|
||||||
final List<ConditionalCard> conditionsV2 = mConditionsV2;
|
|
||||||
final boolean hasConditionsV2 = sizeOf(conditionsV2) > 0;
|
|
||||||
final boolean hasConditions = hasConditionsV1 || hasConditionsV2;
|
|
||||||
|
|
||||||
final List<Suggestion> suggestions = getSuggestionsToShow(mSuggestions);
|
final List<Suggestion> suggestions = getSuggestionsToShow(mSuggestions);
|
||||||
final boolean hasSuggestions = sizeOf(suggestions) > 0;
|
final boolean hasSuggestions = sizeOf(suggestions) > 0;
|
||||||
@@ -203,20 +198,14 @@ public class DashboardData {
|
|||||||
STABLE_ID_SUGGESTION_CONDITION_DIVIDER, hasSuggestions && hasConditions);
|
STABLE_ID_SUGGESTION_CONDITION_DIVIDER, hasSuggestions && hasConditions);
|
||||||
|
|
||||||
/* Condition header. This will be present when there is condition and it is collapsed */
|
/* Condition header. This will be present when there is condition and it is collapsed */
|
||||||
addToItemList(new ConditionHeaderData(conditionsV1, conditionsV2),
|
addToItemList(new ConditionHeaderData(conditions),
|
||||||
R.layout.condition_header,
|
R.layout.condition_header,
|
||||||
STABLE_ID_CONDITION_HEADER, hasConditions && !mConditionExpanded);
|
STABLE_ID_CONDITION_HEADER, hasConditions && !mConditionExpanded);
|
||||||
|
|
||||||
/* Condition container. This is the card view that contains the list of conditions.
|
/* Condition container. This is the card view that contains the list of conditions.
|
||||||
* This will be added whenever the condition list is not empty and expanded */
|
* This will be added whenever the condition list is not empty and expanded */
|
||||||
if (hasConditionsV1) {
|
addToItemList(conditions, R.layout.condition_container,
|
||||||
addToItemList(conditionsV1, R.layout.condition_container,
|
STABLE_ID_CONDITION_CONTAINER, hasConditions && mConditionExpanded);
|
||||||
STABLE_ID_CONDITION_CONTAINER, hasConditionsV1 && mConditionExpanded);
|
|
||||||
}
|
|
||||||
if (hasConditionsV2) {
|
|
||||||
addToItemList(conditionsV2, R.layout.condition_container,
|
|
||||||
STABLE_ID_CONDITION_CONTAINER, hasConditionsV2 && mConditionExpanded);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Condition footer. This will be present when there is condition and it is expanded */
|
/* Condition footer. This will be present when there is condition and it is expanded */
|
||||||
addToItemList(null /* item */, R.layout.condition_footer,
|
addToItemList(null /* item */, R.layout.condition_footer,
|
||||||
@@ -236,21 +225,6 @@ public class DashboardData {
|
|||||||
return list == null ? 0 : list.size();
|
return list == null ? 0 : list.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<Condition> getConditionsToShow(List<Condition> conditions) {
|
|
||||||
if (conditions == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
List<Condition> result = new ArrayList<>();
|
|
||||||
final int size = conditions == null ? 0 : conditions.size();
|
|
||||||
for (int i = 0; i < size; i++) {
|
|
||||||
final Condition condition = conditions.get(i);
|
|
||||||
if (condition.shouldShow()) {
|
|
||||||
result.add(condition);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
private List<Suggestion> getSuggestionsToShow(List<Suggestion> suggestions) {
|
private List<Suggestion> getSuggestionsToShow(List<Suggestion> suggestions) {
|
||||||
if (suggestions == null) {
|
if (suggestions == null) {
|
||||||
return null;
|
return null;
|
||||||
@@ -270,8 +244,7 @@ public class DashboardData {
|
|||||||
*/
|
*/
|
||||||
public static class Builder {
|
public static class Builder {
|
||||||
private DashboardCategory mCategory;
|
private DashboardCategory mCategory;
|
||||||
private List<Condition> mConditions;
|
private List<ConditionalCard> mConditions;
|
||||||
private List<ConditionalCard> mConditionsV2;
|
|
||||||
private List<Suggestion> mSuggestions;
|
private List<Suggestion> mSuggestions;
|
||||||
private boolean mConditionExpanded;
|
private boolean mConditionExpanded;
|
||||||
|
|
||||||
@@ -281,7 +254,6 @@ public class DashboardData {
|
|||||||
public Builder(DashboardData dashboardData) {
|
public Builder(DashboardData dashboardData) {
|
||||||
mCategory = dashboardData.mCategory;
|
mCategory = dashboardData.mCategory;
|
||||||
mConditions = dashboardData.mConditions;
|
mConditions = dashboardData.mConditions;
|
||||||
mConditionsV2 = dashboardData.mConditionsV2;
|
|
||||||
mSuggestions = dashboardData.mSuggestions;
|
mSuggestions = dashboardData.mSuggestions;
|
||||||
mConditionExpanded = dashboardData.mConditionExpanded;
|
mConditionExpanded = dashboardData.mConditionExpanded;
|
||||||
}
|
}
|
||||||
@@ -291,16 +263,11 @@ public class DashboardData {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Builder setConditions(List<Condition> conditions) {
|
public Builder setConditions(List<ConditionalCard> conditions) {
|
||||||
this.mConditions = conditions;
|
this.mConditions = conditions;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Builder setConditionsV2(List<ConditionalCard> conditions) {
|
|
||||||
this.mConditionsV2 = conditions;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Builder setSuggestions(List<Suggestion> suggestions) {
|
public Builder setSuggestions(List<Suggestion> suggestions) {
|
||||||
this.mSuggestions = suggestions;
|
this.mSuggestions = suggestions;
|
||||||
return this;
|
return this;
|
||||||
@@ -374,7 +341,7 @@ public class DashboardData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The main data object in item, usually is a {@link Tile}, {@link Condition}
|
* The main data object in item, usually is a {@link Tile}, {@link ConditionalCard}
|
||||||
* object. This object can also be null when the
|
* object. This object can also be null when the
|
||||||
* item is an divider line. Please refer to {@link #buildItemsData()} for
|
* item is an divider line. Please refer to {@link #buildItemsData()} for
|
||||||
* detail usage of the Item.
|
* detail usage of the Item.
|
||||||
@@ -448,22 +415,15 @@ public class DashboardData {
|
|||||||
public final CharSequence title;
|
public final CharSequence title;
|
||||||
public final int conditionCount;
|
public final int conditionCount;
|
||||||
|
|
||||||
public ConditionHeaderData(List<Condition> conditions, List<ConditionalCard> conditionsV2) {
|
public ConditionHeaderData(List<ConditionalCard> conditions) {
|
||||||
if (conditionsV2 == null) {
|
conditionCount = sizeOf(conditions);
|
||||||
conditionCount = sizeOf(conditions);
|
title = conditionCount > 0 ? conditions.get(0).getTitle() : null;
|
||||||
title = conditionCount > 0 ? conditions.get(0).getTitle() : null;
|
conditionIcons = new ArrayList<>();
|
||||||
conditionIcons = new ArrayList<>();
|
if (conditions == null) {
|
||||||
for (int i = 0; conditions != null && i < conditions.size(); i++) {
|
return;
|
||||||
final Condition condition = conditions.get(i);
|
}
|
||||||
conditionIcons.add(condition.getIcon());
|
for (ConditionalCard card : conditions) {
|
||||||
}
|
conditionIcons.add(card.getIcon());
|
||||||
} else {
|
|
||||||
conditionCount = sizeOf(conditionsV2);
|
|
||||||
title = conditionCount > 0 ? conditionsV2.get(0).getTitle() : null;
|
|
||||||
conditionIcons = new ArrayList<>();
|
|
||||||
for (ConditionalCard card : conditionsV2) {
|
|
||||||
conditionIcons.add(card.getIcon());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -37,11 +37,10 @@ import com.android.settings.core.InstrumentedFragment;
|
|||||||
import com.android.settings.core.SettingsBaseActivity;
|
import com.android.settings.core.SettingsBaseActivity;
|
||||||
import com.android.settings.core.SettingsBaseActivity.CategoryListener;
|
import com.android.settings.core.SettingsBaseActivity.CategoryListener;
|
||||||
import com.android.settings.dashboard.suggestions.SuggestionFeatureProvider;
|
import com.android.settings.dashboard.suggestions.SuggestionFeatureProvider;
|
||||||
import com.android.settings.homepage.conditional.Condition;
|
|
||||||
import com.android.settings.homepage.conditional.ConditionListener;
|
import com.android.settings.homepage.conditional.ConditionListener;
|
||||||
import com.android.settings.homepage.conditional.ConditionManager;
|
|
||||||
import com.android.settings.homepage.conditional.FocusRecyclerView;
|
import com.android.settings.homepage.conditional.FocusRecyclerView;
|
||||||
import com.android.settings.homepage.conditional.FocusRecyclerView.FocusListener;
|
import com.android.settings.homepage.conditional.FocusRecyclerView.FocusListener;
|
||||||
|
import com.android.settings.homepage.conditional.ConditionManager;
|
||||||
import com.android.settings.overlay.FeatureFactory;
|
import com.android.settings.overlay.FeatureFactory;
|
||||||
import com.android.settings.widget.ActionBarShadowController;
|
import com.android.settings.widget.ActionBarShadowController;
|
||||||
import com.android.settingslib.drawer.CategoryKey;
|
import com.android.settingslib.drawer.CategoryKey;
|
||||||
@@ -74,7 +73,6 @@ public class DashboardSummary extends InstrumentedFragment
|
|||||||
private DashboardAdapter mAdapter;
|
private DashboardAdapter mAdapter;
|
||||||
private SummaryLoader mSummaryLoader;
|
private SummaryLoader mSummaryLoader;
|
||||||
private ConditionManager mConditionManager;
|
private ConditionManager mConditionManager;
|
||||||
private com.android.settings.homepage.conditional.v2.ConditionManager mConditionManager2;
|
|
||||||
private LinearLayoutManager mLayoutManager;
|
private LinearLayoutManager mLayoutManager;
|
||||||
private SuggestionControllerMixinCompat mSuggestionControllerMixin;
|
private SuggestionControllerMixinCompat mSuggestionControllerMixin;
|
||||||
private DashboardFeatureProvider mDashboardFeatureProvider;
|
private DashboardFeatureProvider mDashboardFeatureProvider;
|
||||||
@@ -123,18 +121,9 @@ public class DashboardSummary extends InstrumentedFragment
|
|||||||
|
|
||||||
mSummaryLoader = new SummaryLoader(activity, CategoryKey.CATEGORY_HOMEPAGE);
|
mSummaryLoader = new SummaryLoader(activity, CategoryKey.CATEGORY_HOMEPAGE);
|
||||||
|
|
||||||
if (com.android.settings.homepage.conditional.v2.ConditionManager.isEnabled(activity)) {
|
mConditionManager =
|
||||||
mConditionManager = null;
|
new ConditionManager(
|
||||||
mConditionManager2 =
|
activity, this /* listener */);
|
||||||
new com.android.settings.homepage.conditional.v2.ConditionManager(
|
|
||||||
activity, this /* listener */);
|
|
||||||
} else {
|
|
||||||
mConditionManager = ConditionManager.get(activity, false);
|
|
||||||
mConditionManager2 = null;
|
|
||||||
}
|
|
||||||
if (mConditionManager2 == null) {
|
|
||||||
getSettingsLifecycle().addObserver(mConditionManager);
|
|
||||||
}
|
|
||||||
if (savedInstanceState != null) {
|
if (savedInstanceState != null) {
|
||||||
mIsOnCategoriesChangedCalled =
|
mIsOnCategoriesChangedCalled =
|
||||||
savedInstanceState.getBoolean(STATE_CATEGORIES_CHANGE_CALLED);
|
savedInstanceState.getBoolean(STATE_CATEGORIES_CHANGE_CALLED);
|
||||||
@@ -157,17 +146,7 @@ public class DashboardSummary extends InstrumentedFragment
|
|||||||
|
|
||||||
((SettingsBaseActivity) getActivity()).addCategoryListener(this);
|
((SettingsBaseActivity) getActivity()).addCategoryListener(this);
|
||||||
mSummaryLoader.setListening(true);
|
mSummaryLoader.setListening(true);
|
||||||
final int metricsCategory = getMetricsCategory();
|
mConditionManager.startMonitoringStateChange();
|
||||||
if (mConditionManager2 == null) {
|
|
||||||
for (Condition c : mConditionManager.getConditions()) {
|
|
||||||
if (c.shouldShow()) {
|
|
||||||
mMetricsFeatureProvider.visible(getContext(), metricsCategory,
|
|
||||||
c.getMetricsConstant());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
mConditionManager2.startMonitoringStateChange();
|
|
||||||
}
|
|
||||||
if (DEBUG_TIMING) {
|
if (DEBUG_TIMING) {
|
||||||
Log.d(TAG, "onResume took " + (System.currentTimeMillis() - startTime) + " ms");
|
Log.d(TAG, "onResume took " + (System.currentTimeMillis() - startTime) + " ms");
|
||||||
}
|
}
|
||||||
@@ -179,42 +158,16 @@ public class DashboardSummary extends InstrumentedFragment
|
|||||||
|
|
||||||
((SettingsBaseActivity) getActivity()).remCategoryListener(this);
|
((SettingsBaseActivity) getActivity()).remCategoryListener(this);
|
||||||
mSummaryLoader.setListening(false);
|
mSummaryLoader.setListening(false);
|
||||||
if (mConditionManager2 == null) {
|
mConditionManager.stopMonitoringStateChange();
|
||||||
for (Condition c : mConditionManager.getConditions()) {
|
|
||||||
if (c.shouldShow()) {
|
|
||||||
mMetricsFeatureProvider.hidden(getContext(), c.getMetricsConstant());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Unregister condition listeners.
|
|
||||||
if (mConditionManager != null) {
|
|
||||||
mConditionManager.remListener(this);
|
|
||||||
}
|
|
||||||
if (mConditionManager2 != null) {
|
|
||||||
mConditionManager2.stopMonitoringStateChange();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onWindowFocusChanged(boolean hasWindowFocus) {
|
public void onWindowFocusChanged(boolean hasWindowFocus) {
|
||||||
long startTime = System.currentTimeMillis();
|
long startTime = System.currentTimeMillis();
|
||||||
if (mConditionManager2 == null) {
|
if (hasWindowFocus) {
|
||||||
if (hasWindowFocus) {
|
mConditionManager.startMonitoringStateChange();
|
||||||
Log.d(TAG, "Listening for condition changes");
|
|
||||||
mConditionManager.addListener(this);
|
|
||||||
Log.d(TAG, "conditions refreshed");
|
|
||||||
mConditionManager.refreshAll();
|
|
||||||
} else {
|
|
||||||
Log.d(TAG, "Stopped listening for condition changes");
|
|
||||||
mConditionManager.remListener(this);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
// TODO(b/112485407): Register monitoring for condition manager v2.
|
mConditionManager.stopMonitoringStateChange();
|
||||||
if (hasWindowFocus) {
|
|
||||||
mConditionManager2.startMonitoringStateChange();
|
|
||||||
} else {
|
|
||||||
mConditionManager2.stopMonitoringStateChange();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (DEBUG_TIMING) {
|
if (DEBUG_TIMING) {
|
||||||
Log.d(TAG, "onWindowFocusChanged took "
|
Log.d(TAG, "onWindowFocusChanged took "
|
||||||
@@ -248,8 +201,7 @@ public class DashboardSummary extends InstrumentedFragment
|
|||||||
mDashboard.setListener(this);
|
mDashboard.setListener(this);
|
||||||
mDashboard.setItemAnimator(new DashboardItemAnimator());
|
mDashboard.setItemAnimator(new DashboardItemAnimator());
|
||||||
mAdapter = new DashboardAdapter(getContext(), bundle,
|
mAdapter = new DashboardAdapter(getContext(), bundle,
|
||||||
mConditionManager == null ? null : mConditionManager.getConditions(),
|
mConditionManager,
|
||||||
mConditionManager2,
|
|
||||||
mSuggestionControllerMixin,
|
mSuggestionControllerMixin,
|
||||||
getSettingsLifecycle());
|
getSettingsLifecycle());
|
||||||
mDashboard.setAdapter(mAdapter);
|
mDashboard.setAdapter(mAdapter);
|
||||||
@@ -290,14 +242,10 @@ public class DashboardSummary extends InstrumentedFragment
|
|||||||
// constructor when we create the view, the first handling is not necessary.
|
// constructor when we create the view, the first handling is not necessary.
|
||||||
// But, on the subsequent calls we need to handle it because there might be real changes to
|
// But, on the subsequent calls we need to handle it because there might be real changes to
|
||||||
// conditions.
|
// conditions.
|
||||||
if (mOnConditionsChangedCalled || mConditionManager2 != null) {
|
if (mOnConditionsChangedCalled) {
|
||||||
final boolean scrollToTop =
|
final boolean scrollToTop =
|
||||||
mLayoutManager.findFirstCompletelyVisibleItemPosition() <= 1;
|
mLayoutManager.findFirstCompletelyVisibleItemPosition() <= 1;
|
||||||
if (mConditionManager2 == null) {
|
mAdapter.setConditions(mConditionManager.getDisplayableCards());
|
||||||
mAdapter.setConditions(mConditionManager.getConditions());
|
|
||||||
} else {
|
|
||||||
mAdapter.setConditionsV2(mConditionManager2.getDisplayableCards());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (scrollToTop) {
|
if (scrollToTop) {
|
||||||
mDashboard.scrollToPosition(0);
|
mDashboard.scrollToPosition(0);
|
||||||
|
@@ -1,84 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2018 The Android Open Source Project
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.android.settings.homepage.conditional;
|
|
||||||
|
|
||||||
import android.content.BroadcastReceiver;
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.content.IntentFilter;
|
|
||||||
import android.media.AudioManager;
|
|
||||||
import android.provider.Settings;
|
|
||||||
|
|
||||||
import com.android.settings.R;
|
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
public abstract class AbnormalRingerConditionBase extends Condition {
|
|
||||||
|
|
||||||
private final IntentFilter mFilter;
|
|
||||||
|
|
||||||
protected final AudioManager mAudioManager;
|
|
||||||
|
|
||||||
private final RingerModeChangeReceiver mReceiver;
|
|
||||||
|
|
||||||
AbnormalRingerConditionBase(ConditionManager manager) {
|
|
||||||
super(manager);
|
|
||||||
mAudioManager =
|
|
||||||
(AudioManager) mManager.getContext().getSystemService(Context.AUDIO_SERVICE);
|
|
||||||
mReceiver = new RingerModeChangeReceiver(this);
|
|
||||||
|
|
||||||
mFilter = new IntentFilter(AudioManager.INTERNAL_RINGER_MODE_CHANGED_ACTION);
|
|
||||||
manager.getContext().registerReceiver(mReceiver, mFilter);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public CharSequence[] getActions() {
|
|
||||||
return new CharSequence[]{
|
|
||||||
mManager.getContext().getText(R.string.condition_device_muted_action_turn_on_sound)
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onPrimaryClick() {
|
|
||||||
mManager.getContext().startActivity(
|
|
||||||
new Intent(Settings.ACTION_SOUND_SETTINGS)
|
|
||||||
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onActionClick(int index) {
|
|
||||||
mAudioManager.setRingerModeInternal(AudioManager.RINGER_MODE_NORMAL);
|
|
||||||
mAudioManager.setStreamVolume(AudioManager.STREAM_RING, 1, 0 /* flags */);
|
|
||||||
refreshState();
|
|
||||||
}
|
|
||||||
|
|
||||||
static class RingerModeChangeReceiver extends BroadcastReceiver {
|
|
||||||
|
|
||||||
private final AbnormalRingerConditionBase mCondition;
|
|
||||||
|
|
||||||
public RingerModeChangeReceiver(AbnormalRingerConditionBase condition) {
|
|
||||||
mCondition = condition;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onReceive(Context context, Intent intent) {
|
|
||||||
final String action = intent.getAction();
|
|
||||||
if (AudioManager.INTERNAL_RINGER_MODE_CHANGED_ACTION.equals(action)) {
|
|
||||||
mCondition.refreshState();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -14,7 +14,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.android.settings.homepage.conditional.v2;
|
package com.android.settings.homepage.conditional;
|
||||||
|
|
||||||
import android.content.BroadcastReceiver;
|
import android.content.BroadcastReceiver;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
@@ -23,8 +23,6 @@ import android.content.IntentFilter;
|
|||||||
import android.media.AudioManager;
|
import android.media.AudioManager;
|
||||||
import android.provider.Settings;
|
import android.provider.Settings;
|
||||||
|
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
public abstract class AbnormalRingerConditionController implements ConditionalCardController {
|
public abstract class AbnormalRingerConditionController implements ConditionalCardController {
|
||||||
|
|
||||||
private static final IntentFilter FILTER =
|
private static final IntentFilter FILTER =
|
@@ -1,121 +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.homepage.conditional;
|
|
||||||
|
|
||||||
import android.content.BroadcastReceiver;
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.content.IntentFilter;
|
|
||||||
import android.graphics.drawable.Drawable;
|
|
||||||
import android.net.ConnectivityManager;
|
|
||||||
import android.provider.Settings;
|
|
||||||
import android.util.Log;
|
|
||||||
|
|
||||||
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
|
||||||
import com.android.settings.R;
|
|
||||||
import com.android.settingslib.WirelessUtils;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @deprecated in favor of {@link AirplaneModeConditionCard}.
|
|
||||||
*/
|
|
||||||
@Deprecated
|
|
||||||
public class AirplaneModeCondition extends Condition {
|
|
||||||
public static String TAG = "APM_Condition";
|
|
||||||
|
|
||||||
private final Receiver mReceiver;
|
|
||||||
|
|
||||||
private static final IntentFilter AIRPLANE_MODE_FILTER =
|
|
||||||
new IntentFilter(Intent.ACTION_AIRPLANE_MODE_CHANGED);
|
|
||||||
|
|
||||||
public AirplaneModeCondition(ConditionManager conditionManager) {
|
|
||||||
super(conditionManager);
|
|
||||||
mReceiver = new Receiver();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void refreshState() {
|
|
||||||
Log.d(TAG, "APM condition refreshed");
|
|
||||||
setActive(WirelessUtils.isAirplaneModeOn(mManager.getContext()));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected BroadcastReceiver getReceiver() {
|
|
||||||
return mReceiver;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected IntentFilter getIntentFilter() {
|
|
||||||
return AIRPLANE_MODE_FILTER;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Drawable getIcon() {
|
|
||||||
return mManager.getContext().getDrawable(R.drawable.ic_airplane);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void setActive(boolean active) {
|
|
||||||
super.setActive(active);
|
|
||||||
Log.d(TAG, "setActive was called with " + active);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public CharSequence getTitle() {
|
|
||||||
return mManager.getContext().getString(R.string.condition_airplane_title);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public CharSequence getSummary() {
|
|
||||||
return mManager.getContext().getString(R.string.condition_airplane_summary);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public CharSequence[] getActions() {
|
|
||||||
return new CharSequence[] {mManager.getContext().getString(R.string.condition_turn_off)};
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onPrimaryClick() {
|
|
||||||
mManager.getContext().startActivity(
|
|
||||||
new Intent(Settings.ACTION_WIRELESS_SETTINGS)
|
|
||||||
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onActionClick(int index) {
|
|
||||||
if (index == 0) {
|
|
||||||
ConnectivityManager.from(mManager.getContext()).setAirplaneMode(false);
|
|
||||||
setActive(false);
|
|
||||||
} else {
|
|
||||||
throw new IllegalArgumentException("Unexpected index " + index);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getMetricsConstant() {
|
|
||||||
return MetricsEvent.SETTINGS_CONDITION_AIRPLANE_MODE;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class Receiver extends BroadcastReceiver {
|
|
||||||
@Override
|
|
||||||
public void onReceive(Context context, Intent intent) {
|
|
||||||
if (Intent.ACTION_AIRPLANE_MODE_CHANGED.equals(intent.getAction())) {
|
|
||||||
ConditionManager.get(context).getCondition(AirplaneModeCondition.class)
|
|
||||||
.refreshState();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -14,7 +14,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.android.settings.homepage.conditional.v2;
|
package com.android.settings.homepage.conditional;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
@@ -14,7 +14,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.android.settings.homepage.conditional.v2;
|
package com.android.settings.homepage.conditional;
|
||||||
|
|
||||||
import android.content.BroadcastReceiver;
|
import android.content.BroadcastReceiver;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
@@ -1,79 +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.homepage.conditional;
|
|
||||||
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.graphics.drawable.Drawable;
|
|
||||||
import android.net.NetworkPolicyManager;
|
|
||||||
|
|
||||||
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
|
||||||
import com.android.settings.R;
|
|
||||||
import com.android.settings.Settings;
|
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
public class BackgroundDataCondition extends Condition {
|
|
||||||
|
|
||||||
public BackgroundDataCondition(ConditionManager manager) {
|
|
||||||
super(manager);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void refreshState() {
|
|
||||||
setActive(NetworkPolicyManager.from(mManager.getContext()).getRestrictBackground());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Drawable getIcon() {
|
|
||||||
return mManager.getContext().getDrawable(R.drawable.ic_data_saver);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public CharSequence getTitle() {
|
|
||||||
return mManager.getContext().getString(R.string.condition_bg_data_title);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public CharSequence getSummary() {
|
|
||||||
return mManager.getContext().getString(R.string.condition_bg_data_summary);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public CharSequence[] getActions() {
|
|
||||||
return new CharSequence[] {mManager.getContext().getString(R.string.condition_turn_off)};
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onPrimaryClick() {
|
|
||||||
mManager.getContext().startActivity(new Intent(mManager.getContext(),
|
|
||||||
Settings.DataUsageSummaryActivity.class)
|
|
||||||
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getMetricsConstant() {
|
|
||||||
return MetricsEvent.SETTINGS_CONDITION_BACKGROUND_DATA;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onActionClick(int index) {
|
|
||||||
if (index == 0) {
|
|
||||||
NetworkPolicyManager.from(mManager.getContext()).setRestrictBackground(false);
|
|
||||||
setActive(false);
|
|
||||||
} else {
|
|
||||||
throw new IllegalArgumentException("Unexpected index " + index);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -14,7 +14,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.android.settings.homepage.conditional.v2;
|
package com.android.settings.homepage.conditional;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
@@ -14,7 +14,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.android.settings.homepage.conditional.v2;
|
package com.android.settings.homepage.conditional;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
@@ -1,117 +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.homepage.conditional;
|
|
||||||
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.graphics.drawable.Drawable;
|
|
||||||
import android.os.PowerManager;
|
|
||||||
|
|
||||||
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
|
||||||
import com.android.settings.R;
|
|
||||||
import com.android.settings.core.SubSettingLauncher;
|
|
||||||
import com.android.settings.fuelgauge.BatterySaverReceiver;
|
|
||||||
import com.android.settings.fuelgauge.batterysaver.BatterySaverSettings;
|
|
||||||
import com.android.settingslib.fuelgauge.BatterySaverUtils;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @deprecated in favor of {@link BatterySaverConditionCard}
|
|
||||||
*/
|
|
||||||
@Deprecated
|
|
||||||
public class BatterySaverCondition extends Condition implements
|
|
||||||
BatterySaverReceiver.BatterySaverListener {
|
|
||||||
|
|
||||||
private final BatterySaverReceiver mReceiver;
|
|
||||||
|
|
||||||
public BatterySaverCondition(ConditionManager manager) {
|
|
||||||
super(manager);
|
|
||||||
|
|
||||||
mReceiver = new BatterySaverReceiver(manager.getContext());
|
|
||||||
mReceiver.setBatterySaverListener(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void refreshState() {
|
|
||||||
PowerManager powerManager = mManager.getContext().getSystemService(PowerManager.class);
|
|
||||||
setActive(powerManager.isPowerSaveMode());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Drawable getIcon() {
|
|
||||||
return mManager.getContext().getDrawable(R.drawable.ic_battery_saver_accent_24dp);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public CharSequence getTitle() {
|
|
||||||
return mManager.getContext().getString(R.string.condition_battery_title);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public CharSequence getSummary() {
|
|
||||||
return mManager.getContext().getString(R.string.condition_battery_summary);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public CharSequence[] getActions() {
|
|
||||||
return new CharSequence[]{mManager.getContext().getString(R.string.condition_turn_off)};
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onPrimaryClick() {
|
|
||||||
new SubSettingLauncher(mManager.getContext())
|
|
||||||
.setDestination(BatterySaverSettings.class.getName())
|
|
||||||
.setSourceMetricsCategory(MetricsEvent.DASHBOARD_SUMMARY)
|
|
||||||
.setTitleRes(R.string.battery_saver)
|
|
||||||
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
|
||||||
.launch();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onActionClick(int index) {
|
|
||||||
if (index == 0) {
|
|
||||||
BatterySaverUtils.setPowerSaveMode(mManager.getContext(), false,
|
|
||||||
/*needFirstTimeWarning*/ false);
|
|
||||||
refreshState();
|
|
||||||
} else {
|
|
||||||
throw new IllegalArgumentException("Unexpected index " + index);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getMetricsConstant() {
|
|
||||||
return MetricsEvent.SETTINGS_CONDITION_BATTERY_SAVER;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onResume() {
|
|
||||||
mReceiver.setListening(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onPause() {
|
|
||||||
mReceiver.setListening(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onPowerSaveModeChanged() {
|
|
||||||
ConditionManager.get(mManager.getContext()).getCondition(BatterySaverCondition.class)
|
|
||||||
.refreshState();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onBatteryChanged(boolean pluggedIn) {
|
|
||||||
// do nothing
|
|
||||||
}
|
|
||||||
}
|
|
@@ -14,7 +14,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.android.settings.homepage.conditional.v2;
|
package com.android.settings.homepage.conditional;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
@@ -14,7 +14,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.android.settings.homepage.conditional.v2;
|
package com.android.settings.homepage.conditional;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.os.PowerManager;
|
import android.os.PowerManager;
|
@@ -1,118 +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.homepage.conditional;
|
|
||||||
|
|
||||||
import android.content.BroadcastReceiver;
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.content.IntentFilter;
|
|
||||||
import android.graphics.drawable.Drawable;
|
|
||||||
import android.net.ConnectivityManager;
|
|
||||||
import android.telephony.TelephonyManager;
|
|
||||||
|
|
||||||
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
|
||||||
import com.android.internal.telephony.TelephonyIntents;
|
|
||||||
import com.android.settings.R;
|
|
||||||
import com.android.settings.Settings;
|
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
public class CellularDataCondition extends Condition {
|
|
||||||
|
|
||||||
private final Receiver mReceiver;
|
|
||||||
|
|
||||||
private static final IntentFilter DATA_CONNECTION_FILTER =
|
|
||||||
new IntentFilter(TelephonyIntents.ACTION_ANY_DATA_CONNECTION_STATE_CHANGED);
|
|
||||||
|
|
||||||
public CellularDataCondition(ConditionManager manager) {
|
|
||||||
super(manager);
|
|
||||||
mReceiver = new Receiver();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void refreshState() {
|
|
||||||
ConnectivityManager connectivity = mManager.getContext().getSystemService(
|
|
||||||
ConnectivityManager.class);
|
|
||||||
TelephonyManager telephony = mManager.getContext().getSystemService(TelephonyManager.class);
|
|
||||||
if (!connectivity.isNetworkSupported(ConnectivityManager.TYPE_MOBILE)
|
|
||||||
|| telephony.getSimState() != TelephonyManager.SIM_STATE_READY) {
|
|
||||||
setActive(false);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
setActive(!telephony.isDataEnabled());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected BroadcastReceiver getReceiver() {
|
|
||||||
return mReceiver;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected IntentFilter getIntentFilter() {
|
|
||||||
return DATA_CONNECTION_FILTER;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Drawable getIcon() {
|
|
||||||
return mManager.getContext().getDrawable(R.drawable.ic_cellular_off);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public CharSequence getTitle() {
|
|
||||||
return mManager.getContext().getString(R.string.condition_cellular_title);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public CharSequence getSummary() {
|
|
||||||
return mManager.getContext().getString(R.string.condition_cellular_summary);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public CharSequence[] getActions() {
|
|
||||||
return new CharSequence[] { mManager.getContext().getString(R.string.condition_turn_on) };
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onPrimaryClick() {
|
|
||||||
mManager.getContext().startActivity(new Intent(mManager.getContext(),
|
|
||||||
Settings.DataUsageSummaryActivity.class).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onActionClick(int index) {
|
|
||||||
if (index == 0) {
|
|
||||||
TelephonyManager telephony = mManager.getContext().getSystemService(
|
|
||||||
TelephonyManager.class);
|
|
||||||
telephony.setDataEnabled(true);
|
|
||||||
setActive(false);
|
|
||||||
} else {
|
|
||||||
throw new IllegalArgumentException("Unexpected index " + index);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getMetricsConstant() {
|
|
||||||
return MetricsEvent.SETTINGS_CONDITION_CELLULAR_DATA;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class Receiver extends BroadcastReceiver {
|
|
||||||
@Override
|
|
||||||
public void onReceive(Context context, Intent intent) {
|
|
||||||
if (TelephonyIntents.ACTION_ANY_DATA_CONNECTION_STATE_CHANGED.equals(
|
|
||||||
intent.getAction())) {
|
|
||||||
CellularDataCondition condition = ConditionManager.get(context).getCondition(
|
|
||||||
CellularDataCondition.class);
|
|
||||||
if (condition != null) {
|
|
||||||
condition.refreshState();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -14,7 +14,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.android.settings.homepage.conditional.v2;
|
package com.android.settings.homepage.conditional;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
@@ -14,7 +14,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.android.settings.homepage.conditional.v2;
|
package com.android.settings.homepage.conditional;
|
||||||
|
|
||||||
import android.content.BroadcastReceiver;
|
import android.content.BroadcastReceiver;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
@@ -1,162 +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.homepage.conditional;
|
|
||||||
|
|
||||||
import android.content.BroadcastReceiver;
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.IntentFilter;
|
|
||||||
import android.graphics.drawable.Drawable;
|
|
||||||
import android.os.PersistableBundle;
|
|
||||||
|
|
||||||
import androidx.annotation.VisibleForTesting;
|
|
||||||
|
|
||||||
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
|
||||||
import com.android.settings.overlay.FeatureFactory;
|
|
||||||
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
|
|
||||||
|
|
||||||
public abstract class Condition {
|
|
||||||
|
|
||||||
private static final String KEY_SILENCE = "silence";
|
|
||||||
private static final String KEY_ACTIVE = "active";
|
|
||||||
private static final String KEY_LAST_STATE = "last_state";
|
|
||||||
|
|
||||||
protected final ConditionManager mManager;
|
|
||||||
protected final MetricsFeatureProvider mMetricsFeatureProvider;
|
|
||||||
protected boolean mReceiverRegistered;
|
|
||||||
|
|
||||||
private boolean mIsSilenced;
|
|
||||||
private boolean mIsActive;
|
|
||||||
private long mLastStateChange;
|
|
||||||
|
|
||||||
// All conditions must live in this package.
|
|
||||||
Condition(ConditionManager manager) {
|
|
||||||
this(manager, FeatureFactory.getFactory(manager.getContext()).getMetricsFeatureProvider());
|
|
||||||
}
|
|
||||||
|
|
||||||
Condition(ConditionManager manager, MetricsFeatureProvider metricsFeatureProvider) {
|
|
||||||
mManager = manager;
|
|
||||||
mMetricsFeatureProvider = metricsFeatureProvider;
|
|
||||||
}
|
|
||||||
|
|
||||||
void restoreState(PersistableBundle bundle) {
|
|
||||||
mIsSilenced = bundle.getBoolean(KEY_SILENCE);
|
|
||||||
mIsActive = bundle.getBoolean(KEY_ACTIVE);
|
|
||||||
mLastStateChange = bundle.getLong(KEY_LAST_STATE);
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean saveState(PersistableBundle bundle) {
|
|
||||||
if (mIsSilenced) {
|
|
||||||
bundle.putBoolean(KEY_SILENCE, mIsSilenced);
|
|
||||||
}
|
|
||||||
if (mIsActive) {
|
|
||||||
bundle.putBoolean(KEY_ACTIVE, mIsActive);
|
|
||||||
bundle.putLong(KEY_LAST_STATE, mLastStateChange);
|
|
||||||
}
|
|
||||||
return mIsSilenced || mIsActive;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void notifyChanged() {
|
|
||||||
mManager.notifyChanged(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isSilenced() {
|
|
||||||
return mIsSilenced;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isActive() {
|
|
||||||
return mIsActive;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void setActive(boolean active) {
|
|
||||||
if (mIsActive == active) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
mIsActive = active;
|
|
||||||
mLastStateChange = System.currentTimeMillis();
|
|
||||||
if (mIsSilenced && !active) {
|
|
||||||
mIsSilenced = false;
|
|
||||||
onSilenceChanged(mIsSilenced);
|
|
||||||
}
|
|
||||||
notifyChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void silence() {
|
|
||||||
if (!mIsSilenced) {
|
|
||||||
mIsSilenced = true;
|
|
||||||
Context context = mManager.getContext();
|
|
||||||
mMetricsFeatureProvider.action(context, MetricsEvent.ACTION_SETTINGS_CONDITION_DISMISS,
|
|
||||||
getMetricsConstant());
|
|
||||||
onSilenceChanged(mIsSilenced);
|
|
||||||
notifyChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@VisibleForTesting
|
|
||||||
void onSilenceChanged(boolean silenced) {
|
|
||||||
final BroadcastReceiver receiver = getReceiver();
|
|
||||||
if (receiver == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (silenced) {
|
|
||||||
if (!mReceiverRegistered) {
|
|
||||||
mManager.getContext().registerReceiver(receiver, getIntentFilter());
|
|
||||||
mReceiverRegistered = true;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (mReceiverRegistered) {
|
|
||||||
mManager.getContext().unregisterReceiver(receiver);
|
|
||||||
mReceiverRegistered = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected BroadcastReceiver getReceiver() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected IntentFilter getIntentFilter() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean shouldShow() {
|
|
||||||
return isActive() && !isSilenced();
|
|
||||||
}
|
|
||||||
|
|
||||||
long getLastChange() {
|
|
||||||
return mLastStateChange;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onResume() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onPause() {
|
|
||||||
}
|
|
||||||
|
|
||||||
// State.
|
|
||||||
public abstract void refreshState();
|
|
||||||
|
|
||||||
public abstract int getMetricsConstant();
|
|
||||||
|
|
||||||
// UI.
|
|
||||||
public abstract Drawable getIcon();
|
|
||||||
public abstract CharSequence getTitle();
|
|
||||||
public abstract CharSequence getSummary();
|
|
||||||
public abstract CharSequence[] getActions();
|
|
||||||
|
|
||||||
public abstract void onPrimaryClick();
|
|
||||||
public abstract void onActionClick(int index);
|
|
||||||
}
|
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2017 The Android Open Source Project
|
* Copyright (C) 2018 The Android Open Source Project
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -13,77 +13,38 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.android.settings.homepage.conditional;
|
package com.android.settings.homepage.conditional;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.util.Log;
|
import android.text.TextUtils;
|
||||||
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 android.widget.Button;
|
||||||
|
|
||||||
import androidx.annotation.VisibleForTesting;
|
|
||||||
import androidx.recyclerview.widget.ItemTouchHelper;
|
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
import com.android.internal.logging.nano.MetricsProto;
|
||||||
import com.android.settings.R;
|
import com.android.settings.R;
|
||||||
import com.android.settings.dashboard.DashboardAdapter.DashboardItemHolder;
|
import com.android.settings.dashboard.DashboardAdapter;
|
||||||
import com.android.settings.overlay.FeatureFactory;
|
import com.android.settings.overlay.FeatureFactory;
|
||||||
import com.android.settingslib.WirelessUtils;
|
|
||||||
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
|
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
public class ConditionAdapter extends RecyclerView.Adapter<DashboardItemHolder> {
|
public class ConditionAdapter extends RecyclerView.Adapter<DashboardAdapter.DashboardItemHolder> {
|
||||||
public static final String TAG = "ConditionAdapter";
|
|
||||||
|
|
||||||
private final Context mContext;
|
private final Context mContext;
|
||||||
private final MetricsFeatureProvider mMetricsFeatureProvider;
|
private final MetricsFeatureProvider mMetricsFeatureProvider;
|
||||||
private List<Condition> mConditions;
|
private final ConditionManager mConditionManager;
|
||||||
private boolean mExpanded;
|
private final List<ConditionalCard> mConditions;
|
||||||
|
private final boolean mExpanded;
|
||||||
|
|
||||||
private View.OnClickListener mConditionClickListener = new View.OnClickListener() {
|
public ConditionAdapter(Context context, ConditionManager conditionManager,
|
||||||
|
List<ConditionalCard> conditions, boolean expanded) {
|
||||||
@Override
|
|
||||||
public void onClick(View v) {
|
|
||||||
//TODO: get rid of setTag/getTag
|
|
||||||
Condition condition = (Condition) v.getTag();
|
|
||||||
mMetricsFeatureProvider.action(mContext,
|
|
||||||
MetricsEvent.ACTION_SETTINGS_CONDITION_CLICK,
|
|
||||||
condition.getMetricsConstant());
|
|
||||||
condition.onPrimaryClick();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
@VisibleForTesting
|
|
||||||
ItemTouchHelper.SimpleCallback mSwipeCallback = 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
|
|
||||||
? super.getSwipeDirs(recyclerView, viewHolder) : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
|
|
||||||
Object item = getItem(viewHolder.getItemId());
|
|
||||||
// item can become null when running monkey
|
|
||||||
if (item != null) {
|
|
||||||
((Condition) item).silence();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
public ConditionAdapter(Context context, List<Condition> conditions, boolean expanded) {
|
|
||||||
mContext = context;
|
mContext = context;
|
||||||
|
mConditionManager = conditionManager;
|
||||||
mConditions = conditions;
|
mConditions = conditions;
|
||||||
mExpanded = expanded;
|
mExpanded = expanded;
|
||||||
mMetricsFeatureProvider = FeatureFactory.getFactory(context).getMetricsFeatureProvider();
|
mMetricsFeatureProvider = FeatureFactory.getFactory(context).getMetricsFeatureProvider();
|
||||||
@@ -91,30 +52,22 @@ public class ConditionAdapter extends RecyclerView.Adapter<DashboardItemHolder>
|
|||||||
setHasStableIds(true);
|
setHasStableIds(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Object getItem(long itemId) {
|
@Override
|
||||||
for (Condition condition : mConditions) {
|
public DashboardAdapter.DashboardItemHolder onCreateViewHolder(ViewGroup parent, int viewType) {
|
||||||
if (Objects.hash(condition.getTitle()) == itemId) {
|
return new DashboardAdapter.DashboardItemHolder(LayoutInflater.from(parent.getContext())
|
||||||
return condition;
|
.inflate(viewType, parent, false));
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DashboardItemHolder onCreateViewHolder(ViewGroup parent, int viewType) {
|
public void onBindViewHolder(DashboardAdapter.DashboardItemHolder holder, int position) {
|
||||||
return new DashboardItemHolder(LayoutInflater.from(parent.getContext()).inflate(
|
final ConditionalCard condition = mConditions.get(position);
|
||||||
viewType, parent, false));
|
final boolean isLastItem = position == mConditions.size() - 1;
|
||||||
}
|
bindViews(condition, holder, isLastItem);
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onBindViewHolder(DashboardItemHolder holder, int position) {
|
|
||||||
bindViews(mConditions.get(position), holder,
|
|
||||||
position == mConditions.size() - 1, mConditionClickListener);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long getItemId(int position) {
|
public long getItemId(int position) {
|
||||||
return Objects.hash(mConditions.get(position).getTitle());
|
return mConditions.get(position).getId();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -130,52 +83,42 @@ public class ConditionAdapter extends RecyclerView.Adapter<DashboardItemHolder>
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addDismissHandling(final RecyclerView recyclerView) {
|
private void bindViews(final ConditionalCard condition,
|
||||||
final ItemTouchHelper itemTouchHelper = new ItemTouchHelper(mSwipeCallback);
|
DashboardAdapter.DashboardItemHolder view, boolean isLastItem) {
|
||||||
itemTouchHelper.attachToRecyclerView(recyclerView);
|
mMetricsFeatureProvider.visible(mContext, MetricsProto.MetricsEvent.DASHBOARD_SUMMARY,
|
||||||
}
|
condition.getMetricsConstant());
|
||||||
|
view.itemView.findViewById(R.id.content).setOnClickListener(
|
||||||
private void bindViews(final Condition condition,
|
v -> {
|
||||||
DashboardItemHolder view, boolean isLastItem,
|
mMetricsFeatureProvider.action(mContext,
|
||||||
View.OnClickListener onClickListener) {
|
MetricsProto.MetricsEvent.ACTION_SETTINGS_CONDITION_CLICK,
|
||||||
if (condition instanceof AirplaneModeCondition) {
|
condition.getMetricsConstant());
|
||||||
Log.d(TAG, "Airplane mode condition has been bound with "
|
mConditionManager.onPrimaryClick(mContext, condition.getId());
|
||||||
+ "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.setImageDrawable(condition.getIcon());
|
view.icon.setImageDrawable(condition.getIcon());
|
||||||
view.title.setText(condition.getTitle());
|
view.title.setText(condition.getTitle());
|
||||||
|
view.summary.setText(condition.getSummary());
|
||||||
|
|
||||||
CharSequence[] actions = condition.getActions();
|
setViewVisibility(view.itemView, R.id.divider, !isLastItem);
|
||||||
final boolean hasButtons = actions.length > 0;
|
|
||||||
|
final CharSequence action = condition.getActionText();
|
||||||
|
final boolean hasButtons = !TextUtils.isEmpty(action);
|
||||||
setViewVisibility(view.itemView, R.id.buttonBar, hasButtons);
|
setViewVisibility(view.itemView, R.id.buttonBar, hasButtons);
|
||||||
|
|
||||||
view.summary.setText(condition.getSummary());
|
final Button button = view.itemView.findViewById(R.id.first_action);
|
||||||
for (int i = 0; i < 2; i++) {
|
if (hasButtons) {
|
||||||
Button button = (Button) view.itemView.findViewById(i == 0
|
button.setVisibility(View.VISIBLE);
|
||||||
? R.id.first_action : R.id.second_action);
|
button.setText(action);
|
||||||
if (actions.length > i) {
|
button.setOnClickListener(v -> {
|
||||||
button.setVisibility(View.VISIBLE);
|
final Context context = v.getContext();
|
||||||
button.setText(actions[i]);
|
mMetricsFeatureProvider.action(
|
||||||
final int index = i;
|
context, MetricsProto.MetricsEvent.ACTION_SETTINGS_CONDITION_BUTTON,
|
||||||
button.setOnClickListener(new View.OnClickListener() {
|
condition.getMetricsConstant());
|
||||||
@Override
|
mConditionManager.onActionClick(condition.getId());
|
||||||
public void onClick(View v) {
|
});
|
||||||
Context context = v.getContext();
|
} else {
|
||||||
FeatureFactory.getFactory(context).getMetricsFeatureProvider()
|
button.setVisibility(View.GONE);
|
||||||
.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) {
|
private void setViewVisibility(View containerView, int viewId, boolean visible) {
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2015 The Android Open Source Project
|
* Copyright (C) 2018 The Android Open Source Project
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -13,279 +13,187 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.android.settings.homepage.conditional;
|
package com.android.settings.homepage.conditional;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.os.AsyncTask;
|
|
||||||
import android.os.PersistableBundle;
|
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.util.Xml;
|
|
||||||
|
|
||||||
import com.android.settingslib.core.lifecycle.LifecycleObserver;
|
import androidx.annotation.NonNull;
|
||||||
import com.android.settingslib.core.lifecycle.events.OnPause;
|
import androidx.annotation.VisibleForTesting;
|
||||||
import com.android.settingslib.core.lifecycle.events.OnResume;
|
|
||||||
|
|
||||||
import org.xmlpull.v1.XmlPullParser;
|
|
||||||
import org.xmlpull.v1.XmlPullParserException;
|
|
||||||
import org.xmlpull.v1.XmlSerializer;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileReader;
|
|
||||||
import java.io.FileWriter;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.Comparator;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.concurrent.Callable;
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
import java.util.concurrent.Future;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.concurrent.TimeoutException;
|
||||||
|
|
||||||
public class ConditionManager implements LifecycleObserver, OnResume, OnPause {
|
public class ConditionManager {
|
||||||
|
|
||||||
private static final String TAG = "ConditionManager";
|
private static final String TAG = "ConditionManager";
|
||||||
|
|
||||||
private static final boolean DEBUG = false;
|
@VisibleForTesting
|
||||||
|
final List<ConditionalCard> mCandidates;
|
||||||
|
@VisibleForTesting
|
||||||
|
final List<ConditionalCardController> mCardControllers;
|
||||||
|
|
||||||
private static final String PKG = "com.android.settings.homepage.conditional.";
|
private static final long DISPLAYABLE_CHECKER_TIMEOUT_MS = 20;
|
||||||
|
|
||||||
private static final String FILE_NAME = "condition_state.xml";
|
private final ExecutorService mExecutorService;
|
||||||
private static final String TAG_CONDITIONS = "cs";
|
private final Context mAppContext;
|
||||||
private static final String TAG_CONDITION = "c";
|
private final ConditionListener mListener;
|
||||||
private static final String ATTR_CLASS = "cls";
|
|
||||||
|
|
||||||
private static ConditionManager sInstance;
|
private boolean mIsListeningToStateChange;
|
||||||
|
|
||||||
private final Context mContext;
|
public ConditionManager(Context context, ConditionListener listener) {
|
||||||
private final ArrayList<Condition> mConditions;
|
mAppContext = context.getApplicationContext();
|
||||||
private File mXmlFile;
|
mExecutorService = Executors.newCachedThreadPool();
|
||||||
|
mCandidates = new ArrayList<>();
|
||||||
private final ArrayList<ConditionListener> mListeners = new ArrayList<>();
|
mCardControllers = new ArrayList<>();
|
||||||
|
mListener = listener;
|
||||||
private ConditionManager(Context context, boolean loadConditionsNow) {
|
initCandidates();
|
||||||
mContext = context;
|
|
||||||
mConditions = new ArrayList<>();
|
|
||||||
if (loadConditionsNow) {
|
|
||||||
Log.d(TAG, "conditions loading synchronously");
|
|
||||||
ConditionLoader loader = new ConditionLoader();
|
|
||||||
loader.onPostExecute(loader.doInBackground());
|
|
||||||
} else {
|
|
||||||
Log.d(TAG, "conditions loading asychronously");
|
|
||||||
new ConditionLoader().execute();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void refreshAll() {
|
/**
|
||||||
final int N = mConditions.size();
|
* Returns a list of {@link ConditionalCard}s eligible for display.
|
||||||
for (int i = 0; i < N; i++) {
|
*/
|
||||||
mConditions.get(i).refreshState();
|
public List<ConditionalCard> getDisplayableCards() {
|
||||||
|
final List<ConditionalCard> cards = new ArrayList<>();
|
||||||
|
final List<Future<ConditionalCard>> displayableCards = new ArrayList<>();
|
||||||
|
// Check displayable future
|
||||||
|
for (ConditionalCard card : mCandidates) {
|
||||||
|
final DisplayableChecker future = new DisplayableChecker(
|
||||||
|
card, getController(card.getId()));
|
||||||
|
displayableCards.add(mExecutorService.submit(future));
|
||||||
}
|
}
|
||||||
}
|
// Collect future and add displayable cards
|
||||||
|
for (Future<ConditionalCard> cardFuture : displayableCards) {
|
||||||
private void readFromXml(File xmlFile, ArrayList<Condition> conditions) {
|
try {
|
||||||
if (DEBUG) Log.d(TAG, "Reading from " + xmlFile.toString());
|
final ConditionalCard card = cardFuture.get(DISPLAYABLE_CHECKER_TIMEOUT_MS,
|
||||||
try {
|
TimeUnit.MILLISECONDS);
|
||||||
XmlPullParser parser = Xml.newPullParser();
|
if (card != null) {
|
||||||
FileReader in = new FileReader(xmlFile);
|
cards.add(card);
|
||||||
parser.setInput(in);
|
|
||||||
int state = parser.getEventType();
|
|
||||||
|
|
||||||
while (state != XmlPullParser.END_DOCUMENT) {
|
|
||||||
if (TAG_CONDITION.equals(parser.getName())) {
|
|
||||||
int depth = parser.getDepth();
|
|
||||||
String clz = parser.getAttributeValue("", ATTR_CLASS);
|
|
||||||
if (!clz.startsWith(PKG)) {
|
|
||||||
clz = PKG + clz;
|
|
||||||
}
|
|
||||||
Condition condition = createCondition(Class.forName(clz));
|
|
||||||
PersistableBundle bundle = PersistableBundle.restoreFromXml(parser);
|
|
||||||
if (DEBUG) Log.d(TAG, "Reading " + clz + " -- " + bundle);
|
|
||||||
if (condition != null) {
|
|
||||||
condition.restoreState(bundle);
|
|
||||||
conditions.add(condition);
|
|
||||||
} else {
|
|
||||||
Log.e(TAG, "failed to add condition: " + clz);
|
|
||||||
}
|
|
||||||
while (parser.getDepth() > depth) {
|
|
||||||
parser.next();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
state = parser.next();
|
} catch (InterruptedException | ExecutionException | TimeoutException e) {
|
||||||
}
|
Log.w(TAG, "Failed to get displayable state for card, likely timeout. Skipping", e);
|
||||||
in.close();
|
|
||||||
} catch (XmlPullParserException | IOException | ClassNotFoundException e) {
|
|
||||||
Log.w(TAG, "Problem reading " + FILE_NAME, e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void saveToXml() {
|
|
||||||
if (DEBUG) Log.d(TAG, "Writing to " + mXmlFile.toString());
|
|
||||||
try {
|
|
||||||
XmlSerializer serializer = Xml.newSerializer();
|
|
||||||
FileWriter writer = new FileWriter(mXmlFile);
|
|
||||||
serializer.setOutput(writer);
|
|
||||||
|
|
||||||
serializer.startDocument("UTF-8", true);
|
|
||||||
serializer.startTag("", TAG_CONDITIONS);
|
|
||||||
|
|
||||||
final int N = mConditions.size();
|
|
||||||
for (int i = 0; i < N; i++) {
|
|
||||||
PersistableBundle bundle = new PersistableBundle();
|
|
||||||
if (mConditions.get(i).saveState(bundle)) {
|
|
||||||
serializer.startTag("", TAG_CONDITION);
|
|
||||||
final String clz = mConditions.get(i).getClass().getSimpleName();
|
|
||||||
serializer.attribute("", ATTR_CLASS, clz);
|
|
||||||
bundle.saveToXml(serializer);
|
|
||||||
serializer.endTag("", TAG_CONDITION);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
serializer.endTag("", TAG_CONDITIONS);
|
|
||||||
serializer.flush();
|
|
||||||
writer.close();
|
|
||||||
} catch (XmlPullParserException | IOException e) {
|
|
||||||
Log.w(TAG, "Problem writing " + FILE_NAME, e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void addMissingConditions(ArrayList<Condition> conditions) {
|
|
||||||
addIfMissing(AirplaneModeCondition.class, conditions);
|
|
||||||
addIfMissing(HotspotCondition.class, conditions);
|
|
||||||
addIfMissing(DndCondition.class, conditions);
|
|
||||||
addIfMissing(BatterySaverCondition.class, conditions);
|
|
||||||
addIfMissing(CellularDataCondition.class, conditions);
|
|
||||||
addIfMissing(BackgroundDataCondition.class, conditions);
|
|
||||||
addIfMissing(WorkModeCondition.class, conditions);
|
|
||||||
addIfMissing(NightDisplayCondition.class, conditions);
|
|
||||||
addIfMissing(RingerMutedCondition.class, conditions);
|
|
||||||
addIfMissing(RingerVibrateCondition.class, conditions);
|
|
||||||
Collections.sort(conditions, CONDITION_COMPARATOR);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void addIfMissing(Class<? extends Condition> clz, ArrayList<Condition> conditions) {
|
|
||||||
if (getCondition(clz, conditions) == null) {
|
|
||||||
if (DEBUG) Log.d(TAG, "Adding missing " + clz.getName());
|
|
||||||
Condition condition = createCondition(clz);
|
|
||||||
if (condition != null) {
|
|
||||||
conditions.add(condition);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return cards;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Condition createCondition(Class<?> clz) {
|
/**
|
||||||
if (AirplaneModeCondition.class == clz) {
|
* Handler when the card is clicked.
|
||||||
return new AirplaneModeCondition(this);
|
*
|
||||||
} else if (HotspotCondition.class == clz) {
|
* @see {@link ConditionalCardController#onPrimaryClick(Context)}
|
||||||
return new HotspotCondition(this);
|
*/
|
||||||
} else if (DndCondition.class == clz) {
|
public void onPrimaryClick(Context context, long id) {
|
||||||
return new DndCondition(this);
|
getController(id).onPrimaryClick(context);
|
||||||
} else if (BatterySaverCondition.class == clz) {
|
}
|
||||||
return new BatterySaverCondition(this);
|
|
||||||
} else if (CellularDataCondition.class == clz) {
|
/**
|
||||||
return new CellularDataCondition(this);
|
* Handler when the card action is clicked.
|
||||||
} else if (BackgroundDataCondition.class == clz) {
|
*
|
||||||
return new BackgroundDataCondition(this);
|
* @see {@link ConditionalCardController#onActionClick()}
|
||||||
} else if (WorkModeCondition.class == clz) {
|
*/
|
||||||
return new WorkModeCondition(this);
|
public void onActionClick(long id) {
|
||||||
} else if (NightDisplayCondition.class == clz) {
|
getController(id).onActionClick();
|
||||||
return new NightDisplayCondition(this);
|
onConditionChanged();
|
||||||
} else if (RingerMutedCondition.class == clz) {
|
}
|
||||||
return new RingerMutedCondition(this);
|
|
||||||
} else if (RingerVibrateCondition.class == clz) {
|
/**
|
||||||
return new RingerVibrateCondition(this);
|
* Start monitoring state change for all conditions
|
||||||
|
*/
|
||||||
|
public void startMonitoringStateChange() {
|
||||||
|
if (mIsListeningToStateChange) {
|
||||||
|
Log.d(TAG, "Already listening to condition state changes, skipping");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
Log.e(TAG, "unknown condition class: " + clz.getSimpleName());
|
mIsListeningToStateChange = true;
|
||||||
return null;
|
for (ConditionalCardController controller : mCardControllers) {
|
||||||
|
controller.startMonitoringStateChange();
|
||||||
|
}
|
||||||
|
// Force a refresh on listener
|
||||||
|
onConditionChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
Context getContext() {
|
/**
|
||||||
return mContext;
|
* Stop monitoring state change for all conditions
|
||||||
|
*/
|
||||||
|
public void stopMonitoringStateChange() {
|
||||||
|
if (!mIsListeningToStateChange) {
|
||||||
|
Log.d(TAG, "Not listening to condition state changes, skipping");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (ConditionalCardController controller : mCardControllers) {
|
||||||
|
controller.stopMonitoringStateChange();
|
||||||
|
}
|
||||||
|
mIsListeningToStateChange = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public <T extends Condition> T getCondition(Class<T> clz) {
|
/**
|
||||||
return getCondition(clz, mConditions);
|
* Called when some conditional card's state has changed
|
||||||
|
*/
|
||||||
|
void onConditionChanged() {
|
||||||
|
if (mListener != null) {
|
||||||
|
mListener.onConditionsChanged();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private <T extends Condition> T getCondition(Class<T> clz, List<Condition> conditions) {
|
@NonNull
|
||||||
final int N = conditions.size();
|
<T extends ConditionalCardController> T getController(long id) {
|
||||||
for (int i = 0; i < N; i++) {
|
for (ConditionalCardController controller : mCardControllers) {
|
||||||
if (clz.equals(conditions.get(i).getClass())) {
|
if (controller.getId() == id) {
|
||||||
return (T) conditions.get(i);
|
return (T) controller;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
throw new IllegalStateException("Cannot find controller for " + id);
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<Condition> getConditions() {
|
private void initCandidates() {
|
||||||
return mConditions;
|
// Initialize controllers first.
|
||||||
|
mCardControllers.add(new AirplaneModeConditionController(mAppContext, this /* manager */));
|
||||||
|
mCardControllers.add(new BackgroundDataConditionController(mAppContext));
|
||||||
|
mCardControllers.add(new BatterySaverConditionController(mAppContext, this /* manager */));
|
||||||
|
mCardControllers.add(new CellularDataConditionController(mAppContext, this /* manager */));
|
||||||
|
mCardControllers.add(new DndConditionCardController(mAppContext, this /* manager */));
|
||||||
|
mCardControllers.add(new HotspotConditionController(mAppContext, this /* manager */));
|
||||||
|
mCardControllers.add(new NightDisplayConditionController(mAppContext));
|
||||||
|
mCardControllers.add(new RingerVibrateConditionController(mAppContext, this /* manager */));
|
||||||
|
mCardControllers.add(new RingerMutedConditionController(mAppContext, this /* manager */));
|
||||||
|
mCardControllers.add(new WorkModeConditionController(mAppContext));
|
||||||
|
|
||||||
|
// Initialize ui model later. UI model depends on controller.
|
||||||
|
mCandidates.add(new AirplaneModeConditionCard(mAppContext));
|
||||||
|
mCandidates.add(new BackgroundDataConditionCard(mAppContext));
|
||||||
|
mCandidates.add(new BatterySaverConditionCard(mAppContext));
|
||||||
|
mCandidates.add(new CellularDataConditionCard(mAppContext));
|
||||||
|
mCandidates.add(new DndConditionCard(mAppContext, this /* manager */));
|
||||||
|
mCandidates.add(new HotspotConditionCard(mAppContext, this /* manager */));
|
||||||
|
mCandidates.add(new NightDisplayConditionCard(mAppContext));
|
||||||
|
mCandidates.add(new RingerMutedConditionCard(mAppContext));
|
||||||
|
mCandidates.add(new RingerVibrateConditionCard(mAppContext));
|
||||||
|
mCandidates.add(new WorkModeConditionCard(mAppContext));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void notifyChanged(Condition condition) {
|
/**
|
||||||
saveToXml();
|
* Returns card if controller says it's displayable. Otherwise returns null.
|
||||||
Collections.sort(mConditions, CONDITION_COMPARATOR);
|
*/
|
||||||
final int N = mListeners.size();
|
public static class DisplayableChecker implements Callable<ConditionalCard> {
|
||||||
for (int i = 0; i < N; i++) {
|
|
||||||
mListeners.get(i).onConditionsChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addListener(ConditionListener listener) {
|
private final ConditionalCard mCard;
|
||||||
mListeners.add(listener);
|
private final ConditionalCardController mController;
|
||||||
listener.onConditionsChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void remListener(ConditionListener listener) {
|
private DisplayableChecker(ConditionalCard card, ConditionalCardController controller) {
|
||||||
mListeners.remove(listener);
|
mCard = card;
|
||||||
}
|
mController = controller;
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onResume() {
|
|
||||||
for (int i = 0, size = mConditions.size(); i < size; i++) {
|
|
||||||
mConditions.get(i).onResume();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onPause() {
|
|
||||||
for (int i = 0, size = mConditions.size(); i < size; i++) {
|
|
||||||
mConditions.get(i).onPause();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private class ConditionLoader extends AsyncTask<Void, Void, ArrayList<Condition>> {
|
|
||||||
@Override
|
|
||||||
protected ArrayList<Condition> doInBackground(Void... params) {
|
|
||||||
Log.d(TAG, "loading conditions from xml");
|
|
||||||
ArrayList<Condition> conditions = new ArrayList<>();
|
|
||||||
mXmlFile = new File(mContext.getFilesDir(), FILE_NAME);
|
|
||||||
if (mXmlFile.exists()) {
|
|
||||||
readFromXml(mXmlFile, conditions);
|
|
||||||
}
|
|
||||||
addMissingConditions(conditions);
|
|
||||||
return conditions;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onPostExecute(ArrayList<Condition> conditions) {
|
public ConditionalCard call() throws Exception {
|
||||||
Log.d(TAG, "conditions loaded from xml, refreshing conditions");
|
return mController.isDisplayable() ? mCard : null;
|
||||||
mConditions.clear();
|
|
||||||
mConditions.addAll(conditions);
|
|
||||||
refreshAll();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ConditionManager get(Context context) {
|
|
||||||
return get(context, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static ConditionManager get(Context context, boolean loadConditionsNow) {
|
|
||||||
if (sInstance == null) {
|
|
||||||
sInstance = new ConditionManager(context.getApplicationContext(), loadConditionsNow);
|
|
||||||
}
|
|
||||||
return sInstance;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final Comparator<Condition> CONDITION_COMPARATOR = new Comparator<Condition>() {
|
|
||||||
@Override
|
|
||||||
public int compare(Condition lhs, Condition rhs) {
|
|
||||||
return Long.compare(lhs.getLastChange(), rhs.getLastChange());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
@@ -14,7 +14,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.android.settings.homepage.conditional.v2;
|
package com.android.settings.homepage.conditional;
|
||||||
|
|
||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
||||||
|
|
@@ -14,7 +14,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.android.settings.homepage.conditional.v2;
|
package com.android.settings.homepage.conditional;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
|
@@ -1,166 +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.homepage.conditional;
|
|
||||||
|
|
||||||
import android.app.NotificationManager;
|
|
||||||
import android.content.BroadcastReceiver;
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.content.IntentFilter;
|
|
||||||
import android.graphics.drawable.Drawable;
|
|
||||||
import android.os.PersistableBundle;
|
|
||||||
import android.provider.Settings;
|
|
||||||
import android.provider.Settings.Global;
|
|
||||||
import android.service.notification.ZenModeConfig;
|
|
||||||
|
|
||||||
import androidx.annotation.VisibleForTesting;
|
|
||||||
|
|
||||||
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
|
||||||
import com.android.settings.R;
|
|
||||||
import com.android.settings.core.SubSettingLauncher;
|
|
||||||
import com.android.settings.notification.ZenModeSettings;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @deprecated in favor of {@link com.android.settings.homepage.conditional.v2.DndConditionCard}
|
|
||||||
*/
|
|
||||||
@Deprecated
|
|
||||||
public class DndCondition extends Condition {
|
|
||||||
|
|
||||||
private static final String TAG = "DndCondition";
|
|
||||||
private static final String KEY_STATE = "state";
|
|
||||||
|
|
||||||
private boolean mRegistered;
|
|
||||||
|
|
||||||
@VisibleForTesting
|
|
||||||
static final IntentFilter DND_FILTER =
|
|
||||||
new IntentFilter(NotificationManager.ACTION_INTERRUPTION_FILTER_CHANGED_INTERNAL);
|
|
||||||
@VisibleForTesting
|
|
||||||
protected ZenModeConfig mConfig;
|
|
||||||
|
|
||||||
private int mZen;
|
|
||||||
private final Receiver mReceiver;
|
|
||||||
|
|
||||||
public DndCondition(ConditionManager manager) {
|
|
||||||
super(manager);
|
|
||||||
mReceiver = new Receiver();
|
|
||||||
mManager.getContext().registerReceiver(mReceiver, DND_FILTER);
|
|
||||||
mRegistered = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void refreshState() {
|
|
||||||
NotificationManager notificationManager =
|
|
||||||
mManager.getContext().getSystemService(NotificationManager.class);
|
|
||||||
mZen = notificationManager.getZenMode();
|
|
||||||
boolean zenModeEnabled = mZen != Settings.Global.ZEN_MODE_OFF;
|
|
||||||
if (zenModeEnabled) {
|
|
||||||
mConfig = notificationManager.getZenModeConfig();
|
|
||||||
} else {
|
|
||||||
mConfig = null;
|
|
||||||
}
|
|
||||||
setActive(zenModeEnabled);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
boolean saveState(PersistableBundle bundle) {
|
|
||||||
bundle.putInt(KEY_STATE, mZen);
|
|
||||||
return super.saveState(bundle);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
void restoreState(PersistableBundle bundle) {
|
|
||||||
super.restoreState(bundle);
|
|
||||||
mZen = bundle.getInt(KEY_STATE, Global.ZEN_MODE_OFF);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Drawable getIcon() {
|
|
||||||
return mManager.getContext().getDrawable(R.drawable.ic_do_not_disturb_on_24dp);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public CharSequence getTitle() {
|
|
||||||
return mManager.getContext().getString(R.string.condition_zen_title);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public CharSequence getSummary() {
|
|
||||||
return ZenModeConfig.getDescription(mManager.getContext(), mZen != Global.ZEN_MODE_OFF,
|
|
||||||
mConfig, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public CharSequence[] getActions() {
|
|
||||||
return new CharSequence[] { mManager.getContext().getString(R.string.condition_turn_off) };
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onPrimaryClick() {
|
|
||||||
new SubSettingLauncher(mManager.getContext())
|
|
||||||
.setDestination(ZenModeSettings.class.getName())
|
|
||||||
.setSourceMetricsCategory(MetricsEvent.DASHBOARD_SUMMARY)
|
|
||||||
.setTitleRes(R.string.zen_mode_settings_title)
|
|
||||||
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
|
||||||
.launch();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onActionClick(int index) {
|
|
||||||
if (index == 0) {
|
|
||||||
NotificationManager notificationManager = mManager.getContext().getSystemService(
|
|
||||||
NotificationManager.class);
|
|
||||||
notificationManager.setZenMode(Settings.Global.ZEN_MODE_OFF, null, TAG);
|
|
||||||
setActive(false);
|
|
||||||
} else {
|
|
||||||
throw new IllegalArgumentException("Unexpected index " + index);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getMetricsConstant() {
|
|
||||||
return MetricsEvent.SETTINGS_CONDITION_DND;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class Receiver extends BroadcastReceiver {
|
|
||||||
@Override
|
|
||||||
public void onReceive(Context context, Intent intent) {
|
|
||||||
if (NotificationManager.ACTION_INTERRUPTION_FILTER_CHANGED_INTERNAL
|
|
||||||
.equals(intent.getAction())) {
|
|
||||||
final Condition condition =
|
|
||||||
ConditionManager.get(context).getCondition(DndCondition.class);
|
|
||||||
if (condition != null) {
|
|
||||||
condition.refreshState();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onResume() {
|
|
||||||
if (!mRegistered) {
|
|
||||||
mManager.getContext().registerReceiver(mReceiver, DND_FILTER);
|
|
||||||
mRegistered = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onPause() {
|
|
||||||
if (mRegistered) {
|
|
||||||
mManager.getContext().unregisterReceiver(mReceiver);
|
|
||||||
mRegistered = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -14,7 +14,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.android.settings.homepage.conditional.v2;
|
package com.android.settings.homepage.conditional;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
||||||
@@ -25,12 +25,10 @@ import com.android.settings.R;
|
|||||||
public class DndConditionCard implements ConditionalCard {
|
public class DndConditionCard implements ConditionalCard {
|
||||||
|
|
||||||
private final Context mAppContext;
|
private final Context mAppContext;
|
||||||
private final ConditionManager mManager;
|
|
||||||
private final DndConditionCardController mController;
|
private final DndConditionCardController mController;
|
||||||
|
|
||||||
public DndConditionCard(Context appContext, ConditionManager manager) {
|
public DndConditionCard(Context appContext, ConditionManager manager) {
|
||||||
mAppContext = appContext;
|
mAppContext = appContext;
|
||||||
mManager = manager;
|
|
||||||
mController = manager.getController(getId());
|
mController = manager.getController(getId());
|
||||||
}
|
}
|
||||||
|
|
@@ -14,7 +14,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.android.settings.homepage.conditional.v2;
|
package com.android.settings.homepage.conditional;
|
||||||
|
|
||||||
import android.app.NotificationManager;
|
import android.app.NotificationManager;
|
||||||
import android.content.BroadcastReceiver;
|
import android.content.BroadcastReceiver;
|
@@ -1,145 +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.homepage.conditional;
|
|
||||||
|
|
||||||
import android.content.BroadcastReceiver;
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.content.IntentFilter;
|
|
||||||
import android.graphics.drawable.Drawable;
|
|
||||||
import android.net.ConnectivityManager;
|
|
||||||
import android.net.wifi.WifiConfiguration;
|
|
||||||
import android.net.wifi.WifiManager;
|
|
||||||
import android.os.UserHandle;
|
|
||||||
import android.os.UserManager;
|
|
||||||
|
|
||||||
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
|
||||||
import com.android.settings.R;
|
|
||||||
import com.android.settings.TetherSettings;
|
|
||||||
import com.android.settings.core.SubSettingLauncher;
|
|
||||||
import com.android.settingslib.RestrictedLockUtils;
|
|
||||||
import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
|
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
public class HotspotCondition extends Condition {
|
|
||||||
|
|
||||||
private final WifiManager mWifiManager;
|
|
||||||
private final Receiver mReceiver;
|
|
||||||
|
|
||||||
private static final IntentFilter WIFI_AP_STATE_FILTER =
|
|
||||||
new IntentFilter(WifiManager.WIFI_AP_STATE_CHANGED_ACTION);
|
|
||||||
|
|
||||||
public HotspotCondition(ConditionManager manager) {
|
|
||||||
super(manager);
|
|
||||||
mWifiManager = mManager.getContext().getSystemService(WifiManager.class);
|
|
||||||
mReceiver = new Receiver();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void refreshState() {
|
|
||||||
boolean wifiTetherEnabled = mWifiManager.isWifiApEnabled();
|
|
||||||
setActive(wifiTetherEnabled);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected BroadcastReceiver getReceiver() {
|
|
||||||
return mReceiver;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected IntentFilter getIntentFilter() {
|
|
||||||
return WIFI_AP_STATE_FILTER;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Drawable getIcon() {
|
|
||||||
return mManager.getContext().getDrawable(R.drawable.ic_hotspot);
|
|
||||||
}
|
|
||||||
|
|
||||||
private String getSsid() {
|
|
||||||
WifiConfiguration wifiConfig = mWifiManager.getWifiApConfiguration();
|
|
||||||
if (wifiConfig == null) {
|
|
||||||
return mManager.getContext().getString(
|
|
||||||
com.android.internal.R.string.wifi_tether_configure_ssid_default);
|
|
||||||
} else {
|
|
||||||
return wifiConfig.SSID;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public CharSequence getTitle() {
|
|
||||||
return mManager.getContext().getString(R.string.condition_hotspot_title);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public CharSequence getSummary() {
|
|
||||||
return mManager.getContext().getString(R.string.condition_hotspot_summary, getSsid());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public CharSequence[] getActions() {
|
|
||||||
final Context context = mManager.getContext();
|
|
||||||
if (RestrictedLockUtils.hasBaseUserRestriction(context,
|
|
||||||
UserManager.DISALLOW_CONFIG_TETHERING, UserHandle.myUserId())) {
|
|
||||||
return new CharSequence[0];
|
|
||||||
}
|
|
||||||
return new CharSequence[]{context.getString(R.string.condition_turn_off)};
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onPrimaryClick() {
|
|
||||||
new SubSettingLauncher(mManager.getContext())
|
|
||||||
.setDestination(TetherSettings.class.getName())
|
|
||||||
.setSourceMetricsCategory(MetricsEvent.DASHBOARD_SUMMARY)
|
|
||||||
.setTitleRes(R.string.tether_settings_title_all)
|
|
||||||
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
|
||||||
.launch();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onActionClick(int index) {
|
|
||||||
if (index == 0) {
|
|
||||||
final Context context = mManager.getContext();
|
|
||||||
final EnforcedAdmin admin = RestrictedLockUtils.checkIfRestrictionEnforced(context,
|
|
||||||
UserManager.DISALLOW_CONFIG_TETHERING, UserHandle.myUserId());
|
|
||||||
if (admin != null) {
|
|
||||||
RestrictedLockUtils.sendShowAdminSupportDetailsIntent(context, admin);
|
|
||||||
} else {
|
|
||||||
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(
|
|
||||||
Context.CONNECTIVITY_SERVICE);
|
|
||||||
cm.stopTethering(ConnectivityManager.TETHERING_WIFI);
|
|
||||||
setActive(false);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
throw new IllegalArgumentException("Unexpected index " + index);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getMetricsConstant() {
|
|
||||||
return MetricsEvent.SETTINGS_CONDITION_HOTSPOT;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class Receiver extends BroadcastReceiver {
|
|
||||||
@Override
|
|
||||||
public void onReceive(Context context, Intent intent) {
|
|
||||||
if (WifiManager.WIFI_AP_STATE_CHANGED_ACTION.equals(intent.getAction())) {
|
|
||||||
ConditionManager.get(context).getCondition(HotspotCondition.class)
|
|
||||||
.refreshState();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -14,7 +14,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.android.settings.homepage.conditional.v2;
|
package com.android.settings.homepage.conditional;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
@@ -14,7 +14,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.android.settings.homepage.conditional.v2;
|
package com.android.settings.homepage.conditional;
|
||||||
|
|
||||||
import android.content.BroadcastReceiver;
|
import android.content.BroadcastReceiver;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
@@ -1,96 +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.homepage.conditional;
|
|
||||||
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.graphics.drawable.Drawable;
|
|
||||||
|
|
||||||
import com.android.internal.app.ColorDisplayController;
|
|
||||||
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
|
||||||
import com.android.settings.R;
|
|
||||||
import com.android.settings.core.SubSettingLauncher;
|
|
||||||
import com.android.settings.display.NightDisplaySettings;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @deprecated in favor of {@link NightDisplayConditionController}
|
|
||||||
*/
|
|
||||||
@Deprecated
|
|
||||||
public final class NightDisplayCondition extends Condition
|
|
||||||
implements ColorDisplayController.Callback {
|
|
||||||
|
|
||||||
private ColorDisplayController mController;
|
|
||||||
|
|
||||||
NightDisplayCondition(ConditionManager manager) {
|
|
||||||
super(manager);
|
|
||||||
mController = new ColorDisplayController(manager.getContext());
|
|
||||||
mController.setListener(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getMetricsConstant() {
|
|
||||||
return MetricsEvent.SETTINGS_CONDITION_NIGHT_DISPLAY;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Drawable getIcon() {
|
|
||||||
return mManager.getContext().getDrawable(R.drawable.ic_settings_night_display);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public CharSequence getTitle() {
|
|
||||||
return mManager.getContext().getString(R.string.condition_night_display_title);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public CharSequence getSummary() {
|
|
||||||
return mManager.getContext().getString(R.string.condition_night_display_summary);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public CharSequence[] getActions() {
|
|
||||||
return new CharSequence[] {mManager.getContext().getString(R.string.condition_turn_off)};
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onPrimaryClick() {
|
|
||||||
new SubSettingLauncher(mManager.getContext())
|
|
||||||
.setDestination(NightDisplaySettings.class.getName())
|
|
||||||
.setSourceMetricsCategory(MetricsEvent.DASHBOARD_SUMMARY)
|
|
||||||
.setTitleRes(R.string.night_display_title)
|
|
||||||
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
|
||||||
.launch();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onActionClick(int index) {
|
|
||||||
if (index == 0) {
|
|
||||||
mController.setActivated(false);
|
|
||||||
} else {
|
|
||||||
throw new IllegalArgumentException("Unexpected index " + index);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void refreshState() {
|
|
||||||
setActive(mController.isActivated());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onActivated(boolean activated) {
|
|
||||||
refreshState();
|
|
||||||
}
|
|
||||||
}
|
|
@@ -14,7 +14,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.android.settings.homepage.conditional.v2;
|
package com.android.settings.homepage.conditional;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
@@ -14,7 +14,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.android.settings.homepage.conditional.v2;
|
package com.android.settings.homepage.conditional;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
|
@@ -1,71 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2018 The Android Open Source Project
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.android.settings.homepage.conditional;
|
|
||||||
|
|
||||||
import static android.content.Context.NOTIFICATION_SERVICE;
|
|
||||||
|
|
||||||
import android.app.NotificationManager;
|
|
||||||
import android.graphics.drawable.Drawable;
|
|
||||||
import android.media.AudioManager;
|
|
||||||
import android.provider.Settings;
|
|
||||||
|
|
||||||
import com.android.internal.logging.nano.MetricsProto;
|
|
||||||
import com.android.settings.R;
|
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
public class RingerMutedCondition extends AbnormalRingerConditionBase {
|
|
||||||
|
|
||||||
private final NotificationManager mNotificationManager;
|
|
||||||
|
|
||||||
RingerMutedCondition(ConditionManager manager) {
|
|
||||||
super(manager);
|
|
||||||
mNotificationManager =
|
|
||||||
(NotificationManager) mManager.getContext().getSystemService(NOTIFICATION_SERVICE);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void refreshState() {
|
|
||||||
int zen = Settings.Global.ZEN_MODE_OFF;
|
|
||||||
if (mNotificationManager != null) {
|
|
||||||
zen = mNotificationManager.getZenMode();
|
|
||||||
}
|
|
||||||
final boolean zenModeEnabled = zen != Settings.Global.ZEN_MODE_OFF;
|
|
||||||
final boolean isSilent =
|
|
||||||
mAudioManager.getRingerModeInternal() == AudioManager.RINGER_MODE_SILENT;
|
|
||||||
setActive(isSilent && !zenModeEnabled);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getMetricsConstant() {
|
|
||||||
return MetricsProto.MetricsEvent.SETTINGS_CONDITION_DEVICE_MUTED;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Drawable getIcon() {
|
|
||||||
return mManager.getContext().getDrawable(R.drawable.ic_notifications_off_24dp);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public CharSequence getTitle() {
|
|
||||||
return mManager.getContext().getText(R.string.condition_device_muted_title);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public CharSequence getSummary() {
|
|
||||||
return mManager.getContext().getText(R.string.condition_device_muted_summary);
|
|
||||||
}
|
|
||||||
}
|
|
@@ -14,7 +14,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.android.settings.homepage.conditional.v2;
|
package com.android.settings.homepage.conditional;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
@@ -14,7 +14,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.android.settings.homepage.conditional.v2;
|
package com.android.settings.homepage.conditional;
|
||||||
|
|
||||||
import static android.content.Context.NOTIFICATION_SERVICE;
|
import static android.content.Context.NOTIFICATION_SERVICE;
|
||||||
|
|
@@ -1,56 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2018 The Android Open Source Project
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.android.settings.homepage.conditional;
|
|
||||||
|
|
||||||
import android.graphics.drawable.Drawable;
|
|
||||||
import android.media.AudioManager;
|
|
||||||
|
|
||||||
import com.android.internal.logging.nano.MetricsProto;
|
|
||||||
import com.android.settings.R;
|
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
public class RingerVibrateCondition extends AbnormalRingerConditionBase {
|
|
||||||
|
|
||||||
RingerVibrateCondition(ConditionManager manager) {
|
|
||||||
super(manager);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void refreshState() {
|
|
||||||
setActive(mAudioManager.getRingerModeInternal() == AudioManager.RINGER_MODE_VIBRATE);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getMetricsConstant() {
|
|
||||||
return MetricsProto.MetricsEvent.SETTINGS_CONDITION_DEVICE_VIBRATE;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Drawable getIcon() {
|
|
||||||
return mManager.getContext().getDrawable(R.drawable.ic_volume_ringer_vibrate);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public CharSequence getTitle() {
|
|
||||||
return mManager.getContext().getText(R.string.condition_device_vibrate_title);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public CharSequence getSummary() {
|
|
||||||
return mManager.getContext().getText(R.string.condition_device_vibrate_summary);
|
|
||||||
}
|
|
||||||
}
|
|
@@ -14,7 +14,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.android.settings.homepage.conditional.v2;
|
package com.android.settings.homepage.conditional;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
@@ -14,7 +14,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.android.settings.homepage.conditional.v2;
|
package com.android.settings.homepage.conditional;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.media.AudioManager;
|
import android.media.AudioManager;
|
@@ -1,108 +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.homepage.conditional;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.content.pm.UserInfo;
|
|
||||||
import android.graphics.drawable.Drawable;
|
|
||||||
import android.os.UserHandle;
|
|
||||||
import android.os.UserManager;
|
|
||||||
|
|
||||||
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
|
||||||
import com.android.settings.R;
|
|
||||||
import com.android.settings.Settings;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
public class WorkModeCondition extends Condition {
|
|
||||||
|
|
||||||
private UserManager mUm;
|
|
||||||
private UserHandle mUserHandle;
|
|
||||||
|
|
||||||
public WorkModeCondition(ConditionManager conditionManager) {
|
|
||||||
super(conditionManager);
|
|
||||||
mUm = (UserManager) mManager.getContext().getSystemService(Context.USER_SERVICE);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateUserHandle() {
|
|
||||||
List<UserInfo> profiles = mUm.getProfiles(UserHandle.myUserId());
|
|
||||||
final int profilesCount = profiles.size();
|
|
||||||
mUserHandle = null;
|
|
||||||
for (int i = 0; i < profilesCount; i++) {
|
|
||||||
UserInfo userInfo = profiles.get(i);
|
|
||||||
if (userInfo.isManagedProfile()) {
|
|
||||||
// We assume there's only one managed profile, otherwise UI needs to change.
|
|
||||||
mUserHandle = userInfo.getUserHandle();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void refreshState() {
|
|
||||||
updateUserHandle();
|
|
||||||
setActive(mUserHandle != null && mUm.isQuietModeEnabled(mUserHandle));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Drawable getIcon() {
|
|
||||||
return mManager.getContext().getDrawable(R.drawable.ic_signal_workmode_enable);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public CharSequence getTitle() {
|
|
||||||
return mManager.getContext().getString(R.string.condition_work_title);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public CharSequence getSummary() {
|
|
||||||
return mManager.getContext().getString(R.string.condition_work_summary);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public CharSequence[] getActions() {
|
|
||||||
return new CharSequence[] {
|
|
||||||
mManager.getContext().getString(R.string.condition_turn_on)
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onPrimaryClick() {
|
|
||||||
mManager.getContext().startActivity(new Intent(mManager.getContext(),
|
|
||||||
Settings.AccountDashboardActivity.class)
|
|
||||||
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onActionClick(int index) {
|
|
||||||
if (index == 0) {
|
|
||||||
if (mUserHandle != null) {
|
|
||||||
mUm.requestQuietModeEnabled(false, mUserHandle);
|
|
||||||
}
|
|
||||||
setActive(false);
|
|
||||||
} else {
|
|
||||||
throw new IllegalArgumentException("Unexpected index " + index);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getMetricsConstant() {
|
|
||||||
return MetricsEvent.SETTINGS_CONDITION_WORK_MODE;
|
|
||||||
}
|
|
||||||
}
|
|
@@ -14,7 +14,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.android.settings.homepage.conditional.v2;
|
package com.android.settings.homepage.conditional;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
@@ -14,7 +14,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.android.settings.homepage.conditional.v2;
|
package com.android.settings.homepage.conditional;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
@@ -1,130 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2018 The Android Open Source Project
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.android.settings.homepage.conditional.v2;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.text.TextUtils;
|
|
||||||
import android.view.LayoutInflater;
|
|
||||||
import android.view.View;
|
|
||||||
import android.view.ViewGroup;
|
|
||||||
import android.widget.Button;
|
|
||||||
|
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
|
||||||
|
|
||||||
import com.android.internal.logging.nano.MetricsProto;
|
|
||||||
import com.android.settings.R;
|
|
||||||
import com.android.settings.dashboard.DashboardAdapter;
|
|
||||||
import com.android.settings.overlay.FeatureFactory;
|
|
||||||
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class ConditionAdapter extends RecyclerView.Adapter<DashboardAdapter.DashboardItemHolder> {
|
|
||||||
|
|
||||||
private final Context mContext;
|
|
||||||
private final MetricsFeatureProvider mMetricsFeatureProvider;
|
|
||||||
private final ConditionManager mConditionManager;
|
|
||||||
private final List<ConditionalCard> mConditions;
|
|
||||||
private final boolean mExpanded;
|
|
||||||
|
|
||||||
public ConditionAdapter(Context context, ConditionManager conditionManager,
|
|
||||||
List<ConditionalCard> conditions, boolean expanded) {
|
|
||||||
mContext = context;
|
|
||||||
mConditionManager = conditionManager;
|
|
||||||
mConditions = conditions;
|
|
||||||
mExpanded = expanded;
|
|
||||||
mMetricsFeatureProvider = FeatureFactory.getFactory(context).getMetricsFeatureProvider();
|
|
||||||
|
|
||||||
setHasStableIds(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public DashboardAdapter.DashboardItemHolder onCreateViewHolder(ViewGroup parent, int viewType) {
|
|
||||||
return new DashboardAdapter.DashboardItemHolder(LayoutInflater.from(parent.getContext())
|
|
||||||
.inflate(viewType, parent, false));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onBindViewHolder(DashboardAdapter.DashboardItemHolder holder, int position) {
|
|
||||||
final ConditionalCard condition = mConditions.get(position);
|
|
||||||
final boolean isLastItem = position == mConditions.size() - 1;
|
|
||||||
bindViews(condition, holder, isLastItem);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public long getItemId(int position) {
|
|
||||||
return mConditions.get(position).getId();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getItemViewType(int position) {
|
|
||||||
return R.layout.condition_tile;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getItemCount() {
|
|
||||||
if (mExpanded) {
|
|
||||||
return mConditions.size();
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void bindViews(final ConditionalCard condition,
|
|
||||||
DashboardAdapter.DashboardItemHolder view, boolean isLastItem) {
|
|
||||||
mMetricsFeatureProvider.visible(mContext, MetricsProto.MetricsEvent.DASHBOARD_SUMMARY,
|
|
||||||
condition.getMetricsConstant());
|
|
||||||
view.itemView.findViewById(R.id.content).setOnClickListener(
|
|
||||||
v -> {
|
|
||||||
mMetricsFeatureProvider.action(mContext,
|
|
||||||
MetricsProto.MetricsEvent.ACTION_SETTINGS_CONDITION_CLICK,
|
|
||||||
condition.getMetricsConstant());
|
|
||||||
mConditionManager.onPrimaryClick(mContext, condition.getId());
|
|
||||||
});
|
|
||||||
view.icon.setImageDrawable(condition.getIcon());
|
|
||||||
view.title.setText(condition.getTitle());
|
|
||||||
view.summary.setText(condition.getSummary());
|
|
||||||
|
|
||||||
setViewVisibility(view.itemView, R.id.divider, !isLastItem);
|
|
||||||
|
|
||||||
final CharSequence action = condition.getActionText();
|
|
||||||
final boolean hasButtons = !TextUtils.isEmpty(action);
|
|
||||||
setViewVisibility(view.itemView, R.id.buttonBar, hasButtons);
|
|
||||||
|
|
||||||
final Button button = view.itemView.findViewById(R.id.first_action);
|
|
||||||
if (hasButtons) {
|
|
||||||
button.setVisibility(View.VISIBLE);
|
|
||||||
button.setText(action);
|
|
||||||
button.setOnClickListener(v -> {
|
|
||||||
final Context context = v.getContext();
|
|
||||||
mMetricsFeatureProvider.action(
|
|
||||||
context, MetricsProto.MetricsEvent.ACTION_SETTINGS_CONDITION_BUTTON,
|
|
||||||
condition.getMetricsConstant());
|
|
||||||
mConditionManager.onActionClick(condition.getId());
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
button.setVisibility(View.GONE);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
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,210 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2018 The Android Open Source Project
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.android.settings.homepage.conditional.v2;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.util.FeatureFlagUtils;
|
|
||||||
import android.util.Log;
|
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
import androidx.annotation.VisibleForTesting;
|
|
||||||
|
|
||||||
import com.android.settings.core.FeatureFlags;
|
|
||||||
import com.android.settings.homepage.conditional.ConditionListener;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.concurrent.Callable;
|
|
||||||
import java.util.concurrent.ExecutionException;
|
|
||||||
import java.util.concurrent.ExecutorService;
|
|
||||||
import java.util.concurrent.Executors;
|
|
||||||
import java.util.concurrent.Future;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
import java.util.concurrent.TimeoutException;
|
|
||||||
|
|
||||||
public class ConditionManager {
|
|
||||||
private static final String TAG = "ConditionManager";
|
|
||||||
|
|
||||||
@VisibleForTesting
|
|
||||||
final List<ConditionalCard> mCandidates;
|
|
||||||
@VisibleForTesting
|
|
||||||
final List<ConditionalCardController> mCardControllers;
|
|
||||||
|
|
||||||
private static final long DISPLAYABLE_CHECKER_TIMEOUT_MS = 20;
|
|
||||||
|
|
||||||
private final ExecutorService mExecutorService;
|
|
||||||
private final Context mAppContext;
|
|
||||||
private final ConditionListener mListener;
|
|
||||||
|
|
||||||
private boolean mIsListeningToStateChange;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Whether or not the new condition manager is should be used.
|
|
||||||
*/
|
|
||||||
public static boolean isEnabled(Context context) {
|
|
||||||
return FeatureFlagUtils.isEnabled(context, FeatureFlags.CONDITION_MANAGER_V2);
|
|
||||||
}
|
|
||||||
|
|
||||||
public ConditionManager(Context context, ConditionListener listener) {
|
|
||||||
mAppContext = context.getApplicationContext();
|
|
||||||
mExecutorService = Executors.newCachedThreadPool();
|
|
||||||
mCandidates = new ArrayList<>();
|
|
||||||
mCardControllers = new ArrayList<>();
|
|
||||||
mListener = listener;
|
|
||||||
initCandidates();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a list of {@link ConditionalCard}s eligible for display.
|
|
||||||
*/
|
|
||||||
public List<ConditionalCard> getDisplayableCards() {
|
|
||||||
final List<ConditionalCard> cards = new ArrayList<>();
|
|
||||||
final List<Future<ConditionalCard>> displayableCards = new ArrayList<>();
|
|
||||||
// Check displayable future
|
|
||||||
for (ConditionalCard card : mCandidates) {
|
|
||||||
final DisplayableChecker future = new DisplayableChecker(
|
|
||||||
card, getController(card.getId()));
|
|
||||||
displayableCards.add(mExecutorService.submit(future));
|
|
||||||
}
|
|
||||||
// Collect future and add displayable cards
|
|
||||||
for (Future<ConditionalCard> cardFuture : displayableCards) {
|
|
||||||
try {
|
|
||||||
final ConditionalCard card = cardFuture.get(DISPLAYABLE_CHECKER_TIMEOUT_MS,
|
|
||||||
TimeUnit.MILLISECONDS);
|
|
||||||
if (card != null) {
|
|
||||||
cards.add(card);
|
|
||||||
}
|
|
||||||
} catch (InterruptedException | ExecutionException | TimeoutException e) {
|
|
||||||
Log.w(TAG, "Failed to get displayable state for card, likely timeout. Skipping", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return cards;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handler when the card is clicked.
|
|
||||||
*
|
|
||||||
* @see {@link ConditionalCardController#onPrimaryClick(Context)}
|
|
||||||
*/
|
|
||||||
public void onPrimaryClick(Context context, long id) {
|
|
||||||
getController(id).onPrimaryClick(context);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handler when the card action is clicked.
|
|
||||||
*
|
|
||||||
* @see {@link ConditionalCardController#onActionClick()}
|
|
||||||
*/
|
|
||||||
public void onActionClick(long id) {
|
|
||||||
getController(id).onActionClick();
|
|
||||||
onConditionChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Start monitoring state change for all conditions
|
|
||||||
*/
|
|
||||||
public void startMonitoringStateChange() {
|
|
||||||
if (mIsListeningToStateChange) {
|
|
||||||
Log.d(TAG, "Already listening to condition state changes, skipping");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
mIsListeningToStateChange = true;
|
|
||||||
for (ConditionalCardController controller : mCardControllers) {
|
|
||||||
controller.startMonitoringStateChange();
|
|
||||||
}
|
|
||||||
// Force a refresh on listener
|
|
||||||
onConditionChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Stop monitoring state change for all conditions
|
|
||||||
*/
|
|
||||||
public void stopMonitoringStateChange() {
|
|
||||||
if (!mIsListeningToStateChange) {
|
|
||||||
Log.d(TAG, "Not listening to condition state changes, skipping");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
for (ConditionalCardController controller : mCardControllers) {
|
|
||||||
controller.stopMonitoringStateChange();
|
|
||||||
}
|
|
||||||
mIsListeningToStateChange = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Called when some conditional card's state has changed
|
|
||||||
*/
|
|
||||||
void onConditionChanged() {
|
|
||||||
if (mListener != null) {
|
|
||||||
mListener.onConditionsChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@NonNull
|
|
||||||
<T extends ConditionalCardController> T getController(long id) {
|
|
||||||
for (ConditionalCardController controller : mCardControllers) {
|
|
||||||
if (controller.getId() == id) {
|
|
||||||
return (T) controller;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
throw new IllegalStateException("Cannot find controller for " + id);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void initCandidates() {
|
|
||||||
// Initialize controllers first.
|
|
||||||
mCardControllers.add(new AirplaneModeConditionController(mAppContext, this /* manager */));
|
|
||||||
mCardControllers.add(new BackgroundDataConditionController(mAppContext));
|
|
||||||
mCardControllers.add(new BatterySaverConditionController(mAppContext, this /* manager */));
|
|
||||||
mCardControllers.add(new CellularDataConditionController(mAppContext, this /* manager */));
|
|
||||||
mCardControllers.add(new DndConditionCardController(mAppContext, this /* manager */));
|
|
||||||
mCardControllers.add(new HotspotConditionController(mAppContext, this /* manager */));
|
|
||||||
mCardControllers.add(new NightDisplayConditionController(mAppContext));
|
|
||||||
mCardControllers.add(new RingerVibrateConditionController(mAppContext, this /* manager */));
|
|
||||||
mCardControllers.add(new RingerMutedConditionController(mAppContext, this /* manager */));
|
|
||||||
mCardControllers.add(new WorkModeConditionController(mAppContext));
|
|
||||||
|
|
||||||
// Initialize ui model later. UI model depends on controller.
|
|
||||||
mCandidates.add(new AirplaneModeConditionCard(mAppContext));
|
|
||||||
mCandidates.add(new BackgroundDataConditionCard(mAppContext));
|
|
||||||
mCandidates.add(new BatterySaverConditionCard(mAppContext));
|
|
||||||
mCandidates.add(new CellularDataConditionCard(mAppContext));
|
|
||||||
mCandidates.add(new DndConditionCard(mAppContext, this /* manager */));
|
|
||||||
mCandidates.add(new HotspotConditionCard(mAppContext, this /* manager */));
|
|
||||||
mCandidates.add(new NightDisplayConditionCard(mAppContext));
|
|
||||||
mCandidates.add(new RingerMutedConditionCard(mAppContext));
|
|
||||||
mCandidates.add(new RingerVibrateConditionCard(mAppContext));
|
|
||||||
mCandidates.add(new WorkModeConditionCard(mAppContext));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns card if controller says it's displayable. Otherwise returns null.
|
|
||||||
*/
|
|
||||||
public static class DisplayableChecker implements Callable<ConditionalCard> {
|
|
||||||
|
|
||||||
private final ConditionalCard mCard;
|
|
||||||
private final ConditionalCardController mController;
|
|
||||||
|
|
||||||
private DisplayableChecker(ConditionalCard card, ConditionalCardController controller) {
|
|
||||||
mCard = card;
|
|
||||||
mController = controller;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ConditionalCard call() throws Exception {
|
|
||||||
return mController.isDisplayable() ? mCard : null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -47,8 +47,9 @@ import androidx.recyclerview.widget.RecyclerView;
|
|||||||
|
|
||||||
import com.android.settings.R;
|
import com.android.settings.R;
|
||||||
import com.android.settings.SettingsActivity;
|
import com.android.settings.SettingsActivity;
|
||||||
import com.android.settings.homepage.conditional.Condition;
|
|
||||||
import com.android.settings.dashboard.suggestions.SuggestionAdapter;
|
import com.android.settings.dashboard.suggestions.SuggestionAdapter;
|
||||||
|
import com.android.settings.homepage.conditional.ConditionManager;
|
||||||
|
import com.android.settings.homepage.conditional.ConditionalCard;
|
||||||
import com.android.settings.testutils.FakeFeatureFactory;
|
import com.android.settings.testutils.FakeFeatureFactory;
|
||||||
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||||
import com.android.settings.testutils.shadow.SettingsShadowResources;
|
import com.android.settings.testutils.shadow.SettingsShadowResources;
|
||||||
@@ -77,22 +78,22 @@ public class DashboardAdapterTest {
|
|||||||
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
|
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
|
||||||
private SettingsActivity mContext;
|
private SettingsActivity mContext;
|
||||||
@Mock
|
@Mock
|
||||||
private View mView;
|
private ConditionalCard mCondition;
|
||||||
@Mock
|
|
||||||
private Condition mCondition;
|
|
||||||
@Mock
|
@Mock
|
||||||
private Resources mResources;
|
private Resources mResources;
|
||||||
@Mock
|
@Mock
|
||||||
private WindowManager mWindowManager;
|
private WindowManager mWindowManager;
|
||||||
|
@Mock
|
||||||
|
private ConditionManager mConditionManager;
|
||||||
|
|
||||||
private ActivityInfo mActivityInfo;
|
private ActivityInfo mActivityInfo;
|
||||||
private FakeFeatureFactory mFactory;
|
|
||||||
private DashboardAdapter mDashboardAdapter;
|
private DashboardAdapter mDashboardAdapter;
|
||||||
private List<Condition> mConditionList;
|
private List<ConditionalCard> mConditionList;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() {
|
public void setUp() {
|
||||||
MockitoAnnotations.initMocks(this);
|
MockitoAnnotations.initMocks(this);
|
||||||
mFactory = FakeFeatureFactory.setupForTest();
|
FakeFeatureFactory.setupForTest();
|
||||||
mActivityInfo = new ActivityInfo();
|
mActivityInfo = new ActivityInfo();
|
||||||
mActivityInfo.packageName = "pkg";
|
mActivityInfo.packageName = "pkg";
|
||||||
mActivityInfo.name = "class";
|
mActivityInfo.name = "class";
|
||||||
@@ -105,18 +106,15 @@ public class DashboardAdapterTest {
|
|||||||
|
|
||||||
mConditionList = new ArrayList<>();
|
mConditionList = new ArrayList<>();
|
||||||
mConditionList.add(mCondition);
|
mConditionList.add(mCondition);
|
||||||
when(mCondition.shouldShow()).thenReturn(true);
|
|
||||||
mDashboardAdapter = new DashboardAdapter(mContext, null /* savedInstanceState */,
|
mDashboardAdapter = new DashboardAdapter(mContext, null /* savedInstanceState */,
|
||||||
mConditionList, null /* conditionManager */,
|
mConditionManager, null /* suggestionControllerMixin */, null /* lifecycle */);
|
||||||
null /* suggestionControllerMixin */, null /* lifecycle */);
|
|
||||||
when(mView.getTag()).thenReturn(mCondition);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void onSuggestionClosed_notOnlySuggestion_updateSuggestionOnly() {
|
public void onSuggestionClosed_notOnlySuggestion_updateSuggestionOnly() {
|
||||||
final DashboardAdapter adapter =
|
final DashboardAdapter adapter =
|
||||||
spy(new DashboardAdapter(mContext, null /* savedInstanceState */,
|
spy(new DashboardAdapter(mContext, null /* savedInstanceState */,
|
||||||
null /* conditions */, null /* conditionManager */,
|
mConditionManager,
|
||||||
null /* suggestionControllerMixin */,
|
null /* suggestionControllerMixin */,
|
||||||
null /* lifecycle */));
|
null /* lifecycle */));
|
||||||
final List<Suggestion> suggestions = makeSuggestions("pkg1", "pkg2", "pkg3");
|
final List<Suggestion> suggestions = makeSuggestions("pkg1", "pkg2", "pkg3");
|
||||||
@@ -149,7 +147,7 @@ public class DashboardAdapterTest {
|
|||||||
public void onSuggestionClosed_onlySuggestion_updateDashboardData() {
|
public void onSuggestionClosed_onlySuggestion_updateDashboardData() {
|
||||||
final DashboardAdapter adapter =
|
final DashboardAdapter adapter =
|
||||||
spy(new DashboardAdapter(mContext, null /* savedInstanceState */,
|
spy(new DashboardAdapter(mContext, null /* savedInstanceState */,
|
||||||
null /* conditions */, null /* conditionManager */,
|
mConditionManager,
|
||||||
null /* suggestionControllerMixin */, null /* lifecycle */));
|
null /* suggestionControllerMixin */, null /* lifecycle */));
|
||||||
final List<Suggestion> suggestions = makeSuggestions("pkg1");
|
final List<Suggestion> suggestions = makeSuggestions("pkg1");
|
||||||
adapter.setSuggestions(suggestions);
|
adapter.setSuggestions(suggestions);
|
||||||
@@ -166,7 +164,7 @@ public class DashboardAdapterTest {
|
|||||||
public void onSuggestionClosed_notInSuggestionList_shouldNotUpdateSuggestionList() {
|
public void onSuggestionClosed_notInSuggestionList_shouldNotUpdateSuggestionList() {
|
||||||
final DashboardAdapter adapter =
|
final DashboardAdapter adapter =
|
||||||
spy(new DashboardAdapter(mContext, null /* savedInstanceState */,
|
spy(new DashboardAdapter(mContext, null /* savedInstanceState */,
|
||||||
null /* conditions */, null /* conditionManager */,
|
mConditionManager,
|
||||||
null /* suggestionControllerMixin */, null /* lifecycle */));
|
null /* suggestionControllerMixin */, null /* lifecycle */));
|
||||||
final List<Suggestion> suggestions = makeSuggestions("pkg1");
|
final List<Suggestion> suggestions = makeSuggestions("pkg1");
|
||||||
adapter.setSuggestions(suggestions);
|
adapter.setSuggestions(suggestions);
|
||||||
@@ -181,8 +179,7 @@ public class DashboardAdapterTest {
|
|||||||
@Test
|
@Test
|
||||||
public void onBindSuggestion_shouldSetSuggestionAdapterAndNoCrash() {
|
public void onBindSuggestion_shouldSetSuggestionAdapterAndNoCrash() {
|
||||||
mDashboardAdapter = new DashboardAdapter(mContext, null /* savedInstanceState */,
|
mDashboardAdapter = new DashboardAdapter(mContext, null /* savedInstanceState */,
|
||||||
null /* conditions */, null /* conditionManager */,
|
mConditionManager, null /* suggestionControllerMixin */, null /* lifecycle */);
|
||||||
null /* suggestionControllerMixin */, null /* lifecycle */);
|
|
||||||
final List<Suggestion> suggestions = makeSuggestions("pkg1");
|
final List<Suggestion> suggestions = makeSuggestions("pkg1");
|
||||||
|
|
||||||
mDashboardAdapter.setSuggestions(suggestions);
|
mDashboardAdapter.setSuggestions(suggestions);
|
||||||
@@ -218,8 +215,7 @@ public class DashboardAdapterTest {
|
|||||||
.thenReturn(context.getDrawable(R.drawable.ic_settings));
|
.thenReturn(context.getDrawable(R.drawable.ic_settings));
|
||||||
|
|
||||||
mDashboardAdapter = new DashboardAdapter(context, null /* savedInstanceState */,
|
mDashboardAdapter = new DashboardAdapter(context, null /* savedInstanceState */,
|
||||||
null /* conditions */, null /* conditionManager */,
|
mConditionManager, null /* suggestionControllerMixin */, null /* lifecycle */);
|
||||||
null /* suggestionControllerMixin */, null /* lifecycle */);
|
|
||||||
ReflectionHelpers.setField(mDashboardAdapter, "mCache", iconCache);
|
ReflectionHelpers.setField(mDashboardAdapter, "mCache", iconCache);
|
||||||
mDashboardAdapter.onBindTile(holder, tile);
|
mDashboardAdapter.onBindTile(holder, tile);
|
||||||
|
|
||||||
@@ -239,7 +235,7 @@ public class DashboardAdapterTest {
|
|||||||
final IconCache iconCache = new IconCache(context);
|
final IconCache iconCache = new IconCache(context);
|
||||||
|
|
||||||
mDashboardAdapter = new DashboardAdapter(context, null /* savedInstanceState */,
|
mDashboardAdapter = new DashboardAdapter(context, null /* savedInstanceState */,
|
||||||
null /* conditions */, null /* conditionManager */,
|
mConditionManager,
|
||||||
null /* suggestionControllerMixin */, null /* lifecycle */);
|
null /* suggestionControllerMixin */, null /* lifecycle */);
|
||||||
ReflectionHelpers.setField(mDashboardAdapter, "mCache", iconCache);
|
ReflectionHelpers.setField(mDashboardAdapter, "mCache", iconCache);
|
||||||
|
|
||||||
@@ -264,8 +260,7 @@ public class DashboardAdapterTest {
|
|||||||
when(iconCache.getIcon(tile.getIcon(context))).thenReturn(mock(RoundedHomepageIcon.class));
|
when(iconCache.getIcon(tile.getIcon(context))).thenReturn(mock(RoundedHomepageIcon.class));
|
||||||
|
|
||||||
mDashboardAdapter = new DashboardAdapter(context, null /* savedInstanceState */,
|
mDashboardAdapter = new DashboardAdapter(context, null /* savedInstanceState */,
|
||||||
null /* conditions */, null /* conditionManager */,
|
mConditionManager, null /* suggestionControllerMixin */, null /* lifecycle */);
|
||||||
null /* suggestionControllerMixin */, null /* lifecycle */);
|
|
||||||
ReflectionHelpers.setField(mDashboardAdapter, "mCache", iconCache);
|
ReflectionHelpers.setField(mDashboardAdapter, "mCache", iconCache);
|
||||||
|
|
||||||
mDashboardAdapter.onBindTile(holder, tile);
|
mDashboardAdapter.onBindTile(holder, tile);
|
||||||
|
@@ -33,8 +33,8 @@ import androidx.annotation.NonNull;
|
|||||||
import androidx.recyclerview.widget.DiffUtil;
|
import androidx.recyclerview.widget.DiffUtil;
|
||||||
import androidx.recyclerview.widget.ListUpdateCallback;
|
import androidx.recyclerview.widget.ListUpdateCallback;
|
||||||
|
|
||||||
import com.android.settings.homepage.conditional.AirplaneModeCondition;
|
import com.android.settings.homepage.conditional.AirplaneModeConditionCard;
|
||||||
import com.android.settings.homepage.conditional.Condition;
|
import com.android.settings.homepage.conditional.ConditionalCard;
|
||||||
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||||
import com.android.settingslib.drawer.CategoryKey;
|
import com.android.settingslib.drawer.CategoryKey;
|
||||||
import com.android.settingslib.drawer.DashboardCategory;
|
import com.android.settingslib.drawer.DashboardCategory;
|
||||||
@@ -63,9 +63,9 @@ public class DashboardDataTest {
|
|||||||
@Mock
|
@Mock
|
||||||
private Tile mTestCategoryTile;
|
private Tile mTestCategoryTile;
|
||||||
@Mock
|
@Mock
|
||||||
private Condition mTestCondition;
|
private ConditionalCard mTestCondition;
|
||||||
@Mock
|
@Mock
|
||||||
private Condition mSecondCondition; // condition used to test insert in DiffUtil
|
private ConditionalCard mSecondCondition; // condition used to test insert in DiffUtil
|
||||||
private Suggestion mTestSuggestion;
|
private Suggestion mTestSuggestion;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
@@ -83,13 +83,11 @@ public class DashboardDataTest {
|
|||||||
suggestions.add(mTestSuggestion);
|
suggestions.add(mTestSuggestion);
|
||||||
|
|
||||||
// Build oneItemConditions
|
// Build oneItemConditions
|
||||||
final List<Condition> oneItemConditions = new ArrayList<>();
|
final List<ConditionalCard> oneItemConditions = new ArrayList<>();
|
||||||
when(mTestCondition.shouldShow()).thenReturn(true);
|
|
||||||
oneItemConditions.add(mTestCondition);
|
oneItemConditions.add(mTestCondition);
|
||||||
|
|
||||||
// Build twoItemConditions
|
// Build twoItemConditions
|
||||||
final List<Condition> twoItemsConditions = new ArrayList<>();
|
final List<ConditionalCard> twoItemsConditions = new ArrayList<>();
|
||||||
when(mSecondCondition.shouldShow()).thenReturn(true);
|
|
||||||
twoItemsConditions.add(mTestCondition);
|
twoItemsConditions.add(mTestCondition);
|
||||||
twoItemsConditions.add(mSecondCondition);
|
twoItemsConditions.add(mSecondCondition);
|
||||||
|
|
||||||
@@ -170,7 +168,7 @@ public class DashboardDataTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testGetPositionByEntity_notExisted_returnNotFound() {
|
public void testGetPositionByEntity_notExisted_returnNotFound() {
|
||||||
final Condition condition = mock(AirplaneModeCondition.class);
|
final ConditionalCard condition = mock(AirplaneModeConditionCard.class);
|
||||||
final int position = mDashboardDataWithOneConditions.getPositionByEntity(condition);
|
final int position = mDashboardDataWithOneConditions.getPositionByEntity(condition);
|
||||||
assertThat(position).isEqualTo(DashboardData.POSITION_NOT_FOUND);
|
assertThat(position).isEqualTo(DashboardData.POSITION_NOT_FOUND);
|
||||||
}
|
}
|
||||||
@@ -227,8 +225,8 @@ public class DashboardDataTest {
|
|||||||
testResultData.add(new ListUpdateResult.ResultData(
|
testResultData.add(new ListUpdateResult.ResultData(
|
||||||
ListUpdateResult.ResultData.TYPE_OPERATION_CHANGE, 2, 1));
|
ListUpdateResult.ResultData.TYPE_OPERATION_CHANGE, 2, 1));
|
||||||
// Build DashboardData
|
// Build DashboardData
|
||||||
final List<Condition> oneItemConditions = new ArrayList<>();
|
final List<ConditionalCard> oneItemConditions = new ArrayList<>();
|
||||||
when(mTestCondition.shouldShow()).thenReturn(true);
|
|
||||||
oneItemConditions.add(mTestCondition);
|
oneItemConditions.add(mTestCondition);
|
||||||
final List<Suggestion> suggestions = new ArrayList<>();
|
final List<Suggestion> suggestions = new ArrayList<>();
|
||||||
suggestions.add(mTestSuggestion);
|
suggestions.add(mTestSuggestion);
|
||||||
|
@@ -27,7 +27,6 @@ import static org.mockito.Mockito.spy;
|
|||||||
import static org.mockito.Mockito.verify;
|
import static org.mockito.Mockito.verify;
|
||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
import android.app.Activity;
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
|
||||||
import com.android.settings.homepage.conditional.ConditionManager;
|
import com.android.settings.homepage.conditional.ConditionManager;
|
||||||
|
@@ -14,7 +14,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.android.settings.homepage.conditional.v2;
|
package com.android.settings.homepage.conditional;
|
||||||
|
|
||||||
import static org.mockito.Mockito.never;
|
import static org.mockito.Mockito.never;
|
||||||
import static org.mockito.Mockito.verify;
|
import static org.mockito.Mockito.verify;
|
||||||
@@ -23,6 +23,8 @@ import android.content.Context;
|
|||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.media.AudioManager;
|
import android.media.AudioManager;
|
||||||
|
|
||||||
|
import com.android.settings.homepage.conditional.AbnormalRingerConditionController;
|
||||||
|
import com.android.settings.homepage.conditional.ConditionManager;
|
||||||
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||||
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
@@ -13,7 +13,7 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package com.android.settings.homepage.conditional.v2;
|
package com.android.settings.homepage.conditional;
|
||||||
|
|
||||||
import static com.google.common.truth.Truth.assertThat;
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
|
|
||||||
@@ -24,6 +24,7 @@ import android.content.Context;
|
|||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
|
||||||
import com.android.settings.Settings;
|
import com.android.settings.Settings;
|
||||||
|
import com.android.settings.homepage.conditional.BackgroundDataConditionController;
|
||||||
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||||
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
@@ -14,7 +14,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.android.settings.homepage.conditional.v2;
|
package com.android.settings.homepage.conditional;
|
||||||
|
|
||||||
import static com.google.common.truth.Truth.assertThat;
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
|
|
||||||
@@ -27,6 +27,8 @@ import android.content.IntentFilter;
|
|||||||
import android.os.PowerManager;
|
import android.os.PowerManager;
|
||||||
|
|
||||||
import com.android.settings.fuelgauge.BatterySaverReceiver;
|
import com.android.settings.fuelgauge.BatterySaverReceiver;
|
||||||
|
import com.android.settings.homepage.conditional.BatterySaverConditionController;
|
||||||
|
import com.android.settings.homepage.conditional.ConditionManager;
|
||||||
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||||
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
@@ -1,103 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2018 The Android Open Source Project
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.android.settings.homepage.conditional;
|
|
||||||
|
|
||||||
import static com.google.common.truth.Truth.assertThat;
|
|
||||||
|
|
||||||
import static org.mockito.Matchers.any;
|
|
||||||
import static org.mockito.Mockito.spy;
|
|
||||||
import static org.mockito.Mockito.verify;
|
|
||||||
import static org.mockito.Mockito.when;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.IntentFilter;
|
|
||||||
import android.os.PowerManager;
|
|
||||||
|
|
||||||
import com.android.settings.R;
|
|
||||||
import com.android.settings.fuelgauge.BatterySaverReceiver;
|
|
||||||
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
|
||||||
|
|
||||||
import org.junit.Before;
|
|
||||||
import org.junit.Test;
|
|
||||||
import org.junit.runner.RunWith;
|
|
||||||
import org.mockito.Mock;
|
|
||||||
import org.mockito.MockitoAnnotations;
|
|
||||||
import org.robolectric.RuntimeEnvironment;
|
|
||||||
import org.robolectric.Shadows;
|
|
||||||
import org.robolectric.shadows.ShadowPowerManager;
|
|
||||||
|
|
||||||
@RunWith(SettingsRobolectricTestRunner.class)
|
|
||||||
public class BatterySaverConditionTest {
|
|
||||||
@Mock
|
|
||||||
private ConditionManager mConditionManager;
|
|
||||||
|
|
||||||
private ShadowPowerManager mPowerManager;
|
|
||||||
private Context mContext;
|
|
||||||
private BatterySaverCondition mCondition;
|
|
||||||
|
|
||||||
@Before
|
|
||||||
public void setUp() {
|
|
||||||
MockitoAnnotations.initMocks(this);
|
|
||||||
mContext = spy(RuntimeEnvironment.application);
|
|
||||||
mPowerManager = Shadows.shadowOf(mContext.getSystemService(PowerManager.class));
|
|
||||||
when(mConditionManager.getContext()).thenReturn(mContext);
|
|
||||||
mCondition = spy(new BatterySaverCondition(mConditionManager));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void verifyText() {
|
|
||||||
assertThat(mCondition.getTitle()).isEqualTo(
|
|
||||||
mContext.getText(R.string.condition_battery_title));
|
|
||||||
assertThat(mCondition.getSummary()).isEqualTo(
|
|
||||||
mContext.getText(R.string.condition_battery_summary));
|
|
||||||
assertThat(mCondition.getActions()[0]).isEqualTo(
|
|
||||||
mContext.getText(R.string.condition_turn_off));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void onResume_shouldRegisterReceiver() {
|
|
||||||
mCondition.onResume();
|
|
||||||
|
|
||||||
verify(mContext).registerReceiver(any(BatterySaverReceiver.class), any(IntentFilter.class));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void onPause_shouldUnregisterReceiver() {
|
|
||||||
mCondition.onResume();
|
|
||||||
mCondition.onPause();
|
|
||||||
|
|
||||||
verify(mContext).unregisterReceiver(any(BatterySaverReceiver.class));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void refreshState_PowerSaverOn_shouldActivate() {
|
|
||||||
mPowerManager.setIsPowerSaveMode(true);
|
|
||||||
|
|
||||||
mCondition.refreshState();
|
|
||||||
|
|
||||||
assertThat(mCondition.isActive()).isTrue();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void refreshState_PowerSaverOff_shouldNotActivate() {
|
|
||||||
mPowerManager.setIsPowerSaveMode(false);
|
|
||||||
|
|
||||||
mCondition.refreshState();
|
|
||||||
|
|
||||||
assertThat(mCondition.isActive()).isFalse();
|
|
||||||
}
|
|
||||||
}
|
|
@@ -17,6 +17,8 @@ package com.android.settings.homepage.conditional;
|
|||||||
|
|
||||||
import static com.google.common.truth.Truth.assertThat;
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
|
|
||||||
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
|
import static org.mockito.ArgumentMatchers.anyLong;
|
||||||
import static org.mockito.Mockito.verify;
|
import static org.mockito.Mockito.verify;
|
||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
@@ -25,8 +27,6 @@ import android.view.LayoutInflater;
|
|||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.widget.LinearLayout;
|
import android.widget.LinearLayout;
|
||||||
|
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
|
||||||
|
|
||||||
import com.android.settings.R;
|
import com.android.settings.R;
|
||||||
import com.android.settings.dashboard.DashboardAdapter;
|
import com.android.settings.dashboard.DashboardAdapter;
|
||||||
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||||
@@ -45,22 +45,23 @@ import java.util.List;
|
|||||||
public class ConditionAdapterTest {
|
public class ConditionAdapterTest {
|
||||||
|
|
||||||
@Mock
|
@Mock
|
||||||
private Condition mCondition1;
|
private ConditionalCard mCondition1;
|
||||||
@Mock
|
@Mock
|
||||||
private Condition mCondition2;
|
private ConditionalCard mCondition2;
|
||||||
|
@Mock
|
||||||
|
private ConditionManager mConditionManager;
|
||||||
|
|
||||||
private Context mContext;
|
private Context mContext;
|
||||||
private ConditionAdapter mConditionAdapter;
|
private ConditionAdapter mConditionAdapter;
|
||||||
private List<Condition> mOneCondition;
|
private List<ConditionalCard> mOneCondition;
|
||||||
private List<Condition> mTwoConditions;
|
private List<ConditionalCard> mTwoConditions;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() {
|
public void setUp() {
|
||||||
MockitoAnnotations.initMocks(this);
|
MockitoAnnotations.initMocks(this);
|
||||||
mContext = RuntimeEnvironment.application;
|
mContext = RuntimeEnvironment.application;
|
||||||
final CharSequence[] actions = new CharSequence[2];
|
final CharSequence action = "action";
|
||||||
when(mCondition1.getActions()).thenReturn(actions);
|
when(mCondition1.getActionText()).thenReturn(action);
|
||||||
when(mCondition1.shouldShow()).thenReturn(true);
|
|
||||||
mOneCondition = new ArrayList<>();
|
mOneCondition = new ArrayList<>();
|
||||||
mOneCondition.add(mCondition1);
|
mOneCondition.add(mCondition1);
|
||||||
mTwoConditions = new ArrayList<>();
|
mTwoConditions = new ArrayList<>();
|
||||||
@@ -70,32 +71,32 @@ public class ConditionAdapterTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void getItemCount_notExpanded_shouldReturn0() {
|
public void getItemCount_notExpanded_shouldReturn0() {
|
||||||
mConditionAdapter = new ConditionAdapter(mContext, mOneCondition, false);
|
mConditionAdapter = new ConditionAdapter(mContext, mConditionManager, mOneCondition, false);
|
||||||
assertThat(mConditionAdapter.getItemCount()).isEqualTo(0);
|
assertThat(mConditionAdapter.getItemCount()).isEqualTo(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void getItemCount_expanded_shouldReturnListSize() {
|
public void getItemCount_expanded_shouldReturnListSize() {
|
||||||
mConditionAdapter = new ConditionAdapter(mContext, mOneCondition, true);
|
mConditionAdapter = new ConditionAdapter(mContext, mConditionManager, mOneCondition, true);
|
||||||
assertThat(mConditionAdapter.getItemCount()).isEqualTo(1);
|
assertThat(mConditionAdapter.getItemCount()).isEqualTo(1);
|
||||||
|
|
||||||
mConditionAdapter = new ConditionAdapter(mContext, mTwoConditions, true);
|
mConditionAdapter = new ConditionAdapter(mContext, mConditionManager, mTwoConditions, true);
|
||||||
assertThat(mConditionAdapter.getItemCount()).isEqualTo(2);
|
assertThat(mConditionAdapter.getItemCount()).isEqualTo(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void getItemViewType_shouldReturnConditionTile() {
|
public void getItemViewType_shouldReturnConditionTile() {
|
||||||
mConditionAdapter = new ConditionAdapter(mContext, mTwoConditions, true);
|
mConditionAdapter = new ConditionAdapter(mContext, mConditionManager, mTwoConditions, true);
|
||||||
assertThat(mConditionAdapter.getItemViewType(0)).isEqualTo(R.layout.condition_tile);
|
assertThat(mConditionAdapter.getItemViewType(0)).isEqualTo(R.layout.condition_tile);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void onBindViewHolder_shouldSetListener() {
|
public void onBindViewHolder_shouldSetListener() {
|
||||||
final View view = LayoutInflater.from(mContext)
|
final View view = LayoutInflater.from(mContext)
|
||||||
.inflate(R.layout.condition_tile, new LinearLayout(mContext), true);
|
.inflate(R.layout.condition_tile, new LinearLayout(mContext), true);
|
||||||
final DashboardAdapter.DashboardItemHolder viewHolder =
|
final DashboardAdapter.DashboardItemHolder viewHolder =
|
||||||
new DashboardAdapter.DashboardItemHolder(view);
|
new DashboardAdapter.DashboardItemHolder(view);
|
||||||
mConditionAdapter = new ConditionAdapter(mContext, mOneCondition, true);
|
mConditionAdapter = new ConditionAdapter(mContext, mConditionManager, mOneCondition, true);
|
||||||
|
|
||||||
mConditionAdapter.onBindViewHolder(viewHolder, 0);
|
mConditionAdapter.onBindViewHolder(viewHolder, 0);
|
||||||
final View card = view.findViewById(R.id.content);
|
final View card = view.findViewById(R.id.content);
|
||||||
@@ -106,30 +107,15 @@ public class ConditionAdapterTest {
|
|||||||
@Test
|
@Test
|
||||||
public void viewClick_shouldInvokeConditionPrimaryClick() {
|
public void viewClick_shouldInvokeConditionPrimaryClick() {
|
||||||
final View view = LayoutInflater.from(mContext)
|
final View view = LayoutInflater.from(mContext)
|
||||||
.inflate(R.layout.condition_tile, new LinearLayout(mContext), true);
|
.inflate(R.layout.condition_tile, new LinearLayout(mContext), true);
|
||||||
final DashboardAdapter.DashboardItemHolder viewHolder =
|
final DashboardAdapter.DashboardItemHolder viewHolder =
|
||||||
new DashboardAdapter.DashboardItemHolder(view);
|
new DashboardAdapter.DashboardItemHolder(view);
|
||||||
mConditionAdapter = new ConditionAdapter(mContext, mOneCondition, true);
|
mConditionAdapter = new ConditionAdapter(mContext, mConditionManager, mOneCondition, true);
|
||||||
|
|
||||||
mConditionAdapter.onBindViewHolder(viewHolder, 0);
|
mConditionAdapter.onBindViewHolder(viewHolder, 0);
|
||||||
final View card = view.findViewById(R.id.content);
|
final View card = view.findViewById(R.id.content);
|
||||||
assertThat(card).isNotNull();
|
assertThat(card).isNotNull();
|
||||||
card.performClick();
|
card.performClick();
|
||||||
verify(mCondition1).onPrimaryClick();
|
verify(mConditionManager).onPrimaryClick(any(Context.class), anyLong());
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void onSwiped_nullCondition_shouldNotCrash() {
|
|
||||||
final RecyclerView recyclerView = new RecyclerView(mContext);
|
|
||||||
final View view = LayoutInflater.from(mContext).inflate(
|
|
||||||
R.layout.condition_tile, new LinearLayout(mContext), true);
|
|
||||||
final DashboardAdapter.DashboardItemHolder viewHolder =
|
|
||||||
new DashboardAdapter.DashboardItemHolder(view);
|
|
||||||
mConditionAdapter = new ConditionAdapter(mContext, mOneCondition, true);
|
|
||||||
mConditionAdapter.addDismissHandling(recyclerView);
|
|
||||||
|
|
||||||
// do not bind viewholder to simulate the null condition scenario
|
|
||||||
mConditionAdapter.mSwipeCallback.onSwiped(viewHolder, 0);
|
|
||||||
// no crash
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -14,7 +14,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.android.settings.homepage.conditional.v2;
|
package com.android.settings.homepage.conditional;
|
||||||
|
|
||||||
import static com.google.common.truth.Truth.assertThat;
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
|
|
||||||
@@ -25,6 +25,9 @@ import static org.mockito.Mockito.when;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
|
||||||
import com.android.settings.homepage.conditional.ConditionListener;
|
import com.android.settings.homepage.conditional.ConditionListener;
|
||||||
|
import com.android.settings.homepage.conditional.ConditionManager;
|
||||||
|
import com.android.settings.homepage.conditional.ConditionalCard;
|
||||||
|
import com.android.settings.homepage.conditional.ConditionalCardController;
|
||||||
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||||
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
@@ -1,161 +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.homepage.conditional;
|
|
||||||
|
|
||||||
import static com.google.common.truth.Truth.assertThat;
|
|
||||||
|
|
||||||
import static org.mockito.Matchers.any;
|
|
||||||
import static org.mockito.Matchers.eq;
|
|
||||||
import static org.mockito.Mockito.mock;
|
|
||||||
import static org.mockito.Mockito.never;
|
|
||||||
import static org.mockito.Mockito.spy;
|
|
||||||
import static org.mockito.Mockito.verify;
|
|
||||||
import static org.mockito.Mockito.when;
|
|
||||||
|
|
||||||
import android.content.BroadcastReceiver;
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.IntentFilter;
|
|
||||||
import android.graphics.drawable.Drawable;
|
|
||||||
|
|
||||||
import com.android.internal.logging.nano.MetricsProto;
|
|
||||||
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
|
||||||
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
|
|
||||||
|
|
||||||
import org.junit.Before;
|
|
||||||
import org.junit.Test;
|
|
||||||
import org.junit.runner.RunWith;
|
|
||||||
import org.mockito.Mock;
|
|
||||||
import org.mockito.MockitoAnnotations;
|
|
||||||
import org.robolectric.RuntimeEnvironment;
|
|
||||||
|
|
||||||
@RunWith(SettingsRobolectricTestRunner.class)
|
|
||||||
public class ConditionTest {
|
|
||||||
|
|
||||||
@Mock
|
|
||||||
private ConditionManager mConditionManager;
|
|
||||||
@Mock
|
|
||||||
private MetricsFeatureProvider mMetricsFeatureProvider;
|
|
||||||
|
|
||||||
private Context mContext;
|
|
||||||
private TestCondition mCondition;
|
|
||||||
|
|
||||||
@Before
|
|
||||||
public void setUp() {
|
|
||||||
MockitoAnnotations.initMocks(this);
|
|
||||||
mContext = spy(RuntimeEnvironment.application);
|
|
||||||
mCondition = new TestCondition(mConditionManager, mMetricsFeatureProvider);
|
|
||||||
when(mConditionManager.getContext()).thenReturn(mContext);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void initialize_shouldNotBeSilenced() {
|
|
||||||
assertThat(mCondition.isSilenced()).isFalse();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void silence_shouldNotifyDataChangeAndLog() {
|
|
||||||
mCondition.silence();
|
|
||||||
|
|
||||||
assertThat(mCondition.isSilenced()).isTrue();
|
|
||||||
verify(mConditionManager).notifyChanged(mCondition);
|
|
||||||
verify(mMetricsFeatureProvider).action(any(Context.class),
|
|
||||||
eq(MetricsProto.MetricsEvent.ACTION_SETTINGS_CONDITION_DISMISS),
|
|
||||||
eq(TestCondition.TEST_METRIC_CONSTANT));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void onSilenceChanged_silenced_shouldRegisterReceiver() {
|
|
||||||
mCondition.onSilenceChanged(true);
|
|
||||||
|
|
||||||
verify(mContext).registerReceiver(
|
|
||||||
TestCondition.mReceiver, TestCondition.TESTS_INTENT_FILTER);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void onSilenceChanged_notSilenced_registered_shouldUnregisterReceiver() {
|
|
||||||
mCondition.onSilenceChanged(true);
|
|
||||||
|
|
||||||
mCondition.onSilenceChanged(false);
|
|
||||||
|
|
||||||
verify(mContext).unregisterReceiver(TestCondition.mReceiver);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void onSilenceChanged_notSilenced_notRegistered_shouldNotCrash() {
|
|
||||||
mCondition.onSilenceChanged(false);
|
|
||||||
|
|
||||||
verify(mContext, never()).unregisterReceiver(TestCondition.mReceiver);
|
|
||||||
// no crash
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final class TestCondition extends Condition {
|
|
||||||
|
|
||||||
private static final int TEST_METRIC_CONSTANT = 1234;
|
|
||||||
private static final IntentFilter TESTS_INTENT_FILTER = new IntentFilter("TestIntent");
|
|
||||||
private static final BroadcastReceiver mReceiver = mock(BroadcastReceiver.class);
|
|
||||||
|
|
||||||
TestCondition(ConditionManager manager, MetricsFeatureProvider metricsFeatureProvider) {
|
|
||||||
super(manager, metricsFeatureProvider);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void refreshState() {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getMetricsConstant() {
|
|
||||||
return TEST_METRIC_CONSTANT;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Drawable getIcon() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public CharSequence getTitle() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public CharSequence getSummary() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public CharSequence[] getActions() {
|
|
||||||
return new CharSequence[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onPrimaryClick() {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onActionClick(int index) {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public BroadcastReceiver getReceiver() {
|
|
||||||
return mReceiver;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public IntentFilter getIntentFilter() {
|
|
||||||
return TESTS_INTENT_FILTER;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,118 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2017 The Android Open Source Project
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License
|
|
||||||
*/
|
|
||||||
package com.android.settings.homepage.conditional;
|
|
||||||
|
|
||||||
import static com.google.common.truth.Truth.assertThat;
|
|
||||||
|
|
||||||
import static org.mockito.Matchers.any;
|
|
||||||
import static org.mockito.Matchers.eq;
|
|
||||||
import static org.mockito.Mockito.never;
|
|
||||||
import static org.mockito.Mockito.reset;
|
|
||||||
import static org.mockito.Mockito.times;
|
|
||||||
import static org.mockito.Mockito.verify;
|
|
||||||
import static org.mockito.Mockito.when;
|
|
||||||
|
|
||||||
import android.content.ComponentName;
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.pm.PackageManager;
|
|
||||||
|
|
||||||
import com.android.settings.testutils.FakeFeatureFactory;
|
|
||||||
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
|
||||||
|
|
||||||
import org.junit.Before;
|
|
||||||
import org.junit.Test;
|
|
||||||
import org.junit.runner.RunWith;
|
|
||||||
import org.mockito.Mock;
|
|
||||||
import org.mockito.MockitoAnnotations;
|
|
||||||
|
|
||||||
@RunWith(SettingsRobolectricTestRunner.class)
|
|
||||||
public class DndConditionTest {
|
|
||||||
|
|
||||||
@Mock
|
|
||||||
private ConditionManager mConditionManager;
|
|
||||||
@Mock
|
|
||||||
private PackageManager mPackageManager;
|
|
||||||
@Mock
|
|
||||||
private Context mContext;
|
|
||||||
|
|
||||||
@Before
|
|
||||||
public void setUp() {
|
|
||||||
MockitoAnnotations.initMocks(this);
|
|
||||||
FakeFeatureFactory.setupForTest();
|
|
||||||
when(mConditionManager.getContext()).thenReturn(mContext);
|
|
||||||
when(mContext.getPackageManager()).thenReturn(mPackageManager);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void constructor_shouldNotDisableReceiver() {
|
|
||||||
new DndCondition(mConditionManager);
|
|
||||||
verify(mPackageManager, never()).setComponentEnabledSetting(any(ComponentName.class),
|
|
||||||
eq(PackageManager.COMPONENT_ENABLED_STATE_DISABLED), eq(PackageManager.DONT_KILL_APP));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void constructor_shouldRegisterReceiver() {
|
|
||||||
new DndCondition(mConditionManager);
|
|
||||||
verify(mContext).registerReceiver(any(DndCondition.Receiver.class),
|
|
||||||
eq(DndCondition.DND_FILTER));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void silence_shouldNotDisableReceiver() {
|
|
||||||
new DndCondition(mConditionManager).silence();
|
|
||||||
|
|
||||||
verify(mPackageManager, never()).setComponentEnabledSetting(any(ComponentName.class),
|
|
||||||
eq(PackageManager.COMPONENT_ENABLED_STATE_DISABLED), eq(PackageManager.DONT_KILL_APP));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void onResume_shouldRegisterReceiver() {
|
|
||||||
DndCondition condition = new DndCondition(mConditionManager);
|
|
||||||
condition.onPause();
|
|
||||||
condition.onResume();
|
|
||||||
|
|
||||||
// one from constructor, one from onResume()
|
|
||||||
verify(mContext, times(2)).registerReceiver(any(DndCondition.Receiver.class),
|
|
||||||
eq(DndCondition.DND_FILTER));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void onPause_shouldUnregisterReceiver() {
|
|
||||||
new DndCondition(mConditionManager).onPause();
|
|
||||||
|
|
||||||
verify(mContext).unregisterReceiver(any(DndCondition.Receiver.class));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void onPause_noReceiverRegistered_shouldNotUnregisterReceiver() {
|
|
||||||
DndCondition condition = new DndCondition(mConditionManager);
|
|
||||||
condition.onPause();
|
|
||||||
reset(mContext);
|
|
||||||
|
|
||||||
condition.onPause();
|
|
||||||
|
|
||||||
verify(mContext, never()).unregisterReceiver(any(DndCondition.Receiver.class));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void nullZenConfig_noCrash() {
|
|
||||||
DndCondition condition = new DndCondition(mConditionManager);
|
|
||||||
assertThat(condition.mConfig).isNull();
|
|
||||||
|
|
||||||
// should not crash, instead summary is null
|
|
||||||
assertThat(condition.getSummary()).isNull();
|
|
||||||
}
|
|
||||||
}
|
|
@@ -14,7 +14,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.android.settings.homepage.conditional.v2;
|
package com.android.settings.homepage.conditional;
|
||||||
|
|
||||||
|
|
||||||
import static org.mockito.ArgumentMatchers.any;
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
@@ -24,6 +24,8 @@ import static org.mockito.Mockito.verify;
|
|||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
|
||||||
|
import com.android.settings.homepage.conditional.ConditionManager;
|
||||||
|
import com.android.settings.homepage.conditional.DndConditionCardController;
|
||||||
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||||
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
@@ -14,7 +14,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.android.settings.homepage.conditional.v2;
|
package com.android.settings.homepage.conditional;
|
||||||
|
|
||||||
import static com.google.common.truth.Truth.assertThat;
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
|
|
||||||
@@ -24,6 +24,9 @@ import static org.mockito.Mockito.when;
|
|||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
|
||||||
|
import com.android.settings.homepage.conditional.ConditionManager;
|
||||||
|
import com.android.settings.homepage.conditional.DndConditionCard;
|
||||||
|
import com.android.settings.homepage.conditional.DndConditionCardController;
|
||||||
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||||
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
@@ -1,96 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2018 The Android Open Source Project
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.android.settings.homepage.conditional;
|
|
||||||
|
|
||||||
|
|
||||||
import static com.google.common.truth.Truth.assertThat;
|
|
||||||
|
|
||||||
import static org.mockito.Mockito.spy;
|
|
||||||
import static org.mockito.Mockito.verify;
|
|
||||||
import static org.mockito.Mockito.when;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.media.AudioManager;
|
|
||||||
import android.provider.Settings;
|
|
||||||
|
|
||||||
import com.android.settings.R;
|
|
||||||
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
|
||||||
import com.android.settings.testutils.shadow.ShadowAudioManager;
|
|
||||||
import com.android.settings.testutils.shadow.ShadowNotificationManager;
|
|
||||||
|
|
||||||
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 org.robolectric.shadow.api.Shadow;
|
|
||||||
|
|
||||||
@RunWith(SettingsRobolectricTestRunner.class)
|
|
||||||
@Config(shadows = {ShadowNotificationManager.class, ShadowAudioManager.class})
|
|
||||||
public class RingerMutedConditionTest {
|
|
||||||
private static final String TAG = "RingerMutedConditionTest";
|
|
||||||
@Mock
|
|
||||||
private ConditionManager mConditionManager;
|
|
||||||
|
|
||||||
private Context mContext;
|
|
||||||
private ShadowNotificationManager mNotificationManager;
|
|
||||||
private ShadowAudioManager mAudioManager;
|
|
||||||
private RingerMutedCondition mCondition;
|
|
||||||
|
|
||||||
@Before
|
|
||||||
public void setUp() {
|
|
||||||
MockitoAnnotations.initMocks(this);
|
|
||||||
mContext = RuntimeEnvironment.application;
|
|
||||||
mAudioManager = Shadow.extract(mContext.getSystemService(Context.AUDIO_SERVICE));
|
|
||||||
mNotificationManager = Shadow.extract(
|
|
||||||
mContext.getSystemService(Context.NOTIFICATION_SERVICE));
|
|
||||||
when(mConditionManager.getContext()).thenReturn(mContext);
|
|
||||||
mCondition = spy(new RingerMutedCondition(mConditionManager));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void verifyText() {
|
|
||||||
assertThat(mCondition.getTitle()).isEqualTo(
|
|
||||||
mContext.getText(R.string.condition_device_muted_title));
|
|
||||||
assertThat(mCondition.getSummary()).isEqualTo(
|
|
||||||
mContext.getText(R.string.condition_device_muted_summary));
|
|
||||||
assertThat(mCondition.getActions()[0]).isEqualTo(
|
|
||||||
mContext.getText(R.string.condition_device_muted_action_turn_on_sound));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void refreshState_zenModeOn_shouldNotActivate() {
|
|
||||||
mAudioManager.setRingerModeInternal(AudioManager.RINGER_MODE_SILENT);
|
|
||||||
mNotificationManager.setZenMode(Settings.Global.ZEN_MODE_NO_INTERRUPTIONS, null, TAG);
|
|
||||||
|
|
||||||
mCondition.refreshState();
|
|
||||||
|
|
||||||
verify(mCondition).setActive(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void refreshState_zenModeOff_shouldActivate() {
|
|
||||||
mAudioManager.setRingerModeInternal(AudioManager.RINGER_MODE_SILENT);
|
|
||||||
mNotificationManager.setZenMode(Settings.Global.ZEN_MODE_OFF, null, TAG);
|
|
||||||
|
|
||||||
mCondition.refreshState();
|
|
||||||
|
|
||||||
verify(mCondition).setActive(true);
|
|
||||||
}
|
|
||||||
}
|
|
@@ -19,8 +19,6 @@ package com.android.settings.homepage.conditional;
|
|||||||
|
|
||||||
import static com.google.common.truth.Truth.assertThat;
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
|
|
||||||
import static org.mockito.Mockito.when;
|
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
|
||||||
import com.android.settings.R;
|
import com.android.settings.R;
|
||||||
@@ -29,33 +27,29 @@ import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
|||||||
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.Mock;
|
|
||||||
import org.mockito.MockitoAnnotations;
|
import org.mockito.MockitoAnnotations;
|
||||||
import org.robolectric.RuntimeEnvironment;
|
import org.robolectric.RuntimeEnvironment;
|
||||||
|
|
||||||
@RunWith(SettingsRobolectricTestRunner.class)
|
@RunWith(SettingsRobolectricTestRunner.class)
|
||||||
public class RingerVibrateConditionTest {
|
public class RingerVibrateConditionCardTest {
|
||||||
@Mock
|
|
||||||
private ConditionManager mConditionManager;
|
|
||||||
|
|
||||||
private Context mContext;
|
private Context mContext;
|
||||||
private RingerVibrateCondition mCondition;
|
private RingerVibrateConditionCard mCard;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() {
|
public void setUp() {
|
||||||
MockitoAnnotations.initMocks(this);
|
MockitoAnnotations.initMocks(this);
|
||||||
mContext = RuntimeEnvironment.application;
|
mContext = RuntimeEnvironment.application;
|
||||||
when(mConditionManager.getContext()).thenReturn(mContext);
|
mCard = new RingerVibrateConditionCard(mContext);
|
||||||
mCondition = new RingerVibrateCondition(mConditionManager);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void verifyText() {
|
public void verifyText() {
|
||||||
assertThat(mCondition.getTitle()).isEqualTo(
|
assertThat(mCard.getTitle()).isEqualTo(
|
||||||
mContext.getText(R.string.condition_device_vibrate_title));
|
mContext.getText(R.string.condition_device_vibrate_title));
|
||||||
assertThat(mCondition.getSummary()).isEqualTo(
|
assertThat(mCard.getSummary()).isEqualTo(
|
||||||
mContext.getText(R.string.condition_device_vibrate_summary));
|
mContext.getText(R.string.condition_device_vibrate_summary));
|
||||||
assertThat(mCondition.getActions()[0]).isEqualTo(
|
assertThat(mCard.getActionText()).isEqualTo(
|
||||||
mContext.getText(R.string.condition_device_muted_action_turn_on_sound));
|
mContext.getText(R.string.condition_device_muted_action_turn_on_sound));
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -14,7 +14,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.android.settings.homepage.conditional.v2;
|
package com.android.settings.homepage.conditional;
|
||||||
|
|
||||||
import static org.mockito.ArgumentMatchers.argThat;
|
import static org.mockito.ArgumentMatchers.argThat;
|
||||||
import static org.mockito.Mockito.spy;
|
import static org.mockito.Mockito.spy;
|
||||||
@@ -24,6 +24,7 @@ import android.content.ComponentName;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
|
||||||
import com.android.settings.Settings;
|
import com.android.settings.Settings;
|
||||||
|
import com.android.settings.homepage.conditional.WorkModeConditionController;
|
||||||
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||||
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
@@ -1,65 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2018 The Android Open Source Project
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License
|
|
||||||
*/
|
|
||||||
package com.android.settings.homepage.conditional;
|
|
||||||
|
|
||||||
import static org.mockito.ArgumentMatchers.argThat;
|
|
||||||
import static org.mockito.Mockito.spy;
|
|
||||||
import static org.mockito.Mockito.verify;
|
|
||||||
import static org.mockito.Mockito.when;
|
|
||||||
|
|
||||||
import android.content.ComponentName;
|
|
||||||
import android.content.Context;
|
|
||||||
|
|
||||||
import com.android.settings.Settings;
|
|
||||||
import com.android.settings.testutils.FakeFeatureFactory;
|
|
||||||
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
|
||||||
|
|
||||||
import org.junit.Before;
|
|
||||||
import org.junit.Test;
|
|
||||||
import org.junit.runner.RunWith;
|
|
||||||
import org.mockito.Mock;
|
|
||||||
import org.mockito.MockitoAnnotations;
|
|
||||||
import org.robolectric.RuntimeEnvironment;
|
|
||||||
|
|
||||||
@RunWith(SettingsRobolectricTestRunner.class)
|
|
||||||
public class WorkModeConditionTest {
|
|
||||||
|
|
||||||
@Mock
|
|
||||||
private ConditionManager mConditionManager;
|
|
||||||
|
|
||||||
private Context mContext;
|
|
||||||
private WorkModeCondition mCondition;
|
|
||||||
|
|
||||||
@Before
|
|
||||||
public void setUp() {
|
|
||||||
MockitoAnnotations.initMocks(this);
|
|
||||||
mContext = spy(RuntimeEnvironment.application);
|
|
||||||
FakeFeatureFactory.setupForTest();
|
|
||||||
when(mConditionManager.getContext()).thenReturn(mContext);
|
|
||||||
mCondition = new WorkModeCondition(mConditionManager);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void onPrimaryClick_shouldLaunchAccountsSetting() {
|
|
||||||
final ComponentName componentName =
|
|
||||||
new ComponentName(mContext, Settings.AccountDashboardActivity.class);
|
|
||||||
|
|
||||||
mCondition.onPrimaryClick();
|
|
||||||
|
|
||||||
verify(mContext).startActivity(
|
|
||||||
argThat(intent-> intent.getComponent().equals(componentName)));
|
|
||||||
}
|
|
||||||
}
|
|
Reference in New Issue
Block a user