package us.nineworlds.serenity; import android.app.Service; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import com.atomjack.shared.Logger; import com.atomjack.vcfp.activities.MainActivity; import com.atomjack.vcfp.model.Connection; import com.atomjack.vcfp.model.PlexClient; import com.atomjack.vcfp.model.PlexServer; import com.atomjack.vcfp.services.GDMService; import com.atomjack.vcfp.services.PlexScannerService; import java.util.ArrayList; import java.util.HashMap; import java.util.regex.Matcher; import java.util.regex.Pattern; public class GDMReceiver extends BroadcastReceiver { private boolean cancel = false; public static final String ACTION_CANCEL = ".GDMReceiver.ACTION_CANCEL"; private ArrayList<PlexClient> clients = new ArrayList<PlexClient>(); private ArrayList<PlexServer> servers = new ArrayList<>(); @Override public void onReceive(Context context, Intent intent) { Logger.d("GDMReceiver onReceive: %s", intent.getAction()); if (intent.getAction().equals(GDMService.MSG_RECEIVED)) { String message = intent.getStringExtra("data").trim(); String ipAddress = intent.getStringExtra("ipaddress").substring(1); Logger.d("[GDMReceiver] message: %s", message); HashMap<String, String> responseMap = processResponse(message); if(responseMap.get("resource-identifier") != null) { if(responseMap.get("content-type").equals("plex/media-server")) { PlexServer server = new PlexServer(); server.port = responseMap.get("port"); server.name = responseMap.get("name"); server.address = ipAddress; server.machineIdentifier = responseMap.get("resource-identifier"); server.version = responseMap.get("version"); server.local = true; Connection connection = new Connection("http", server.address, server.port); server.connections = new ArrayList<>(); server.connections.add(connection); servers.add(server); } else if(responseMap.get("content-type").equals("plex/media-player") && responseMap.get("protocol") != null && responseMap.get("protocol").equals("plex") && !responseMap.get("product").equals("Plex Web")) { PlexClient client = new PlexClient(); client.port = responseMap.get("port"); client.name = responseMap.get("name"); client.address = ipAddress; client.machineIdentifier = responseMap.get("resource-identifier"); client.version = responseMap.get("version"); client.product = responseMap.get("product"); clients.add(client); } } } else if (intent.getAction().equals(GDMService.SOCKET_CLOSED)) { Logger.i("Finished Searching"); if(cancel) { cancel = false; Logger.d("[GDMReceiver] canceling"); return; } String scanType = intent.getStringExtra(com.atomjack.shared.Intent.SCAN_TYPE); // Send the reply back to whichever class called for it. Class theClass = (Class) intent.getSerializableExtra(com.atomjack.shared.Intent.EXTRA_CLASS); Intent i = new Intent(context, theClass); Logger.d("Scantype: %s, class: %s", scanType, theClass); i.setAction(scanType.equals(com.atomjack.shared.Intent.SCAN_TYPE_SERVER) ? PlexScannerService.ACTION_SERVER_SCAN_FINISHED : PlexScannerService.ACTION_CLIENT_SCAN_FINISHED); i.putExtra(com.atomjack.shared.Intent.SHOWRESOURCE, intent.getBooleanExtra(com.atomjack.shared.Intent.SHOWRESOURCE, false)); if (clients.size() > 0 && scanType.equals(com.atomjack.shared.Intent.SCAN_TYPE_CLIENT)) i.putParcelableArrayListExtra(com.atomjack.shared.Intent.EXTRA_CLIENTS, clients); if(scanType.equals(com.atomjack.shared.Intent.SCAN_TYPE_SERVER)) i.putParcelableArrayListExtra(com.atomjack.shared.Intent.EXTRA_SERVERS, servers); i.putExtra(com.atomjack.shared.Intent.SCAN_TYPE, intent.getStringExtra(com.atomjack.shared.Intent.SCAN_TYPE)); i.putExtra(com.atomjack.shared.Intent.EXTRA_CONNECT_TO_CLIENT, intent.getBooleanExtra(com.atomjack.shared.Intent.EXTRA_CONNECT_TO_CLIENT, false)); i.putExtra(com.atomjack.shared.Intent.EXTRA_CLASS, theClass); i.putExtra(com.atomjack.shared.Intent.EXTRA_SILENT, intent.getBooleanExtra(com.atomjack.shared.Intent.EXTRA_SILENT, false)); i.addFlags(Intent.FLAG_FROM_BACKGROUND); i.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP); i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); if (theClass.getSuperclass() == Service.class) { context.startService(i); } else if (theClass == MainActivity.class) { Logger.d("Sending to activity"); context.startActivity(i); } // Clear the list of servers & clients so the next scan sends a reinitialized list. clients = new ArrayList<>(); servers = new ArrayList<>(); } else if(intent.getAction().equals(ACTION_CANCEL)) { Logger.d("[GDMReceiver] cancel"); cancel = true; clients = new ArrayList<>(); servers = new ArrayList<>(); } } private HashMap<String, String> processResponse(String response) { HashMap<String, String> responseMap = new HashMap<String, String>(); String[] lines = response.split("[\n\r]"); Pattern p = Pattern.compile("([^:]+): ([^\r^\n]+)"); Matcher matcher; for(String line : lines) { matcher = p.matcher(line); if(matcher.find()) { Logger.d("%s: %s", matcher.group(1).toLowerCase(), matcher.group(2)); if(!responseMap.containsKey(matcher.group(1).toLowerCase())) responseMap.put(matcher.group(1).toLowerCase(), matcher.group(2)); } } return responseMap; } }