mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-09 11:25:00 +00:00
Bug 650110 Update SUTAgent in m-c to 1.01, main agent update r=ctalbert
This commit is contained in:
parent
76a71c68e8
commit
482731d7c2
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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
@ -51,6 +51,7 @@ JAVAFILES = \
|
||||
DataWorkerThread.java \
|
||||
DoAlert.java \
|
||||
DoCommand.java \
|
||||
NtpMessage.java \
|
||||
Power.java \
|
||||
RedirOutputThread.java \
|
||||
RunCmdThread.java \
|
||||
|
468
build/mobile/sutagent/android/NtpMessage.java
Normal file
468
build/mobile/sutagent/android/NtpMessage.java
Normal 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 "";
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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()
|
||||
{
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
Loading…
Reference in New Issue
Block a user