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 }