Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Works for me, but it needs the shell scripts for other

  • Loading branch information...
commit 226fcf9481cd69c61d65bb2722480ea1aceeb226 0 parents
@ghk authored
17 .gitignore
@@ -0,0 +1,17 @@
+.metadata
+tmp/**
+.DS_Store
+*.tmp
+*.bak
+tmp/**/*
+*.swp
+*~.nib
+Thumbs.db
+Desktop.ini
+*~
+*.apk
+bin
+gen
+local.properties
+*.jar
+.classpath
33 .project
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>debian</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>com.android.ide.eclipse.adt.ResourceManagerBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>com.android.ide.eclipse.adt.PreCompilerBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>com.android.ide.eclipse.adt.ApkBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>com.android.ide.eclipse.adt.AndroidNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
20 AndroidManifest.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.kaulahcintaku.debian"
+ android:versionCode="1"
+ android:versionName="1.0">
+ <supports-screens android:anyDensity="true"
+ android:largeScreens="true" android:normalScreens="true"
+ android:resizeable="true" android:smallScreens="true"/>
+ <application android:icon="@drawable/icon" android:label="@string/app_name" android:theme="@android:style/Theme.Light">
+ <activity android:name=".DebianManager"
+ android:label="@string/app_name">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+ <activity android:name=".HostedCommandActivity" android:configChanges="orientation|keyboard|keyboardHidden"/>
+
+ </application>
+</manifest>
3  README
@@ -0,0 +1,3 @@
+Mount/Unmount, initd runners, scripts runner for chrooted debian.
+
+see http://tungchingkai.blogspot.com/2010/12/how-to-install-debian-on-samsung-galaxy.html
11 default.properties
@@ -0,0 +1,11 @@
+# This file is automatically generated by Android Tools.
+# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
+#
+# This file must be checked in Version Control Systems.
+#
+# To customize properties used by the Ant build system use,
+# "build.properties", and override values to adapt the script to your
+# project structure.
+
+# Project target.
+target=android-8
36 proguard.cfg
@@ -0,0 +1,36 @@
+-optimizationpasses 5
+-dontusemixedcaseclassnames
+-dontskipnonpubliclibraryclasses
+-dontpreverify
+-verbose
+-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*
+
+-keep public class * extends android.app.Activity
+-keep public class * extends android.app.Application
+-keep public class * extends android.app.Service
+-keep public class * extends android.content.BroadcastReceiver
+-keep public class * extends android.content.ContentProvider
+-keep public class * extends android.app.backup.BackupAgentHelper
+-keep public class * extends android.preference.Preference
+-keep public class com.android.vending.licensing.ILicensingService
+
+-keepclasseswithmembernames class * {
+ native <methods>;
+}
+
+-keepclasseswithmembernames class * {
+ public <init>(android.content.Context, android.util.AttributeSet);
+}
+
+-keepclasseswithmembernames class * {
+ public <init>(android.content.Context, android.util.AttributeSet, int);
+}
+
+-keepclassmembers enum * {
+ public static **[] values();
+ public static ** valueOf(java.lang.String);
+}
+
+-keep class * implements android.os.Parcelable {
+ public static final android.os.Parcelable$Creator *;
+}
BIN  res/drawable-hdpi/icon.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
22 res/layout/command.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical" android:layout_width="fill_parent"
+ android:layout_height="fill_parent">
+ <ScrollView
+ android:layout_width="match_parent"
+ android:layout_height="fill_parent"
+ android:layout_weight="1"
+ android:gravity="center"
+ >
+ <TextView android:id="@+id/output"
+ android:layout_width="fill_parent"
+ android:typeface="monospace"
+ android:scrollbars="vertical"
+ android:layout_height="wrap_content"
+ >
+ </TextView>
+ </ScrollView>
+
+ <Button android:id="@+id/status" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Kill"
+ />
+</LinearLayout>
75 res/layout/main.xml
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ >
+ <LinearLayout android:orientation="horizontal"
+ android:background="@android:drawable/bottom_bar" android:paddingLeft="4.0dip"
+ android:paddingTop="5.0dip" android:paddingRight="4.0dip"
+ android:paddingBottom="1.0dip" android:layout_width="fill_parent"
+ android:layout_height="wrap_content" android:layout_below="@+id/TextView01">
+ <Button android:id="@+id/mount" android:layout_width="0.0dip"
+ android:layout_height="fill_parent" android:text="Mount"
+ android:layout_weight="1.0" />
+ <Button android:id="@+id/umount" android:layout_width="0.0dip"
+ android:layout_height="fill_parent" android:text="Unmount"
+ android:layout_weight="1.0" />
+ </LinearLayout>
+ <ScrollView android:layout_width="fill_parent" android:layout_height="fill_parent"
+ android:scrollbarStyle="insideOverlay" android:id="@+id/scroll"
+ >
+ <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ >
+ <ImageView android:src="@android:drawable/divider_horizontal_dark"
+ android:layout_width="fill_parent" android:layout_height="wrap_content"
+ android:scaleType="fitXY" android:paddingLeft="5dp"
+ android:paddingRight="5dp" android:paddingBottom="2dp"
+ android:paddingTop="2dp" />
+ <TextView
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:text="/etc/init.d"
+ android:textSize="18dip"
+ android:background="@android:drawable/divider_horizontal_bright"
+ android:padding="10dp"
+ />
+ <ImageView android:src="@android:drawable/divider_horizontal_dark"
+ android:layout_width="fill_parent" android:layout_height="wrap_content"
+ android:scaleType="fitXY" android:paddingLeft="5dp"
+ android:paddingRight="5dp" android:paddingBottom="2dp"
+ android:paddingTop="2dp" />
+ <ListView
+ android:id="@+id/initd_entry"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ />
+ <ImageView android:src="@android:drawable/divider_horizontal_dark"
+ android:layout_width="fill_parent" android:layout_height="wrap_content"
+ android:scaleType="fitXY" android:paddingLeft="5dp"
+ android:paddingRight="5dp" android:paddingBottom="2dp"
+ android:paddingTop="2dp" />
+ <TextView
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:text="scripts"
+ android:textSize="18dip"
+ android:background="@android:drawable/divider_horizontal_bright"
+ android:padding="10dp"
+ />
+ <ImageView android:src="@android:drawable/divider_horizontal_dark"
+ android:layout_width="fill_parent" android:layout_height="wrap_content"
+ android:scaleType="fitXY" android:paddingLeft="5dp"
+ android:paddingRight="5dp" android:paddingBottom="2dp"
+ android:paddingTop="2dp" />
+ <ListView
+ android:id="@+id/scripts_entry"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ />
+ </LinearLayout>
+ </ScrollView>
+</LinearLayout>
5 res/values/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <string name="hello">Hello World, DebianManager!</string>
+ <string name="app_name">Debian Manager</string>
+</resources>
45 src/com/kaulahcintaku/debian/Command.java
@@ -0,0 +1,45 @@
+package com.kaulahcintaku.debian;
+
+public class Command {
+
+ public static String debianUserCommand(String command){
+ return "/system/bin/debian -u "+command;
+ }
+
+ public static String debianRootCommand(String command){
+ return "/system/bin/debian "+command;
+ }
+
+ public static String initdCommand(String initd, String command){
+ return debianRootCommand("/etc/init.d/"+initd+" "+command);
+ }
+
+ private String command;
+ private String caption;
+ private boolean needRoot;
+
+ public Command(String config) {
+ String[] splitted = config.split("#");
+ caption = splitted[0];
+ command = splitted[1];
+ needRoot = Boolean.parseBoolean(splitted[2]);
+ }
+
+ public String getCaption() {
+ return caption;
+ }
+
+ public String getCommand() {
+ return command;
+ }
+
+ public boolean isNeedRoot() {
+ return needRoot;
+ }
+
+ @Override
+ public String toString() {
+ return caption;
+ }
+
+}
144 src/com/kaulahcintaku/debian/DebianManager.java
@@ -0,0 +1,144 @@
+package com.kaulahcintaku.debian;
+
+import java.io.BufferedReader;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.util.ArrayList;
+import java.util.List;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.net.Uri;
+import android.os.Bundle;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.AdapterView;
+import android.widget.ArrayAdapter;
+import android.widget.Button;
+import android.widget.ListView;
+
+public class DebianManager extends Activity {
+
+ private static String MOUNTED_KIT_LOCATION = "/mnt/external/debian";
+ private static String UNMOUNTED_KIT_LOCATION = "/mnt/sdcard/external_sd/debian";
+
+ private static String MOUNT_COMMAND = "/system/bin/debian -m";
+ private static String UMOUNT_COMMAND;
+ static{
+ UMOUNT_COMMAND = Command.debianRootCommand("sh "+MOUNTED_KIT_LOCATION+"/stop.sh");
+ }
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.main);
+
+ ((Button)findViewById(R.id.mount)).setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ runCommand(MOUNT_COMMAND, true);
+ }
+ });
+ ((Button)findViewById(R.id.umount)).setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ runCommand(UMOUNT_COMMAND, true);
+ }
+ });
+
+ final List<String> initdScripts = readAllLines(UNMOUNTED_KIT_LOCATION+"/initd.txt");
+ ArrayAdapter<String> initdAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, initdScripts);
+ ListView initdView = (ListView)findViewById(R.id.initd_entry);
+ initdView.setAdapter(initdAdapter);
+ initdView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
+ @Override
+ public void onItemClick(AdapterView<?> arg0, View arg1, int item,
+ long arg3) {
+ createInitdCommandsDialog(initdScripts.get(item)).show();
+ }
+ });
+ configureHeight(initdView, initdAdapter);
+
+ List<String> scriptConfigs = readAllLines(UNMOUNTED_KIT_LOCATION+"/scripts.txt");
+ final List<Command> commands = new ArrayList<Command>();
+ for(String config: scriptConfigs)
+ commands.add(new Command(config));
+ ArrayAdapter<Command> scriptsAdapter = new ArrayAdapter<Command>(this, android.R.layout.simple_list_item_1, commands);
+ ListView scriptsView = ((ListView)findViewById(R.id.scripts_entry));
+ scriptsView.setAdapter(scriptsAdapter);
+ scriptsView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
+ @Override
+ public void onItemClick(AdapterView<?> arg0, View arg1, int item,
+ long arg3) {
+ Command command = commands.get(item);
+ String commandText = command.isNeedRoot()
+ ? Command.debianRootCommand(command.getCommand())
+ : Command.debianUserCommand(command.getCommand()) ;
+ runCommand(commandText, true);
+ }
+ });
+ configureHeight(scriptsView, scriptsAdapter);
+ }
+
+ private List<String> readAllLines(String file){
+ List<String> results = new ArrayList<String>();
+ try{
+ BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(file)));
+ String line = null;
+ while((line = reader.readLine()) != null){
+ String trimmed = line.trim();
+ if(trimmed.length() != 0)
+ results.add(trimmed);
+ }
+ }
+ catch(IOException ioe){
+ HostedCommandActivity.showException(ioe, this);
+ }
+ return results;
+ }
+
+ private AlertDialog createInitdCommandsDialog(final String initd) {
+ final CharSequence[] commands = new CharSequence[]{"start", "stop", "restart", "status"};
+ AlertDialog.Builder builder = new AlertDialog.Builder(this);
+ builder.setTitle("Pick Command");
+ builder.setItems(commands, new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int item) {
+ runCommand(Command.initdCommand(initd, (String)commands[item]), true);
+ }
+ });
+ AlertDialog alert = builder.create();
+ return alert;
+ }
+
+ private void runCommand(String command, boolean isHosted){
+ if(isHosted){
+ Intent intent = new Intent(this, HostedCommandActivity.class);
+ Bundle data = new Bundle();
+ data.putString("command", command);
+ intent.putExtras(data);
+ startActivity(intent);
+ }
+ else{
+ Intent intent = new Intent(
+ Intent.ACTION_VIEW,
+ Uri.parse("exe:#"+command+"#"));
+ startActivity(intent);
+ }
+ }
+
+ private void configureHeight(ListView listView, ArrayAdapter<?> adapter){
+ int totalHeight = 0;
+ for (int i = 0; i < adapter.getCount(); i++) {
+ View listItem = adapter.getView(i, null, listView);
+ listItem.measure(0, 0);
+ totalHeight += listItem.getMeasuredHeight();
+ }
+
+ ViewGroup.LayoutParams params = listView.getLayoutParams();
+ params.height = totalHeight + (listView.getDividerHeight() * (adapter.getCount() - 1));
+ listView.setLayoutParams(params);
+ }
+}
163 src/com/kaulahcintaku/debian/HostedCommandActivity.java
@@ -0,0 +1,163 @@
+package com.kaulahcintaku.debian;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
+import android.view.View;
+import android.widget.Button;
+import android.widget.TextView;
+
+public class HostedCommandActivity extends Activity {
+
+ private static final int OUTPUT_RECEIVED = 1000;
+
+ private String command;
+ private Process process;
+ private ProcessWaitingThread waitingThread;
+
+ private Handler handler = new Handler(){
+ public void dispatchMessage(Message msg) {
+ switch(msg.what){
+ case OUTPUT_RECEIVED:
+ String line = (String) msg.obj;
+ ((TextView)findViewById(R.id.output)).append(line+"\n");
+ }
+ };
+ };
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ Bundle data = this.getIntent().getExtras();
+ if(data != null){
+ command = data.getString("command");
+ setContentView(R.layout.command);
+ ((Button)findViewById(R.id.status)).setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ if(waitingThread != null && !waitingThread.isProcessFinished())
+ process.destroy();
+ }
+ });
+ runCommand();
+ }
+ else{
+ finish();
+ }
+ }
+
+ @Override
+ protected void onDestroy() {
+ if(process != null){
+ try{
+ process.destroy();
+ }
+ catch(Exception e){
+ }
+ }
+ super.onDestroy();
+ }
+
+ private void runCommand(){
+ try{
+ process = Runtime.getRuntime().exec(command);
+ waitingThread = new ProcessWaitingThread(process);
+ waitingThread.start();
+ new OutputReadingThread(process.getInputStream()).start();
+ new OutputReadingThread(process.getErrorStream()).start();
+ }
+ catch(Exception e){
+ showException(e, this);
+ }
+ }
+
+ private class OutputReadingThread extends Thread{
+ private InputStream input;
+
+ public OutputReadingThread(InputStream input) {
+ this.input = input;
+ }
+
+ public void run() {
+ BufferedReader reader = new BufferedReader(new InputStreamReader(input));
+ try {
+ String line = null;
+ while ((line = reader.readLine()) != null) {
+ handler.sendMessage(Message.obtain(handler, OUTPUT_RECEIVED, line));
+ }
+ } catch (IOException ioe) {
+ } finally {
+ try {
+ reader.close();
+ input.close();
+ } catch (Exception e) {
+ }
+ }
+ }
+ }
+
+ private class ProcessWaitingThread extends Thread{
+
+ private Process process;
+ private boolean processFinished = false;
+ private int exitValue = 0;
+
+ public ProcessWaitingThread(Process process) {
+ this.process = process;
+ }
+
+ public void run() {
+ while(!processFinished)
+ {
+ try{
+ exitValue = process.exitValue();
+ processFinished = true;
+ }
+ catch(Exception e){
+ try{
+ exitValue = process.waitFor();
+ processFinished = true;
+ }
+ catch(InterruptedException ie){
+ }
+ }
+ }
+ runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ ((Button)findViewById(R.id.status)).setText("Finished ("+exitValue+")");
+ }
+ });
+ }
+
+ public boolean isProcessFinished() {
+ return processFinished;
+ }
+ }
+
+ public static void showException(final Exception e, final Activity context) {
+ Runnable runnable = new Runnable() {
+ @Override
+ public void run() {
+ AlertDialog alertDialog = new AlertDialog.Builder(context)
+ .create();
+ StringWriter sw = new StringWriter();
+ PrintWriter pw = new PrintWriter(sw);
+ e.printStackTrace(pw);
+ alertDialog.setMessage(sw.toString());
+ alertDialog.show();
+ }
+ };
+ context.runOnUiThread(runnable);
+ }
+
+}
Please sign in to comment.
Something went wrong with that request. Please try again.