/* * 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.protocoder; import android.annotation.SuppressLint; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.net.ConnectivityManager; import android.os.Bundle; import android.os.FileObserver; import android.support.v4.app.Fragment; import android.support.v7.app.ActionBar; import android.support.v7.widget.Toolbar; import android.view.KeyEvent; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; import android.view.ViewConfiguration; import android.view.ViewGroup; import android.widget.AdapterView.AdapterContextMenuInfo; import org.protocoder.appApi.Protocoder; import org.protocoder.fragments.SettingsFragment; import org.protocoderrunner.apprunner.AppRunnerInterpreter; import org.protocoderrunner.apprunner.api.PFileIO; import org.protocoderrunner.apprunner.api.PMedia; import org.protocoderrunner.apprunner.api.PNetwork; import org.protocoderrunner.apprunner.api.PUI; import org.protocoderrunner.apprunner.api.PUtil; import org.protocoderrunner.base.BaseActivity; import org.protocoderrunner.events.Events; import org.protocoderrunner.events.Events.ProjectEvent; import org.protocoderrunner.network.IDEcommunication; import org.protocoderrunner.project.Project; import org.protocoderrunner.project.ProjectManager; import org.protocoderrunner.utils.AndroidUtils; import org.protocoderrunner.utils.MLog; import java.lang.reflect.Field; import de.greenrobot.event.EventBus; @SuppressLint("NewApi") public class MainActivity extends BaseActivity { private static final String TAG = "MainActivity"; MainActivity c; Menu mMenu; private FileObserver observer; // connection BroadcastReceiver mStopServerReceiver; private ConnectivityChangeReceiver connectivityChangeReceiver; private Protocoder mProtocoder; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_forfragments); c = this; // Create the action bar programmatically if (!isWear()) { Toolbar toolbar = (Toolbar) findViewById(R.id.my_awesome_toolbar); setSupportActionBar(toolbar); //ActionBar actionBar = getSupportActionBar(); //actionBar.setHomeButtonEnabled(true); } mProtocoder = Protocoder.getInstance(this); mProtocoder.init(); /* * Views */ if (savedInstanceState == null) { addFragments(); } else { mProtocoder.protoScripts.reinitScriptList(); } // Check when a file is changed in the protocoder dir observer = new FileObserver(ProjectManager.FOLDER_USER_PROJECTS, FileObserver.CREATE | FileObserver.DELETE) { @Override public void onEvent(int event, String file) { if ((FileObserver.CREATE & event) != 0) { MLog.d(TAG, "File created [" + ProjectManager.FOLDER_USER_PROJECTS + "/" + file + "]"); // check if its a "create" and not equal to probe because // thats created every time camera is // launched } else if ((FileObserver.DELETE & event) != 0) { MLog.d(TAG, "File deleted [" + ProjectManager.FOLDER_USER_PROJECTS + "/" + file + "]"); } } }; connectivityChangeReceiver = new ConnectivityChangeReceiver(); } private void addFragments() { MLog.d(TAG, "fragments adding "); //colors final int c0 = getResources().getColor(R.color.project_user_color); final int c1 = getResources().getColor(R.color.project_example_color); mProtocoder.protoScripts.addScriptList(R.drawable.protocoder_script_project, "projects", c0, false); mProtocoder.protoScripts.addScriptList(R.drawable.protocoder_script_example, "examples", c1, true); MLog.d(TAG, "fragments added "); } @Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); } /** * onResume */ @Override protected void onResume() { super.onResume(); //set settings setScreenAlwaysOn(SettingsFragment.getScreenOn(this)); MLog.d(TAG, "Registering as an EventBus listener in MainActivity"); EventBus.getDefault().register(this); mStopServerReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { mProtocoder.app.hardKillConnections(); } }; registerReceiver(connectivityChangeReceiver, new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION)); mProtocoder.app.startServers(); IntentFilter filterSend = new IntentFilter(); filterSend.addAction("org.protocoder.intent.action.STOP_SERVER"); registerReceiver(mStopServerReceiver, filterSend); observer.startWatching(); try { ViewConfiguration config = ViewConfiguration.get(this); Field menuKeyField = ViewConfiguration.class.getDeclaredField("sHasPermanentMenuKey"); if (menuKeyField != null) { menuKeyField.setAccessible(true); menuKeyField.setBoolean(config, false); } } catch (Exception e) { // presumably, not relevant } IDEcommunication.getInstance(this).ready(false); } /** * onPause */ @Override protected void onPause() { super.onPause(); EventBus.getDefault().unregister(this); unregisterReceiver(mStopServerReceiver); observer.stopWatching(); unregisterReceiver(connectivityChangeReceiver); } /** * onDestroy */ @Override protected void onDestroy() { super.onDestroy(); ViewGroup vg = (ViewGroup) findViewById(R.layout.activity_forfragments); if (vg != null) { vg.invalidate(); vg.removeAllViews(); } mProtocoder.app.killConnections(); } // TODO call intent and kill it in an appropiate way public void onEventMainThread(ProjectEvent evt) { // Using transaction so the view blocks MLog.d(TAG, "event -> " + evt.getAction()); if (evt.getAction() == "run") { Project p = evt.getProject(); mProtocoder.protoScripts.run(p.getFolder(), p.getName()); } else if (evt.getAction() == "save") { Project p = evt.getProject(); mProtocoder.protoScripts.refresh(p.getFolder(), p.getName()); } else if (evt.getAction() == "new") { MLog.d(TAG, "creating new project " + evt.getProject().getName()); mProtocoder.protoScripts.createProject("projects", evt.getProject().getName()); } else if (evt.getAction() == "update") { mProtocoder.protoScripts.listRefresh(); } } // execute lines public void onEventMainThread(Events.ExecuteCodeEvent evt) { String code = evt.getCode(); MLog.d(TAG, "event -> " + code); //TODO apprunner // if (debugApp) { // interp.eval(code); // } } public void onEventMainThread(Events.SelectedProjectEvent evt) { String folder = evt.getFolder(); String name = evt.getName(); mProtocoder.protoScripts.goTo(folder, name); mProtocoder.protoScripts.resetHighlighting(folder); mProtocoder.protoScripts.highlight(folder, name); } @Override public boolean onCreateOptionsMenu(Menu menu) { MenuInflater inflater = getMenuInflater(); inflater.inflate(R.menu.main_activity_menu, menu); mMenu = menu; return super.onCreateOptionsMenu(menu); } @Override public boolean onOptionsItemSelected(MenuItem item) { AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo(); int itemId = item.getItemId(); if (itemId == android.R.id.home) { return true; } else if (itemId == R.id.menu_new) { Protocoder.getInstance(this).protoScripts.createProjectDialog(); return true; } else if (itemId == R.id.menu_help) { Protocoder.getInstance(this).app.showHelp(true); return true; } else if (itemId == R.id.menu_settings) { Protocoder.getInstance(this).app.showSettings(true); return true; } else { return super.onOptionsItemSelected(item); } } /* * Key management */ @Override public boolean onKeyDown(int keyCode, KeyEvent evt) { MLog.d("BACK BUTTON", "Back button was pressed"); if (keyCode == 4) { Fragment fragment = getSupportFragmentManager().findFragmentByTag("editorFragment"); if (fragment != null && fragment.isVisible()) { MLog.d(TAG, "Removing editor"); removeFragment(fragment); return true; } else { finish(); return true; } } return true; } @Override public boolean dispatchKeyEvent(KeyEvent event) { if (event.getAction() == KeyEvent.ACTION_DOWN && event.isCtrlPressed()) { int keyCode = event.getKeyCode(); switch (keyCode) { case KeyEvent.KEYCODE_R: MLog.d(TAG, "run app"); break; default: break; } } return super.dispatchKeyEvent(event); } // check if connection has changed public class ConnectivityChangeReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { AndroidUtils.debugIntent("connectivityChangerReceiver", intent); mProtocoder.app.startServers(); } } }