Bug 650110 Update SUTAgent in m-c to 1.01, main agent update r=ctalbert

This commit is contained in:
Bob Moss 2011-04-18 11:55:24 -07:00
parent 76a71c68e8
commit 482731d7c2
10 changed files with 2100 additions and 873 deletions

View File

@ -37,15 +37,21 @@
package com.mozilla.SUTAgentAndroid.service;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.ServerSocket;
import java.util.Timer;
import com.mozilla.SUTAgentAndroid.R;
import android.app.Notification;
import android.app.NotificationManager;
import android.content.Context;
import android.content.Intent;
// import android.os.Binder;
import android.os.Handler;
import android.os.IBinder;
import android.util.Log;
import android.view.Gravity;
import android.widget.Toast;
public class ASMozStub extends android.app.Service {
@ -58,7 +64,20 @@ public class ASMozStub extends android.app.Service {
Thread monitor = null;
Timer timer = null;
@Override
@SuppressWarnings("unchecked")
private static final Class[] mStartForegroundSignature = new Class[] {
int.class, Notification.class};
@SuppressWarnings("unchecked")
private static final Class[] mStopForegroundSignature = new Class[] {
boolean.class};
private NotificationManager mNM;
private Method mStartForeground;
private Method mStopForeground;
private Object[] mStartForegroundArgs = new Object[2];
private Object[] mStopForegroundArgs = new Object[1];
@Override
public IBinder onBind(Intent intent)
{
return null;
@ -67,7 +86,18 @@ public class ASMozStub extends android.app.Service {
@Override
public void onCreate() {
super.onCreate();
Toast.makeText(this, "Listener Service created...", Toast.LENGTH_LONG).show();
mNM = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
try {
mStartForeground = getClass().getMethod("startForeground", mStartForegroundSignature);
mStopForeground = getClass().getMethod("stopForeground", mStopForegroundSignature);
}
catch (NoSuchMethodException e) {
// Running on an older platform.
mStartForeground = mStopForeground = null;
}
doToast("Listener Service created...");
}
public void onStart(Intent intent, int startId) {
@ -77,14 +107,18 @@ public class ASMozStub extends android.app.Service {
cmdChnl = new ServerSocket(20701);
runCmdThrd = new RunCmdThread(cmdChnl, this, handler);
runCmdThrd.start();
Toast.makeText(this, "Command channel port 20701 ...", Toast.LENGTH_LONG).show();
doToast("Command channel port 20701 ...");
dataChnl = new ServerSocket(20700);
runDataThrd = new RunDataThread(dataChnl, this);
runDataThrd.start();
Toast.makeText(this, "Data channel port 20700 ...", Toast.LENGTH_LONG).show();
doToast("Data channel port 20700 ...");
Notification notification = new Notification();
startForegroundCompat(R.string.foreground_service_started, notification);
}
catch (Exception e) {
doToast(e.toString());
// Toast.makeText(getApplication().getApplicationContext(), e.toString(), Toast.LENGTH_LONG).show();
}
@ -94,6 +128,7 @@ public class ASMozStub extends android.app.Service {
public void onDestroy()
{
super.onDestroy();
if (runCmdThrd.isAlive())
{
runCmdThrd.StopListening();
@ -107,7 +142,9 @@ public class ASMozStub extends android.app.Service {
NotificationManager notificationManager = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.cancel(1959);
Toast.makeText(this, "Listener Service destroyed...", Toast.LENGTH_LONG).show();
stopForegroundCompat(R.string.foreground_service_started);
doToast("Listener Service destroyed...");
System.exit(0);
}
@ -115,8 +152,64 @@ public class ASMozStub extends android.app.Service {
public void SendToDataChannel(String strToSend)
{
if (runDataThrd.isAlive())
{
runDataThrd.SendToDataChannel(strToSend);
}
}
public void doToast(String sMsg) {
Toast toast = Toast.makeText(this, sMsg, Toast.LENGTH_LONG);
toast.setGravity(Gravity.TOP|Gravity.CENTER_HORIZONTAL, 0, 100);
toast.show();
}
/**
* This is a wrapper around the new startForeground method, using the older
* APIs if it is not available.
*/
void startForegroundCompat(int id, Notification notification) {
// If we have the new startForeground API, then use it.
if (mStartForeground != null) {
mStartForegroundArgs[0] = Integer.valueOf(id);
mStartForegroundArgs[1] = notification;
try {
mStartForeground.invoke(this, mStartForegroundArgs);
} catch (InvocationTargetException e) {
// Should not happen.
Log.w("ScreenOnWidget", "Unable to invoke startForeground", e);
} catch (IllegalAccessException e) {
// Should not happen.
Log.w("ScreenOnWidget", "Unable to invoke startForeground", e);
}
return;
}
// Fall back on the old API.
setForeground(true);
mNM.notify(id, notification);
}
/**
* This is a wrapper around the new stopForeground method, using the older
* APIs if it is not available.
*/
void stopForegroundCompat(int id) {
// If we have the new stopForeground API, then use it.
if (mStopForeground != null) {
mStopForegroundArgs[0] = Boolean.TRUE;
try {
mStopForeground.invoke(this, mStopForegroundArgs);
} catch (InvocationTargetException e) {
// Should not happen.
Log.w("ScreenOnWidget", "Unable to invoke stopForeground", e);
} catch (IllegalAccessException e) {
// Should not happen.
Log.w("ScreenOnWidget", "Unable to invoke stopForeground", e);
}
return;
}
// Fall back on the old API. Note to cancel BEFORE changing the
// foreground state, since we could be killed at that point.
mNM.cancel(id);
setForeground(false);
}
}

View File

@ -1,8 +1,7 @@
<?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">
android:versionCode="1" android:versionName="1.01">
<application android:icon="@drawable/icon" android:label="@string/app_name" android:debuggable="true">
<activity android:name=".SUTAgentAndroid"
android:screenOrientation="nosensor"
@ -23,8 +22,7 @@
<action android:name="com.mozilla.SUTAgentAndroid.service.LISTENER_SERVICE" />
</intent-filter>
</service>
</application>
</application>
<uses-sdk android:minSdkVersion="5" android:targetSdkVersion="8"/>
@ -43,29 +41,17 @@
<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>
<uses-permission android:name="android.permission.STATUS_BAR"></uses-permission>
<uses-permission android:name="android.permission.VIBRATE"></uses-permission>
<uses-permission android:name="android.permission.SET_TIME"></uses-permission>
<uses-permission android:name="android.permission.SET_TIME_ZONE"></uses-permission>
<uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS"></uses-permission>
<uses-permission android:name="android.permission.WRITE_SYNC_SETTINGS"></uses-permission>
</manifest>

File diff suppressed because it is too large Load Diff

View File

@ -51,6 +51,7 @@ JAVAFILES = \
DataWorkerThread.java \
DoAlert.java \
DoCommand.java \
NtpMessage.java \
Power.java \
RedirOutputThread.java \
RunCmdThread.java \

View File

@ -0,0 +1,468 @@
/* ***** BEGIN LICENSE BLOCK *****
* This class represents a NTP message, as specified in RFC 2030. The message
* format is compatible with all versions of NTP and SNTP.
*
* This class does not support the optional authentication protocol, and
* ignores the key ID and message digest fields.
*
* For convenience, this class exposes message values as native Java types, not
* the NTP-specified data formats. For example, timestamps are
* stored as doubles (as opposed to the NTP unsigned 64-bit fixed point
* format).
*
* However, the contructor NtpMessage(byte[]) and the method toByteArray()
* allow the import and export of the raw NTP message format.
*
*
* Usage example
*
* // Send message
* DatagramSocket socket = new DatagramSocket();
* InetAddress address = InetAddress.getByName("ntp.cais.rnp.br");
* byte[] buf = new NtpMessage().toByteArray();
* DatagramPacket packet = new DatagramPacket(buf, buf.length, address, 123);
* socket.send(packet);
*
* // Get response
* socket.receive(packet);
* System.out.println(msg.toString());
*
*
* This code is copyright (c) Adam Buckley 2004
*
* Contributor(s):
* Bob Moss <bmoss@mozilla.com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation; either version 2 of the License, or (at your option)
* any later version. A HTML version of the GNU General Public License can be
* seen at http://www.gnu.org/licenses/gpl.html
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
*
* Comments for member variables are taken from RFC2030 by David Mills,
* University of Delaware.
*
* Number format conversion code in NtpMessage(byte[] array) and toByteArray()
* inspired by http://www.pps.jussieu.fr/~jch/enseignement/reseaux/
* NTPMessage.java which is copyright (c) 2003 by Juliusz Chroboczek
*
* @author Adam Buckley
* ***** END LICENSE BLOCK ***** */
package com.mozilla.SUTAgentAndroid;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
public class NtpMessage
{
/**
* This is a two-bit code warning of an impending leap second to be
* inserted/deleted in the last minute of the current day. It's values
* may be as follows:
*
* Value Meaning
* ----- -------
* 0 no warning
* 1 last minute has 61 seconds
* 2 last minute has 59 seconds)
* 3 alarm condition (clock not synchronized)
*/
public byte leapIndicator = 0;
/**
* This value indicates the NTP/SNTP version number. The version number
* is 3 for Version 3 (IPv4 only) and 4 for Version 4 (IPv4, IPv6 and OSI).
* If necessary to distinguish between IPv4, IPv6 and OSI, the
* encapsulating context must be inspected.
*/
public byte version = 3;
/**
* This value indicates the mode, with values defined as follows:
*
* Mode Meaning
* ---- -------
* 0 reserved
* 1 symmetric active
* 2 symmetric passive
* 3 client
* 4 server
* 5 broadcast
* 6 reserved for NTP control message
* 7 reserved for private use
*
* In unicast and anycast modes, the client sets this field to 3 (client)
* in the request and the server sets it to 4 (server) in the reply. In
* multicast mode, the server sets this field to 5 (broadcast).
*/
public byte mode = 0;
/**
* This value indicates the stratum level of the local clock, with values
* defined as follows:
*
* Stratum Meaning
* ----------------------------------------------
* 0 unspecified or unavailable
* 1 primary reference (e.g., radio clock)
* 2-15 secondary reference (via NTP or SNTP)
* 16-255 reserved
*/
public short stratum = 0;
/**
* This value indicates the maximum interval between successive messages,
* in seconds to the nearest power of two. The values that can appear in
* this field presently range from 4 (16 s) to 14 (16284 s); however, most
* applications use only the sub-range 6 (64 s) to 10 (1024 s).
*/
public byte pollInterval = 0;
/**
* This value indicates the precision of the local clock, in seconds to
* the nearest power of two. The values that normally appear in this field
* range from -6 for mains-frequency clocks to -20 for microsecond clocks
* found in some workstations.
*/
public byte precision = 0;
/**
* This value indicates the total roundtrip delay to the primary reference
* source, in seconds. Note that this variable can take on both positive
* and negative values, depending on the relative time and frequency
* offsets. The values that normally appear in this field range from
* negative values of a few milliseconds to positive values of several
* hundred milliseconds.
*/
public double rootDelay = 0;
/**
* This value indicates the nominal error relative to the primary reference
* source, in seconds. The values that normally appear in this field
* range from 0 to several hundred milliseconds.
*/
public double rootDispersion = 0;
/**
* This is a 4-byte array identifying the particular reference source.
* In the case of NTP Version 3 or Version 4 stratum-0 (unspecified) or
* stratum-1 (primary) servers, this is a four-character ASCII string, left
* justified and zero padded to 32 bits. In NTP Version 3 secondary
* servers, this is the 32-bit IPv4 address of the reference source. In NTP
* Version 4 secondary servers, this is the low order 32 bits of the latest
* transmit timestamp of the reference source. NTP primary (stratum 1)
* servers should set this field to a code identifying the external
* reference source according to the following list. If the external
* reference is one of those listed, the associated code should be used.
* Codes for sources not listed can be contrived as appropriate.
*
* Code External Reference Source
* ---- -------------------------
* LOCL uncalibrated local clock used as a primary reference for
* a subnet without external means of synchronization
* PPS atomic clock or other pulse-per-second source
* individually calibrated to national standards
* ACTS NIST dialup modem service
* USNO USNO modem service
* PTB PTB (Germany) modem service
* TDF Allouis (France) Radio 164 kHz
* DCF Mainflingen (Germany) Radio 77.5 kHz
* MSF Rugby (UK) Radio 60 kHz
* WWV Ft. Collins (US) Radio 2.5, 5, 10, 15, 20 MHz
* WWVB Boulder (US) Radio 60 kHz
* WWVH Kaui Hawaii (US) Radio 2.5, 5, 10, 15 MHz
* CHU Ottawa (Canada) Radio 3330, 7335, 14670 kHz
* LORC LORAN-C radionavigation system
* OMEG OMEGA radionavigation system
* GPS Global Positioning Service
* GOES Geostationary Orbit Environment Satellite
*/
public byte[] referenceIdentifier = {0, 0, 0, 0};
/**
* This is the time at which the local clock was last set or corrected, in
* seconds since 00:00 1-Jan-1900.
*/
public double referenceTimestamp = 0;
/**
* This is the time at which the request departed the client for the
* server, in seconds since 00:00 1-Jan-1900.
*/
public double originateTimestamp = 0;
/**
* This is the time at which the request arrived at the server, in seconds
* since 00:00 1-Jan-1900.
*/
public double receiveTimestamp = 0;
/**
* This is the time at which the reply departed the server for the client,
* in seconds since 00:00 1-Jan-1900.
*/
public double transmitTimestamp = 0;
/**
* Constructs a new NtpMessage from an array of bytes.
*/
public NtpMessage(byte[] array)
{
// See the packet format diagram in RFC 2030 for details
leapIndicator = (byte) ((array[0] >> 6) & 0x3);
version = (byte) ((array[0] >> 3) & 0x7);
mode = (byte) (array[0] & 0x7);
stratum = unsignedByteToShort(array[1]);
pollInterval = array[2];
precision = array[3];
rootDelay = (array[4] * 256.0) +
unsignedByteToShort(array[5]) +
(unsignedByteToShort(array[6]) / 256.0) +
(unsignedByteToShort(array[7]) / 65536.0);
rootDispersion = (unsignedByteToShort(array[8]) * 256.0) +
unsignedByteToShort(array[9]) +
(unsignedByteToShort(array[10]) / 256.0) +
(unsignedByteToShort(array[11]) / 65536.0);
referenceIdentifier[0] = array[12];
referenceIdentifier[1] = array[13];
referenceIdentifier[2] = array[14];
referenceIdentifier[3] = array[15];
referenceTimestamp = decodeTimestamp(array, 16);
originateTimestamp = decodeTimestamp(array, 24);
receiveTimestamp = decodeTimestamp(array, 32);
transmitTimestamp = decodeTimestamp(array, 40);
}
/**
* Constructs a new NtpMessage in client -> server mode, and sets the
* transmit timestamp to the current time.
*/
public NtpMessage()
{
// Note that all the other member variables are already set with
// appropriate default values.
this.mode = 3;
this.transmitTimestamp = (System.currentTimeMillis()/1000.0) + 2208988800.0;
}
/**
* This method constructs the data bytes of a raw NTP packet.
*/
public byte[] toByteArray()
{
// All bytes are automatically set to 0
byte[] p = new byte[48];
p[0] = (byte) (leapIndicator << 6 | version << 3 | mode);
p[1] = (byte) stratum;
p[2] = (byte) pollInterval;
p[3] = (byte) precision;
// root delay is a signed 16.16-bit FP, in Java an int is 32-bits
int l = (int) (rootDelay * 65536.0);
p[4] = (byte) ((l >> 24) & 0xFF);
p[5] = (byte) ((l >> 16) & 0xFF);
p[6] = (byte) ((l >> 8) & 0xFF);
p[7] = (byte) (l & 0xFF);
// root dispersion is an unsigned 16.16-bit FP, in Java there are no
// unsigned primitive types, so we use a long which is 64-bits
long ul = (long) (rootDispersion * 65536.0);
p[8] = (byte) ((ul >> 24) & 0xFF);
p[9] = (byte) ((ul >> 16) & 0xFF);
p[10] = (byte) ((ul >> 8) & 0xFF);
p[11] = (byte) (ul & 0xFF);
p[12] = referenceIdentifier[0];
p[13] = referenceIdentifier[1];
p[14] = referenceIdentifier[2];
p[15] = referenceIdentifier[3];
encodeTimestamp(p, 16, referenceTimestamp);
encodeTimestamp(p, 24, originateTimestamp);
encodeTimestamp(p, 32, receiveTimestamp);
encodeTimestamp(p, 40, transmitTimestamp);
return p;
}
/**
* Returns a string representation of a NtpMessage
*/
public String toString()
{
String precisionStr =
new DecimalFormat("0.#E0").format(Math.pow(2, precision));
return "Leap indicator: " + leapIndicator + "\n" +
"Version: " + version + "\n" +
"Mode: " + mode + "\n" +
"Stratum: " + stratum + "\n" +
"Poll: " + pollInterval + "\n" +
"Precision: " + precision + " (" + precisionStr + " seconds)\n" +
"Root delay: " + new DecimalFormat("0.00").format(rootDelay*1000) + " ms\n" +
"Root dispersion: " + new DecimalFormat("0.00").format(rootDispersion*1000) + " ms\n" +
"Reference identifier: " + referenceIdentifierToString(referenceIdentifier, stratum, version) + "\n" +
"Reference timestamp: " + timestampToString(referenceTimestamp) + "\n" +
"Originate timestamp: " + timestampToString(originateTimestamp) + "\n" +
"Receive timestamp: " + timestampToString(receiveTimestamp) + "\n" +
"Transmit timestamp: " + timestampToString(transmitTimestamp);
}
/**
* Converts an unsigned byte to a short. By default, Java assumes that
* a byte is signed.
*/
public static short unsignedByteToShort(byte b)
{
if((b & 0x80)==0x80) return (short) (128 + (b & 0x7f));
else return (short) b;
}
/**
* Will read 8 bytes of a message beginning at <code>pointer</code>
* and return it as a double, according to the NTP 64-bit timestamp
* format.
*/
public static double decodeTimestamp(byte[] array, int pointer)
{
double r = 0.0;
for(int i=0; i<8; i++)
{
r += unsignedByteToShort(array[pointer+i]) * Math.pow(2, (3-i)*8);
}
return r;
}
/**
* Encodes a timestamp in the specified position in the message
*/
public static void encodeTimestamp(byte[] array, int pointer, double timestamp)
{
// Converts a double into a 64-bit fixed point
for(int i=0; i<8; i++)
{
// 2^24, 2^16, 2^8, .. 2^-32
double base = Math.pow(2, (3-i)*8);
// Capture byte value
array[pointer+i] = (byte) (timestamp / base);
// Subtract captured value from remaining total
timestamp = timestamp - (double) (unsignedByteToShort(array[pointer+i]) * base);
}
// From RFC 2030: It is advisable to fill the non-significant
// low order bits of the timestamp with a random, unbiased
// bitstring, both to avoid systematic roundoff errors and as
// a means of loop detection and replay detection.
array[7] = (byte) (Math.random()*255.0);
}
/**
* Returns a timestamp (number of seconds since 00:00 1-Jan-1900) as a
* formatted date/time string.
*/
public static String timestampToString(double timestamp)
{
if(timestamp==0) return "0";
// timestamp is relative to 1900, utc is used by Java and is relative
// to 1970
double utc = timestamp - (2208988800.0);
// milliseconds
long ms = (long) (utc * 1000.0);
// date/time
String date = new SimpleDateFormat("dd-MMM-yyyy HH:mm:ss").format(new Date(ms));
// fraction
double fraction = timestamp - ((long) timestamp);
String fractionSting = new DecimalFormat(".000000").format(fraction);
return date + fractionSting;
}
/**
* Returns a string representation of a reference identifier according
* to the rules set out in RFC 2030.
*/
public static String referenceIdentifierToString(byte[] ref, short stratum, byte version)
{
// From the RFC 2030:
// In the case of NTP Version 3 or Version 4 stratum-0 (unspecified)
// or stratum-1 (primary) servers, this is a four-character ASCII
// string, left justified and zero padded to 32 bits.
if(stratum==0 || stratum==1)
{
return new String(ref);
}
// In NTP Version 3 secondary servers, this is the 32-bit IPv4
// address of the reference source.
else if(version==3)
{
return unsignedByteToShort(ref[0]) + "." +
unsignedByteToShort(ref[1]) + "." +
unsignedByteToShort(ref[2]) + "." +
unsignedByteToShort(ref[3]);
}
// In NTP Version 4 secondary servers, this is the low order 32 bits
// of the latest transmit timestamp of the reference source.
else if(version==4)
{
return "" + ((unsignedByteToShort(ref[0]) / 256.0) +
(unsignedByteToShort(ref[1]) / 65536.0) +
(unsignedByteToShort(ref[2]) / 16777216.0) +
(unsignedByteToShort(ref[3]) / 4294967296.0));
}
return "";
}
}

View File

@ -27,6 +27,7 @@ public final class R {
}
public static final class string {
public static final int app_name=0x7f040001;
public static final int foreground_service_started=0x7f040002;
public static final int hello=0x7f040000;
}
}

View File

@ -49,6 +49,7 @@ public class RedirOutputThread extends Thread
InputStream sutOut;
Process pProc;
String strOutput;
int nExitCode = -1;
public RedirOutputThread(Process pProc, OutputStream out)
{
@ -134,7 +135,6 @@ public class RedirOutputThread extends Thread
}
catch (IOException e)
{
// Toast.makeText(SUTAgentAndroid.me.getApplicationContext(), e.getMessage(), Toast.LENGTH_LONG).show();
e.printStackTrace();
}
}
@ -147,15 +147,14 @@ public class RedirOutputThread extends Thread
private boolean IsProcRunning(Process pProc)
{
boolean bRet = false;
@SuppressWarnings("unused")
int nExitCode = 0;
try
{
nExitCode = pProc.exitValue();
}
catch (IllegalThreadStateException z)
{
{
nExitCode = -1;
bRet = true;
}

View File

@ -45,18 +45,17 @@ import java.net.SocketException;
import java.util.Enumeration;
import java.util.List;
import java.util.Timer;
import com.mozilla.SUTAgentAndroid.service.ASMozStub;
import com.mozilla.SUTAgentAndroid.service.DoCommand;
// import dalvik.system.VMRuntime;
import android.app.Activity;
import android.app.KeyguardManager;
import android.bluetooth.BluetoothAdapter;
import android.content.BroadcastReceiver;
// import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
import android.net.Uri;
import android.net.wifi.SupplicantState;
import android.net.wifi.WifiConfiguration;
@ -65,8 +64,7 @@ import android.net.wifi.WifiManager;
import android.net.wifi.WifiManager.WifiLock;
import android.os.BatteryManager;
import android.os.Bundle;
import android.os.Debug;
import android.os.PowerManager;
import android.os.Handler;
import android.telephony.TelephonyManager;
import android.util.Log;
import android.view.Menu;
@ -79,11 +77,12 @@ import android.widget.Toast;
public class SUTAgentAndroid extends Activity
{
final Handler mHandler = new Handler();
public 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;
@ -100,13 +99,14 @@ public class SUTAgentAndroid extends Activity
private static String HardwareID = "";
private static String Pool = "";
private static String sRegString = "";
private static String sNTPServer = "";
private WifiLock wl = null;
private PowerManager.WakeLock pwl = null;
private BroadcastReceiver battReceiver = null;
// private ComponentName service = null;
private TextView tv = null;
public boolean onCreateOptionsMenu(Menu menu)
{
mExitMenuItem = menu.add("Exit");
@ -133,31 +133,10 @@ public class SUTAgentAndroid extends Activity
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// Debug.waitForDebugger();
// 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();
}
fixScreenOrientation();
DoCommand dc = new DoCommand(getApplication());
@ -170,14 +149,13 @@ public class SUTAgentAndroid extends Activity
SUTAgentAndroid.RegSvrIPPort = dc.GetIniData("Registration Server", "PORT", sIniFile);
SUTAgentAndroid.HardwareID = dc.GetIniData("Registration Server", "HARDWARE", sIniFile);
SUTAgentAndroid.Pool = dc.GetIniData("Registration Server", "POOL", sIniFile);
SUTAgentAndroid.sNTPServer = dc.GetIniData("NTP Server", "IPAddr", sIniFile);
TextView tv = (TextView) this.findViewById(R.id.Textview01);
tv = (TextView) this.findViewById(R.id.Textview01);
if (getLocalIpAddress() == null)
setUpNetwork(sIniFile);
// me = this;
WifiInfo wifi;
WifiManager wifiMan = (WifiManager)getSystemService(Context.WIFI_SERVICE);
String macAddress = "Unknown";
@ -195,7 +173,7 @@ public class SUTAgentAndroid extends Activity
if (sUniqueID == null)
{
BluetoothAdapter ba = BluetoothAdapter.getDefaultAdapter();
if (ba.isEnabled() != true)
if ((ba != null) && (ba.isEnabled() != true))
{
ba.enable();
while(ba.getState() != BluetoothAdapter.STATE_ON)
@ -225,8 +203,11 @@ public class SUTAgentAndroid extends Activity
}
else
{
sUniqueID = ba.getAddress();
sUniqueID.toLowerCase();
if (ba != null)
{
sUniqueID = ba.getAddress();
sUniqueID.toLowerCase();
}
}
}
@ -258,6 +239,8 @@ public class SUTAgentAndroid extends Activity
sConfig += "Network Info" + lineSep;
sConfig += "\tMac Address: " + macAddress + lineSep;
sConfig += "\tIP Address: " + sLocalIPAddr + lineSep;
displayStatus(sConfig);
sRegString = "NAME=" + sUniqueID;
sRegString += "&IPADDR=" + sLocalIPAddr;
@ -273,35 +256,28 @@ public class SUTAgentAndroid extends Activity
String sTemp = Uri.encode(sRegString,"=&");
sRegString = "register " + sTemp;
if (!bNetworkingStarted)
{
Thread thread = new Thread(null, doStartService, "StartServiceBkgnd");
thread.start();
// ToDoListening(1,300,dc);
bNetworkingStarted = true;
String sRegRet = "";
if (RegSvrIPAddr.length() > 0)
{
sRegRet = dc.RegisterTheDevice(RegSvrIPAddr, RegSvrIPPort, sRegString);
if (sRegRet.contains("ok"))
{
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;
Thread thread2 = new Thread(null, doRegisterDevice, "RegisterDeviceBkgnd");
thread2.start();
}
tv.setText(sConfig);
monitorBatteryState();
// If we are returning from an update let'em know we're back
Thread thread3 = new Thread(null, doUpdateCallback, "UpdateCallbackBkgnd");
thread3.start();
if (SUTAgentAndroid.sNTPServer.length() > 0) {
Thread thread4 = new Thread(null, doSetClock, "SetClockBkgrnd");
thread4.start();
}
final Button goButton = (Button) findViewById(R.id.Button01);
goButton.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
@ -310,6 +286,31 @@ public class SUTAgentAndroid extends Activity
});
}
private class UpdateStatus implements Runnable {
public String sText = "";
UpdateStatus(String sStatus) {
sText = sStatus;
}
@Override
public void run() {
displayStatus(sText);
}
}
public synchronized void displayStatus(String sStatus) {
String sTVText = (String) tv.getText();
sTVText += sStatus;
tv.setText(sTVText);
}
public void fixScreenOrientation()
{
setRequestedOrientation((getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) ?
ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE : ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
if (requestCode == START_PRG)
@ -330,19 +331,11 @@ public class SUTAgentAndroid extends Activity
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();
}
if (pwl != null)
pwl.release();
if (wl != null)
wl.release();
System.exit(0);
}
}
@ -453,7 +446,6 @@ public class SUTAgentAndroid extends Activity
nRet = Settings.System.getInt(cr, Settings.System.WIFI_USE_STATIC_IP);
String foo2 = "" + nRet;
} catch (SettingNotFoundException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
*/
@ -614,7 +606,67 @@ public class SUTAgentAndroid extends Activity
return(bRet);
}
// If there is an update.info file callback the server and send the status
private Runnable doUpdateCallback = new Runnable() {
public void run() {
DoCommand dc = new DoCommand(getApplication());
String sRet = dc.UpdateCallBack("update.info");
if (sRet.length() > 0) {
if (sRet.contains("ok")) {
sRet = "Callback Server contacted successfully" + lineSep;
} else if (sRet.contains("Nothing to do")) {
sRet = "";
} else {
sRet = "Callback Server NOT contacted successfully" + lineSep;
}
}
if (sRet.length() > 0)
mHandler.post(new UpdateStatus(sRet));
dc = null;
}
};
private Runnable doSetClock = new Runnable() {
public void run() {
String sRet = "";
DoCommand dc = new DoCommand(getApplication());
sRet = dc.SetSystemTime(sNTPServer, null, null);
mHandler.post(new UpdateStatus(sRet));
dc = null;
}
};
// registers with the reg server defined in the SUTAgent.ini file
private Runnable doRegisterDevice = new Runnable() {
public void run() {
DoCommand dc = new DoCommand(getApplication());
String sRet = "";
if (RegSvrIPAddr.length() > 0) {
String sRegRet = dc.RegisterTheDevice(RegSvrIPAddr, RegSvrIPPort, sRegString);
if (sRegRet.contains("ok")) {
sRet += "Registered with testserver" + lineSep;
sRet += "\tIPAddress: " + RegSvrIPAddr + lineSep;
if (RegSvrIPPort.length() > 0)
sRet += "\tPort: " + RegSvrIPPort + lineSep;
} else {
sRet += "Not registered with testserver" + lineSep;
}
} else {
sRet += "Not registered with testserver" + lineSep;
}
if (sRet.length() > 0)
mHandler.post(new UpdateStatus(sRet));
dc = null;
}
};
// this starts the listener service for the command and data channels
private Runnable doStartService = new Runnable()
{
public void run()
@ -622,101 +674,8 @@ public class SUTAgentAndroid extends Activity
Intent listenerService = new Intent();
listenerService.setAction("com.mozilla.SUTAgentAndroid.service.LISTENER_SERVICE");
startService(listenerService);
// service = startService(listenerService);
}
};
/*
class ToDoListener extends TimerTask
{
boolean bFirstRun = true;
DoCommand dc = null;
ToDoListener() {}
ToDoListener(DoCommand dc)
{
this.dc = dc;
}
public void run ()
{
if (bFirstRun == true)
{
Intent listenerService = new Intent();
listenerService.setAction("com.mozilla.SUTAgentAndroid.service.LISTENER_SERVICE");
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);
timer.schedule(new ToDoListener(), 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()
{

View File

@ -14,4 +14,6 @@
<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

@ -3,4 +3,8 @@
<string name="hello">Hello World, SUTAgentAndroid!</string>
<string name="app_name">SUTAgentAndroid</string>
<string name="foreground_service_started">Foreground Service Started (ASMozStub)</string>
</resources>