de.badaix.snapcast.control.RemoteControl.java Source code

Java tutorial

Introduction

Here is the source code for de.badaix.snapcast.control.RemoteControl.java

Source

/*
 *     This file is part of snapcast
 *     Copyright (C) 2014-2016  Johannes Pohl
 *
 *     This program is free software: you can redistribute it and/or modify
 *     it under the terms of the GNU General Public License as published by
 *     the Free Software Foundation, either version 3 of the License, or
 *     (at your option) any later version.
 *
 *     This program is distributed in the hope that it will be useful,
 *     but WITHOUT ANY WARRANTY; without even the implied warranty of
 *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *     GNU General Public License for more details.
 *
 *     You should have received a copy of the GNU General Public License
 *     along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package de.badaix.snapcast.control;

import android.text.TextUtils;
import android.util.Log;

import org.json.JSONException;
import org.json.JSONObject;

import java.util.HashMap;

import de.badaix.snapcast.control.json.Client;
import de.badaix.snapcast.control.json.ServerStatus;
import de.badaix.snapcast.control.json.Stream;

/**
 * Created by johannes on 13.01.16.
 */
public class RemoteControl implements TcpClient.TcpClientListener {

    private static final String TAG = "RC";

    private TcpClient tcpClient;
    private long msgId;
    private RemoteControlListener listener;
    private ServerStatus serverStatus;
    private String host;
    private int port;
    private HashMap<Long, String> pendingRequests;

    public RemoteControl(RemoteControlListener listener) {
        this.listener = listener;
        serverStatus = new ServerStatus();
        msgId = 0;
        pendingRequests = new HashMap<>();
    }

    public String getHost() {
        return host;
    }

    public int getPort() {
        return port;
    }

    public synchronized void connect(final String host, final int port) {
        if ((tcpClient != null) && tcpClient.isConnected()) {
            if (this.host.equals(host) && (this.port == port))
                return;
            else
                disconnect();
        }
        this.host = host;
        this.port = port;

        tcpClient = new TcpClient(this);
        tcpClient.start(host, port);
    }

    public void disconnect() {
        if ((tcpClient != null) && (tcpClient.isConnected()))
            tcpClient.stop();
        tcpClient = null;
        pendingRequests.clear();
    }

    public boolean isConnected() {
        return ((tcpClient != null) && tcpClient.isConnected());
    }

    @Override
    public void onMessageReceived(TcpClient tcpClient, String message) {
        //        Log.d(TAG, "Msg received: " + message);
        try {
            JSONObject json = new JSONObject(message);
            if (json.has("id")) {
                //                Log.d(TAG, "ID: " + json.getString("id"));
                long id = json.getLong("id");
                String request = "";
                synchronized (pendingRequests) {
                    if (pendingRequests.containsKey(id)) {
                        request = pendingRequests.get(id);
                        //                        Log.d(TAG, "Response to: " + request);
                        pendingRequests.remove(id);
                    }
                }
                if (json.has("error")) {
                    JSONObject error = json.getJSONObject("error");
                    Log.e(TAG, "error " + error.getInt("code") + ": " + error.getString("message"));
                } else if (!TextUtils.isEmpty(request)) {
                    if (request.equals("Server.GetStatus")) {
                        serverStatus.fromJson(json.getJSONObject("result"));
                        if (listener != null)
                            listener.onServerStatus(this, serverStatus);
                    }
                }
            } else {
                String method = json.getString("method");
                //                Log.d(TAG, "Notification: " + method);
                if (method.contains("Client.On")) {
                    final Client client = new Client(json.getJSONObject("params").getJSONObject("data"));
                    //                    serverStatus.addClient(client);
                    if (listener != null) {
                        ClientEvent event;
                        if (method.equals("Client.OnUpdate"))
                            listener.onClientEvent(this, client, ClientEvent.updated);
                        else if (method.equals("Client.OnConnect"))
                            listener.onClientEvent(this, client, ClientEvent.connected);
                        else if (method.equals("Client.OnDisconnect"))
                            listener.onClientEvent(this, client, ClientEvent.disconnected);
                        else if (method.equals("Client.OnDelete")) {
                            listener.onClientEvent(this, client, ClientEvent.deleted);
                        }
                    }
                } else if (method.equals("Stream.OnUpdate")) {
                    Stream stream = new Stream(json.getJSONObject("params").getJSONObject("data"));
                    listener.onStreamUpdate(this, stream);
                    Log.d(TAG, stream.toString());
                }
            }

        } catch (JSONException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void onConnecting(TcpClient tcpClient) {
        Log.d(TAG, "onConnecting");
        if (listener != null)
            listener.onConnecting(this);
    }

    @Override
    public void onConnected(TcpClient tcpClient) {
        Log.d(TAG, "onConnected");
        serverStatus = new ServerStatus();
        if (listener != null)
            listener.onConnected(this);
    }

    @Override
    public void onDisconnected(TcpClient tcpClient, Exception e) {
        Log.d(TAG, "onDisconnected");
        serverStatus = null;
        if (listener != null)
            listener.onDisconnected(this, e);
    }

    private JSONObject jsonRequest(String method, JSONObject params) {
        JSONObject request = new JSONObject();
        try {
            request.put("jsonrpc", "2.0");
            request.put("method", method);
            request.put("id", msgId);
            if (params != null)
                request.put("params", params);
            synchronized (pendingRequests) {
                pendingRequests.put(msgId, method);
            }
            msgId++;
        } catch (JSONException e) {
            e.printStackTrace();
        }
        return request;
    }

    public void getServerStatus() {
        JSONObject request = jsonRequest("Server.GetStatus", null);
        tcpClient.sendMessage(request.toString());
    }

    public void setName(Client client, String name) {
        try {
            JSONObject request = jsonRequest("Client.SetName",
                    new JSONObject("{\"client\": \"" + client.getMac() + "\", \"name\": \"" + name + "\"}"));
            tcpClient.sendMessage(request.toString());
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }

    public void setLatency(Client client, int latency) {
        try {
            JSONObject request = jsonRequest("Client.SetLatency",
                    new JSONObject("{\"client\": \"" + client.getMac() + "\", \"latency\": " + latency + "}"));
            tcpClient.sendMessage(request.toString());
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }

    public void setStream(Client client, String id) {
        try {
            JSONObject request = jsonRequest("Client.SetStream",
                    new JSONObject("{\"client\": \"" + client.getMac() + "\", \"id\": \"" + id + "\"}"));
            tcpClient.sendMessage(request.toString());
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }

    public void setVolume(Client client, int percent) {
        try {
            JSONObject request = jsonRequest("Client.SetVolume",
                    new JSONObject("{\"client\": \"" + client.getMac() + "\", \"volume\": " + percent + "}"));
            tcpClient.sendMessage(request.toString());
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }

    public void setMute(Client client, boolean mute) {
        try {
            JSONObject request = jsonRequest("Client.SetMute",
                    new JSONObject("{\"client\": \"" + client.getMac() + "\", \"mute\": " + mute + "}"));
            tcpClient.sendMessage(request.toString());
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }

    public void delete(Client client) {
        try {
            JSONObject request = jsonRequest("Server.DeleteClient",
                    new JSONObject("{\"client\": \"" + client.getMac() + "\"}"));
            tcpClient.sendMessage(request.toString());
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }

    public enum ClientEvent {
        connected, disconnected, updated, deleted
    }

    public interface RemoteControlListener {
        void onConnected(RemoteControl remoteControl);

        void onConnecting(RemoteControl remoteControl);

        void onDisconnected(RemoteControl remoteControl, Exception e);

        void onClientEvent(RemoteControl remoteControl, Client client, ClientEvent event);

        void onServerStatus(RemoteControl remoteControl, ServerStatus serverStatus);

        void onStreamUpdate(RemoteControl remoteControl, Stream stream);
    }
}