Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3adbe907 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "New ConditionManager"

parents 5f116ced 06e25e75
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -25,4 +25,5 @@ public class FeatureFlags {
    public static final String AUDIO_SWITCHER_SETTINGS = "settings_audio_switcher";
    public static final String DYNAMIC_HOMEPAGE = "settings_dynamic_homepage";
    public static final String HEARING_AID_SETTINGS = "settings_bluetooth_hearing_aid";
    public static final String CONDITION_MANAGER_V2 = "settings_condition_manager_v2";
}
+42 −7
Original line number Diff line number Diff line
@@ -42,6 +42,8 @@ import com.android.settings.dashboard.DashboardData.ConditionHeaderData;
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.v2.ConditionManager;
import com.android.settings.homepage.conditional.v2.ConditionalCard;
import com.android.settings.overlay.FeatureFactory;
import com.android.settings.widget.RoundedHomepageIcon;
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
@@ -71,6 +73,7 @@ public class DashboardAdapter extends RecyclerView.Adapter<DashboardAdapter.Dash
    private boolean mFirstFrameDrawn;
    private RecyclerView mRecyclerView;
    private SuggestionAdapter mSuggestionAdapter;
    private ConditionManager mConditionManager;

    @VisibleForTesting
    DashboardData mDashboardData;
@@ -85,8 +88,8 @@ public class DashboardAdapter extends RecyclerView.Adapter<DashboardAdapter.Dash
    };

    public DashboardAdapter(Context context, Bundle savedInstanceState,
            List<Condition> conditions, SuggestionControllerMixinCompat suggestionControllerMixin,
            Lifecycle lifecycle) {
            List<Condition> conditions, ConditionManager conditionManager,
            SuggestionControllerMixinCompat suggestionControllerMixin, Lifecycle lifecycle) {

        DashboardCategory category = null;
        boolean conditionExpanded = false;
@@ -96,6 +99,7 @@ public class DashboardAdapter extends RecyclerView.Adapter<DashboardAdapter.Dash
        mMetricsFeatureProvider = factory.getMetricsFeatureProvider();
        mDashboardFeatureProvider = factory.getDashboardFeatureProvider(context);
        mCache = new IconCache(context);
        mConditionManager = conditionManager;
        mSuggestionAdapter = new SuggestionAdapter(mContext, suggestionControllerMixin,
                savedInstanceState, this /* callback */, lifecycle);

@@ -113,6 +117,8 @@ public class DashboardAdapter extends RecyclerView.Adapter<DashboardAdapter.Dash

        mDashboardData = new DashboardData.Builder()
                .setConditions(conditions)
                .setConditionsV2(
                        conditionManager == null ? null : conditionManager.getDisplayableCards())
                .setSuggestions(mSuggestionAdapter.getSuggestions())
                .setCategory(category)
                .setConditionExpanded(conditionExpanded)
@@ -145,6 +151,15 @@ public class DashboardAdapter extends RecyclerView.Adapter<DashboardAdapter.Dash
        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
    public void onSuggestionClosed(Suggestion suggestion) {
        final List<Suggestion> list = mDashboardData.getSuggestions();
@@ -286,11 +301,31 @@ public class DashboardAdapter extends RecyclerView.Adapter<DashboardAdapter.Dash

    @VisibleForTesting
    void onBindCondition(final ConditionContainerHolder holder, int position) {
        final List conditions = (List) mDashboardData.getItemEntityByPosition(position);
        final List<Condition> conditionsV1;
        final List<ConditionalCard> conditionsV2;
        if (conditions == null || conditions.isEmpty()) {
            conditionsV1 = null;
            conditionsV2 = null;
        } 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,
                (List<Condition>) mDashboardData.getItemEntityByPosition(position),
                mDashboardData.isConditionExpanded());
                    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));
    }

+51 −23
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@ import androidx.recyclerview.widget.DiffUtil;

import com.android.settings.R;
import com.android.settings.homepage.conditional.Condition;
import com.android.settings.homepage.conditional.v2.ConditionalCard;
import com.android.settingslib.drawer.DashboardCategory;
import com.android.settingslib.drawer.Tile;

@@ -58,12 +59,14 @@ public class DashboardData {
    private final List<Item> mItems;
    private final DashboardCategory mCategory;
    private final List<Condition> mConditions;
    private final List<ConditionalCard> mConditionsV2;
    private final List<Suggestion> mSuggestions;
    private final boolean mConditionExpanded;

    private DashboardData(Builder builder) {
        mCategory = builder.mCategory;
        mConditions = builder.mConditions;
        mConditionsV2 = builder.mConditionsV2;
        mSuggestions = builder.mSuggestions;
        mConditionExpanded = builder.mConditionExpanded;
        mItems = new ArrayList<>();
@@ -182,8 +185,11 @@ public class DashboardData {
     * and mIsShowingAll, mConditionExpanded flag.
     */
    private void buildItemsData() {
        final List<Condition> conditions = getConditionsToShow(mConditions);
        final boolean hasConditions = sizeOf(conditions) > 0;
        final List<Condition> conditionsV1 = getConditionsToShow(mConditions);
        final boolean hasConditionsV1 = sizeOf(conditionsV1) > 0;
        final List<ConditionalCard> conditionsV2 = mConditionsV2;
        final boolean hasConditionsV2 = sizeOf(conditionsV2) > 0;
        final boolean hasConditions = hasConditionsV1 || hasConditionsV2;

        final List<Suggestion> suggestions = getSuggestionsToShow(mSuggestions);
        final boolean hasSuggestions = sizeOf(suggestions) > 0;
@@ -198,14 +204,20 @@ public class DashboardData {
                STABLE_ID_SUGGESTION_CONDITION_DIVIDER, hasSuggestions && hasConditions);

        /* Condition header. This will be present when there is condition and it is collapsed */
        addToItemList(new ConditionHeaderData(conditions),
        addToItemList(new ConditionHeaderData(conditionsV1, conditionsV2),
                R.layout.condition_header,
                STABLE_ID_CONDITION_HEADER, hasConditions && !mConditionExpanded);

        /* 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 */
        addToItemList(conditions, R.layout.condition_container,
            STABLE_ID_CONDITION_CONTAINER, hasConditions && mConditionExpanded);
        if (hasConditionsV1) {
            addToItemList(conditionsV1, R.layout.condition_container,
                    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 */
        addToItemList(null /* item */, R.layout.condition_footer,
@@ -260,6 +272,7 @@ public class DashboardData {
    public static class Builder {
        private DashboardCategory mCategory;
        private List<Condition> mConditions;
        private List<ConditionalCard> mConditionsV2;
        private List<Suggestion> mSuggestions;
        private boolean mConditionExpanded;

@@ -269,6 +282,7 @@ public class DashboardData {
        public Builder(DashboardData dashboardData) {
            mCategory = dashboardData.mCategory;
            mConditions = dashboardData.mConditions;
            mConditionsV2 = dashboardData.mConditionsV2;
            mSuggestions = dashboardData.mSuggestions;
            mConditionExpanded = dashboardData.mConditionExpanded;
        }
@@ -283,6 +297,11 @@ public class DashboardData {
            return this;
        }

        public Builder setConditionsV2(List<ConditionalCard> conditions) {
            this.mConditionsV2 = conditions;
            return this;
        }

        public Builder setSuggestions(List<Suggestion> suggestions) {
            this.mSuggestions = suggestions;
            return this;
@@ -428,7 +447,8 @@ public class DashboardData {
        public final CharSequence title;
        public final int conditionCount;

        public ConditionHeaderData(List<Condition> conditions) {
        public ConditionHeaderData(List<Condition> conditions, List<ConditionalCard> conditionsV2) {
            if (conditionsV2 == null) {
                conditionCount = sizeOf(conditions);
                title = conditionCount > 0 ? conditions.get(0).getTitle() : null;
                conditionIcons = new ArrayList<>();
@@ -436,6 +456,14 @@ public class DashboardData {
                    final Condition condition = conditions.get(i);
                    conditionIcons.add(condition.getIcon());
                }
            } else {
                conditionCount = sizeOf(conditionsV2);
                title = conditionCount > 0 ? conditionsV2.get(0).getTitle() : null;
                conditionIcons = new ArrayList<>();
                for (ConditionalCard card : conditionsV2) {
                    conditionIcons.add(card.getIcon());
                }
            }
        }
    }

+60 −19
Original line number Diff line number Diff line
@@ -38,8 +38,8 @@ import com.android.settings.core.SettingsBaseActivity;
import com.android.settings.core.SettingsBaseActivity.CategoryListener;
import com.android.settings.dashboard.suggestions.SuggestionFeatureProvider;
import com.android.settings.homepage.conditional.Condition;
import com.android.settings.homepage.conditional.ConditionManager;
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.FocusListener;
import com.android.settings.overlay.FeatureFactory;
@@ -74,6 +74,7 @@ public class DashboardSummary extends InstrumentedFragment
    private DashboardAdapter mAdapter;
    private SummaryLoader mSummaryLoader;
    private ConditionManager mConditionManager;
    private com.android.settings.homepage.conditional.v2.ConditionManager mConditionManager2;
    private LinearLayoutManager mLayoutManager;
    private SuggestionControllerMixinCompat mSuggestionControllerMixin;
    private DashboardFeatureProvider mDashboardFeatureProvider;
@@ -123,7 +124,18 @@ public class DashboardSummary extends InstrumentedFragment
        mSummaryLoader = new SummaryLoader(activity, CategoryKey.CATEGORY_HOMEPAGE);

        mConditionManager = ConditionManager.get(activity, false);
        if (com.android.settings.homepage.conditional.v2.ConditionManager.isEnabled(activity)) {
            mConditionManager = null;
            mConditionManager2 =
                    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) {
            mIsOnCategoriesChangedCalled =
                    savedInstanceState.getBoolean(STATE_CATEGORIES_CHANGE_CALLED);
@@ -147,12 +159,16 @@ public class DashboardSummary extends InstrumentedFragment
        ((SettingsBaseActivity) getActivity()).addCategoryListener(this);
        mSummaryLoader.setListening(true);
        final int metricsCategory = getMetricsCategory();
        if (mConditionManager2 == null) {
            for (Condition c : mConditionManager.getConditions()) {
                if (c.shouldShow()) {
                    mMetricsFeatureProvider.visible(getContext(), metricsCategory,
                            c.getMetricsConstant());
                }
            }
        } else {
            mConditionManager2.startMonitoringStateChange();
        }
        if (DEBUG_TIMING) {
            Log.d(TAG, "onResume took " + (System.currentTimeMillis() - startTime) + " ms");
        }
@@ -164,16 +180,26 @@ public class DashboardSummary extends InstrumentedFragment

        ((SettingsBaseActivity) getActivity()).remCategoryListener(this);
        mSummaryLoader.setListening(false);
        if (mConditionManager2 == null) {
            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
    public void onWindowFocusChanged(boolean hasWindowFocus) {
        long startTime = System.currentTimeMillis();
        if (mConditionManager2 == null) {
            if (hasWindowFocus) {
                Log.d(TAG, "Listening for condition changes");
                mConditionManager.addListener(this);
@@ -183,6 +209,14 @@ public class DashboardSummary extends InstrumentedFragment
                Log.d(TAG, "Stopped listening for condition changes");
                mConditionManager.remListener(this);
            }
        } else {
            // TODO(b/112485407): Register monitoring for condition manager v2.
            if (hasWindowFocus) {
                mConditionManager2.startMonitoringStateChange();
            } else {
                mConditionManager2.stopMonitoringStateChange();
            }
        }
        if (DEBUG_TIMING) {
            Log.d(TAG, "onWindowFocusChanged took "
                    + (System.currentTimeMillis() - startTime) + " ms");
@@ -215,7 +249,9 @@ public class DashboardSummary extends InstrumentedFragment
        mDashboard.setListener(this);
        mDashboard.setItemAnimator(new DashboardItemAnimator());
        mAdapter = new DashboardAdapter(getContext(), bundle,
                mConditionManager.getConditions(), mSuggestionControllerMixin,
                mConditionManager == null ? null : mConditionManager.getConditions(),
                mConditionManager2,
                mSuggestionControllerMixin,
                getSettingsLifecycle());
        mDashboard.setAdapter(mAdapter);
        mSummaryLoader.setSummaryConsumer(mAdapter);
@@ -255,10 +291,15 @@ public class DashboardSummary extends InstrumentedFragment
        // 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
        // conditions.
        if (mOnConditionsChangedCalled) {
        if (mOnConditionsChangedCalled || mConditionManager2 != null) {
            final boolean scrollToTop =
                    mLayoutManager.findFirstCompletelyVisibleItemPosition() <= 1;
            if (mConditionManager2 == null) {
                mAdapter.setConditions(mConditionManager.getConditions());
            } else {
                mAdapter.setConditionsV2(mConditionManager2.getDisplayableCards());
            }

            if (scrollToTop) {
                mDashboard.scrollToPosition(0);
            }
+130 −0
Original line number Diff line number Diff line
/*
 * 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);
        }
    }
}
Loading