• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2018 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.settings.panel;
18 
19 import static com.android.settings.slices.CustomSliceRegistry.MEDIA_OUTPUT_INDICATOR_SLICE_URI;
20 
21 import android.app.settings.SettingsEnums;
22 import android.content.Context;
23 import android.view.LayoutInflater;
24 import android.view.View;
25 import android.view.ViewGroup;
26 
27 import androidx.annotation.NonNull;
28 import androidx.annotation.VisibleForTesting;
29 import androidx.lifecycle.LiveData;
30 import androidx.recyclerview.widget.RecyclerView;
31 import androidx.slice.Slice;
32 import androidx.slice.widget.SliceView;
33 
34 import com.android.settings.R;
35 import com.android.settings.overlay.FeatureFactory;
36 
37 import com.google.android.setupdesign.DividerItemDecoration;
38 
39 import java.util.ArrayList;
40 import java.util.List;
41 
42 /**
43  * RecyclerView adapter for Slices in Settings Panels.
44  */
45 public class PanelSlicesAdapter
46         extends RecyclerView.Adapter<PanelSlicesAdapter.SliceRowViewHolder> {
47 
48     /**
49      * Maximum number of slices allowed on the panel view.
50      */
51     @VisibleForTesting
52     static final int MAX_NUM_OF_SLICES = 5;
53 
54     private final List<LiveData<Slice>> mSliceLiveData;
55     private final int mMetricsCategory;
56     private final PanelFragment mPanelFragment;
57 
PanelSlicesAdapter( PanelFragment fragment, List<LiveData<Slice>> sliceLiveData, int metricsCategory)58     public PanelSlicesAdapter(
59             PanelFragment fragment, List<LiveData<Slice>> sliceLiveData, int metricsCategory) {
60         mPanelFragment = fragment;
61         mSliceLiveData = new ArrayList<>(sliceLiveData);
62         mMetricsCategory = metricsCategory;
63     }
64 
65     @NonNull
66     @Override
onCreateViewHolder(@onNull ViewGroup viewGroup, int viewType)67     public SliceRowViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int viewType) {
68         final Context context = viewGroup.getContext();
69         final LayoutInflater inflater = LayoutInflater.from(context);
70         final View view = inflater.inflate(R.layout.panel_slice_row, viewGroup, false);
71 
72         return new SliceRowViewHolder(view);
73     }
74 
75     @Override
onBindViewHolder(@onNull SliceRowViewHolder sliceRowViewHolder, int position)76     public void onBindViewHolder(@NonNull SliceRowViewHolder sliceRowViewHolder, int position) {
77         sliceRowViewHolder.onBind(mSliceLiveData.get(position));
78     }
79 
80     /**
81      * Return the number of available items in the adapter with max number of slices enforced.
82      */
83     @Override
getItemCount()84     public int getItemCount() {
85         return Math.min(mSliceLiveData.size(), MAX_NUM_OF_SLICES);
86     }
87 
88     /**
89      * Return the available data from the adapter. If the number of Slices over the max number
90      * allowed, the list will only have the first MAX_NUM_OF_SLICES of slices.
91      */
92     @VisibleForTesting
getData()93     List<LiveData<Slice>> getData() {
94         return mSliceLiveData.subList(0, getItemCount());
95     }
96 
97     /**
98      * ViewHolder for binding Slices to SliceViews.
99      */
100     public class SliceRowViewHolder extends RecyclerView.ViewHolder
101             implements DividerItemDecoration.DividedViewHolder {
102 
103         private boolean mDividerAllowedAbove = true;
104 
105         @VisibleForTesting
106         final SliceView sliceView;
107 
SliceRowViewHolder(View view)108         public SliceRowViewHolder(View view) {
109             super(view);
110             sliceView = view.findViewById(R.id.slice_view);
111             sliceView.setMode(SliceView.MODE_LARGE);
112             sliceView.showTitleItems(true);
113         }
114 
onBind(LiveData<Slice> sliceLiveData)115         public void onBind(LiveData<Slice> sliceLiveData) {
116             sliceLiveData.observe(mPanelFragment.getViewLifecycleOwner(), sliceView);
117 
118             // Do not show the divider above media devices switcher slice per request
119             final Slice slice = sliceLiveData.getValue();
120             if (slice != null && slice.getUri().equals(MEDIA_OUTPUT_INDICATOR_SLICE_URI)) {
121                 mDividerAllowedAbove = false;
122             }
123 
124             // Log Panel interaction
125             sliceView.setOnSliceActionListener(
126                     ((eventInfo, sliceItem) -> {
127                         FeatureFactory.getFactory(sliceView.getContext())
128                                 .getMetricsFeatureProvider()
129                                 .action(0 /* attribution */,
130                                         SettingsEnums.ACTION_PANEL_INTERACTION,
131                                         mMetricsCategory,
132                                         sliceLiveData.getValue().getUri().getLastPathSegment()
133                                         /* log key */,
134                                         eventInfo.actionType /* value */);
135                     })
136             );
137         }
138 
139         @Override
isDividerAllowedAbove()140         public boolean isDividerAllowedAbove() {
141             return mDividerAllowedAbove;
142         }
143 
144         @Override
isDividerAllowedBelow()145         public boolean isDividerAllowedBelow() {
146             return true;
147         }
148     }
149 }
150