1 /*
2  * Copyright 2021 HIMSA II K/S - www.himsa.com.
3  * Represented by EHIMA - www.ehima.com
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 package com.android.bluetooth.leaudio;
19 
20 import android.bluetooth.BluetoothLeBroadcastMetadata;
21 import android.content.res.ColorStateList;
22 import android.graphics.Color;
23 import android.view.LayoutInflater;
24 import android.view.View;
25 import android.view.ViewGroup;
26 import android.widget.TextView;
27 
28 import androidx.annotation.NonNull;
29 import androidx.cardview.widget.CardView;
30 import androidx.recyclerview.widget.RecyclerView;
31 
32 import java.util.ArrayList;
33 import java.util.HashMap;
34 import java.util.List;
35 import java.util.Map;
36 
37 public class BroadcastItemsAdapter
38         extends RecyclerView.Adapter<BroadcastItemsAdapter.BroadcastItemHolder> {
39     private List<BluetoothLeBroadcastMetadata> mBroadcastMetadataList = new ArrayList<>();
40     private final Map<Integer /* broadcastId */, Boolean /* isPlaying */> mBroadcastPlaybackMap =
41             new HashMap<>();
42     private OnItemClickListener mOnItemClickListener;
43 
44     @NonNull
45     @Override
onCreateViewHolder(@onNull ViewGroup parent, int viewType)46     public BroadcastItemHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
47         View item_view =
48                 LayoutInflater.from(parent.getContext())
49                         .inflate(R.layout.broadcast_item, parent, false);
50         return new BroadcastItemHolder(item_view, mOnItemClickListener);
51     }
52 
setOnItemClickListener(OnItemClickListener listener)53     public void setOnItemClickListener(OnItemClickListener listener) {
54         this.mOnItemClickListener = listener;
55     }
56 
57     @Override
onBindViewHolder(@onNull BroadcastItemHolder holder, int position)58     public void onBindViewHolder(@NonNull BroadcastItemHolder holder, int position) {
59         BluetoothLeBroadcastMetadata meta = mBroadcastMetadataList.get(position);
60         Integer broadcastId = meta.getBroadcastId();
61         Boolean isPlaybackStateKnown = mBroadcastPlaybackMap.containsKey(broadcastId);
62 
63         String broadcastText =
64                 "ID: " + broadcastId + "(" + String.format("0x%06x", broadcastId) + ")";
65 
66         ColorStateList color = ColorStateList.valueOf(Color.WHITE);
67 
68         if (isPlaybackStateKnown) {
69             // Set card color based on the playback state
70             Boolean isPlaying = mBroadcastPlaybackMap.getOrDefault(broadcastId, false);
71 
72             if (isPlaying) {
73                 color = ColorStateList.valueOf(Color.parseColor("#92b141"));
74                 broadcastText += " ▶️";
75             } else {
76                 broadcastText += " ⏸";
77             }
78         }
79 
80         broadcastText += ("\nAddress: " + meta.getSourceDevice().getAddress());
81         broadcastText += ("\nName: " + meta.getSourceDevice().getName());
82         broadcastText += ("\nBroadcastName: " + meta.getBroadcastName());
83         broadcastText += ("\nSID: " + String.valueOf(meta.getSourceAdvertisingSid()));
84         broadcastText += ("\nisPublic: " + String.valueOf(meta.isPublicBroadcast()));
85         broadcastText += ("\nisEncrypted: " + String.valueOf(meta.isEncrypted()));
86 
87         holder.background.setCardBackgroundColor(color);
88         holder.mTextViewBroadcastId.setText(broadcastText);
89     }
90 
91     @Override
getItemCount()92     public int getItemCount() {
93         return mBroadcastMetadataList.size();
94     }
95 
updateBroadcastsMetadata(List<BluetoothLeBroadcastMetadata> broadcasts)96     public void updateBroadcastsMetadata(List<BluetoothLeBroadcastMetadata> broadcasts) {
97         mBroadcastMetadataList = broadcasts;
98         notifyDataSetChanged();
99     }
100 
updateBroadcastMetadata(BluetoothLeBroadcastMetadata broadcast)101     public void updateBroadcastMetadata(BluetoothLeBroadcastMetadata broadcast) {
102         mBroadcastMetadataList.removeIf(bc -> (bc.getBroadcastId() == broadcast.getBroadcastId()));
103         mBroadcastMetadataList.add(broadcast);
104         notifyDataSetChanged();
105     }
106 
addBroadcasts(Integer broadcastId)107     public void addBroadcasts(Integer broadcastId) {
108         if (!mBroadcastPlaybackMap.containsKey(broadcastId))
109             mBroadcastPlaybackMap.put(broadcastId, false);
110     }
111 
removeBroadcast(Integer broadcastId)112     public void removeBroadcast(Integer broadcastId) {
113         mBroadcastMetadataList.removeIf(bc -> (broadcastId.equals(bc.getBroadcastId())));
114         mBroadcastPlaybackMap.remove(broadcastId);
115         notifyDataSetChanged();
116     }
117 
setBroadcasts(List<BluetoothLeBroadcastMetadata> broadcasts)118     public void setBroadcasts(List<BluetoothLeBroadcastMetadata> broadcasts) {
119         mBroadcastMetadataList.clear();
120         mBroadcastMetadataList.addAll(broadcasts);
121 
122         for (BluetoothLeBroadcastMetadata b : broadcasts) {
123             int broadcastId = b.getBroadcastId();
124             if (mBroadcastPlaybackMap.containsKey(broadcastId)) {
125                 continue;
126             }
127             //          mBroadcastPlaybackMap.remove(broadcastId);
128             mBroadcastPlaybackMap.put(broadcastId, false);
129         }
130         notifyDataSetChanged();
131     }
132 
updateBroadcastPlayback(Integer broadcastId, boolean isPlaying)133     public void updateBroadcastPlayback(Integer broadcastId, boolean isPlaying) {
134         mBroadcastPlaybackMap.put(broadcastId, isPlaying);
135         notifyDataSetChanged();
136     }
137 
138     public interface OnItemClickListener {
onItemClick(Integer broadcastId)139         void onItemClick(Integer broadcastId);
140     }
141 
142     class BroadcastItemHolder extends RecyclerView.ViewHolder {
143         private final TextView mTextViewBroadcastId;
144         private final CardView background;
145 
BroadcastItemHolder(@onNull View itemView, OnItemClickListener listener)146         public BroadcastItemHolder(@NonNull View itemView, OnItemClickListener listener) {
147             super(itemView);
148 
149             mTextViewBroadcastId = itemView.findViewById(R.id.broadcast_id_text);
150             background = itemView.findViewById(R.id.broadcast_item_card_view);
151 
152             itemView.setOnClickListener(
153                     v -> {
154                         if (listener == null) return;
155 
156                         int position = getAdapterPosition();
157                         if (position != RecyclerView.NO_POSITION) {
158                             Integer broadcastId =
159                                     mBroadcastMetadataList.get(position).getBroadcastId();
160                             listener.onItemClick(broadcastId);
161                         }
162                     });
163         }
164     }
165 }
166