/* * Protocoder * A prototyping platform for Android devices * * Victor Diaz Barrales victormdb@gmail.com * * Copyright (C) 2014 Victor Diaz * Copyright (C) 2013 Motorola Mobility LLC * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the Software * is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * */ package org.protocoderrunner.apprunner.api; import android.annotation.TargetApi; import android.app.NotificationManager; import android.app.PendingIntent; import android.app.TaskStackBuilder; import android.content.ContentValues; import android.content.Context; import android.content.Intent; import android.net.Uri; import android.os.Build; import android.provider.MediaStore; import android.provider.MediaStore.MediaColumns; import android.support.v4.app.NotificationCompat; import org.mozilla.javascript.NativeObject; import org.protocoderrunner.R; import org.protocoderrunner.apidoc.annotation.APIMethod; import org.protocoderrunner.apidoc.annotation.APIParam; import org.protocoderrunner.apprunner.AppRunnerActivity; import org.protocoderrunner.apprunner.PInterface; import org.protocoderrunner.apprunner.ProtocoderScript; import org.protocoderrunner.apprunner.api.other.PEvents; import org.protocoderrunner.apprunner.api.other.PLiveCodingFeedback; import org.protocoderrunner.project.Project; import org.protocoderrunner.project.ProjectManager; import org.protocoderrunner.project.SchedulerManager; import org.protocoderrunner.utils.ExecuteCmd; import org.protocoderrunner.utils.FileIO; public class PApp extends PInterface { public interface onAppStatus { public void onStart(); public void onPause(); public void onResume(); public void onStop(); } PEvents pevents; public PApp(Context a) { super(a); pevents = new PEvents(a); } @ProtocoderScript @APIMethod(description = "get the script runner context", example = "") public AppRunnerActivity getContext() { return (AppRunnerActivity) a.get(); } //TODO @ProtocoderScript @APIMethod(description = "", example = "") public void setDelayedAlarm(int delay, boolean alarmRepeat, boolean wakeUpScreen) { Project p = ProjectManager.getInstance().getCurrentProject(); SchedulerManager.getInstance(a.get()).setAlarmDelayed(p, delay, alarmRepeat, wakeUpScreen); } //TODO @ProtocoderScript @APIMethod(description = "", example = "") public void setDelayedAlarm(int hour, int minute, int second, boolean wakeUpScreen) { Project p = ProjectManager.getInstance().getCurrentProject(); SchedulerManager.getInstance(a.get()).setAlarm(p, hour, minute, second, wakeUpScreen); } //TODO @ProtocoderScript @APIMethod(description = "", example = "") public void setExactAlarm(int hour, int minute, int second, boolean wakeUpScreen) { Project p = ProjectManager.getInstance().getCurrentProject(); SchedulerManager.getInstance(a.get()).setAlarm(p, hour, minute, second, wakeUpScreen); } @ProtocoderScript @APIMethod(description = "close the running script", example = "") public void close() { ((AppRunnerActivity) a.get()).finish(); } @android.webkit.JavascriptInterface @ProtocoderScript @APIMethod(description = "evaluate a script", example = "") @APIParam(params = { "code" }) public void eval(String code) { ((AppRunnerActivity) a.get()).interp.eval(code); } @ProtocoderScript @APIMethod(description = "loads and external file containing code", example = "") @APIParam(params = { "fileName" }) public void load(String filename) { String code = FileIO.loadFile(filename); ((AppRunnerActivity) a.get()).interp.eval(code); } @ProtocoderScript @APIMethod(description = "loads a library stored in the <i>libraries</i>' folder", example = "") @APIParam(params = { "libraryName" }) public void loadLibrary(String name) { String code = FileIO.loadFile("../../libraries/" + name + "/main.js"); ((AppRunnerActivity) a.get()).interp.eval(code); } //TODO way to cancel notification and come back to the script @TargetApi(Build.VERSION_CODES.JELLY_BEAN) @ProtocoderScript @APIMethod(description = "", example = "") @APIParam(params = { "id", "title", "description" }) public void setNotification(int id, String title, String description) { NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(a.get()) .setSmallIcon(R.drawable.app_icon).setContentTitle(title).setContentText(description); // Creates an explicit intent for an Activity in your app Intent resultIntent = new Intent(a.get(), AppRunnerActivity.class); // The stack builder object will contain an artificial back stack for // the started Activity. // This ensures that navigating backward from the Activity leads out of // your application to the Home screen. TaskStackBuilder stackBuilder = TaskStackBuilder.create(a.get()); // Adds the back stack for the Intent (but not the Intent itself) stackBuilder.addParentStack(AppRunnerActivity.class); // Adds the Intent that starts the Activity to the top of the stack stackBuilder.addNextIntent(resultIntent); PendingIntent resultPendingIntent = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT); mBuilder.setContentIntent(resultPendingIntent); NotificationManager mNotificationManager = (NotificationManager) a.get().getSystemService( a.get().NOTIFICATION_SERVICE); // mId allows you to update the notification later on. mNotificationManager.notify(id, mBuilder.build()); } // TOFIX not working yet // @ProtocoderScript // @APIMethod(description = "", example = "") // @APIParam(params = { "id" }) public void shareImage(String imagePath) { ContentValues values = new ContentValues(); values.put(MediaColumns.MIME_TYPE, "image/png"); //values.put(MediaColumns.DATA, AppRunnerSettings.get().project.getStoragePath() + "/" + imagePath); Uri uri = a.get().getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values); Intent shareIntent = new Intent(Intent.ACTION_SEND); shareIntent.setType("image/png"); shareIntent.putExtra(Intent.EXTRA_STREAM, uri); a.get().startActivity(shareIntent); } @ProtocoderScript @APIMethod(description = "launch the share intent with the included text", example = "") @APIParam(params = { "text" }) public void shareText(String text) { Intent shareIntent = new Intent(Intent.ACTION_SEND); shareIntent.setType("text/*"); shareIntent.putExtra(Intent.EXTRA_TEXT, text); a.get().startActivity(shareIntent); } @ProtocoderScript @APIMethod(description = "get the current project HTTP URL", example = "") public String getProjectUrl() { String url = ProjectManager.getInstance().getCurrentProject().getServingURL(); return url; } @ProtocoderScript @APIMethod(description = "get the current project path", example = "") public String getProjectPath() { String url = ProjectManager.getInstance().getCurrentProject().getStoragePath() + "/"; return url; } // --------- doNotExecute ---------// public interface DoNothingCB { void event(); } @ProtocoderScript @APIMethod(description = "this dummy function doesn't execute the callback", example = "") @APIParam(params = { "function()" }) public void doNotExecute(DoNothingCB callbackfn) { } @ProtocoderScript @APIMethod(description = "execute a shell command", example = "") @APIParam(params = { "cmd", "function(data)" }) public ExecuteCmd executeCommand(final String cmd, final ExecuteCmd.ExecuteCommandCB callbackfn) { return new ExecuteCmd(cmd, callbackfn); } @ProtocoderScript @APIMethod(description = "shows a feedback overlay with the live-executed code", example = "") @APIParam(params = { }) public PLiveCodingFeedback liveCodingFeedback() { appRunnerActivity.get().initLayout(); PLiveCodingFeedback l = appRunnerActivity.get().liveCoding; l.enable = true; return l; } @ProtocoderScript @APIMethod(description = "sends a name event with a json object", example = "") @APIParam(params = { "name", "jsonObject"}) public void sendEvent(String name, Object obj) { pevents.sendEvent(name, (NativeObject) obj); } @ProtocoderScript @APIMethod(description = "receives a named event with a json object", example = "") @APIParam(params = { "name", "function(name, jsonObject)"}) public String listenEvent(String name, PEvents.EventCB callback) { return pevents.add(name, callback); } @ProtocoderScript @APIMethod(description = "receives a named event with a json object", example = "") @APIParam(params = { "name", "function(name, jsonObject)"}) public void removeEvent(String id) { pevents.remove(id); } // // @ProtocoderScript // @APIMethod(description = "", example = "") // @APIParam(params = { "fileName" }) // public void openWithApp(final String src) { // final String projectPath = ProjectManager.getInstance().getCurrentProject().getStoragePath(); // // Intent intent = new Intent(Intent.ACTION_VIEW); // intent.setData(Uri.parse(projectPath + "/" + src)); // // a.get().startActivity(intent); // } @ProtocoderScript @APIMethod(description = "opens a file with a given app provided as package name ", example = "") @APIParam(params = { "fileName", "packageName" }) public void openWithApp(final String src, String packageName) { final String projectPath = ProjectManager.getInstance().getCurrentProject().getStoragePath(); Intent intent = new Intent(Intent.ACTION_VIEW); intent.setDataAndType(Uri.parse("file://" + projectPath + "/" + src), packageName); //intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); a.get().startActivity(intent); } }