import static ro.ieval.fonbot.R.string.*;
import static ro.ieval.fonbot.Utils.toNonNull;
+import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
+import java.io.FileOutputStream;
import java.io.FileNotFoundException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
import java.io.IOException;
+import java.io.OutputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.UnknownHostException;
+import java.net.URL;
+import java.net.URLConnection;
import java.nio.channels.FileChannel;
import java.nio.channels.SocketChannel;
import java.util.ArrayList;
import android.os.Bundle;
import android.os.Handler;
import android.os.PowerManager;
+import android.os.SystemClock;
import android.os.Vibrator;
import android.preference.PreferenceManager;
import android.provider.BaseColumns;
sb.append(toNonNull(context.getString(at)));
sb.append(" ");
sb.append(locationDate.toString());
+ sb.append(". ");
+
+ sb.append("http://openstreetmap.org/?zoom=15&mlat=");
+ sb.append(loc.getLatitude());
+ sb.append("&mlon=");
+ sb.append(loc.getLongitude());
Utils.sendMessage(toNonNull(context), toNonNull(replyTo), toNonNull(sb.toString()));
}
Utils.sendMessage(toNonNull(context), toNonNull(replyTo), cannot_connect_to_host_on_port, hostname, Integer.valueOf(port));
return null;
}
- Utils.sendMessage(toNonNull(context), toNonNull(replyTo), photo_sent);
+ Utils.sendConfirmMessage(toNonNull(context), toNonNull(replyTo), photo_sent);
return null;
}
}
+ /**
+ * ExecutableRunnable that uploads a file to a given host and port, netcat-style
+ *
+ * @author Marius Gavrilescu <marius@ieval.ro>
+ */
+ private static final class NcfileExecutableRunnable extends ExecutableRunnable {
+ private final Context context;
+ private final Address replyTo;
+ private final String filename;
+ private final String hostname;
+ private final int port;
+
+ /**
+ * Construct a NcfileExecutableRunnable
+ *
+ * @param context Context instance
+ * @param replyTo reply Address
+ * @param filename filename to upload
+ * @param hostname hostname to upload to
+ * @param port port to upload to
+ */
+ NcfileExecutableRunnable(final Context context, final Address replyTo, final String filename, final String hostname, final int port){
+ this.context=context;
+ this.replyTo=replyTo;
+ this.filename=filename;
+ this.hostname=hostname;
+ this.port=port;
+ }
+
+ @Override public void run(){
+ final FileChannel in;
+ final SocketChannel sock;
+ try{
+ in=new FileInputStream(filename).getChannel();
+ } catch (final FileNotFoundException e){
+ Utils.sendMessage(context, replyTo, file_not_found, filename);
+ return;
+ }
+
+ try{
+ sock = SocketChannel.open(new InetSocketAddress(hostname, port));
+ } catch (final IOException e){
+ Utils.sendMessage(context, replyTo, cannot_connect_to_host_on_port, hostname, Integer.valueOf(port));
+ try {
+ in.close();
+ } catch (IOException ex) {
+ //ignored
+ }
+ return;
+ }
+
+ try{
+ in.transferTo(0, in.size(), sock);
+ } catch (final IOException e){
+ Utils.sendMessage(context, replyTo, io_error, e.getMessage());
+ } finally {
+ try{
+ in.close();
+ } catch (IOException e){
+ //ignored
+ }
+ try{
+ sock.close();
+ } catch(IOException e){
+ //ignored
+ }
+ }
+ Utils.sendConfirmMessage(context, replyTo, file_sent);
+ }
+ }
+
+ /**
+ * ExecutableRunnable that downloads a file from a given host and port, netcat-style
+ *
+ * @author Marius Gavrilescu <marius@ieval.ro>
+ */
+ private static final class GetfileExecutableRunnable extends ExecutableRunnable {
+ private final Context context;
+ private final Address replyTo;
+ private final String filename;
+ private final String hostname;
+ private final int port;
+
+ /**
+ * Construct a GetfileExecutableRunnable
+ *
+ * @param context Context instance
+ * @param replyTo reply Address
+ * @param filename filename to save to
+ * @param hostname hostname to download from
+ * @param port port to download from
+ */
+ GetfileExecutableRunnable(final Context context, final Address replyTo, final String filename, final String hostname, final int port){
+ this.context=context;
+ this.replyTo=replyTo;
+ this.filename=filename;
+ this.hostname=hostname;
+ this.port=port;
+ }
+
+ @Override public void run(){
+ final InputStream in;
+ final FileOutputStream out;
+ final Socket sock;
+ try{
+ out=new FileOutputStream(filename);
+ } catch (final IOException e){
+ Utils.sendMessage(context, replyTo, error_opening_file, filename, e.getMessage());
+ return;
+ }
+
+ try{
+ sock = new Socket(hostname, port);
+ in = sock.getInputStream();
+ } catch (final IOException e){
+ Utils.sendMessage(context, replyTo, cannot_connect_to_host_on_port, hostname, Integer.valueOf(port));
+ try {
+ out.close();
+ } catch (IOException ex) {
+ //ignored
+ }
+ return;
+ }
+
+ try{
+ byte[] buffer=new byte[1024*1024*2];
+ int nread;
+ while((nread = in.read(buffer)) > 0)
+ out.write(buffer, 0, nread);
+ } catch (final IOException e){
+ Utils.sendMessage(context, replyTo, io_error, e.getMessage());
+ } finally {
+ try{
+ out.close();
+ } catch (IOException e){
+ //ignored
+ }
+ try{
+ sock.close();
+ } catch(IOException e){
+ //ignored
+ }
+ }
+ Utils.sendConfirmMessage(context, replyTo, file_received);
+ }
+ }
+
/**
* PictureCallback that sends the picture to a server.
*
return;
camera.stopPreview();
stopCamera();
- Utils.sendMessage(toNonNull(context), toNonNull(replyTo), sending_photo);
+ Utils.sendConfirmMessage(toNonNull(context), toNonNull(replyTo), sending_photo);
new SendDataAsyncTask(toNonNull(context), toNonNull(replyTo), toNonNull(hostname), port, data).execute();
}
}
+ /**
+ * Runnable that takes a screen capture and stores it in a file.
+ */
+ private static final class ScreencapRunnable implements Runnable{
+ private final Context context;
+ private final Address replyTo;
+ private final String filename;
+
+ ScreencapRunnable(final Context context, final Address replyTo, final String filename){
+ this.context=context;
+ this.replyTo=replyTo;
+ this.filename=filename;
+ }
+
+ @Override
+ public void run(){
+ final int exitCode;
+ try {
+ exitCode=Runtime.getRuntime().exec(new String[]{
+ "su",
+ "-c",
+ "screencap -p \"" + filename + "\""
+ }).waitFor();
+ } catch (final Exception e){
+ e.printStackTrace();
+ Utils.sendMessage(toNonNull(context), toNonNull(replyTo), screencap_failed);
+ return;
+ }
+
+ if(exitCode == 0 && new File(filename).exists())
+ Utils.sendConfirmMessage(toNonNull(context), toNonNull(replyTo), screencap_successful);
+ else
+ Utils.sendMessage(toNonNull(context), toNonNull(replyTo), screencap_failed);
+ }
+ }
+
/**
* Get help for a particular command
*
case SMS:
Utils.sendMessage(context, replyTo, sms_help);
break;
+ case SMSQ:
+ Utils.sendMessage(context, replyTo, smsq_help);
+ break;
case SMSLOG:
Utils.sendMessage(context, replyTo, smslog_help);
break;
case REBOOT:
Utils.sendMessage(context, replyTo, reboot_help);
break;
- case SHUTDOWN:
- Utils.sendMessage(context, replyTo, shutdown_help);
- break;
case NOTIFY:
Utils.sendMessage(context, replyTo, notify_help);
+ break;
+ case SCREENCAP:
+ Utils.sendMessage(context, replyTo, screencap_help);
+ break;
+ case TORCH:
+ Utils.sendMessage(context, replyTo, torch_help);
+ break;
+ case GETFILE:
+ Utils.sendMessage(context, replyTo, getfile_help);
+ break;
+ case SH:
+ Utils.sendMessage(context, replyTo, sh_help);
+ break;
+ case ROOTSH:
+ Utils.sendMessage(context, replyTo, rootsh_help);
+ break;
+ default:
+ Utils.sendMessage(context, replyTo, command_not_documented);
}
}
man.setRingerMode(AudioManager.RINGER_MODE_NORMAL);
savedRingVolume=man.getStreamVolume(AudioManager.STREAM_RING);
man.setStreamVolume(AudioManager.STREAM_RING, man.getStreamMaxVolume(AudioManager.STREAM_RING), 0);
- Utils.sendMessage(context, replyTo, ringing);
+ Utils.sendConfirmMessage(context, replyTo, ringing);
ringtone.play();
}
* @param context Context instance
* @param replyTo reply Address
*/
- private static void startCamera(final Context context, final Address replyTo){
+ private static void startCamera(final Context context, final Address replyTo, final int cameraNumber){
if(camera!=null)
return;
try{
- camera=Camera.open();
+ try{
+ camera=Camera.open(cameraNumber);
+ } catch (Exception ex){
+ camera=Camera.open();
+ }
} catch (Exception e){
Utils.sendMessage(context, replyTo, cannot_grab_camera);
}
private static void stopAlarm(final Context context, final Address replyTo){
Utils.unregisterOngoing(context, toNonNull(OngoingEvent.RING));
final AudioManager man=(AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
- Utils.sendMessage(context, replyTo, no_longer_ringing);
+ Utils.sendConfirmMessage(context, replyTo, no_longer_ringing);
ringtone.stop();
man.setStreamVolume(AudioManager.STREAM_RING, savedRingVolume, 0);
man.setRingerMode(savedRingerMode);
if(on) {
adapter.enable();
- Utils.sendMessage(context, replyTo, enabling_bluetooth);
+ Utils.sendConfirmMessage(context, replyTo, enabling_bluetooth);
}
else {
adapter.disable();
- Utils.sendMessage(context, replyTo, disabling_bluetooth);
+ Utils.sendConfirmMessage(context, replyTo, disabling_bluetooth);
}
}
case LOCATION:
nolocation(context, toNonNull(Address.BLACKHOLE));
break;
- case POLL:
- poll(context, toNonNull(Address.BLACKHOLE), 0);
- break;
case RING:
ring(context, toNonNull(Address.BLACKHOLE), false);
break;
CommonDataKinds.Phone.LABEL);
while(inCursor.moveToNext())
- Utils.sendMessage(context, replyTo, toNonNull(context.getString(contact_info,
+ Utils.sendMessage(context, replyTo, contact_info,
cursor.getString(0),
inCursor.getString(0),
- phoneNumberType(context, inCursor.getInt(1), inCursor.getString(2)))));
+ phoneNumberType(context, inCursor.getInt(1), inCursor.getString(2)));
inCursor.close();
}
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
final String name=Utils.callerId(context, nr);
if(name==null)
- Utils.sendMessage(context, replyTo, dialing, nr);
+ Utils.sendConfirmMessage(context, replyTo, dialing, nr);
else
- Utils.sendMessage(context, replyTo, dialing, nr+" ("+name+")");
+ Utils.sendConfirmMessage(context, replyTo, dialing, nr+" ("+name+")");
context.startActivity(intent);
}
Intent.FLAG_ACTIVITY_NEW_TASK|
Intent.FLAG_ACTIVITY_NO_USER_ACTION|
Intent.FLAG_FROM_BACKGROUND);
- Utils.sendMessage(context, toNonNull(replyTo), showing_dialog);
+ Utils.sendConfirmMessage(context, toNonNull(replyTo), showing_dialog);
context.startActivity(intent);
}
* @param on requested flashlight state
*/
public static void flash(final Context context, final Address replyTo, final boolean on){
- startCamera(context, replyTo);
+ startCamera(context, replyTo, 0);
if(camera==null)
return;
final Camera.Parameters parms=camera.getParameters();
Utils.sendMessage(context, replyTo, last_known_location);
locationListener.onLocationChanged(lastKnownLocation);
}
- Utils.sendMessage(context, replyTo, listening_for_location_updates);
+ Utils.sendConfirmMessage(context, replyTo, listening_for_location_updates);
man.requestLocationUpdates(provider, minTime, minDistance, locationListener);
}
public static void lock(final Context context, final Address replyTo) {
final DevicePolicyManager dpm=(DevicePolicyManager) context.getSystemService(Context.DEVICE_POLICY_SERVICE);
dpm.lockNow();
- Utils.sendMessage(context, replyTo, device_locked);
+ Utils.sendConfirmMessage(context, replyTo, device_locked);
}
/**
final Intent intent=new Intent("com.android.music.musicservicecommand");
intent.putExtra("command", command);
context.sendBroadcast(intent);
- Utils.sendMessage(context, replyTo, command_sent);
+ Utils.sendConfirmMessage(context, replyTo, command_sent);
}
/**
* @param port server port
*/
public static void ncfile(final Context context, final Address replyTo, final String filename,final String hostname,final int port){
- new AsyncTask<Void, Void, Void>() {
- @Override
- protected @Nullable Void doInBackground(@Nullable final Void... params) {
- final FileChannel in;
- try{
- in=new FileInputStream(filename).getChannel();
- } catch (final FileNotFoundException e){
- Utils.sendMessage(context, replyTo, file_not_found, filename);
- return null;
- }
- final SocketChannel sock;
- try{
- sock = SocketChannel.open(new InetSocketAddress(hostname, port));
- } catch (final IOException e){
- Utils.sendMessage(context, replyTo, toNonNull(context.getString(
- cannot_connect_to_host_on_port, hostname, Integer.valueOf(port))));
- try {
- in.close();
- } catch (IOException ex) {
- //ignored
- }
- return null;
- }
-
- try{
- in.transferTo(0, in.size(), sock);
- } catch (final IOException e){
- Utils.sendMessage(context, replyTo, toNonNull(context.getString(
- io_error, e.getMessage())));
- } finally {
- try{
- in.close();
- } catch (IOException e){
- //ignored
- }
- try{
- sock.close();
- } catch(IOException e){
- //ignored
- }
- }
- return null;
- }
-
- @Override
- protected void onPostExecute(@Nullable final Void result) {
- Utils.sendMessage(context, replyTo, file_sent);
- }
- }.execute();
+ new NcfileExecutableRunnable(context, replyTo, filename, hostname, port).execute();
}
/**
final LocationManager man=(LocationManager) context.getApplicationContext().getSystemService(Context.LOCATION_SERVICE);
man.removeUpdates(locationListener);
locationListener=null;
- Utils.sendMessage(context, replyTo, no_longer_listening_for_location_updates);
+ Utils.sendConfirmMessage(context, replyTo, no_longer_listening_for_location_updates);
}
/**
*
* @param context Context instance
* @param replyTo reply Address
+ * @param cameraNumber camera to take photo with
* @param hostname server hostname
* @param port server port
*/
- public static void photo(final Context context, final Address replyTo, final String hostname, final int port){
- startCamera(context, replyTo);
+ public static void photo(final Context context, final Address replyTo, final int cameraNumber, final String hostname, final int port){
+ startCamera(context, replyTo, cameraNumber);
if(camera==null)
return;
final Camera.Parameters parms=camera.getParameters();
new Thread(new Runnable() {
@Override
public void run() {
- try {
- Thread.sleep(2000);
- } catch (InterruptedException e) {
- //ignored
- }
+ SystemClock.sleep(2000);
handler.post(new Runnable() {
@Override
public void run() {
- camera.takePicture(null, null, new FonBotPictureCallback(context, replyTo, hostname, port));
+ try {
+ camera.takePicture(null, null, new FonBotPictureCallback(context, replyTo, hostname, port));
+ } catch(Exception e){
+ Utils.sendMessage(context, replyTo, error_while_processing_command, e.getClass().getName(), e.getMessage());
+ }
}
});
}
*/
public static void rm(final Context context, final Address replyTo, final String filename){
if(new File(filename).delete())
- Utils.sendMessage(context, replyTo, file_deleted);
+ Utils.sendConfirmMessage(context, replyTo, file_deleted);
else
Utils.sendMessage(context, replyTo, error_while_deleting_file);
}
final DevicePolicyManager dpm=(DevicePolicyManager) context.getSystemService(Context.DEVICE_POLICY_SERVICE);
dpm.resetPassword("", 0);
- Utils.sendMessage(context, replyTo, password_cleared);
+ Utils.sendConfirmMessage(context, replyTo, password_cleared);
}
/**
final DevicePolicyManager dpm=(DevicePolicyManager) context.getSystemService(Context.DEVICE_POLICY_SERVICE);
dpm.resetPassword(password, 0);
- Utils.sendMessage(context, replyTo, password_set);
+ Utils.sendConfirmMessage(context, replyTo, password_set);
}
/**
* @param destination destination phone number
* @param text text message contents
*/
- public static void sms(final Context context, final Address replyTo, final String destination, final String text){
+ public static void sms(final Context context, final Address replyTo, final String destination, final String text, final boolean quiet){
final SmsManager manager=SmsManager.getDefault();
final ArrayList<String> messages=manager.divideMessage(text);
if(messages.size() > 1)
- Utils.sendMessage(context, replyTo, message_was_split_into_parts, Integer.valueOf(messages.size()));
+ Utils.sendConfirmMessage(context, replyTo, message_was_split_into_parts, Integer.valueOf(messages.size()));
final ArrayList<PendingIntent> sents=new ArrayList<PendingIntent>(messages.size());
final ArrayList<PendingIntent> delivereds=new ArrayList<PendingIntent>(messages.size());
sent.putExtra(SmsStatusReceiver.EXTRA_PART, i+1);
sent.putExtra(SmsStatusReceiver.EXTRA_TOTAL, messages.size());
sent.putExtra(SmsStatusReceiver.EXTRA_REPLY_TO, replyTo.toString());
- sent.setAction(SmsStatusReceiver.SENT_ACTION+i);//actions must be unique
+ sent.setAction(SmsStatusReceiver.SENT_ACTION+i+System.currentTimeMillis());//actions must be unique
sents.add(PendingIntent.getBroadcast(context, 0, sent, PendingIntent.FLAG_UPDATE_CURRENT));
final Intent delivered=new Intent(context, SmsStatusReceiver.class);
delivered.putExtra(SmsStatusReceiver.EXTRA_PART, i+1);
delivered.putExtra(SmsStatusReceiver.EXTRA_TOTAL, messages.size());
delivered.putExtra(SmsStatusReceiver.EXTRA_REPLY_TO, replyTo.toString());
- delivered.setAction(SmsStatusReceiver.DELIVERED_ACTION+i);//actions must be unique
+ delivered.setAction(SmsStatusReceiver.DELIVERED_ACTION+i+System.currentTimeMillis());//actions must be unique
delivereds.add(PendingIntent.getBroadcast(context, 0, delivered, PendingIntent.FLAG_UPDATE_CURRENT));
}
Log.d(Heavy.class.getName(), "Sending sms to "+destination);
- manager.sendMultipartTextMessage(destination, null, messages, sents, delivereds);
+ manager.sendMultipartTextMessage(destination, null, messages, sents, quiet ? null : delivereds);
}
/**
do {
final String fromNumber=cursor.getString(1);
final String from;
- final String name=Utils.callerId(context, Utils.toNonNull(fromNumber));
- if(name==null)
- from=fromNumber;
- else
- from=fromNumber+" ("+name+')';
+ if(fromNumber == null)
+ from = null;
+ else {
+ final String name=Utils.callerId(context, Utils.toNonNull(fromNumber));
+ if(name==null)
+ from=fromNumber;
+ else
+ from=fromNumber+" ("+name+')';
+ }
+
final String message=cursor.getString(2).replace("\n", "\n ");
final Date date=new Date(cursor.getLong(3));
@Override
public void onInit(final int status) {
if(status==TextToSpeech.SUCCESS){
- Utils.sendMessage(context, replyTo, speaking);
+ Utils.sendConfirmMessage(context, replyTo, speaking);
tts.speak(text, TextToSpeech.QUEUE_ADD, null);
} else
Utils.sendMessage(context, replyTo, tts_engine_not_available);
*/
public static void toast(final Context context, final Address replyTo, final String text, final int duration){
Toast.makeText(context,text,duration).show();
- Utils.sendMessage(context, replyTo, toast_shown);
+ Utils.sendConfirmMessage(context, replyTo, toast_shown);
}
/**
*/
public static void vibrate(final Context context, final Address replyTo, final long ms){
final Vibrator v=(Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE);
- Utils.sendMessage(context, replyTo, vibrating);
+ Utils.sendConfirmMessage(context, replyTo, vibrating);
v.vibrate(ms);
}
intent.setData(uri);
intent.setFlags(Intent.FLAG_FROM_BACKGROUND|Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
- Utils.sendMessage(context, replyTo, url_opened);
+ Utils.sendConfirmMessage(context, replyTo, url_opened);
} catch(ActivityNotFoundException e){
Utils.sendMessage(context, replyTo, no_activity_found_for_this_url);
} catch(Exception e){
final WifiManager man=(WifiManager) context.getSystemService(Context.WIFI_SERVICE);
man.setWifiEnabled(on);
if(on)
- Utils.sendMessage(context, replyTo, enabling_wifi);
+ Utils.sendConfirmMessage(context, replyTo, enabling_wifi);
else
- Utils.sendMessage(context, replyTo, disabling_wifi);
+ Utils.sendConfirmMessage(context, replyTo, disabling_wifi);
}
/**
public static void disable(final Context context, final Address replyTo, final Command command){
PreferenceManager.getDefaultSharedPreferences(context).edit()
.putBoolean(command+"disabled", true).commit();
- Utils.sendMessage(context, replyTo, command_disabled, command);
+ Utils.sendConfirmMessage(context, replyTo, command_disabled, command);
}
/**
public static void enable(final Context context, final Address replyTo, final Command command){
PreferenceManager.getDefaultSharedPreferences(context).edit()
.remove(command+"disabled").commit();
- Utils.sendMessage(context, replyTo, command_enabled, command);
+ Utils.sendConfirmMessage(context, replyTo, command_enabled, command);
}
}
/**
- * Poll the server for pending commands.
+ * Start long polling if stopped
*
* @param context Context instance
* @param replyTo reply Address
*/
public static void poll(final Context context, final Address replyTo) {
- Utils.sendMessage(context, replyTo, polling_server);
- Utils.pollServer(context);
- }
-
- /**
- * Change the server poll interval.
- *
- * @param context Context instance
- * @param replyTo reply Address
- * @param ms server poll interval in milliseconds. If 0, server poll is disabled
- */
- public static void poll(final Context context, final Address replyTo, final long ms){
- final AlarmManager man=(AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
- final Intent pollAlarm=new Intent(context, FonBotMainService.class);
- pollAlarm.setAction(FonBotMainService.ACTION_TRIGGER_POLL);
- final PendingIntent intent=PendingIntent.getService(context, 0, pollAlarm, 0);
- if(ms==0){
- Utils.unregisterOngoing(context, toNonNull(OngoingEvent.POLL));
- man.cancel(intent);
- Utils.sendMessage(context, replyTo, polling_stopped);
- } else {
- Utils.registerOngoing(context, toNonNull(OngoingEvent.POLL));
- man.setRepeating(AlarmManager.RTC_WAKEUP, 0, ms, intent);
- Utils.sendMessage(context, replyTo, polling_every_milliseconds, Long.valueOf(ms));
- }
+ Utils.sendConfirmMessage(context, replyTo, starting_long_polling_if_stopped);
+ context.startService(new Intent(context, FonBotMainService.class));
}
/**
return;
}
context.startActivity(intent);
- Utils.sendMessage(context, replyTo, app_launched);
+ Utils.sendConfirmMessage(context, replyTo, app_launched);
}
/**
try{
if(enable){
getITelephony(context).enableDataConnectivity();
- Utils.sendMessage(context, replyTo, enabling_data);
+ Utils.sendConfirmMessage(context, replyTo, enabling_data);
} else {
getITelephony(context).disableDataConnectivity();
- Utils.sendMessage(context, replyTo, disabling_data);
+ Utils.sendConfirmMessage(context, replyTo, disabling_data);
}
} catch(Exception e){
Utils.sendMessage(context, replyTo, exception_while_getting_itelephony,
public static void gps(final Context context, final Address replyTo, final boolean enabled) {
Secure.setLocationProviderEnabled(context.getContentResolver(), LocationManager.GPS_PROVIDER, enabled);
if(enabled)
- Utils.sendMessage(context, replyTo, enabling_gps);
+ Utils.sendConfirmMessage(context, replyTo, enabling_gps);
else
- Utils.sendMessage(context, replyTo, disabling_gps);
+ Utils.sendConfirmMessage(context, replyTo, disabling_gps);
}
/**
public static void glocation(final Context context, final Address replyTo, final boolean enabled) {
Secure.setLocationProviderEnabled(context.getContentResolver(), LocationManager.NETWORK_PROVIDER, enabled);
if(enabled)
- Utils.sendMessage(context, replyTo, enabling_network_location);
+ Utils.sendConfirmMessage(context, replyTo, enabling_network_location);
else
- Utils.sendMessage(context, replyTo, disabling_network_location);
+ Utils.sendConfirmMessage(context, replyTo, disabling_network_location);
}
/**
*/
public static void reboot(final Context context, final Address replyTo, final @Nullable String reason) {
final PowerManager pm=(PowerManager) context.getSystemService(Context.POWER_SERVICE);
- Utils.sendMessage(context, replyTo, rebooting);
- pm.reboot(reason);
+ Utils.sendConfirmMessage(context, replyTo, rebooting);
+ try {
+ pm.reboot(reason);
+ } catch (final Exception e){
+ e.printStackTrace();
+ }
+ try {
+ Runtime.getRuntime().exec(new String[]{
+ "su",
+ "-c",
+ "reboot"
+ }).waitFor();
+ } catch (final Exception e){
+ e.printStackTrace();
+ }
+ Utils.sendMessage(toNonNull(context), toNonNull(replyTo), reboot_failed);
}
/**
public static void notify(final Context context, final Address replyTo, final int id) {
final NotificationManager man=(NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
man.cancel(id);
- Utils.sendMessage(context, replyTo, notification_canceled);
+ Utils.sendConfirmMessage(context, replyTo, notification_canceled);
}
/**
setContentText(text).
setSmallIcon(android.R.drawable.stat_notify_sync_noanim).
build());
- Utils.sendMessage(context, replyTo, notification_shown);
+ Utils.sendConfirmMessage(context, replyTo, notification_shown);
+ }
+
+ /**
+ * Take a screen capture. Uses the screencap utility and requires root.
+ *
+ * @param context Context instance
+ * @param replyTo reply Address
+ * @param filename capture file location
+ */
+ public static void screencap(final Context context, final Address replyTo, final String filename){
+ new Thread(new ScreencapRunnable(context, replyTo, filename)).start();
+ }
+
+ /**
+ * Toggle the torch state using the Torch (net.cactii.torch2) app.
+ *
+ * @param context Context instance
+ * @param replyTo reply Address
+ */
+ public static void torch(final Context context, final Address replyTo){
+ context.sendBroadcast(new Intent("net.cactii.flash2.TOGGLE_FLASHLIGHT"));
+ Utils.sendConfirmMessage(context, replyTo, toggling_torch_state);
+ }
+
+ /**
+ * Download a file from a given URL to a given filename
+ *
+ * @param context Context instance
+ * @param replyTo reply Address
+ * @param filename filename to save to
+ * @param hostname hostname to download from
+ * @param port port to download from
+ */
+ public static void getfile(final Context context, final Address replyTo, final String filename, final String hostname, final int port){
+ new GetfileExecutableRunnable(context, replyTo, filename, hostname, port).execute();
+ }
+
+ /**
+ * Execute a command using a given shell and reply with the output.
+ *
+ * @param context Context instance
+ * @param replyTo reply Address
+ * @param shell The shell to execute with. Usually sh or su.
+ * @param command The command to pass to the shell.
+ */
+ public static void execute(final Context context, final Address replyTo, final String shell, final String command) {
+ try {
+ final Process proc = Runtime.getRuntime().exec(new String[]{
+ shell,
+ "-c",
+ command
+ });
+ final BufferedReader br = new BufferedReader (new InputStreamReader(proc.getInputStream()));
+ String line;
+ while((line = br.readLine()) != null)
+ Utils.sendMessage(context, replyTo, line);
+ proc.waitFor();
+ } catch (final Exception e){
+ Utils.sendMessage(context, replyTo, error_while_processing_command, e.getClass().getName(), e.getMessage());
+ Log.w(Heavy.class.getName(), "Error while processing command", e);
+ }
}
}