X-Git-Url: http://git.ieval.ro/?a=blobdiff_plain;f=src%2Fro%2Fieval%2Ffonbot%2FUtils.java;h=40a5e57dfbf66a93a52b772b4de9fe7201544647;hb=a5259b32f390d9adf8bca1b7a4bbb620bde11479;hp=79ff2e1e37236de3b571e246f434415827527ed0;hpb=582cbf066b7c47eecef759ca0755649a6bc0e39e;p=fonbot.git diff --git a/src/ro/ieval/fonbot/Utils.java b/src/ro/ieval/fonbot/Utils.java index 79ff2e1..40a5e57 100644 --- a/src/ro/ieval/fonbot/Utils.java +++ b/src/ro/ieval/fonbot/Utils.java @@ -1,31 +1,10 @@ package ro.ieval.fonbot; -import static ro.ieval.fonbot.R.string.cannot_parse_count; -import static ro.ieval.fonbot.R.string.cannot_parse_interval; -import static ro.ieval.fonbot.R.string.cannot_parse_min_distance; -import static ro.ieval.fonbot.R.string.cannot_parse_min_time; -import static ro.ieval.fonbot.R.string.cannot_parse_port; -import static ro.ieval.fonbot.R.string.cannot_parse_provider_allowed_values_are; -import static ro.ieval.fonbot.R.string.command_disabled; -import static ro.ieval.fonbot.R.string.could_not_parse_argument_allowed_values_are; -import static ro.ieval.fonbot.R.string.could_not_parse_ms; -import static ro.ieval.fonbot.R.string.error_while_processing_command; -import static ro.ieval.fonbot.R.string.invalid_length_allowed_values_are; -import static ro.ieval.fonbot.R.string.invalid_ringer_mode_valid_values_are; -import static ro.ieval.fonbot.R.string.location_tracking_is_active; -import static ro.ieval.fonbot.R.string.messagetype_should_be_one_of; -import static ro.ieval.fonbot.R.string.no_such_command_command_list; -import static ro.ieval.fonbot.R.string.notification_disabled; -import static ro.ieval.fonbot.R.string.notification_enabled; -import static ro.ieval.fonbot.R.string.ringing; -import static ro.ieval.fonbot.R.string.security_exception; -import static ro.ieval.fonbot.R.string.the_polling_service_is_running; -import static ro.ieval.fonbot.R.string.the_second_argument_to_wipe_must_be; -import static ro.ieval.fonbot.R.string.unknown_command; -import static ro.ieval.fonbot.R.string.wipetype_should_be_one_of; +import static ro.ieval.fonbot.R.string.*; import java.net.MalformedURLException; import java.net.URL; +import java.util.ArrayList; import java.util.Arrays; import java.util.Locale; @@ -40,6 +19,8 @@ import android.database.Cursor; import android.location.LocationManager; import android.media.AudioManager; import android.net.Uri; +import android.os.Handler; +import android.os.Looper; import android.preference.PreferenceManager; import android.provider.ContactsContract.PhoneLookup; import android.telephony.SmsManager; @@ -78,7 +59,7 @@ public final class Utils { */ @SuppressWarnings("javadoc") public static enum Command{ - TOAST, ECHO, SMS, FLASH, WIFI, + TOAST, ECHO, SMS, SMSQ, FLASH, WIFI, BLUETOOTH, DIAL, RING, SPEAK, VIBRATE, DIALOG, LOCATION, NOLOCATION, RINGER, NCFILE, PHOTO, SETNOTIFICATION, DELNOTIFICATION, SETPASSWORD, HELP, @@ -87,7 +68,7 @@ public final class Utils { LS, RM, CONTACTS, DISABLE, ENABLE, POLL, HANGUP, ANSWER, LAUNCH, DATA, GPS, GLOCATION, REBOOT, NOTIFY, SCREENCAP, - TORCH + TORCH, GETFILE, SH, ROOTSH } /** @@ -184,9 +165,7 @@ public final class Utils { /** Location tracking is active. Registered by {@link Command#LOCATION}, unregistered by {@link Command#NOLOCATION} */ LOCATION(location_tracking_is_active), /** The phone is ringing. Registered/unregistered by {@link Command#RING} */ - RING(ringing), - /** The polling alarm is on. Registered/unregistered by {@link Command#POLL} */ - POLL(the_polling_service_is_running); + RING(ringing); /** String resource: the event description */ public final int resource; @@ -212,10 +191,8 @@ public final class Utils { * @throws AssertionError if the given object is null */ public static T toNonNull(@Nullable T object) throws AssertionError{ - if(object==null){ - Log.wtf(Utils.class.getName(), "toNonNull called with null"); - throw new AssertionError("Log.wtf did not terminate the process"); - } + if(object==null) + throw new NullPointerException(); return object; } @@ -294,6 +271,22 @@ public final class Utils { sendMessage(context, address, toNonNull(context.getString(resource, args))); } + /** + * Send a confirmation message to a certain Address. A confirm message is a message that: + * 1) Confers no information (except for confirming that the command was executed). + * 2) May be dropped if the user asked so. + * + * @param context Context instance + * @param address destination Address + * @param resource String resource for the message text + * @param args format parameters for the resource + */ + public static void sendConfirmMessage(final Context context, final Address address, final int resource, final Object... args){ + final SharedPreferences sp=PreferenceManager.getDefaultSharedPreferences(context); + if(address.protocol != Protocol.SMS || !sp.getBoolean("expensive_sms", false)) + sendMessage(context, address, resource, args); + } + /** * Send a notification to the user. * @@ -319,12 +312,17 @@ public final class Utils { public static void sendMessage(final Context context, final Address address, final String message){ switch(address.protocol){ case HTTP: - new HttpCallExecutableRunnable("/send", toNonNull(Arrays.asList( - new Header("X-Destination", toNonNull(address.data)))), context, null, true, message).execute(); + new HttpCallExecutableRunnable("/send", toNonNull(Arrays.asList(new Header("X-Destination", toNonNull(address.data)))), context, null, true, address.requestId == null ? message : address.requestId + " " + message).execute(); break; case SMS: - SmsManager.getDefault().sendTextMessage(address.data, null, message, null, null); + new Handler(Looper.getMainLooper()).post(new Runnable(){ + @Override + public void run(){ + final ArrayList parts = SmsManager.getDefault().divideMessage(message); + SmsManager.getDefault().sendMultipartTextMessage(address.data, null, parts, null, null); + } + }); break; case LOCAL: @@ -407,31 +405,13 @@ public final class Utils { * @throws MalformedURLException if the user preferences create an invalid URL */ public static URL getServerURL(final Context context, final String path) throws MalformedURLException{ + final String protocol=PreferenceManager.getDefaultSharedPreferences(context).getString("protocol", "https"); final String hostname=PreferenceManager.getDefaultSharedPreferences(context).getString("hostname", "fonbot.ieval.ro"); final int port=Integer.parseInt(PreferenceManager.getDefaultSharedPreferences(context).getString("port", "443")); - final URL url=new URL("https", hostname, port, path); + final URL url=new URL(protocol, hostname, port, path); return url; } - /** - * Poll the server for pending commands. This function must not be called from BroadcastReceivers - * - * @param context Context instance - */ - public static void pollServer(final Context context){ - new HttpCallExecutableRunnable("/get", null, context, new PollResultCallback(context), false).execute(); - } - - /** - * Poll the server for pending commands from {@link FonBotMainService}. This function should be used from BroadcastReceviers instead of {@link #pollServer} - * - * @param context Context instance - */ - public static void safePollServer(final Context context){ - final Intent intent=new Intent(context, FonBotMainService.class); - intent.setAction(FonBotMainService.ACTION_TRIGGER_POLL); - context.startService(intent); - } /** * Executes a given command * @@ -483,7 +463,15 @@ public final class Utils { Heavy.help(context, replyTo, toNonNull(Command.SMS)); break; } - Heavy.sms(context, replyTo, toNonNull(args[0]), join(" ", 1, args)); + Heavy.sms(context, replyTo, toNonNull(args[0]), join(" ", 1, args), false); + break; + + case SMSQ: + if(args.length < 2){ + Heavy.help(context, replyTo, toNonNull(Command.SMSQ)); + break; + } + Heavy.sms(context, replyTo, toNonNull(args[0]), join(" ", 1, args), true); break; case FLASH: @@ -683,18 +671,27 @@ public final class Utils { break; case PHOTO: - if(args.length!=2){ + if(args.length!=3){ Heavy.help(context, replyTo, toNonNull(Command.PHOTO)); break; } + + final int cameraNumber; + try{ + cameraNumber=Integer.parseInt(args[0]); + } catch (NumberFormatException e){ + sendMessage(context, replyTo, cannot_parse_camera_number); + break; + } + final int photoPort; try{ - photoPort=Integer.parseInt(args[1]); + photoPort=Integer.parseInt(args[2]); } catch (NumberFormatException e){ sendMessage(context, replyTo, cannot_parse_port); break; } - Heavy.photo(context, replyTo, toNonNull(args[0]), photoPort); + Heavy.photo(context, replyTo, cameraNumber, toNonNull(args[1]), photoPort); break; case SETNOTIFICATION: @@ -707,7 +704,7 @@ public final class Utils { PreferenceManager.getDefaultSharedPreferences(context).edit() .putString(MessageType.valueOf(args[0].toUpperCase(Locale.ENGLISH)).toString(), replyTo.toString()) .commit(); - sendMessage(context, replyTo, notification_enabled); + sendConfirmMessage(context, replyTo, notification_enabled); } catch (IllegalArgumentException e){ sendMessage(context, replyTo, messagetype_should_be_one_of, join(", ",toNonNull(MessageType.values()))); break; @@ -725,7 +722,7 @@ public final class Utils { PreferenceManager.getDefaultSharedPreferences(context).edit() .remove(MessageType.valueOf(args[0].toUpperCase(Locale.ENGLISH)).toString()) .commit(); - sendMessage(context, replyTo, notification_disabled); + sendConfirmMessage(context, replyTo, notification_disabled); } catch (IllegalArgumentException e){ sendMessage(context, replyTo, messagetype_should_be_one_of, join(", ",toNonNull(MessageType.values()))); break; @@ -745,7 +742,7 @@ public final class Utils { else Heavy.setPassword(context, replyTo, toNonNull(args[0])); } catch (SecurityException e){ - sendMessage(context, replyTo, security_exception+e.getMessage()); + sendMessage(context, replyTo, security_exception, e.getMessage()); } break; @@ -907,25 +904,7 @@ public final class Utils { break; case POLL: - if(args.length>1){ - Heavy.help(context, replyTo, toNonNull(Command.POLL)); - break; - } - - if(args.length==0){ - Heavy.poll(context, replyTo); - break; - } - - final long interval; - try{ - interval=Long.parseLong(args[0]); - } catch(NumberFormatException e){ - sendMessage(context, replyTo, cannot_parse_interval); - break; - } - - Heavy.poll(context, replyTo, interval); + Heavy.poll(context, replyTo); break; case HANGUP: @@ -1038,6 +1017,40 @@ public final class Utils { case TORCH: Heavy.torch(context, replyTo); break; + + case GETFILE: + if(args.length != 3){ + Heavy.help(context, replyTo, toNonNull(Command.GETFILE)); + return; + } + + final int getfilePort; + try{ + getfilePort=Integer.parseInt(args[2]); + } catch (NumberFormatException e){ + sendMessage(context, replyTo, cannot_parse_port); + break; + } + Heavy.getfile(context, replyTo, toNonNull(args[0]), toNonNull(args[1]), getfilePort); + break; + + case SH: + if(args.length == 0){ + Heavy.help(context, replyTo, toNonNull(Command.SH)); + return; + } + + Heavy.execute(context, replyTo, "sh", join(" ", args)); + break; + + case ROOTSH: + if(args.length == 0){ + Heavy.help(context, replyTo, toNonNull(Command.ROOTSH)); + return; + } + + Heavy.execute(context, replyTo, "su", join(" ", args)); + break; } }