/* * Copyright (C) 2010 Google Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of * the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. */ /* * Copyright (C) 2012, Anthony Prieur & Daniel Oppenheim. All rights reserved. * * Original from SL4A modified to allow to embed Interpreter and scripts into an APK */ package com.beckersweet.opmub; import android.app.Notification; import android.app.PendingIntent; import android.content.Context; import android.content.Intent; import android.net.Uri; import android.os.AsyncTask; import android.os.Binder; import android.os.Environment; import android.os.Handler; import android.os.IBinder; import android.util.Log; import com.beckersweet.opmub.config.GlobalConstants; import com.beckersweet.opmub.process.MyScriptProcess; import com.googlecode.android_scripting.AndroidProxy; import com.googlecode.android_scripting.Constants; import com.googlecode.android_scripting.FeaturedInterpreters; import com.googlecode.android_scripting.ForegroundService; import com.googlecode.android_scripting.NotificationIdFactory; import com.googlecode.android_scripting.interpreter.Interpreter; import com.googlecode.android_scripting.jsonrpc.RpcReceiverManager; import com.googlecode.android_scripting.interpreter.InterpreterConfiguration; import com.googlecode.android_scripting.BaseApplication; import java.io.File; import java.util.ArrayList; import java.util.HashMap; import java.util.Map; import java.util.concurrent.CountDownLatch; public class ScriptService extends ForegroundService { private final static int NOTIFICATION_ID = NotificationIdFactory.create(); private final CountDownLatch mLatch = new CountDownLatch(1); private final IBinder mBinder; private MyScriptProcess myScriptProcess; // private static ScriptService instance; // private boolean killMe; private InterpreterConfiguration mInterpreterConfiguration = null; private RpcReceiverManager mFacadeManager; private AndroidProxy mProxy; private static Context context = null; // static { // instance = null; // } // ------------------------------------------------------------------------------------------------------ public class LocalBinder extends Binder { public ScriptService getService() { return ScriptService.this; } } // ------------------------------------------------------------------------------------------------------ @Override public void onDestroy() { super.onDestroy(); } // ------------------------------------------------------------------------------------------------------ public ScriptService() { super(NOTIFICATION_ID); mBinder = new LocalBinder(); } // ------------------------------------------------------------------------------------------------------ @Override public IBinder onBind(Intent intent) { return mBinder; } // ------------------------------------------------------------------------------------------------------ public static Context getAppContext() { return ScriptService.context; } // ------------------------------------------------------------------------------------------------------ @Override public void onCreate() { super.onCreate(); ScriptService.context = getApplicationContext(); } // ------------------------------------------------------------------------------------------------------ private void killProcess() { // this.killMe = true; // instance = null; if (myScriptProcess != null) { myScriptProcess.kill(); } } // ------------------------------------------------------------------------------------------------------ @SuppressWarnings("deprecation") @Override public void onStart(Intent intent, final int startId) { super.onStart(intent, startId); killProcess(); // instance = this; // this.killMe = false; new startMyAsyncTask().execute(startId); } // ------------------------------------------------------------------------------------------------------ public class startMyAsyncTask extends AsyncTask<Integer, Integer, Boolean> { @Override protected void onPreExecute() { } @Override protected Boolean doInBackground(Integer... params) { startMyMain(params[0]); // TODO return true; } @Override protected void onProgressUpdate(Integer... values) { } @Override protected void onPostExecute(Boolean installStatus) { } } // ------------------------------------------------------------------------------------------------------ private void startMyMain(final int startId) { String scriptName = GlobalConstants.PYTHON_MAIN_SCRIPT_NAME; scriptName = this.getFilesDir().getAbsolutePath() + "/" + scriptName; File script = new File(scriptName); // arguments ArrayList<String> args = new ArrayList<String>(); args.add(scriptName); args.add("--foreground"); File pythonBinary = new File(this.getFilesDir().getAbsolutePath() + "/python/bin/python"); // env var Map<String, String> environmentVariables = null; environmentVariables = new HashMap<String, String>(); environmentVariables.put("PYTHONPATH", Environment.getExternalStorageDirectory().getAbsolutePath()+ "/" + this.getPackageName() + "/extras/python" + ":" + this.getFilesDir().getAbsolutePath() + "/python/lib/python2.7/lib-dynload" + ":" + this.getFilesDir().getAbsolutePath() + "/python/lib/python2.7"); environmentVariables.put("TEMP", Environment.getExternalStorageDirectory().getAbsolutePath() + "/" + this.getPackageName() + "/extras/tmp"); environmentVariables.put("PYTHONHOME", this.getFilesDir().getAbsolutePath() + "/python"); environmentVariables.put("LD_LIBRARY_PATH", this.getFilesDir().getAbsolutePath() + "/python/lib" + ":" + this.getFilesDir().getAbsolutePath() + "/python/lib/python2.7/lib-dynload"); // launch script mProxy = new AndroidProxy(this, null, true); mProxy.startLocal(); mLatch.countDown(); myScriptProcess = MyScriptProcess.launchScript(script, mInterpreterConfiguration, mProxy, new Runnable() { @Override public void run() { //mProxy.shutdown(); //stopSelf(startId); // hard force restart // if (!ScriptService.this.killMe) { // startMyMain(); // } } }, script.getParent(), Environment.getExternalStorageDirectory().getAbsolutePath() + "/" + this.getPackageName(), args, environmentVariables, pythonBinary); } // ------------------------------------------------------------------------------------------------------ RpcReceiverManager getRpcReceiverManager() throws InterruptedException { mLatch.await(); if (mFacadeManager==null) { // Facade manage may not be available on startup. mFacadeManager = mProxy.getRpcReceiverManagerFactory() .getRpcReceiverManagers().get(0); } return mFacadeManager; } // ------------------------------------------------------------------------------------------------------ @Override protected Notification createNotification() { Notification notification = new Notification(R.drawable.ic_launcher, this.getString(R.string.loading), System.currentTimeMillis()); // This contentIntent is a noop. PendingIntent contentIntent = PendingIntent.getService(this, 0, new Intent(), 0); notification.setLatestEventInfo(this, this.getString(R.string.app_name), this.getString(R.string.loading), contentIntent); notification.flags = Notification.FLAG_AUTO_CANCEL; return notification; } }