File indexing completed on 2024-12-22 04:41:41
0001 /* 0002 * SPDX-FileCopyrightText: 2018 Nicolas Fella <nicolas.fella@gmx.de> 0003 * 0004 * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 0005 */ 0006 0007 package org.kde.kdeconnect.Plugins.SystemVolumePlugin; 0008 0009 import android.util.Log; 0010 0011 import androidx.annotation.NonNull; 0012 0013 import org.json.JSONArray; 0014 import org.json.JSONException; 0015 import org.json.JSONObject; 0016 import org.kde.kdeconnect.NetworkPacket; 0017 import org.kde.kdeconnect.Plugins.Plugin; 0018 import org.kde.kdeconnect.Plugins.PluginFactory; 0019 import org.kde.kdeconnect_tp.R; 0020 0021 import java.util.ArrayList; 0022 import java.util.Collection; 0023 import java.util.concurrent.ConcurrentHashMap; 0024 0025 @PluginFactory.LoadablePlugin 0026 public class SystemVolumePlugin extends Plugin { 0027 0028 private final static String PACKET_TYPE_SYSTEMVOLUME = "kdeconnect.systemvolume"; 0029 private final static String PACKET_TYPE_SYSTEMVOLUME_REQUEST = "kdeconnect.systemvolume.request"; 0030 0031 public interface SinkListener { 0032 void sinksChanged(); 0033 } 0034 0035 private final ConcurrentHashMap<String, Sink> sinks; 0036 private final ArrayList<SinkListener> listeners; 0037 0038 public SystemVolumePlugin() { 0039 sinks = new ConcurrentHashMap<>(); 0040 listeners = new ArrayList<>(); 0041 } 0042 0043 @Override 0044 public @NonNull String getDisplayName() { 0045 return context.getResources().getString(R.string.pref_plugin_systemvolume); 0046 } 0047 0048 @Override 0049 public @NonNull String getDescription() { 0050 return context.getResources().getString(R.string.pref_plugin_systemvolume_desc); 0051 } 0052 0053 @Override 0054 public boolean onPacketReceived(@NonNull NetworkPacket np) { 0055 0056 if (np.has("sinkList")) { 0057 sinks.clear(); 0058 0059 try { 0060 JSONArray sinkArray = np.getJSONArray("sinkList"); 0061 0062 for (int i = 0; i < sinkArray.length(); i++) { 0063 JSONObject sinkObj = sinkArray.getJSONObject(i); 0064 Sink sink = new Sink(sinkObj); 0065 sinks.put(sink.getName(), sink); 0066 } 0067 } catch (JSONException e) { 0068 Log.e("KDEConnect", "Exception", e); 0069 } 0070 0071 synchronized(listeners) { 0072 for (SinkListener l : listeners) { 0073 l.sinksChanged(); 0074 } 0075 } 0076 0077 } else { 0078 String name = np.getString("name"); 0079 if (sinks.containsKey(name)) { 0080 if (np.has("volume")) { 0081 sinks.get(name).setVolume(np.getInt("volume")); 0082 } 0083 if (np.has("muted")) { 0084 sinks.get(name).setMute(np.getBoolean("muted")); 0085 } 0086 if (np.has("enabled")) { 0087 sinks.get(name).setDefault(np.getBoolean("enabled")); 0088 } 0089 } 0090 } 0091 return true; 0092 } 0093 0094 void sendVolume(String name, int volume) { 0095 NetworkPacket np = new NetworkPacket(PACKET_TYPE_SYSTEMVOLUME_REQUEST); 0096 np.set("volume", volume); 0097 np.set("name", name); 0098 device.sendPacket(np); 0099 } 0100 0101 void sendMute(String name, boolean mute) { 0102 NetworkPacket np = new NetworkPacket(PACKET_TYPE_SYSTEMVOLUME_REQUEST); 0103 np.set("muted", mute); 0104 np.set("name", name); 0105 device.sendPacket(np); 0106 } 0107 0108 void sendEnable(String name) { 0109 NetworkPacket np = new NetworkPacket(PACKET_TYPE_SYSTEMVOLUME_REQUEST); 0110 np.set("enabled", true); 0111 np.set("name", name); 0112 device.sendPacket(np); 0113 } 0114 0115 void requestSinkList() { 0116 NetworkPacket np = new NetworkPacket(PACKET_TYPE_SYSTEMVOLUME_REQUEST); 0117 np.set("requestSinks", true); 0118 device.sendPacket(np); 0119 } 0120 0121 @Override 0122 public @NonNull String[] getSupportedPacketTypes() { 0123 return new String[]{PACKET_TYPE_SYSTEMVOLUME}; 0124 } 0125 0126 @Override 0127 public @NonNull String[] getOutgoingPacketTypes() { 0128 return new String[]{PACKET_TYPE_SYSTEMVOLUME_REQUEST}; 0129 } 0130 0131 Collection<Sink> getSinks() { 0132 return sinks.values(); 0133 } 0134 0135 void addSinkListener(SinkListener listener) { 0136 synchronized(listeners) { 0137 listeners.add(listener); 0138 } 0139 } 0140 0141 void removeSinkListener(SinkListener listener) { 0142 synchronized(listeners) { 0143 listeners.remove(listener); 0144 } 0145 } 0146 0147 }