Bug 567945 Import of sutagent code for Android

This commit is contained in:
Clint Talbert 2010-06-21 14:26:56 -07:00
parent 7ee47c2f86
commit c1eab73fd3
25 changed files with 5031 additions and 4 deletions

View File

@ -0,0 +1,111 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (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.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Android SUTAgent code.
*
* The Initial Developer of the Original Code is
* Bob Moss.
* Portions created by the Initial Developer are Copyright (C) 2010
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Bob Moss <bmoss@mozilla.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
package com.mozilla.SUTAgentAndroid.service;
import java.net.ServerSocket;
import java.util.Timer;
import com.mozilla.SUTAgentAndroid.RunCmdThread;
import com.mozilla.SUTAgentAndroid.RunDataThread;
import android.content.Intent;
// import android.os.Binder;
import android.os.IBinder;
import android.widget.Toast;
public class ASMozStub extends android.app.Service {
private ServerSocket cmdChnl;
private ServerSocket dataChnl;
RunCmdThread runCmdThrd;
RunDataThread runDataThrd;
Timer timer;
// android.app.Service me;
// Binder theBinder = null;
@Override
public IBinder onBind(Intent intent)
{
// String sData = intent.getDataString();
// return theBinder;
return null;
}
@Override
public void onCreate() {
super.onCreate();
// this.me = this;
// theBinder = new Binder();
Toast.makeText(this, "Listener Service created...", Toast.LENGTH_LONG).show();
}
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
try {
cmdChnl = new ServerSocket(20701);
runCmdThrd = new RunCmdThread(cmdChnl);
runCmdThrd.start();
Toast.makeText(this, "Command channel port 20701 ...", Toast.LENGTH_LONG).show();
dataChnl = new ServerSocket(20700);
runDataThrd = new RunDataThread(dataChnl);
runDataThrd.start();
Toast.makeText(this, "Data channel port 20700 ...", Toast.LENGTH_LONG).show();
}
catch (Exception e) {
// Toast.makeText(getApplication().getApplicationContext(), e.toString(), Toast.LENGTH_LONG).show();
}
return;
}
public void onDestroy()
{
super.onDestroy();
if (runCmdThrd.isAlive())
{
runCmdThrd.StopListening();
}
if (runDataThrd.isAlive())
{
runDataThrd.StopListening();
}
Toast.makeText(this, "Listener Service destroyed...", Toast.LENGTH_LONG).show();
}
}

View File

@ -0,0 +1,88 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (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.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Android SUTAgent code.
*
* The Initial Developer of the Original Code is
* Bob Moss.
* Portions created by the Initial Developer are Copyright (C) 2010
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Bob Moss <bmoss@mozilla.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
package com.mozilla.SUTAgentAndroid;
import java.util.Timer;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
class AlertLooperThread extends Thread
{
public Handler mHandler;
private Looper looper = null;
private DoAlert da = null;
private Timer alertTimer = null;
public Timer getAlertTimer()
{
return alertTimer;
}
public void term()
{
if (da != null)
da.term();
}
public void quit()
{
if (looper != null)
looper.quit();
}
public void run()
{
Looper.prepare();
looper = Looper.myLooper();
mHandler = new Handler()
{
public void handleMessage(Message msg)
{
// process incoming messages here
}
};
alertTimer = new Timer();
da = new DoAlert();
alertTimer.scheduleAtFixedRate(da, 0, 5000);
Looper.loop();
}
}

View File

@ -0,0 +1,57 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.mozilla.SUTAgentAndroid"
android:versionCode="1"
android:versionName="1.0" android:sharedUserId="org.mozilla.sharedID">
<application android:icon="@drawable/icon" android:label="@string/app_name" android:debuggable="true">
<activity android:name=".SUTAgentAndroid"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver android:name=".SUTStartupIntentReceiver">
<intent-filter>
<action android:value="android.intent.action.BOOT_COMPLETED" android:name="android.intent.action.BOOT_COMPLETED"/>
<category android:value="android.intent.category.HOME" android:name="android.intent.category.HOME"/>
</intent-filter>
</receiver>
<service android:name=".service.ASMozStub">
<intent-filter>
<action android:name="com.mozilla.SUTAgentAndroid.service.LISTENER_SERVICE" />
</intent-filter>
</service>
</application>
<uses-sdk android:minSdkVersion="5"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"></uses-permission>
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
<uses-permission android:name="android.permission.REBOOT"></uses-permission>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"></uses-permission>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"></uses-permission>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
<uses-permission android:name="android.permission.RESTART_PACKAGES"></uses-permission>
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"></uses-permission>
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"></uses-permission>
<uses-permission android:name="android.permission.CHANGE_CONFIGURATION"></uses-permission>
<uses-permission android:name="android.permission.READ_PHONE_STATE"></uses-permission>
<uses-permission android:name="android.permission.BATTERY_STATS"></uses-permission>
<uses-permission android:name="android.permission.DEVICE_POWER"></uses-permission>
<uses-permission android:name="android.permission.DISABLE_KEYGUARD"></uses-permission>
<uses-permission android:name="android.permission.WAKE_LOCK"></uses-permission>
<uses-permission android:name="android.permission.WRITE_SETTINGS"></uses-permission>
<uses-permission android:name="android.permission.READ_SYNC_SETTINGS"></uses-permission>
<uses-permission android:name="android.permission.BLUETOOTH"></uses-permission>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"></uses-permission>
<uses-permission android:name="android.permission.INSTALL_PACKAGES"></uses-permission>
</manifest>

View File

@ -0,0 +1,221 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (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.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Android SUTAgent code.
*
* The Initial Developer of the Original Code is
* Bob Moss.
* Portions created by the Initial Developer are Copyright (C) 2010
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Bob Moss <bmoss@mozilla.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
package com.mozilla.SUTAgentAndroid;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.SocketTimeoutException;
public class CmdWorkerThread extends Thread
{
private RunCmdThread theParent = null;
private Socket socket = null;
private String prompt = null;
boolean bListening = true;
public CmdWorkerThread(RunCmdThread theParent, Socket workerSocket)
{
super("CmdWorkerThread");
this.theParent = theParent;
this.socket = workerSocket;
byte pr [] = new byte [3];
pr[0] = '$';
pr[1] = '>';
pr[2] = 0;
prompt = new String(pr,0,3);
}
public void StopListening()
{
bListening = false;
}
private String readLine(BufferedInputStream in)
{
String sRet = "";
int nByte = 0;
char cChar = 0;
try
{
nByte = in.read();
while (nByte != -1)
{
cChar = ((char)(nByte & 0xFF));
if ((cChar != '\r') && (cChar != '\n'))
sRet += cChar;
else
break;
nByte = in.read();
}
if ((in.available() > 0) && (cChar != '\n'))
{
in.mark(1024);
nByte = in.read();
if (nByte != -1)
{
cChar = ((char)(nByte & 0xFF));
if (cChar != '\n')
{
in.reset();
}
}
/*
while (nByte != -1)
{
cChar = ((char)(nByte & 0xFF));
if ((cChar == '\r') || (cChar == '\n'))
{
if (in.available() > 0)
{
in.mark(1024);
nByte = in.read();
}
else
nByte = -1;
}
else
{
in.reset();
break;
}
}
*/
}
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
if (sRet.length() == 0)
sRet = null;
return(sRet);
}
public void run()
{
try {
while(bListening)
{
OutputStream cmdOut = socket.getOutputStream();
InputStream cmdIn = socket.getInputStream();
PrintWriter out = new PrintWriter(cmdOut, true);
BufferedInputStream in = new BufferedInputStream(cmdIn);
String inputLine, outputLine;
DoCommand dc = new DoCommand();
int nAvail = cmdIn.available();
cmdIn.skip(nAvail);
out.print(prompt);
out.flush();
while (bListening)
{
if (!(in.available() > 0))
{
socket.setSoTimeout(500);
try {
int nRead = cmdIn.read();
if (nRead == -1)
{
bListening = false;
continue;
}
else
{
inputLine = ((char)nRead) + "";
socket.setSoTimeout(120000);
}
}
catch(SocketTimeoutException toe)
{
continue;
}
}
else
inputLine = "";
if ((inputLine += readLine(in)) != null)
{
outputLine = dc.processCommand(inputLine, out, in, cmdOut);
if (outputLine.length() > 0)
{
out.print(outputLine + "\n" + prompt);
}
else
out.print(prompt);
out.flush();
if (outputLine.equals("exit"))
{
theParent.StopListening();
bListening = false;
}
if (outputLine.equals("quit"))
{
bListening = false;
}
outputLine = null;
System.gc();
}
else
break;
}
out.close();
out = null;
in.close();
in = null;
socket.close();
}
}
catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}

View File

@ -0,0 +1,202 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (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.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Android SUTAgent code.
*
* The Initial Developer of the Original Code is
* Bob Moss.
* Portions created by the Initial Developer are Copyright (C) 2010
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Bob Moss <bmoss@mozilla.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
package com.mozilla.SUTAgentAndroid;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.SocketTimeoutException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
public class DataWorkerThread extends Thread
{
private RunDataThread theParent = null;
private Socket socket = null;
boolean bListening = true;
public DataWorkerThread(RunDataThread theParent, Socket workerSocket)
{
super("DataWorkerThread");
this.theParent = theParent;
this.socket = workerSocket;
}
public void StopListening()
{
bListening = false;
}
private String readLine(BufferedInputStream in)
{
String sRet = "";
int nByte = 0;
char cChar = 0;
try
{
nByte = in.read();
while (nByte != -1)
{
cChar = ((char)(nByte & 0xFF));
if ((cChar != '\r') && (cChar != '\n'))
sRet += cChar;
else
break;
nByte = in.read();
}
if (in.available() > 0)
{
in.mark(1024);
nByte = in.read();
while (nByte != -1)
{
cChar = ((char)(nByte & 0xFF));
if ((cChar == '\r') || (cChar == '\n'))
{
if (in.available() > 0)
{
in.mark(1024);
nByte = in.read();
}
else
nByte = -1;
}
else
{
in.reset();
break;
}
}
}
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
if (sRet.length() == 0)
sRet = null;
return(sRet);
}
public void run()
{
String sRet = "";
try {
while(bListening)
{
OutputStream cmdOut = socket.getOutputStream();
InputStream cmdIn = socket.getInputStream();
PrintWriter out = new PrintWriter(cmdOut, true);
BufferedInputStream in = new BufferedInputStream(cmdIn);
String inputLine, outputLine;
DoCommand dc = new DoCommand();
Calendar cal = Calendar.getInstance();
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd-HH:mm:ss");
sRet = sdf.format(cal.getTime());
sRet += " trace output";
out.println(sRet);
out.flush();
int nAvail = cmdIn.available();
cmdIn.skip(nAvail);
((SUTAgentAndroid)SUTAgentAndroid.me).StartHeartBeat(out);
while (bListening)
{
if (!(in.available() > 0))
{
socket.setSoTimeout(500);
try {
int nRead = cmdIn.read();
if (nRead == -1)
{
bListening = false;
continue;
}
else
inputLine = (char)nRead + "";
}
catch(SocketTimeoutException toe)
{
continue;
}
}
else
inputLine = "";
if ((inputLine += readLine(in)) != null)
{
outputLine = dc.processCommand(inputLine, out, in, cmdOut);
out.print(outputLine + "\n");
out.flush();
if (outputLine.equals("exit"))
{
theParent.StopListening();
bListening = false;
}
}
else
break;
}
((SUTAgentAndroid)SUTAgentAndroid.me).StopHeartBeat();
out.close();
in.close();
socket.close();
}
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}

View File

@ -0,0 +1,80 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (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.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Android SUTAgent code.
*
* The Initial Developer of the Original Code is
* Bob Moss.
* Portions created by the Initial Developer are Copyright (C) 2010
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Bob Moss <bmoss@mozilla.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
package com.mozilla.SUTAgentAndroid;
import java.util.TimerTask;
import android.content.Context;
import android.media.Ringtone;
import android.media.RingtoneManager;
import android.widget.Toast;
class DoAlert extends TimerTask
{
int lcv = 0;
Toast toast = null;
Ringtone rt = null;
DoAlert()
{
Context ctx = SUTAgentAndroid.me.getApplication().getApplicationContext();
this.toast = Toast.makeText(ctx, "Help me!", Toast.LENGTH_LONG);
rt = RingtoneManager.getRingtone(ctx, RingtoneManager.getDefaultUri(RingtoneManager.TYPE_ALARM));
}
public void term()
{
if (rt != null)
{
if (rt.isPlaying())
rt.stop();
}
if (toast != null)
toast.cancel();
}
public void run ()
{
String sText =(((lcv++ % 2) == 0) ? "Help me!" : "I've fallen down!" );
toast.setText(sText);
toast.show();
if (rt != null)
rt.play();
}
}

File diff suppressed because it is too large Load Diff

0
build/mobile/sutagent/android/Makefile.in Normal file → Executable file
View File

View File

@ -0,0 +1,102 @@
/*
* Copyright (C) 2007 The Android Open Source Project
*
* 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.
*/
package android.os;
import java.io.IOException;
/**
* Class that provides access to some of the power management functions.
*
* {@hide}
*/
public class Power
{
// can't instantiate this class
private Power()
{
}
/**
* Wake lock that ensures that the CPU is running. The screen might
* not be on.
*/
public static final int PARTIAL_WAKE_LOCK = 1;
/**
* Wake lock that ensures that the screen is on.
*/
public static final int FULL_WAKE_LOCK = 2;
public static native void acquireWakeLock(int lock, String id);
public static native void releaseWakeLock(String id);
/**
* Brightness value for fully off
*/
public static final int BRIGHTNESS_OFF = 0;
/**
* Brightness value for dim backlight
*/
public static final int BRIGHTNESS_DIM = 20;
/**
* Brightness value for fully on
*/
public static final int BRIGHTNESS_ON = 255;
/**
* Brightness value to use when battery is low
*/
public static final int BRIGHTNESS_LOW_BATTERY = 10;
/**
* Threshold for BRIGHTNESS_LOW_BATTERY (percentage)
* Screen will stay dim if battery level is <= LOW_BATTERY_THRESHOLD
*/
public static final int LOW_BATTERY_THRESHOLD = 10;
/**
* Turn the screen on or off
*
* @param on Whether you want the screen on or off
*/
public static native int setScreenState(boolean on);
public static native int setLastUserActivityTimeout(long ms);
/**
* Turn the device off.
*
* This method is considered deprecated in favor of
* {@link android.policy.ShutdownThread.shutdownAfterDisablingRadio()}.
*
* @deprecated
* @hide
*/
@Deprecated
public static native void shutdown();
/**
* Reboot the device.
* @param reason code to pass to the kernel (e.g. "recovery"), or null.
*
* @throws IOException if reboot fails for some reason (eg, lack of
* permission)
*/
public static native void reboot(String reason) throws IOException;
}

View File

@ -0,0 +1,27 @@
/* AUTO-GENERATED FILE. DO NOT MODIFY.
*
* This class was automatically generated by the
* aapt tool from the resource data it found. It
* should not be modified by hand.
*/
package com.mozilla.SUTAgentAndroid;
public final class R {
public static final class attr {
}
public static final class drawable {
public static final int icon=0x7f020000;
}
public static final class id {
public static final int Button01=0x7f050001;
public static final int Textview01=0x7f050000;
}
public static final class layout {
public static final int main=0x7f030000;
}
public static final class string {
public static final int app_name=0x7f040001;
public static final int hello=0x7f040000;
}
}

View File

@ -0,0 +1,166 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (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.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Android SUTAgent code.
*
* The Initial Developer of the Original Code is
* Bob Moss.
* Portions created by the Initial Developer are Copyright (C) 2010
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Bob Moss <bmoss@mozilla.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
package com.mozilla.SUTAgentAndroid;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import android.widget.Toast;
public class RedirOutputThread extends Thread
{
OutputStream out;
InputStream sutErr;
InputStream sutOut;
Process pProc;
String strOutput;
public RedirOutputThread(Process pProc, OutputStream out)
{
if (pProc != null)
{
this.pProc = pProc;
sutErr = pProc.getErrorStream(); // Stderr
sutOut = pProc.getInputStream(); // Stdout
}
if (out != null)
this.out = out;
strOutput = "";
}
public void run()
{
boolean bStillRunning = true;
int nBytesOut = 0;
int nBytesErr = 0;
int nBytesRead = 0;
PrintWriter pOut = null;
byte[] buffer = new byte[1024];
if (out != null)
pOut = new PrintWriter(out);
else
bStillRunning = true;
while (bStillRunning)
{
try
{
if ((nBytesOut = sutOut.available()) > 0)
{
if (nBytesOut > buffer.length)
{
buffer = null;
System.gc();
buffer = new byte[nBytesOut];
}
nBytesRead = sutOut.read(buffer, 0, nBytesOut);
if (nBytesRead == -1)
bStillRunning = false;
else
{
String sRep = new String(buffer,0,nBytesRead).replace("\n", "\r\n");
if (pOut != null)
{
pOut.print(sRep);
pOut.flush();
}
else
strOutput += sRep;
}
}
if ((nBytesErr = sutErr.available()) > 0)
{
if (nBytesErr > buffer.length)
{
buffer = null;
System.gc();
buffer = new byte[nBytesErr];
}
nBytesRead = sutErr.read(buffer, 0, nBytesErr);
if (nBytesRead == -1)
bStillRunning = false;
else
{
String sRep = new String(buffer,0,nBytesRead).replace("\n", "\r\n");
if (pOut != null)
{
pOut.print(sRep);
pOut.flush();
}
else
strOutput += sRep;
}
}
bStillRunning = (IsProcRunning(pProc) || (sutOut.available() > 0) || (sutErr.available() > 0));
}
catch (IOException e)
{
Toast.makeText(SUTAgentAndroid.me.getApplicationContext(), e.getMessage(), Toast.LENGTH_LONG).show();
e.printStackTrace();
}
}
pProc.destroy();
buffer = null;
System.gc();
}
private boolean IsProcRunning(Process pProc)
{
boolean bRet = false;
@SuppressWarnings("unused")
int nExitCode = 0;
try
{
nExitCode = pProc.exitValue();
}
catch (IllegalThreadStateException z)
{
bRet = true;
}
return(bRet);
}
}

View File

@ -0,0 +1,109 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (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.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Android SUTAgent code.
*
* The Initial Developer of the Original Code is
* Bob Moss.
* Portions created by the Initial Developer are Copyright (C) 2010
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Bob Moss <bmoss@mozilla.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
package com.mozilla.SUTAgentAndroid;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketTimeoutException;
import java.util.ArrayList;
import java.util.List;
import android.widget.Toast;
public class RunCmdThread extends Thread
{
private ServerSocket SvrSocket = null;
private Socket socket = null;
boolean bListening = true;
List<CmdWorkerThread> theWorkers = new ArrayList<CmdWorkerThread>();
public RunCmdThread(ServerSocket socket)
{
super("RunCmdThread");
this.SvrSocket = socket;
}
public void StopListening()
{
bListening = false;
}
public void run() {
try {
SvrSocket.setSoTimeout(5000);
while (bListening)
{
try
{
socket = SvrSocket.accept();
CmdWorkerThread theWorker = new CmdWorkerThread(this, socket);
theWorker.start();
theWorkers.add(theWorker);
}
catch (SocketTimeoutException toe)
{
continue;
}
}
int nNumWorkers = theWorkers.size();
for (int lcv = 0; lcv < nNumWorkers; lcv++)
{
if (theWorkers.get(lcv).isAlive())
{
theWorkers.get(lcv).StopListening();
while(theWorkers.get(lcv).isAlive())
;
}
}
theWorkers.clear();
SvrSocket.close();
SUTAgentAndroid.me.finish();
}
catch (IOException e)
{
Toast.makeText(SUTAgentAndroid.me.getApplicationContext(), e.getMessage(), Toast.LENGTH_LONG).show();
e.printStackTrace();
}
return;
}
}

View File

@ -0,0 +1,110 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (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.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Android SUTAgent code.
*
* The Initial Developer of the Original Code is
* Bob Moss.
* Portions created by the Initial Developer are Copyright (C) 2010
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Bob Moss <bmoss@mozilla.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
package com.mozilla.SUTAgentAndroid;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketTimeoutException;
import java.util.ArrayList;
import java.util.List;
import java.util.Timer;
import android.widget.Toast;
public class RunDataThread extends Thread
{
Timer heartBeatTimer;
private ServerSocket SvrSocket = null;
private Socket socket = null;
boolean bListening = true;
List<DataWorkerThread> theWorkers = new ArrayList<DataWorkerThread>();
public RunDataThread(ServerSocket socket)
{
super("RunDataThread");
this.SvrSocket = socket;
}
public void StopListening()
{
bListening = false;
}
public void run() {
try {
SvrSocket.setSoTimeout(5000);
while (bListening)
{
try
{
socket = SvrSocket.accept();
DataWorkerThread theWorker = new DataWorkerThread(this, socket);
theWorker.start();
theWorkers.add(theWorker);
}
catch (SocketTimeoutException toe)
{
continue;
}
}
int nNumWorkers = theWorkers.size();
for (int lcv = 0; lcv < nNumWorkers; lcv++)
{
if (theWorkers.get(lcv).isAlive())
{
theWorkers.get(lcv).StopListening();
while(theWorkers.get(lcv).isAlive())
;
}
}
theWorkers.clear();
SvrSocket.close();
}
catch (IOException e)
{
Toast.makeText(SUTAgentAndroid.me.getApplicationContext(), e.getMessage(), Toast.LENGTH_LONG).show();
e.printStackTrace();
}
return;
}
}

View File

@ -0,0 +1,713 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (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.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Android SUTAgent code.
*
* The Initial Developer of the Original Code is
* Bob Moss.
* Portions created by the Initial Developer are Copyright (C) 2010
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Bob Moss <bmoss@mozilla.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
package com.mozilla.SUTAgentAndroid;
import java.io.File;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Enumeration;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
// import dalvik.system.VMRuntime;
import android.app.Activity;
import android.app.KeyguardManager;
import android.bluetooth.BluetoothAdapter;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.Uri;
import android.net.wifi.SupplicantState;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.net.wifi.WifiManager.WifiLock;
import android.os.BatteryManager;
import android.os.Bundle;
import android.os.PowerManager;
import android.telephony.TelephonyManager;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
public class SUTAgentAndroid extends Activity
{
static final int START_PRG = 1959;
MenuItem mExitMenuItem;
Timer timer = null;
public static SUTAgentAndroid me = null;
public static String sUniqueID = null;
public static String sLocalIPAddr = null;
public static String sACStatus = null;
public static String sPowerStatus = null;
public static int nChargeLevel = 0;
public static int nBatteryTemp = 0;
String lineSep = System.getProperty("line.separator");
public PrintWriter dataOut = null;
private static boolean bNetworkingStarted = false;
private static String RegSvrIPAddr = "";
private static String RegSvrIPPort = "";
private static String HardwareID = "";
private static String Pool = "";
private static String sRegString = "";
private WifiLock wl = null;
private PowerManager.WakeLock pwl = null;
private BroadcastReceiver battReceiver = null;
public boolean onCreateOptionsMenu(Menu menu)
{
mExitMenuItem = menu.add("Exit");
mExitMenuItem.setIcon(android.R.drawable.ic_menu_close_clear_cancel);
return super.onCreateOptionsMenu(menu);
}
public boolean onMenuItemSelected(int featureId, MenuItem item)
{
if (item == mExitMenuItem)
{
finish();
}
return super.onMenuItemSelected(featureId, item);
}
public static String getRegSvrIPAddr()
{
return(RegSvrIPAddr);
}
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// long lHeapSize = VMRuntime.getRuntime().getMinimumHeapSize();
// lHeapSize = 16000000;
// VMRuntime.getRuntime().setMinimumHeapSize(lHeapSize);
// Keep phone from locking or remove lock on screen
KeyguardManager km = (KeyguardManager)getSystemService(Context.KEYGUARD_SERVICE);
if (km != null)
{
KeyguardManager.KeyguardLock kl = km.newKeyguardLock("SUTAgent");
if (kl != null)
kl.disableKeyguard();
}
// No sleeping on the job
PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
if (pm != null)
{
pwl = pm.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK, "SUTAgent");
if (pwl != null)
pwl.acquire();
}
DoCommand dc = new DoCommand();
// Get configuration settings from "ini" file
File dir = getFilesDir();
File iniFile = new File(dir, "SUTAgent.ini");
String sIniFile = iniFile.getAbsolutePath();
SUTAgentAndroid.RegSvrIPAddr = dc.GetIniData("Registration Server", "IPAddr", sIniFile);
SUTAgentAndroid.RegSvrIPPort = dc.GetIniData("Registration Server", "PORT", sIniFile);
SUTAgentAndroid.HardwareID = dc.GetIniData("Registration Server", "HARDWARE", sIniFile);
SUTAgentAndroid.Pool = dc.GetIniData("Registration Server", "POOL", sIniFile);
TextView tv = (TextView) this.findViewById(R.id.Textview01);
if (getLocalIpAddress() == null)
setUpNetwork();
me = this;
WifiInfo wifi;
WifiManager wifiMan = (WifiManager)getSystemService(Context.WIFI_SERVICE);
String macAddress = "Unknown";
if (wifiMan != null)
{
wifi = wifiMan.getConnectionInfo();
if (wifi != null)
{
macAddress = wifi.getMacAddress();
if (macAddress != null)
sUniqueID = macAddress;
}
}
if (sUniqueID == null)
{
BluetoothAdapter ba = BluetoothAdapter.getDefaultAdapter();
if (ba.isEnabled() != true)
{
ba.enable();
while(ba.getState() != BluetoothAdapter.STATE_ON)
{
try {
Thread.sleep(1000);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
sUniqueID = ba.getAddress();
ba.disable();
while(ba.getState() != BluetoothAdapter.STATE_OFF)
{
try {
Thread.sleep(1000);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
else
sUniqueID = ba.getAddress();
}
if (sUniqueID == null)
{
TelephonyManager mTelephonyMgr = (TelephonyManager)getSystemService(TELEPHONY_SERVICE);
if (mTelephonyMgr != null)
{
sUniqueID = mTelephonyMgr.getDeviceId();
if (sUniqueID == null)
{
sUniqueID = "0011223344556677";
}
}
}
sLocalIPAddr = getLocalIpAddress();
Toast.makeText(getApplication().getApplicationContext(), "SUTAgent [" + sLocalIPAddr + "] ...", Toast.LENGTH_LONG).show();
String sConfig = "Unique ID: " + sUniqueID + lineSep;
sConfig += "OS Info" + lineSep;
sConfig += "\t" + dc.GetOSInfo() + lineSep;
sConfig += "Screen Info" + lineSep;
int [] xy = dc.GetScreenXY();
sConfig += "\t Width: " + xy[0] + lineSep;
sConfig += "\t Height: " + xy[1] + lineSep;
sConfig += "Memory Info" + lineSep;
sConfig += "\t" + dc.GetMemoryInfo() + lineSep;
sConfig += "Network Info" + lineSep;
sConfig += "\tMac Address: " + macAddress + lineSep;
sConfig += "\tIP Address: " + sLocalIPAddr + lineSep;
sRegString = "NAME=" + sUniqueID;
sRegString += "&IPADDR=" + sLocalIPAddr;
sRegString += "&CMDPORT=" + 20701;
sRegString += "&DATAPORT=" + 20700;
sRegString += "&OS=Android-" + dc.GetOSInfo();
sRegString += "&SCRNWIDTH=" + xy[0];
sRegString += "&SCRNHEIGHT=" + xy[1];
sRegString += "&BPP=8";
sRegString += "&MEMORY=" + dc.GetMemoryConfig();
sRegString += "&HARDWARE=" + HardwareID;
sRegString += "&POOL=" + Pool;
String sTemp = Uri.encode(sRegString,"=&");
sRegString = "register " + sTemp;
if (!bNetworkingStarted)
{
ToDoListening(1,300,dc);
bNetworkingStarted = true;
String sRegRet = "";
if (RegSvrIPAddr.length() > 0)
{
sRegRet = dc.RegisterTheDevice(RegSvrIPAddr, RegSvrIPPort, sRegString);
if (sRegRet.contains("\"ok\": true"))
{
sConfig += "Registered with testserver" + lineSep;
sConfig += "\tIPAddress: " + RegSvrIPAddr + lineSep;
if (RegSvrIPPort.length() > 0)
sConfig += "\tPort: " + RegSvrIPPort + lineSep;
}
else
sConfig += "Not registered with testserver" + lineSep;
}
else
sConfig += "Not registered with testserver" + lineSep;
}
tv.setText(sConfig);
monitorBatteryState();
final Button goButton = (Button) findViewById(R.id.Button01);
goButton.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
finish();
}
});
}
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
if (requestCode == START_PRG)
{
Toast.makeText(getApplication().getApplicationContext(), "SUTAgent startprg finished ...", Toast.LENGTH_LONG).show();
}
}
@Override
public void onDestroy()
{
super.onDestroy();
if (isFinishing())
{
StopHeartBeat();
Intent listenerSvc = new Intent();
listenerSvc.setAction("com.mozilla.SUTAgentAndroid.service.LISTENER_SERVICE");
stopService(listenerSvc);
bNetworkingStarted = false;
unregisterReceiver(battReceiver);
KeyguardManager km = (KeyguardManager)getSystemService(Context.KEYGUARD_SERVICE);
if (km != null)
{
KeyguardManager.KeyguardLock kl = km.newKeyguardLock("SUTAgent");
if (kl != null)
kl.reenableKeyguard();
}
// TextView tv = (TextView) this.findViewById(R.id.Textview01);
// if (tv != null)
// tv.setKeepScreenOn(false);
if (pwl != null)
pwl.release();
if (wl != null)
wl.release();
System.exit(0);
}
}
private void monitorBatteryState()
{
battReceiver = new BroadcastReceiver()
{
public void onReceive(Context context, Intent intent)
{
StringBuilder sb = new StringBuilder();
int rawlevel = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1); // charge level from 0 to scale inclusive
int scale = intent.getIntExtra(BatteryManager.EXTRA_SCALE, -1); // Max value for charge level
int status = intent.getIntExtra(BatteryManager.EXTRA_STATUS, -1);
int health = intent.getIntExtra(BatteryManager.EXTRA_HEALTH, -1);
boolean present = intent.getBooleanExtra(BatteryManager.EXTRA_PRESENT, false);
int plugged = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1); //0 if the device is not plugged in; 1 if plugged into an AC power adapter; 2 if plugged in via USB.
// int voltage = intent.getIntExtra(BatteryManager.EXTRA_VOLTAGE, -1); // voltage in millivolts
nBatteryTemp = intent.getIntExtra(BatteryManager.EXTRA_TEMPERATURE, -1); // current battery temperature in tenths of a degree Centigrade
// String technology = intent.getStringExtra(BatteryManager.EXTRA_TECHNOLOGY);
nChargeLevel = -1; // percentage, or -1 for unknown
if (rawlevel >= 0 && scale > 0)
{
nChargeLevel = (rawlevel * 100) / scale;
}
if (plugged > 0)
sACStatus = "ONLINE";
else
sACStatus = "OFFLINE";
if (present == false)
sb.append("NO BATTERY");
else
{
if (nChargeLevel < 10)
sb.append("Critical");
else if (nChargeLevel < 33)
sb.append("LOW");
else if (nChargeLevel > 80)
sb.append("HIGH");
}
if (BatteryManager.BATTERY_HEALTH_OVERHEAT == health)
{
sb.append("Overheated ");
sb.append((((float)(nBatteryTemp))/10));
sb.append("(°C)");
}
else
{
switch(status)
{
case BatteryManager.BATTERY_STATUS_UNKNOWN:
// old emulator; maybe also when plugged in with no battery
if (present == true)
sb.append(" UNKNOWN");
break;
case BatteryManager.BATTERY_STATUS_CHARGING:
sb.append(" CHARGING");
break;
case BatteryManager.BATTERY_STATUS_DISCHARGING:
sb.append(" DISCHARGING");
break;
case BatteryManager.BATTERY_STATUS_NOT_CHARGING:
sb.append(" NOTCHARGING");
break;
case BatteryManager.BATTERY_STATUS_FULL:
sb.append(" FULL");
break;
default:
if (present == true)
sb.append("Unknown");
break;
}
}
sPowerStatus = sb.toString();
}
};
IntentFilter battFilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
registerReceiver(battReceiver, battFilter);
}
public boolean setUpNetwork()
{
boolean bRet = false;
int lcv = 0;
int lcv2 = 0;
WifiManager wifi = (WifiManager) getSystemService(Context.WIFI_SERVICE);
WifiConfiguration wc = new WifiConfiguration();
Toast.makeText(getApplication().getApplicationContext(), "Starting and configuring network", Toast.LENGTH_LONG).show();
/*
ContentResolver cr = getContentResolver();
int nRet;
try {
nRet = Settings.System.getInt(cr, Settings.System.WIFI_USE_STATIC_IP);
String foo2 = "" + nRet;
} catch (SettingNotFoundException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
*/
/*
wc.SSID = "\"Mozilla-Build\"";
wc.preSharedKey = "\"MozillaBuildQA500\"";
wc.hiddenSSID = true;
wc.status = WifiConfiguration.Status.ENABLED;
wc.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);
wc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
wc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
wc.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
wc.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
wc.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
wc.allowedProtocols.set(WifiConfiguration.Protocol.RSN);
*/
wc.SSID = "\"Mozilla-G\"";
// wc.SSID = "\"Mozilla\"";
wc.preSharedKey = null;
wc.hiddenSSID = false;
wc.status = WifiConfiguration.Status.ENABLED;
wc.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_EAP);
wc.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.IEEE8021X);
wc.allowedProtocols.set(WifiConfiguration.Protocol.RSN);
// wc.allowedProtocols.set(WifiConfiguration.Protocol.WPA);
// wc.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
wc.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
// wc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
wc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
// wc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP104);
// wc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40);
wc.eap.setValue("PEAP");
wc.password.setValue("\"password\"");
wc.identity.setValue("\"bmoss@mozilla.com\"");
if (!wifi.isWifiEnabled())
wifi.setWifiEnabled(true);
while(wifi.getWifiState() != WifiManager.WIFI_STATE_ENABLED)
{
Thread.yield();
if (++lcv > 10000)
return(bRet);
}
wl = wifi.createWifiLock(WifiManager.WIFI_MODE_FULL, "SUTAgent");
if (wl != null)
wl.acquire();
WifiConfiguration foo = null;
int nNetworkID = -1;
List<WifiConfiguration> connsLst = wifi.getConfiguredNetworks();
int nConns = connsLst.size();
for (int i = 0; i < nConns; i++)
{
foo = connsLst.get(i);
if (foo.SSID.equalsIgnoreCase(wc.SSID))
{
nNetworkID = foo.networkId;
wc.networkId = foo.networkId;
break;
}
}
int res;
if (nNetworkID != -1)
{
res = wifi.updateNetwork(wc);
}
else
{
res = wifi.addNetwork(wc);
}
Log.d("WifiPreference", "add Network returned " + res );
boolean b = wifi.enableNetwork(res, true);
Log.d("WifiPreference", "enableNetwork returned " + b );
wifi.saveConfiguration();
WifiInfo wi = wifi.getConnectionInfo();
SupplicantState ss = wi.getSupplicantState();
lcv = 0;
lcv2 = 0;
while (ss.compareTo(SupplicantState.COMPLETED) != 0)
{
try {
Thread.sleep(1000);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
if (wi != null)
wi = null;
if (ss != null)
ss = null;
wi = wifi.getConnectionInfo();
ss = wi.getSupplicantState();
if (++lcv > 60)
{
if (++lcv2 > 5)
{
Toast.makeText(getApplication().getApplicationContext(), "Unable to start and configure network", Toast.LENGTH_LONG).show();
return(bRet);
}
else
{
Toast.makeText(getApplication().getApplicationContext(), "Resetting wifi interface", Toast.LENGTH_LONG).show();
if (wl != null)
wl.release();
wifi.setWifiEnabled(false);
while(wifi.getWifiState() != WifiManager.WIFI_STATE_DISABLED)
{
Thread.yield();
}
wifi.setWifiEnabled(true);
while(wifi.getWifiState() != WifiManager.WIFI_STATE_ENABLED)
{
Thread.yield();
}
b = wifi.enableNetwork(res, true);
Log.d("WifiPreference", "enableNetwork returned " + b );
if (wl != null)
wl.acquire();
lcv = 0;
}
}
}
lcv = 0;
while(getLocalIpAddress() == null)
{
if (++lcv > 10000)
return(bRet);
}
Toast.makeText(getApplication().getApplicationContext(), "Network started and configured", Toast.LENGTH_LONG).show();
bRet = true;
return(bRet);
}
class ToDoListener extends TimerTask
{
boolean bFirstRun = true;
DoCommand dc = null;
ToDoListener(DoCommand dc)
{
this.dc = dc;
}
public void run ()
{
if (bFirstRun == true)
{
Intent listenerService = new Intent();
listenerService.setAction("com.mozilla.SUTAgentAndroid.service.LISTENER_SERVICE");
startService(listenerService);
bFirstRun = false;
}
else
{
if (dc != null)
{
String sRet = this.dc.SendPing("www.mozilla.org", null);
if (sRet.contains("3 received"))
this.dc.StopAlert();
else
this.dc.StartAlert();
sRet = null;
System.gc();
}
}
}
}
public void ToDoListening(int delay, int interval, DoCommand dc)
{
if (timer == null)
timer = new Timer();
timer.scheduleAtFixedRate(new ToDoListener(dc), delay * 1000, interval * 1000);
// timer.schedule(new ToDoListener(dc), delay * 1000);
}
class DoHeartBeat extends TimerTask
{
PrintWriter out;
DoHeartBeat(PrintWriter out)
{
this.out = out;
}
public void run ()
{
String sRet = "";
Calendar cal = Calendar.getInstance();
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd-HH:mm:ss");
sRet = sdf.format(cal.getTime());
sRet += " Thump thump - " + sUniqueID + "\r\n";
out.write(sRet);
out.flush();
}
}
public void StartHeartBeat(PrintWriter out)
{
// start the heartbeat
this.dataOut = out;
if (timer == null)
timer = new Timer();
timer.scheduleAtFixedRate(new DoHeartBeat(dataOut), 0, 60000);
}
public void StopHeartBeat()
{
// stop the heartbeat
this.dataOut = null;
if (timer != null)
{
timer.cancel();
timer.purge();
timer = null;
System.gc();
}
}
public String getLocalIpAddress()
{
try
{
for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements();)
{
NetworkInterface intf = en.nextElement();
for (Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements();)
{
InetAddress inetAddress = enumIpAddr.nextElement();
if (!inetAddress.isLoopbackAddress())
{
return inetAddress.getHostAddress().toString();
}
}
}
}
catch (SocketException ex)
{
Toast.makeText(getApplication().getApplicationContext(), ex.toString(), Toast.LENGTH_LONG).show();
}
return null;
}
}

View File

@ -0,0 +1,53 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (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.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Android SUTAgent code.
*
* The Initial Developer of the Original Code is
* Bob Moss.
* Portions created by the Initial Developer are Copyright (C) 2010
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Bob Moss <bmoss@mozilla.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
package com.mozilla.SUTAgentAndroid;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
public class SUTStartupIntentReceiver extends BroadcastReceiver
{
@Override
public void onReceive(Context context, Intent intent)
{
Intent mySUTAgentIntent = new Intent(context, SUTAgentAndroid.class);
mySUTAgentIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(mySUTAgentIntent);
}
}

View File

@ -0,0 +1,480 @@
/*
* Copyright (C) 2008 The Android Open Source Project
*
* 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.
*/
package android.net.wifi;
import android.os.Parcelable;
import android.os.Parcel;
import java.util.BitSet;
/**
* A class representing a configured Wi-Fi network, including the
* security configuration. Android will not necessarily support
* all of these security schemes initially.
*/
public class WifiConfiguration implements Parcelable {
/** {@hide} */
public static final String ssidVarName = "ssid";
/** {@hide} */
public static final String bssidVarName = "bssid";
/** {@hide} */
public static final String pskVarName = "psk";
/** {@hide} */
public static final String[] wepKeyVarNames = { "wep_key0", "wep_key1", "wep_key2", "wep_key3" };
/** {@hide} */
public static final String wepTxKeyIdxVarName = "wep_tx_keyidx";
/** {@hide} */
public static final String priorityVarName = "priority";
/** {@hide} */
public static final String hiddenSSIDVarName = "scan_ssid";
public class EnterpriseField {
private String varName;
private String value;
private EnterpriseField(String varName) {
this.varName = varName;
this.value = null;
}
public void setValue(String value) {
this.value = value;
}
public String varName() {
return varName;
}
public String value() {
return value;
}
}
public EnterpriseField eap = new EnterpriseField("eap");
public EnterpriseField phase2 = new EnterpriseField("phase2");
public EnterpriseField identity = new EnterpriseField("identity");
public EnterpriseField anonymous_identity = new EnterpriseField("anonymous_identity");
public EnterpriseField password = new EnterpriseField("password");
public EnterpriseField client_cert = new EnterpriseField("client_cert");
public EnterpriseField private_key = new EnterpriseField("private_key");
public EnterpriseField ca_cert = new EnterpriseField("ca_cert");
public EnterpriseField[] enterpriseFields = {
eap, phase2, identity, anonymous_identity, password, client_cert,
private_key, ca_cert };
/**
* Recognized key management schemes.
*/
public static class KeyMgmt {
private KeyMgmt() { }
/** WPA is not used; plaintext or static WEP could be used. */
public static final int NONE = 0;
/** WPA pre-shared key (requires {@code preSharedKey} to be specified). */
public static final int WPA_PSK = 1;
/** WPA using EAP authentication. Generally used with an external authentication server. */
public static final int WPA_EAP = 2;
/** IEEE 802.1X using EAP authentication and (optionally) dynamically
* generated WEP keys. */
public static final int IEEE8021X = 3;
public static final String varName = "key_mgmt";
public static final String[] strings = { "NONE", "WPA_PSK", "WPA_EAP", "IEEE8021X" };
}
/**
* Recognized security protocols.
*/
public static class Protocol {
private Protocol() { }
/** WPA/IEEE 802.11i/D3.0 */
public static final int WPA = 0;
/** WPA2/IEEE 802.11i */
public static final int RSN = 1;
public static final String varName = "proto";
public static final String[] strings = { "WPA", "RSN" };
}
/**
* Recognized IEEE 802.11 authentication algorithms.
*/
public static class AuthAlgorithm {
private AuthAlgorithm() { }
/** Open System authentication (required for WPA/WPA2) */
public static final int OPEN = 0;
/** Shared Key authentication (requires static WEP keys) */
public static final int SHARED = 1;
/** LEAP/Network EAP (only used with LEAP) */
public static final int LEAP = 2;
public static final String varName = "auth_alg";
public static final String[] strings = { "OPEN", "SHARED", "LEAP" };
}
/**
* Recognized pairwise ciphers for WPA.
*/
public static class PairwiseCipher {
private PairwiseCipher() { }
/** Use only Group keys (deprecated) */
public static final int NONE = 0;
/** Temporal Key Integrity Protocol [IEEE 802.11i/D7.0] */
public static final int TKIP = 1;
/** AES in Counter mode with CBC-MAC [RFC 3610, IEEE 802.11i/D7.0] */
public static final int CCMP = 2;
public static final String varName = "pairwise";
public static final String[] strings = { "NONE", "TKIP", "CCMP" };
}
/**
* Recognized group ciphers.
* <pre>
* CCMP = AES in Counter mode with CBC-MAC [RFC 3610, IEEE 802.11i/D7.0]
* TKIP = Temporal Key Integrity Protocol [IEEE 802.11i/D7.0]
* WEP104 = WEP (Wired Equivalent Privacy) with 104-bit key
* WEP40 = WEP (Wired Equivalent Privacy) with 40-bit key (original 802.11)
* </pre>
*/
public static class GroupCipher {
private GroupCipher() { }
/** WEP40 = WEP (Wired Equivalent Privacy) with 40-bit key (original 802.11) */
public static final int WEP40 = 0;
/** WEP104 = WEP (Wired Equivalent Privacy) with 104-bit key */
public static final int WEP104 = 1;
/** Temporal Key Integrity Protocol [IEEE 802.11i/D7.0] */
public static final int TKIP = 2;
/** AES in Counter mode with CBC-MAC [RFC 3610, IEEE 802.11i/D7.0] */
public static final int CCMP = 3;
public static final String varName = "group";
public static final String[] strings = { "WEP40", "WEP104", "TKIP", "CCMP" };
}
/** Possible status of a network configuration. */
public static class Status {
private Status() { }
/** this is the network we are currently connected to */
public static final int CURRENT = 0;
/** supplicant will not attempt to use this network */
public static final int DISABLED = 1;
/** supplicant will consider this network available for association */
public static final int ENABLED = 2;
public static final String[] strings = { "current", "disabled", "enabled" };
}
/**
* The ID number that the supplicant uses to identify this
* network configuration entry. This must be passed as an argument
* to most calls into the supplicant.
*/
public int networkId;
/**
* The current status of this network configuration entry.
* @see Status
*/
public int status;
/**
* The network's SSID. Can either be an ASCII string,
* which must be enclosed in double quotation marks
* (e.g., {@code &quot;MyNetwork&quot;}, or a string of
* hex digits,which are not enclosed in quotes
* (e.g., {@code 01a243f405}).
*/
public String SSID;
/**
* When set, this network configuration entry should only be used when
* associating with the AP having the specified BSSID. The value is
* a string in the format of an Ethernet MAC address, e.g.,
* <code>XX:XX:XX:XX:XX:XX</code> where each <code>X</code> is a hex digit.
*/
public String BSSID;
/**
* Pre-shared key for use with WPA-PSK.
* <p/>
* When the value of this key is read, the actual key is
* not returned, just a "*" if the key has a value, or the null
* string otherwise.
*/
public String preSharedKey;
/**
* Up to four WEP keys. Either an ASCII string enclosed in double
* quotation marks (e.g., {@code &quot;abcdef&quot;} or a string
* of hex digits (e.g., {@code 0102030405}).
* <p/>
* When the value of one of these keys is read, the actual key is
* not returned, just a "*" if the key has a value, or the null
* string otherwise.
*/
public String[] wepKeys;
/** Default WEP key index, ranging from 0 to 3. */
public int wepTxKeyIndex;
/**
* Priority determines the preference given to a network by {@code wpa_supplicant}
* when choosing an access point with which to associate.
*/
public int priority;
/**
* This is a network that does not broadcast its SSID, so an
* SSID-specific probe request must be used for scans.
*/
public boolean hiddenSSID;
/**
* The set of key management protocols supported by this configuration.
* See {@link KeyMgmt} for descriptions of the values.
* Defaults to WPA-PSK WPA-EAP.
*/
public BitSet allowedKeyManagement;
/**
* The set of security protocols supported by this configuration.
* See {@link Protocol} for descriptions of the values.
* Defaults to WPA RSN.
*/
public BitSet allowedProtocols;
/**
* The set of authentication protocols supported by this configuration.
* See {@link AuthAlgorithm} for descriptions of the values.
* Defaults to automatic selection.
*/
public BitSet allowedAuthAlgorithms;
/**
* The set of pairwise ciphers for WPA supported by this configuration.
* See {@link PairwiseCipher} for descriptions of the values.
* Defaults to CCMP TKIP.
*/
public BitSet allowedPairwiseCiphers;
/**
* The set of group ciphers supported by this configuration.
* See {@link GroupCipher} for descriptions of the values.
* Defaults to CCMP TKIP WEP104 WEP40.
*/
public BitSet allowedGroupCiphers;
public WifiConfiguration() {
networkId = -1;
SSID = null;
BSSID = null;
priority = 0;
hiddenSSID = false;
allowedKeyManagement = new BitSet();
allowedProtocols = new BitSet();
allowedAuthAlgorithms = new BitSet();
allowedPairwiseCiphers = new BitSet();
allowedGroupCiphers = new BitSet();
wepKeys = new String[4];
for (int i = 0; i < wepKeys.length; i++)
wepKeys[i] = null;
for (EnterpriseField field : enterpriseFields) {
field.setValue(null);
}
}
public String toString() {
StringBuffer sbuf = new StringBuffer();
if (this.status == WifiConfiguration.Status.CURRENT) {
sbuf.append("* ");
} else if (this.status == WifiConfiguration.Status.DISABLED) {
sbuf.append("- ");
}
sbuf.append("ID: ").append(this.networkId).append(" SSID: ").append(this.SSID).
append(" BSSID: ").append(this.BSSID).append(" PRIO: ").append(this.priority).
append('\n');
sbuf.append(" KeyMgmt:");
for (int k = 0; k < this.allowedKeyManagement.size(); k++) {
if (this.allowedKeyManagement.get(k)) {
sbuf.append(" ");
if (k < KeyMgmt.strings.length) {
sbuf.append(KeyMgmt.strings[k]);
} else {
sbuf.append("??");
}
}
}
sbuf.append(" Protocols:");
for (int p = 0; p < this.allowedProtocols.size(); p++) {
if (this.allowedProtocols.get(p)) {
sbuf.append(" ");
if (p < Protocol.strings.length) {
sbuf.append(Protocol.strings[p]);
} else {
sbuf.append("??");
}
}
}
sbuf.append('\n');
sbuf.append(" AuthAlgorithms:");
for (int a = 0; a < this.allowedAuthAlgorithms.size(); a++) {
if (this.allowedAuthAlgorithms.get(a)) {
sbuf.append(" ");
if (a < AuthAlgorithm.strings.length) {
sbuf.append(AuthAlgorithm.strings[a]);
} else {
sbuf.append("??");
}
}
}
sbuf.append('\n');
sbuf.append(" PairwiseCiphers:");
for (int pc = 0; pc < this.allowedPairwiseCiphers.size(); pc++) {
if (this.allowedPairwiseCiphers.get(pc)) {
sbuf.append(" ");
if (pc < PairwiseCipher.strings.length) {
sbuf.append(PairwiseCipher.strings[pc]);
} else {
sbuf.append("??");
}
}
}
sbuf.append('\n');
sbuf.append(" GroupCiphers:");
for (int gc = 0; gc < this.allowedGroupCiphers.size(); gc++) {
if (this.allowedGroupCiphers.get(gc)) {
sbuf.append(" ");
if (gc < GroupCipher.strings.length) {
sbuf.append(GroupCipher.strings[gc]);
} else {
sbuf.append("??");
}
}
}
sbuf.append('\n').append(" PSK: ");
if (this.preSharedKey != null) {
sbuf.append('*');
}
for (EnterpriseField field : enterpriseFields) {
sbuf.append('\n').append(" " + field.varName() + ": ");
String value = field.value();
if (value != null) sbuf.append(value);
}
sbuf.append('\n');
return sbuf.toString();
}
/**
* Construct a WifiConfiguration from a scanned network
* @param scannedAP the scan result used to construct the config entry
* TODO: figure out whether this is a useful way to construct a new entry.
*
public WifiConfiguration(ScanResult scannedAP) {
networkId = -1;
SSID = scannedAP.SSID;
BSSID = scannedAP.BSSID;
}
*/
private static BitSet readBitSet(Parcel src) {
int cardinality = src.readInt();
BitSet set = new BitSet();
for (int i = 0; i < cardinality; i++)
set.set(src.readInt());
return set;
}
private static void writeBitSet(Parcel dest, BitSet set) {
int nextSetBit = -1;
dest.writeInt(set.cardinality());
while ((nextSetBit = set.nextSetBit(nextSetBit + 1)) != -1)
dest.writeInt(nextSetBit);
}
/** Implement the Parcelable interface {@hide} */
public int describeContents() {
return 0;
}
/** Implement the Parcelable interface {@hide} */
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(networkId);
dest.writeInt(status);
dest.writeString(SSID);
dest.writeString(BSSID);
dest.writeString(preSharedKey);
for (String wepKey : wepKeys)
dest.writeString(wepKey);
dest.writeInt(wepTxKeyIndex);
dest.writeInt(priority);
dest.writeInt(hiddenSSID ? 1 : 0);
writeBitSet(dest, allowedKeyManagement);
writeBitSet(dest, allowedProtocols);
writeBitSet(dest, allowedAuthAlgorithms);
writeBitSet(dest, allowedPairwiseCiphers);
writeBitSet(dest, allowedGroupCiphers);
for (EnterpriseField field : enterpriseFields) {
dest.writeString(field.value());
}
}
/** Implement the Parcelable interface {@hide} */
public static final Creator<WifiConfiguration> CREATOR =
new Creator<WifiConfiguration>() {
public WifiConfiguration createFromParcel(Parcel in) {
WifiConfiguration config = new WifiConfiguration();
config.networkId = in.readInt();
config.status = in.readInt();
config.SSID = in.readString();
config.BSSID = in.readString();
config.preSharedKey = in.readString();
for (int i = 0; i < config.wepKeys.length; i++)
config.wepKeys[i] = in.readString();
config.wepTxKeyIndex = in.readInt();
config.priority = in.readInt();
config.hiddenSSID = in.readInt() != 0;
config.allowedKeyManagement = readBitSet(in);
config.allowedProtocols = readBitSet(in);
config.allowedAuthAlgorithms = readBitSet(in);
config.allowedPairwiseCiphers = readBitSet(in);
config.allowedGroupCiphers = readBitSet(in);
for (EnterpriseField field : config.enterpriseFields) {
field.setValue(in.readString());
}
return config;
}
public WifiConfiguration[] newArray(int size) {
return new WifiConfiguration[size];
}
};
}

View File

@ -0,0 +1,13 @@
# 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.
# Indicates whether an apk should be generated for each density.
split.density=false
# Project target.
target=android-5

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

View File

@ -0,0 +1,17 @@
<?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"
>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="@+id/Textview01"/>
<Button android:id="@+id/Button01" android:layout_width="wrap_content" android:layout_height="wrap_content" android:clickable="true" android:text="Exit"></Button>
</LinearLayout>

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="hello">Hello World, SUTAgentAndroid!</string>
<string name="app_name">SUTAgentAndroid</string>
</resources>

View File

@ -72,7 +72,3 @@ JAVAC_FLAGS = \
-g \
$(NULL)
# Note that we're going to set up a dependency directly between embed_android.dex and the java files
# Instead of on the .class files, since more than one .class file might be produced per .java file
# The $JAVAFILES_IN are for any optional, interpolated java files that are needed.