package tv.piratemedia.lightcontroler.api; import android.app.NotificationManager; import android.app.PendingIntent; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.graphics.Bitmap; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; import android.net.Uri; import android.os.AsyncTask; import android.os.StrictMode; import android.preference.PreferenceManager; import android.support.v4.app.NotificationCompat; import android.util.Log; import java.util.ArrayList; import java.util.HashSet; import java.util.Iterator; import java.util.Set; import tv.piratemedia.lightcontroler.R; import tv.piratemedia.lightcontroler.controlCommands; public class APIReciever extends BroadcastReceiver { public static final String REQUEST_API_PERMISSION = "tv.piratemedia.lightcontroler.requestAPIPermission"; public static final String LIGHT_ON_INTENT = "tv.piratemedia.lightcontroler.LightOn"; public static final String LIGHT_OFF_INTENT = "tv.piratemedia.lightcontroler.LightOff"; public static final String LIGHT_COLOR_INTENT = "tv.piratemedia.lightcontroler.LightColor"; public static final String LIGHT_SET_DEFAULT_INTENT = "tv.piratemedia.lightcontroler.LightDefault"; public static final String LIGHT_FADE_IN_INTENT = "tv.piratemedia.lightcontroler.LightFadeIn"; public static final String LIGHT_FADE_OUT_INTENT = "tv.piratemedia.lightcontroler.LightFadeOut"; public static final String LIGHT_FADE_CANCEL_INTENT = "tv.piratemedia.lightcontroller.LightFadeCancel"; private static final String ACCEPT_APP_INTENT = "tv.piratemedia.lightcontroler.internal.AcceptApp"; private static final String DENY_APP_INTENT = "tv.piratemedia.lightcontroler.internal.DenyApp"; public static final String TYPE_WHITE = "white"; public static final String TYPE_COLOR = "color"; public static final String TYPE_SUPER = "super"; private int mId = 0; private ArrayList<AsyncTask<String,String,String>> tasks = new ArrayList<AsyncTask<String,String,String>>(); @Override public void onReceive(Context context, Intent intent) { StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build(); StrictMode.setThreadPolicy(policy); SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context.getApplicationContext()); Set<String> enabled = prefs.getStringSet("enabled_api_apps", new HashSet<String>()); if(intent.getAction().equals(Intent.ACTION_PACKAGE_REMOVED)) { String packageName = intent.getData().getEncodedSchemeSpecificPart(); Log.d("package", "Package Removed:"+packageName); if(enabled.contains(packageName)) { enabled.remove(packageName); prefs.edit().putStringSet("enabled_api_apps", enabled).apply(); Log.d("package", "API Permission removed"); } return; } if(intent.getAction().equals(ACCEPT_APP_INTENT) || intent.getAction().equals(DENY_APP_INTENT)) { Iterator<String> it = intent.getExtras().keySet().iterator(); while(it.hasNext()) { Log.d("Intent", "key: "+it.next()); } parseIntentRequest(context, intent); } else if(intent.hasExtra("app_id")) { String appId = intent.getStringExtra("app_id"); if(!enabled.contains(appId)) { //show popup mId = makeIdFromPackage(appId); onRequestAPIPermisson(context, appId, intent); } else { parseIntentRequest(context, intent); } } else { Log.e("Light Controller API","No app id received"); } } private void parseIntentRequest(Context context, Intent intent) { controlCommands c = new controlCommands(context, null); NotificationManager manager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); int zone = -1; switch (intent.getAction()) { case ACCEPT_APP_INTENT: SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context.getApplicationContext()); Set<String> enabled = prefs.getStringSet("enabled_api_apps", new HashSet<String>()); String appId = intent.getStringExtra("app_id"); enabled.add(appId); prefs.edit().putStringSet("enabled_api_apps", enabled).commit(); manager.cancel(intent.getIntExtra("notifID", -1)); if(!intent.getStringExtra("initialAction").equals(REQUEST_API_PERMISSION)) { intent.setAction(intent.getStringExtra("initialAction")); parseIntentRequest(context, intent); } context.getContentResolver().notifyChange(Uri.parse("content://tv.piratemedia.lightcontroler.api/permission"), null); break; case DENY_APP_INTENT: Log.d("intent", "remove notification: "+intent.getIntExtra("notifID", -1)); manager.cancel(intent.getIntExtra("notifID", -1)); break; case LIGHT_ON_INTENT: zone = intent.getIntExtra("zone", -1); if (intent.getStringExtra("type").equals(TYPE_COLOR)) { Log.d("Lights on ", "Zone: "+intent.getIntExtra("zone", -1)); cancelCurrentTasks(); c.LightsOn(ControlProviders.ZONE_TYPE_COLOR, zone); } else if (intent.getStringExtra("type").equals(TYPE_WHITE)) { cancelCurrentTasks(); c.LightsOn(ControlProviders.ZONE_TYPE_WHITE, zone); } else if (intent.getStringExtra("type").equals(TYPE_SUPER)) { c.globalOn(); } break; case LIGHT_OFF_INTENT: zone = intent.getIntExtra("zone", -1); if (intent.getStringExtra("type").equals(TYPE_COLOR)) { cancelCurrentTasks(); c.LightsOff(ControlProviders.ZONE_TYPE_COLOR, zone); } else if (intent.getStringExtra("type").equals(TYPE_WHITE)) { cancelCurrentTasks(); c.LightsOff(ControlProviders.ZONE_TYPE_WHITE, zone); } else if (intent.getStringExtra("type").equals(TYPE_SUPER)) { c.globalOff(); } break; case LIGHT_COLOR_INTENT: if (intent.getStringExtra("type").equals(TYPE_COLOR)) { int color = intent.getIntExtra("color", -1); if (color != -1) { zone = intent.getIntExtra("zone", -1); if (intent.getStringExtra("type").equals(TYPE_COLOR)) { cancelCurrentTasks(); c.setColor(ControlProviders.ZONE_TYPE_COLOR, zone, color); } } } break; case LIGHT_SET_DEFAULT_INTENT: zone = intent.getIntExtra("zone", -1); if (intent.getStringExtra("type").equals(TYPE_COLOR)) { cancelCurrentTasks(); c.setToWhite(ControlProviders.ZONE_TYPE_COLOR, zone); } else { cancelCurrentTasks(); c.setToFull(ControlProviders.ZONE_TYPE_WHITE, zone); } break; case LIGHT_FADE_IN_INTENT: if(intent.getIntExtra("zone", -1) < 0 || intent.getIntExtra("zone", -1) > 9) { break; } zone = intent.getIntExtra("zone", -1); if(intent.getStringExtra("type").equals(TYPE_COLOR)) { int duration = intent.getIntExtra("duration", -1); if(duration <= 900 && duration > -1) { c.setToWhite(ControlProviders.ZONE_TYPE_COLOR, zone); c.setBrightness(ControlProviders.ZONE_TYPE_COLOR, zone, 0); } FadeLights(zone, TYPE_COLOR, true, duration, context); } else { int duration = intent.getIntExtra("duration", -1); if(duration <= 900 && duration > 30) { for(int i = 0; i < 10; i++) { c.setBrightnessDownOne(ControlProviders.ZONE_TYPE_WHITE, zone); try { Thread.sleep(50); } catch (InterruptedException e) { e.printStackTrace(); } } FadeLights(zone, TYPE_WHITE, true, duration, context); } } break; case LIGHT_FADE_OUT_INTENT: zone = intent.getIntExtra("zone", -1); if(intent.getIntExtra("zone", -1) < 0 || intent.getIntExtra("zone", -1) > 9) { break; } if(intent.getStringExtra("type").equals(TYPE_COLOR)) { int duration = intent.getIntExtra("duration", -1); if(duration <= 900 && duration > -1) { c.setToWhite(ControlProviders.ZONE_TYPE_COLOR, zone); c.setBrightness(ControlProviders.ZONE_TYPE_COLOR, zone, 19); } FadeLights(zone, TYPE_COLOR, true, duration, context); } else { int duration = intent.getIntExtra("duration", -1); if(duration <= 900 && duration > 30) { c.setToFull(ControlProviders.ZONE_TYPE_WHITE, zone); FadeLights(zone, TYPE_WHITE, true, duration, context); } } break; case LIGHT_FADE_CANCEL_INTENT: cancelCurrentTasks(); break; } } @SuppressWarnings("InstanceVariableMayNotBeInitialized") private void FadeLights(final int Zone, final String Type, final Boolean in, int duration, Context context) { final controlCommands c = new controlCommands(context, null); final int interval; final int Max; if(Type.equals(TYPE_COLOR)) { interval = Math.round(duration / 20); Max = 20; } else { interval = Math.round(duration / 10); Max = 10; } final AsyncTask<String, String, String> runFade = new AsyncTask<String, String, String>() { @Override protected String doInBackground(String... strings) { int step = 0; while(Max > step) { try { Thread.sleep(interval * 1000); } catch (InterruptedException e) { e.printStackTrace(); } if (Type.equals(TYPE_COLOR)) { if(in) { c.setBrightness(ControlProviders.ZONE_TYPE_COLOR, Zone, step); } else { int i = 19 - step; c.setBrightness(ControlProviders.ZONE_TYPE_COLOR, Zone, i); } } else { if(in) { c.setBrightnessUpOne(ControlProviders.ZONE_TYPE_WHITE, Zone); } else { c.setBrightnessDownOne(ControlProviders.ZONE_TYPE_WHITE, Zone); } } step++; } return null; } @Override protected void onPostExecute(String s) { super.onPostExecute(s); } }; runFade.execute(); tasks.add(runFade); } private void cancelCurrentTasks() { for(int i = 0; i < tasks.size(); i++) { AsyncTask<String, String, String> ast = tasks.get(i); ast.cancel(true); tasks.remove(i); } } private void onRequestAPIPermisson(Context context, String appID, Intent in) { final PackageManager pm = context.getPackageManager(); ApplicationInfo ai; try { ai = pm.getApplicationInfo( appID, 0); } catch (final PackageManager.NameNotFoundException e) { ai = null; } if(ai != null) { final String applicationName = (String) pm.getApplicationLabel(ai); NotificationCompat.BigTextStyle notiStyle = new NotificationCompat.BigTextStyle(); notiStyle.setBigContentTitle("Light Control Permission"); notiStyle.bigText("'"+applicationName+"' is requesting permission to control your lights"); long[] pattern = {0, 100, 100}; Drawable d = pm.getApplicationIcon(ai); Bitmap bitmapIcon = ((BitmapDrawable)d).getBitmap(); NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(context) .setLargeIcon(bitmapIcon) .setSmallIcon(R.drawable.bulb) .setColor(context.getResources().getColor(R.color.colorAccent)) .setContentTitle("Light Control Permission") .setContentText("'"+applicationName+"' is requesting permission to control your lights") .addAction(R.drawable.ic_done_24dp, "Accept", AcceptControlRequest(context, in)) .addAction(R.drawable.ic_clear_24dp, "Decline", DeclineControlRequest(context)) .setPriority(NotificationCompat.PRIORITY_HIGH) .setVibrate(pattern) .setStyle(notiStyle); NotificationManager mNotificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); // mId allows you to update the notification later on. mNotificationManager.notify(mId, mBuilder.build()); } } public PendingIntent AcceptControlRequest(Context cont, Intent in) { Intent launchIntent = new Intent(); launchIntent.setClass(cont, APIReciever.class); launchIntent.setAction(ACCEPT_APP_INTENT); launchIntent.putExtras(in.getExtras()); launchIntent.putExtra("notifID", mId); launchIntent.putExtra("initialAction", in.getAction()); PendingIntent pi = PendingIntent.getBroadcast(cont, 0 /* no requestCode */, launchIntent, 0 /* no flags */); return pi; } public PendingIntent DeclineControlRequest(Context cont) { Intent launchIntent = new Intent(); launchIntent.setClass(cont, APIReciever.class); launchIntent.setAction(DENY_APP_INTENT); launchIntent.putExtra("notifID", mId); PendingIntent pi = PendingIntent.getBroadcast(cont, 0 /* no requestCode */, launchIntent, 0 /* no flags */); return pi; } private int makeIdFromPackage(String pid) { String[] pack = pid.split("\\."); int ID = 0; for(int i = 0; i < pack.length; i++) { ID += Character.getNumericValue(pack[i].charAt(0)); ID += Character.getNumericValue(pack[i].charAt(1)); } return ID; } }