/* * LEDD Project * Copyright (C) 2015 LEDD Team * * 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 . */ package com.idlegandalf.ledd.fragments; import android.app.Dialog; import android.app.DialogFragment; import android.content.Context; import android.content.DialogInterface; import android.net.nsd.NsdManager; import android.net.nsd.NsdServiceInfo; import android.os.Bundle; import android.support.design.widget.Snackbar; import android.support.design.widget.TextInputLayout; import android.support.v7.app.AlertDialog; import android.text.Editable; import android.text.TextWatcher; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.EditText; import android.widget.LinearLayout; import android.widget.TextView; import com.google.common.net.InetAddresses; import com.idlegandalf.ledd.ColorActivity; import com.idlegandalf.ledd.ColorApplication; import com.idlegandalf.ledd.R; import com.idlegandalf.ledd.callbacks.DiscoverCallback; import com.idlegandalf.ledd.components.LedDDaemon; import java.net.Inet4Address; import java.util.ArrayList; import java.util.List; import butterknife.Bind; import butterknife.ButterKnife; public class AddDaemonDialog extends DialogFragment implements DialogInterface.OnShowListener, NsdManager.DiscoveryListener { private final String SERVICE_TYPE = "_ledd._tcp."; @Bind(R.id.input_ip) EditText ip; @Bind(R.id.input_ip_layout) TextInputLayout ip_lay; @Bind(R.id.host_container) LinearLayout hostContainer; List ledDDaemons = new ArrayList<>(); NsdManager mNsdManager; private boolean mListening = false; public Dialog onCreateDialog(Bundle savedInstanceState) { View v = View.inflate(getActivity(), R.layout.fragment_adddaemon, null); ButterKnife.bind(this, v); mNsdManager = (NsdManager) getActivity().getApplicationContext().getSystemService(Context.NSD_SERVICE); AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); builder.setView(v).setPositiveButton("Add", null).setNegativeButton("Cancel", null); AlertDialog dialog = builder.create(); dialog.setOnShowListener(this); return dialog; } @Override public void onShow(final DialogInterface dialog) { // start host discovery if (!mListening) { mNsdManager.discoverServices(SERVICE_TYPE, NsdManager.PROTOCOL_DNS_SD, this); mListening = true; } final AlertDialog alertDialog = (AlertDialog) dialog; ip.addTextChangedListener(new TextWatcher() { @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { } @Override public void onTextChanged(CharSequence s, int start, int before, int count) { } @Override public void afterTextChanged(Editable s) { ip_lay.setError(null); } }); alertDialog.getButton(AlertDialog.BUTTON_NEGATIVE).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { mNsdManager.stopServiceDiscovery(AddDaemonDialog.this); AddStripeDialog.instance.onResume(); alertDialog.dismiss(); } }); alertDialog.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { String strIp = ip.getText().toString(); int port; if (strIp.contains(":")) { strIp = strIp.split(":")[0]; try { port = Integer.parseInt(ip.getText().toString().split(":")[1]); } catch (NumberFormatException e) { ip_lay.setError("Please check your port"); return; } if (port < 1024 || port > 65535) { ip_lay.setError("Port is out of range"); return; } } else { port = 1425; } if (InetAddresses.isInetAddress(strIp)) { LedDDaemon daemon = new LedDDaemon(strIp, port); if (!ledDDaemons.contains(daemon)) addDaemon(new LedDDaemon(strIp, port)); else ip_lay.setError("Daemon already exist"); } else { ip_lay.setError("No valid ip address"); } } }); } @Override public void onStartDiscoveryFailed(String serviceType, int errorCode) { Log.e(ColorApplication.TAG, "Discovery failed: Error code:" + errorCode); mNsdManager.stopServiceDiscovery(this); } @Override public void onStopDiscoveryFailed(String serviceType, int errorCode) { Log.e(ColorApplication.TAG, "Discovery failed: Error code:" + errorCode); mNsdManager.stopServiceDiscovery(this); mListening = false; } @Override public void onDiscoveryStarted(String serviceType) { Log.d(ColorApplication.TAG, "Service discovery started"); mListening = true; } @Override public void onDiscoveryStopped(String serviceType) { Log.i(ColorApplication.TAG, "Discovery stopped: " + serviceType); mListening = false; } @Override public void onServiceFound(NsdServiceInfo serviceInfo) { Log.d(ColorApplication.TAG, "Service discovery success: " + serviceInfo); if (serviceInfo.getServiceType().equals(SERVICE_TYPE)) { mNsdManager.resolveService(serviceInfo, new NsdManager.ResolveListener() { @Override public void onResolveFailed(NsdServiceInfo serviceInfo, int errorCode) { Log.e(ColorApplication.TAG, "Resolve failed: " + errorCode); } @Override public void onServiceResolved(final NsdServiceInfo serviceInfo) { Log.e(ColorApplication.TAG, "Resolve Succeeded. " + serviceInfo); if (serviceInfo.getHost() instanceof Inet4Address) { final LedDDaemon nLedDDaemon = new LedDDaemon(serviceInfo.getHost().getHostAddress(), serviceInfo.getPort()); if (!ledDDaemons.contains(nLedDDaemon)) { getActivity().runOnUiThread(new Runnable() { @Override public void run() { View v = ((LayoutInflater) getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(R.layout .host_row, hostContainer, false); TextView host = (TextView) v.findViewById(R.id.text_host); host.setText(nLedDDaemon.toString()); if (ColorApplication.getInstance().getDaemons().contains(nLedDDaemon)) { v.setEnabled(false); host.setEnabled(false); } View.OnClickListener listener = new View.OnClickListener() { @Override public void onClick(View v) { if (v.isEnabled()) { LedDDaemon d; if (v instanceof TextView) { d = (LedDDaemon) ((LinearLayout) v.getParent()).getTag(); } else { d = (LedDDaemon) v.getTag(); } if (d != null) { addDaemon(d); } } } }; v.setOnClickListener(listener); host.setOnClickListener(listener); v.setTag(nLedDDaemon); ledDDaemons.add(nLedDDaemon); hostContainer.addView(v); } }); } } } }); } else { Log.d(ColorApplication.TAG, "Unknown Service Type: " + serviceInfo.getServiceType()); } } @Override public void onServiceLost(NsdServiceInfo serviceInfo) { Log.e(ColorApplication.TAG, "service lost" + serviceInfo); } @Override public void onDestroy() { super.onDestroy(); if (mNsdManager != null && mListening) { mNsdManager.stopServiceDiscovery(this); mListening = false; } } @Override public void onPause() { super.onPause(); if (mNsdManager != null && mListening) { mNsdManager.stopServiceDiscovery(this); mListening = false; } } @Override public void onResume() { super.onResume(); if (mNsdManager != null && !mListening) { mNsdManager.discoverServices(SERVICE_TYPE, NsdManager.PROTOCOL_DNS_SD, this); mListening = true; } } private void addDaemon(final LedDDaemon ledDDaemon) { ColorApplication.getInstance().getHelperForDaemon(ledDDaemon).discover(new DiscoverCallback() { @Override public void onConnectionFailed(final String message) { getActivity().runOnUiThread(new Runnable() { @Override public void run() { Snackbar.make(((ViewGroup) getActivity().getWindow().getDecorView().findViewById(android.R.id.content)).getChildAt(0), "Coudn't connect to" + " daemon at " + ledDDaemon + ": " + message, Snackbar.LENGTH_LONG).show(); } }); AddStripeDialog.instance.onResume(); dismiss(); } @Override public void onDiscoverSuccessfully(final String version) { getActivity().runOnUiThread(new Runnable() { @Override public void run() { Snackbar.make(((ViewGroup) getActivity().getWindow().getDecorView().findViewById(android.R.id.content)).getChildAt(0), "Added LedD Daemon version: " + version, Snackbar.LENGTH_LONG).show(); } }); ((ColorActivity) getActivity()).refreshStripes(); AddStripeDialog.instance.onResume(); dismiss(); } }); } }