Re #1546: Initial version of generic console application loader.
git-svn-id: https://svn.pjsip.org/repos/pjproject/branches/projects/android@4289 74dad513-b988-da41-8d7b-12977e46ad98
This commit is contained in:
parent
3b27e8f073
commit
2ff094467a
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="src" path="src"/>
|
||||
<classpathentry kind="src" path="gen"/>
|
||||
<classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
|
||||
<classpathentry kind="con" path="com.android.ide.eclipse.adt.LIBRARIES"/>
|
||||
<classpathentry kind="output" path="bin/classes"/>
|
||||
</classpath>
|
|
@ -0,0 +1,49 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>org.pjsip.apjloader.MainActivity</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
|
||||
<triggers>clean,full,incremental,</triggers>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<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>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
|
||||
<triggers>full,incremental,</triggers>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>com.android.ide.eclipse.adt.AndroidNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
<nature>org.eclipse.cdt.core.cnature</nature>
|
||||
<nature>org.eclipse.cdt.core.ccnature</nature>
|
||||
<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
|
||||
<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
|
@ -0,0 +1,53 @@
|
|||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="org.pjsip.apjloader"
|
||||
android:versionCode="1"
|
||||
android:versionName="1.0" >
|
||||
|
||||
<uses-sdk
|
||||
android:minSdkVersion="15"
|
||||
android:targetSdkVersion="15" />
|
||||
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.RECORD_AUDIO" />
|
||||
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
|
||||
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" />
|
||||
<uses-permission android:name="android.permission.WRITE_SETTINGS" />
|
||||
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
|
||||
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
|
||||
<uses-permission android:name="android.permission.READ_CONTACTS" />
|
||||
<uses-permission android:name="android.permission.WRITE_CONTACTS" />
|
||||
<uses-permission android:name="android.permission.CALL_PHONE" />
|
||||
<uses-permission android:name="android.permission.WAKE_LOCK" />
|
||||
<uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
|
||||
<uses-permission android:name="android.permission.VIBRATE" />
|
||||
<uses-permission android:name="android.permission.BLUETOOTH" />
|
||||
<uses-permission android:name="android.permission.READ_LOGS" />
|
||||
<uses-permission android:name="android.permission.USE_SIP" />
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="android.permission.CAMERA" />
|
||||
<uses-permission android:name="android.permission.BROADCAST_STICKY" />
|
||||
<uses-permission android:name="android.permission.READ_PROFILE" />
|
||||
|
||||
<uses-feature android:name="android.hardware.sip.voip" android:required="true" />
|
||||
<uses-feature android:name="android.hardware.microphone" android:required="true" />
|
||||
|
||||
<application
|
||||
android:icon="@drawable/ic_launcher"
|
||||
android:label="@string/app_name"
|
||||
android:theme="@android:style/Theme.DeviceDefault.NoActionBar" >
|
||||
<activity
|
||||
android:screenOrientation="portrait"
|
||||
android:configChanges="keyboardHidden|orientation|screenLayout"
|
||||
android:name=".MainActivity"
|
||||
android:label="@string/title_activity_main" >
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
</application>
|
||||
|
||||
</manifest>
|
|
@ -0,0 +1,61 @@
|
|||
# $id$
|
||||
|
||||
LOCAL_PATH := $(call my-dir)
|
||||
include $(CLEAR_VARS)
|
||||
|
||||
# Get PJ build settings
|
||||
include ../../../build.mak
|
||||
include $(PJDIR)/build/common.mak
|
||||
|
||||
# Path to SWIG
|
||||
MY_SWIG := swig
|
||||
|
||||
#========================================================================
|
||||
# Choose console application to load
|
||||
#========================================================================
|
||||
|
||||
# pjlib test
|
||||
MY_MODULE := $(PJDIR)/pjlib/build/output/pjlib-test-$(TARGET_NAME)/*.o
|
||||
|
||||
# pjlib-util test
|
||||
#MY_MODULE := $(PJDIR)/pjlib-util/build/output/pjlib-util-test-$(TARGET_NAME)/*.o
|
||||
|
||||
# pjsip test
|
||||
#MY_MODULE := $(PJDIR)/pjsip/build/output/pjsip-test-$(TARGET_NAME)/*.o
|
||||
|
||||
# pjnath test
|
||||
#MY_MODULE := $(PJDIR)/pjnath/build/output/pjnath-test-$(TARGET_NAME)/*.o
|
||||
|
||||
# pjmedia test
|
||||
# Note: jbuf test requires Jbtest.dat, this jbuf test must be disabled (for now).
|
||||
#MY_MODULE := $(PJDIR)/pjmedia/build/output/pjmedia-test-$(TARGET_NAME)/*.o
|
||||
|
||||
# pjsystest app (not supported yet)
|
||||
# Todo: this test requires some input and output files (log & WAV).
|
||||
#MY_MODULE := $(PJDIR)/pjsip-apps/build/output/pjsystest-$(TARGET_NAME)/*.o
|
||||
|
||||
# pjsua app
|
||||
# Note: must set USE_GUI to zero in config_site.h
|
||||
#MY_MODULE := $(PJDIR)/pjsip-apps/build/output/pjsua-$(TARGET_NAME)/*.o
|
||||
|
||||
#========================================================================
|
||||
|
||||
# Constants
|
||||
MY_JNI_WRAP := apjloader_wrap.c
|
||||
MY_JNI_DIR := jni
|
||||
|
||||
# Android build settings
|
||||
LOCAL_MODULE := libapjloader
|
||||
LOCAL_CFLAGS := -Werror $(APP_CFLAGS)
|
||||
LOCAL_LDFLAGS := $(APP_LDFLAGS)
|
||||
LOCAL_LDLIBS := $(MY_MODULE) $(APP_LDLIBS)
|
||||
LOCAL_SRC_FILES := $(MY_JNI_WRAP) apjloader_pipe.c
|
||||
|
||||
# Invoke SWIG
|
||||
$(MY_JNI_DIR)/$(MY_JNI_WRAP):
|
||||
@echo "Invoking SWIG..."
|
||||
$(MY_SWIG) -o $(MY_JNI_DIR)/$(MY_JNI_WRAP) -package org.pjsip.apjloader -outdir src/org/pjsip/apjloader -java $(MY_JNI_DIR)/apjloader.i
|
||||
|
||||
.PHONY: $(MY_JNI_DIR)/$(MY_JNI_WRAP)
|
||||
|
||||
include $(BUILD_SHARED_LIBRARY)
|
|
@ -0,0 +1,30 @@
|
|||
%module apjloader
|
||||
|
||||
%{
|
||||
int main(int argc, char **argv);
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
int init_stdio_pipe();
|
||||
void destroy_stdio_pipe();
|
||||
int read_from_stdout(char *ch);
|
||||
int write_to_stdin(const char *st);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
%}
|
||||
|
||||
%include "various.i"
|
||||
|
||||
%apply char **STRING_ARRAY { char **argv };
|
||||
int main(int argc, char **argv);
|
||||
|
||||
%include "typemaps.i"
|
||||
%apply signed char *INOUT { char *ch };
|
||||
|
||||
int init_stdio_pipe();
|
||||
void destroy_stdio_pipe();
|
||||
int read_from_stdout(char *ch);
|
||||
int write_to_stdin(const char *st);
|
|
@ -0,0 +1,93 @@
|
|||
/* $id$ */
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#define READ 0
|
||||
#define WRITE 1
|
||||
#define STATUS 2
|
||||
|
||||
static int stdout_pipe[3];
|
||||
static int stdin_pipe[3];
|
||||
|
||||
void destroy_stdio_pipe();
|
||||
|
||||
int init_stdio_pipe()
|
||||
{
|
||||
int rc;
|
||||
|
||||
/* Set stdout no buffer */
|
||||
setvbuf(stdout, NULL, _IONBF, 0);
|
||||
|
||||
rc = pipe(stdout_pipe);
|
||||
if (rc != 0)
|
||||
goto on_error;
|
||||
|
||||
stdout_pipe[STATUS] = 1;
|
||||
|
||||
rc = dup2(stdout_pipe[WRITE], 1);
|
||||
if (rc < 0)
|
||||
goto on_error;
|
||||
|
||||
rc = pipe(stdin_pipe);
|
||||
if (rc != 0)
|
||||
goto on_error;
|
||||
|
||||
stdin_pipe[STATUS] = 1;
|
||||
|
||||
rc = dup2(stdin_pipe[READ], 0);
|
||||
if (rc < 0)
|
||||
goto on_error;
|
||||
|
||||
return 0;
|
||||
|
||||
on_error:
|
||||
rc = errno;
|
||||
destroy_stdio_pipe();
|
||||
return rc;
|
||||
}
|
||||
|
||||
void destroy_stdio_pipe()
|
||||
{
|
||||
if (stdout_pipe[STATUS]) {
|
||||
close(stdout_pipe[READ]);
|
||||
close(stdout_pipe[WRITE]);
|
||||
}
|
||||
stdout_pipe[STATUS] = 0;
|
||||
|
||||
if (stdin_pipe[STATUS]) {
|
||||
close(stdin_pipe[READ]);
|
||||
close(stdin_pipe[WRITE]);
|
||||
}
|
||||
stdin_pipe[STATUS] = 0;
|
||||
}
|
||||
|
||||
int read_from_stdout(char *ch)
|
||||
{
|
||||
int rc;
|
||||
|
||||
rc = read(stdout_pipe[READ], ch, 1);
|
||||
if (rc == 0) {
|
||||
/* EOF */
|
||||
return -1;
|
||||
} else if (rc == -1) {
|
||||
/* ERROR */
|
||||
return -2;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int write_to_stdin(const char *st)
|
||||
{
|
||||
int rc;
|
||||
char buf[100];
|
||||
int len;
|
||||
|
||||
len = snprintf(buf, sizeof(buf), "%s\r\n", st);
|
||||
rc = write(stdin_pipe[WRITE], buf, len);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<lint>
|
||||
</lint>
|
|
@ -0,0 +1,20 @@
|
|||
# To enable ProGuard in your project, edit project.properties
|
||||
# to define the proguard.config property as described in that file.
|
||||
#
|
||||
# Add project specific ProGuard rules here.
|
||||
# By default, the flags in this file are appended to flags specified
|
||||
# in ${sdk.dir}/tools/proguard/proguard-android.txt
|
||||
# You can edit the include path and order by changing the ProGuard
|
||||
# include property in project.properties.
|
||||
#
|
||||
# For more details, see
|
||||
# http://developer.android.com/guide/developing/tools/proguard.html
|
||||
|
||||
# Add any project specific keep options here:
|
||||
|
||||
# If your project uses WebView with JS, uncomment the following
|
||||
# and specify the fully qualified class name to the JavaScript interface
|
||||
# class:
|
||||
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
||||
# public *;
|
||||
#}
|
|
@ -0,0 +1,14 @@
|
|||
# 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 edit
|
||||
# "ant.properties", and override values to adapt the script to your
|
||||
# project structure.
|
||||
#
|
||||
# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
|
||||
#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
|
||||
|
||||
# Project target.
|
||||
target=android-15
|
Binary file not shown.
After Width: | Height: | Size: 3.0 KiB |
Binary file not shown.
After Width: | Height: | Size: 9.2 KiB |
Binary file not shown.
After Width: | Height: | Size: 3.0 KiB |
Binary file not shown.
After Width: | Height: | Size: 5.1 KiB |
Binary file not shown.
After Width: | Height: | Size: 3.1 KiB |
Binary file not shown.
After Width: | Height: | Size: 14 KiB |
|
@ -0,0 +1,50 @@
|
|||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
android:orientation="vertical" >
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" >
|
||||
|
||||
<Button
|
||||
android:id="@+id/send_cmd_button"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Send:" />
|
||||
|
||||
<EditText
|
||||
android:id="@+id/input_cmd"
|
||||
android:layout_width="0dip"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:maxLines="1"
|
||||
android:text=""
|
||||
android:hint="Type string to send">
|
||||
</EditText>
|
||||
|
||||
<Button
|
||||
android:id="@+id/quit_button"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Quit" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<ScrollView
|
||||
android:id="@+id/output_scroller"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:scrollbars="vertical"
|
||||
android:fillViewport="true" >
|
||||
|
||||
<TextView
|
||||
android:id="@+id/output"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textSize="7dip"
|
||||
android:typeface="monospace" />
|
||||
|
||||
</ScrollView>
|
||||
|
||||
</LinearLayout>
|
|
@ -0,0 +1,5 @@
|
|||
<resources>
|
||||
|
||||
<style name="AppTheme" parent="android:Theme.Holo.Light" />
|
||||
|
||||
</resources>
|
|
@ -0,0 +1,5 @@
|
|||
<resources>
|
||||
|
||||
<style name="AppTheme" parent="android:Theme.Holo.Light.DarkActionBar" />
|
||||
|
||||
</resources>
|
|
@ -0,0 +1,6 @@
|
|||
<resources>
|
||||
|
||||
<string name="app_name">Console Loader</string>
|
||||
<string name="title_activity_main">MainActivity</string>
|
||||
|
||||
</resources>
|
|
@ -0,0 +1,5 @@
|
|||
<resources>
|
||||
|
||||
<style name="AppTheme" parent="android:Theme.Light" />
|
||||
|
||||
</resources>
|
|
@ -0,0 +1,254 @@
|
|||
// $id$
|
||||
|
||||
package org.pjsip.apjloader;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.Message;
|
||||
import android.text.method.ScrollingMovementMethod;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.View;
|
||||
import android.view.inputmethod.InputMethodManager;
|
||||
import android.widget.Button;
|
||||
import android.widget.EditText;
|
||||
import android.widget.ScrollView;
|
||||
import android.widget.TextView;
|
||||
|
||||
class CONST {
|
||||
public static final String LIB_FILENAME = "apjloader";
|
||||
public static final String TAG = "apjloader";
|
||||
public static final String NEWLINE = "\r\n";
|
||||
public static final Boolean AUTOKILL_ON_FINISHED = true;
|
||||
public enum MSG_TYPE {
|
||||
STR_INFO,
|
||||
STR_ERROR,
|
||||
QUIT
|
||||
};
|
||||
}
|
||||
|
||||
class LOG {
|
||||
public static void INFO(Handler h, String str) {
|
||||
Message msg = Message.obtain(h, CONST.MSG_TYPE.STR_INFO.ordinal(), str);
|
||||
msg.sendToTarget();
|
||||
}
|
||||
public static void ERROR(Handler h, String str) {
|
||||
Message msg = Message.obtain(h, CONST.MSG_TYPE.STR_ERROR.ordinal(), str);
|
||||
msg.sendToTarget();
|
||||
}
|
||||
}
|
||||
|
||||
class LoaderThread extends Thread {
|
||||
private Handler ui_handler;
|
||||
|
||||
public LoaderThread(Handler ui_handler_) {
|
||||
ui_handler = ui_handler_;
|
||||
}
|
||||
|
||||
public void run() {
|
||||
// Console application's params. Note that, the first param will be
|
||||
// ignored (it is supposed to contain the app path).
|
||||
// Here we just put some pjsua app params, this sample params will be
|
||||
// ignored by PJSIP test apps such as pjlib-test, pjsystest, etc.
|
||||
String argv[] = {"",
|
||||
"--clock-rate=8000",
|
||||
"--auto-answer=200",
|
||||
};
|
||||
|
||||
LOG.INFO(ui_handler, "Starting module.." + CONST.NEWLINE);
|
||||
int rc = apjloader.main(argv.length, argv);
|
||||
LOG.INFO(ui_handler, "Module finished with return code: " +
|
||||
Integer.toString(rc) + CONST.NEWLINE);
|
||||
|
||||
apjloader.destroy_stdio_pipe();
|
||||
|
||||
if (CONST.AUTOKILL_ON_FINISHED) {
|
||||
Message msg = Message.obtain(ui_handler, CONST.MSG_TYPE.QUIT.ordinal());
|
||||
ui_handler.sendMessageDelayed(msg, 2000);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class OutputThread extends Thread {
|
||||
private Handler ui_handler;
|
||||
|
||||
public OutputThread(Handler ui_handler_) {
|
||||
ui_handler = ui_handler_;
|
||||
}
|
||||
|
||||
public void run() {
|
||||
final int BUFFERSIZE = 200;
|
||||
StringBuilder sb = new StringBuilder(BUFFERSIZE);
|
||||
|
||||
while (true)
|
||||
{
|
||||
byte ch[] = new byte[1];
|
||||
int rc = apjloader.read_from_stdout(ch);
|
||||
|
||||
if (rc == 0) {
|
||||
if (ch[0]=='\r' || ch[0]== '\n') {
|
||||
if (sb.length() > 0) {
|
||||
LOG.INFO(ui_handler, sb.toString()+CONST.NEWLINE);
|
||||
sb.delete(0, sb.length());
|
||||
}
|
||||
} else {
|
||||
sb.append((char)ch[0]);
|
||||
}
|
||||
} else {
|
||||
LOG.INFO(ui_handler, "Stdout pipe stopped, rc="+Integer.toString(rc)+CONST.NEWLINE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public class MainActivity extends Activity {
|
||||
private TextView log_view;
|
||||
private ScrollView log_scroll_view;
|
||||
EditText input_cmd;
|
||||
|
||||
/** Called when the activity is first created. */
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_main);
|
||||
|
||||
init_view();
|
||||
|
||||
print_log("Loading module.." + CONST.NEWLINE);
|
||||
int rc = init_lib();
|
||||
if (rc != 0)
|
||||
print_log("Failed loading module: " + Integer.toString(rc) + CONST.NEWLINE);
|
||||
}
|
||||
|
||||
private View.OnClickListener on_send_cmd_click = new View.OnClickListener() {
|
||||
public void onClick(View v) {
|
||||
String cmd = input_cmd.getText().toString().trim();
|
||||
input_cmd.setText("");
|
||||
send_cmd(cmd);
|
||||
}
|
||||
};
|
||||
|
||||
private View.OnClickListener on_quit_click = new View.OnClickListener() {
|
||||
public void onClick(View v) {
|
||||
/* Send quit command, only for pjsua-app */
|
||||
send_cmd("q");
|
||||
|
||||
print_log("Quitting..");
|
||||
Message msg = Message.obtain(ui_handler, CONST.MSG_TYPE.QUIT.ordinal());
|
||||
ui_handler.sendMessageDelayed(msg, 2000);
|
||||
}
|
||||
};
|
||||
|
||||
private View.OnKeyListener on_input_cmd_key = new View.OnKeyListener() {
|
||||
|
||||
public boolean onKey(View v, int keyCode, KeyEvent event) {
|
||||
if ((event.getAction() == KeyEvent.ACTION_DOWN) &&
|
||||
(keyCode == KeyEvent.KEYCODE_ENTER))
|
||||
{
|
||||
String cmd = input_cmd.getText().toString().trim();
|
||||
input_cmd.setText("");
|
||||
send_cmd(cmd);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
private void print_log(String st) {
|
||||
log_view.append(st);
|
||||
//Log.i(CONST.TAG, st);
|
||||
|
||||
log_view.post(new Runnable() {
|
||||
public void run() {
|
||||
log_scroll_view.fullScroll(View.FOCUS_DOWN);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private Handler ui_handler = new Handler() {
|
||||
@Override
|
||||
public void handleMessage(Message m) {
|
||||
if (m.what == CONST.MSG_TYPE.STR_INFO.ordinal() ||
|
||||
m.what == CONST.MSG_TYPE.STR_ERROR.ordinal())
|
||||
{
|
||||
print_log((String)m.obj);
|
||||
} else if (m.what == CONST.MSG_TYPE.QUIT.ordinal()) {
|
||||
finish();
|
||||
System.gc();
|
||||
android.os.Process.killProcess(android.os.Process.myPid());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private void hide_soft_keyboard() {
|
||||
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
|
||||
imm.hideSoftInputFromWindow(input_cmd.getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
|
||||
}
|
||||
|
||||
private void init_view() {
|
||||
Button send_cmd_button = (Button)findViewById(R.id.send_cmd_button);
|
||||
send_cmd_button.setOnClickListener(on_send_cmd_click);
|
||||
|
||||
Button quit_button = (Button)findViewById(R.id.quit_button);
|
||||
quit_button.setOnClickListener(on_quit_click);
|
||||
|
||||
input_cmd = (EditText)findViewById(R.id.input_cmd);
|
||||
input_cmd.setOnKeyListener(on_input_cmd_key);
|
||||
|
||||
log_view = (TextView)findViewById(R.id.output);
|
||||
log_view.setMovementMethod(new ScrollingMovementMethod());
|
||||
log_view.setText("");
|
||||
|
||||
log_scroll_view = (ScrollView)findViewById(R.id.output_scroller);
|
||||
}
|
||||
|
||||
private int init_stdio_pipes() {
|
||||
int rc = apjloader.init_stdio_pipe();
|
||||
if (rc != 0)
|
||||
return rc;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
private int init_lib() {
|
||||
try {
|
||||
System.loadLibrary(CONST.LIB_FILENAME);
|
||||
} catch (UnsatisfiedLinkError e) {
|
||||
print_log("UnsatisfiedLinkError: " + e.getMessage() + CONST.NEWLINE);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Wait for GDB to init
|
||||
if ((getApplicationInfo().flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
|
||||
try {
|
||||
Thread.sleep(5000);
|
||||
} catch (InterruptedException e) {
|
||||
print_log("InterruptedException: " + e.getMessage() + CONST.NEWLINE);
|
||||
}
|
||||
}
|
||||
|
||||
int rc = init_stdio_pipes();
|
||||
print_log("Stdio pipes inited: " + Integer.toString(rc) + CONST.NEWLINE);
|
||||
|
||||
OutputThread ot = new OutputThread(ui_handler);
|
||||
ot.start();
|
||||
|
||||
LoaderThread lt = new LoaderThread(ui_handler);
|
||||
lt.start();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
private void send_cmd(String cmd) {
|
||||
hide_soft_keyboard();
|
||||
if (cmd == "")
|
||||
return;
|
||||
|
||||
print_log("Sending command: " + cmd + CONST.NEWLINE);
|
||||
apjloader.write_to_stdin(cmd);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue