Skip to content

Commit

Permalink
Implemented execution of Python apps. Closes #1
Browse files Browse the repository at this point in the history
The python host provides the necessary libs to execute Python code.
These libs must be loaded by the Python app. To ensure that there is no
security issue the Python host must have the permission
"com.python.permission.PYTHONHOST".

It's a start, but I think that the starting process of the Python apps
is too complicated, not intuitive and takes too long. If anybody has
advice on that topic, please tell me at issue #9.
  • Loading branch information
Abestanis committed Jun 29, 2015
1 parent 495fc7e commit 8f4c196
Show file tree
Hide file tree
Showing 19 changed files with 208 additions and 346 deletions.
18 changes: 11 additions & 7 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@
android:label="@string/pythonHostPermission_label"
android:description="@string/pythonHostPermission_description"
android:icon="@drawable/python_permission_icon"
android:protectionLevel="dangerous"/>
android:protectionLevel="dangerous" />
<!-- Should the permission declaration be here, in the app or both? Should we define a permission tree? -->
<uses-permission android:name="com.python.permission.PYTHONHOST"/>
<uses-permission android:name="com.python.permission.PYTHONHOST" />
<application
android:allowBackup="true"
android:icon="@drawable/python_launcher_icon"
Expand All @@ -17,16 +17,20 @@
<activity
android:name=".MainActivity"
android:label="@string/app_name" >
<intent-filter>
<intent-filter >
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".PythonInterpreterActivity"
android:label="PythonInterpreter"/>
<activity android:name=".ExecutePythonAppActivity">
<activity
android:name=".PythonInterpreterActivity"
android:label="PythonInterpreter" />
<activity
android:name=".GetPythonAppExecutionInfoActivity"
android:excludeFromRecents="true"
android:theme="@android:style/Theme.NoDisplay" >
<intent-filter>
<action android:name="com.python.pythonhost.PYTHON_APP_EXECUTE" />
<action android:name="com.python.pythonhost.PYTHON_APP_GET_EXECUTION_INFO" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package com.apython.python.pythonhost;

import android.app.Activity;
import android.os.Bundle;

/*
* This activity can be launched via an intent with the action
* "com.python.pythonhost.PYTHON_APP_GET_EXECUTION_INFO".
* It is used by the Python apps to execute their Python code.
*
* Created by Sebastian on 27.05.2015.
*/

public class GetPythonAppExecutionInfoActivity extends Activity {

// The communication manager which handles the communication with the Python apps.
PythonAppCommunicationManager communicationManager;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.communicationManager = new PythonAppCommunicationManager(this);
if (this.communicationManager.parseArgs(this.getIntent())) {
this.communicationManager.startPythonApp();
}
}
}
35 changes: 0 additions & 35 deletions app/src/main/java/com/apython/python/pythonhost/MessageIDs.java

This file was deleted.

73 changes: 34 additions & 39 deletions app/src/main/java/com/apython/python/pythonhost/PackageManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
public class PackageManager {

public static File getModulePath(Context context) {
return new File(context.getFilesDir(), "lib");///python2.7");
return new File(context.getFilesDir(), "lib");
}

public static boolean installStandardModules(Context context) {
Expand All @@ -29,57 +29,23 @@ public static boolean installStandardModules(Context context) {
Log.e(MainActivity.TAG, "Failed to create the 'lib' directory!");
return false;
}
makeFileAccessible(modulesDest);
InputStream moduleLocation = context.getResources().openRawResource(R.raw.lib);
return unpackModules(modulesDest, moduleLocation);
}

private static boolean unpackModules(File destination, InputStream moduleLocation)
{
// ZipInputStream archive;
// try {
// String filename;
// archive = new ZipInputStream(new BufferedInputStream(moduleLocation));
// ZipEntry zipEntry;
// byte[] buffer = new byte[1024];
// int count;
//
// while ((zipEntry = archive.getNextEntry()) != null) {
// filename = zipEntry.getName();
// if (zipEntry.isDirectory()) {
// // Create the directory if not exists
// File directory = new File(destination, filename);
// if (!(directory.mkdirs() || directory.isDirectory())) {
// Log.e(MainActivity.TAG, "Could not save directory '" + filename + "' to path '"
// + directory.getAbsolutePath() + "' while trying to install the Python modules!");
// archive.close();
// return false;
// }
// } else {
// // Save the file
// FileOutputStream outputFile = new FileOutputStream(new File(destination, filename));
// while ((count = archive.read(buffer)) != -1) {
// outputFile.write(buffer, 0, count);
// }
// outputFile.close();
// }
// archive.closeEntry();
// }
// archive.close();
// return true;
// }
// catch(IOException e) {
// Log.e(MainActivity.TAG, "Failed to extract the Python modules!");
// e.printStackTrace();
// return false;
// }
byte[] buffer = new byte[1024];
int count;
try {
FileOutputStream outputFile = new FileOutputStream(new File(destination, "python27.zip"));
File destZip = new File(destination, "python27.zip");
FileOutputStream outputFile = new FileOutputStream(destZip);
while ((count = moduleLocation.read(buffer)) != -1) {
outputFile.write(buffer, 0, count);
}
outputFile.close();
makeFileAccessible(destZip);
} catch (IOException e) {
Log.e(MainActivity.TAG, "Failed to extract the Python modules!");
e.printStackTrace();
Expand All @@ -88,4 +54,33 @@ private static boolean unpackModules(File destination, InputStream moduleLocatio
Log.d(MainActivity.TAG, "" + new File(destination, "python2.7.zip").isFile());
return true;
}

private static boolean makeFileAccessible(File file) {
if(!file.exists()) {
try {
if (!file.createNewFile()) {
Log.w(MainActivity.TAG, "Could not make file '" + file.getAbsolutePath() + "' accessible: Could not create file.");
return false;
}
} catch (IOException e) {
Log.w(MainActivity.TAG, "Could not make file '" + file.getAbsolutePath() + "' accessible: Could not create file.");
e.printStackTrace();
return false;
}
}
// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD) { // TODO: Check this
// if (file.setReadable(true, false) && file.setExecutable(true, false)) {
// Log.d(TAG, "Successfully made '" + file.getAbsolutePath() + "' accessible.");
// return true;
// }
// }
try {
Runtime.getRuntime().exec("chmod 755 " + file.getAbsolutePath());
Log.d(MainActivity.TAG, "Successfully made '" + file.getAbsolutePath() + "' accessible via chmod.");
return true;
} catch (IOException e) {
e.printStackTrace();
}
return false;
}
}

This file was deleted.

Loading

0 comments on commit 8f4c196

Please sign in to comment.