Replace GCM and polling with long polling
[fonbot.git] / src / ro / ieval / fonbot / Utils.java
1 package ro.ieval.fonbot;
2
3 import static ro.ieval.fonbot.R.string.cannot_parse_count;
4 import static ro.ieval.fonbot.R.string.cannot_parse_interval;
5 import static ro.ieval.fonbot.R.string.cannot_parse_min_distance;
6 import static ro.ieval.fonbot.R.string.cannot_parse_min_time;
7 import static ro.ieval.fonbot.R.string.cannot_parse_port;
8 import static ro.ieval.fonbot.R.string.cannot_parse_provider_allowed_values_are;
9 import static ro.ieval.fonbot.R.string.command_disabled;
10 import static ro.ieval.fonbot.R.string.could_not_parse_argument_allowed_values_are;
11 import static ro.ieval.fonbot.R.string.could_not_parse_ms;
12 import static ro.ieval.fonbot.R.string.error_while_processing_command;
13 import static ro.ieval.fonbot.R.string.invalid_length_allowed_values_are;
14 import static ro.ieval.fonbot.R.string.invalid_ringer_mode_valid_values_are;
15 import static ro.ieval.fonbot.R.string.location_tracking_is_active;
16 import static ro.ieval.fonbot.R.string.messagetype_should_be_one_of;
17 import static ro.ieval.fonbot.R.string.no_such_command_command_list;
18 import static ro.ieval.fonbot.R.string.notification_disabled;
19 import static ro.ieval.fonbot.R.string.notification_enabled;
20 import static ro.ieval.fonbot.R.string.ringing;
21 import static ro.ieval.fonbot.R.string.security_exception;
22 import static ro.ieval.fonbot.R.string.the_polling_service_is_running;
23 import static ro.ieval.fonbot.R.string.the_second_argument_to_wipe_must_be;
24 import static ro.ieval.fonbot.R.string.unknown_command;
25 import static ro.ieval.fonbot.R.string.wipetype_should_be_one_of;
26
27 import java.net.MalformedURLException;
28 import java.net.URL;
29 import java.util.Arrays;
30 import java.util.Locale;
31
32 import org.eclipse.jdt.annotation.NonNull;
33 import org.eclipse.jdt.annotation.Nullable;
34
35 import ro.ieval.fonbot.Address.Protocol;
36 import android.content.Context;
37 import android.content.Intent;
38 import android.content.SharedPreferences;
39 import android.database.Cursor;
40 import android.location.LocationManager;
41 import android.media.AudioManager;
42 import android.net.Uri;
43 import android.preference.PreferenceManager;
44 import android.provider.ContactsContract.PhoneLookup;
45 import android.telephony.SmsManager;
46 import android.util.Log;
47 import android.widget.Toast;
48
49 /*
50 * Copyright © 2013 Marius Gavrilescu
51 *
52 * This file is part of FonBot.
53 *
54 * FonBot is free software: you can redistribute it and/or modify
55 * it under the terms of the GNU General Public License as published by
56 * the Free Software Foundation, either version 3 of the License, or
57 * (at your option) any later version.
58 *
59 * FonBot is distributed in the hope that it will be useful,
60 * but WITHOUT ANY WARRANTY; without even the implied warranty of
61 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
62 * GNU General Public License for more details.
63 *
64 * You should have received a copy of the GNU General Public License
65 * along with FonBot. If not, see <http://www.gnu.org/licenses/>.
66 */
67
68 /**
69 * Utility functions and enums used in various places.
70 *
71 * @author Marius Gavrilescu <marius@ieval.ro>
72 */
73 public final class Utils {
74 /**
75 * Enum of all FonBot commands.
76 *
77 * @author Marius Gavrilescu <marius@ieval.ro>
78 */
79 @SuppressWarnings("javadoc")
80 public static enum Command{
81 TOAST, ECHO, SMS, FLASH, WIFI,
82 BLUETOOTH, DIAL, RING, SPEAK, VIBRATE,
83 DIALOG, LOCATION, NOLOCATION, RINGER, NCFILE,
84 PHOTO, SETNOTIFICATION, DELNOTIFICATION, SETPASSWORD, HELP,
85 WIPE, LOCK, VIEW, PLAY, PAUSE,
86 NEXT, PREV, BATT, CALLLOG, SMSLOG,
87 LS, RM, CONTACTS, DISABLE, ENABLE,
88 POLL, HANGUP, ANSWER, LAUNCH, DATA,
89 GPS, GLOCATION, REBOOT, NOTIFY, SCREENCAP,
90 TORCH
91 }
92
93 /**
94 * Enum of all message types. Each message type is a kind of notification which can be enabled/disabled by the user and directed to a certain address.
95 *
96 * @author Marius Gavrilescu <marius@ieval.ro>
97 *
98 */
99 public static enum MessageType{
100 /** SMS notifications */
101 SMS,
102 /** Phone state (idle, offhook or ringing) notifications */
103 PHONE_STATE,
104 /** Lockscreen failed password notifications */
105 WATCH_LOGIN,
106 /** Device admin enable/disable notifications */
107 ADMIN,
108 /** Coarse battery status (low battery, ok battery) notifications */
109 BATTERY,
110 /** Fine battery status notifications */
111 BATTERY_CHANGED,
112 /** Headset plug/unplug notifications */
113 HEADSET,
114 /** Phone booted notifications */
115 BOOT,
116 }
117
118 /**
119 * Enum of wipe types. The two defined types are the data wipe (which does not include the SD card) and the full wipe (which includes the SD card).
120 *
121 * @author Marius Gavrilescu <marius@ieval.ro>
122 */
123 public static enum WipeType{
124 /** Factory reset the phone, without touching the SD card */
125 DATA,
126 /** Factory reset the phone and wipe the SD card too */
127 FULL
128 }
129
130 /**
131 * Enum of ringer modes.
132 *
133 * @author Marius Gavrilescu <marius@ieval.ro>
134 */
135 public static enum RingerMode{
136 /** Sound is on */
137 NORMAL,
138 /** Sound is off, vibrate is on */
139 VIBRATE,
140 /** Sound is off, vibrate is off */
141 SILENT
142 }
143
144 /**
145 * Enum of location providers
146 *
147 * @author Marius Gavrilescu <marius@ieval.ro>
148 */
149 public static enum LocationProvider{
150 /** The network location provider */
151 NETWORK,
152 /** The GPS location provider */
153 GPS
154 }
155
156 /**
157 * Enum of toast lengths.
158 *
159 * @author Marius Gavrilescu <marius@ieval.ro>
160 */
161 private static enum ToastLength{
162 /** Long toast */
163 LONG,
164 /** Short toast */
165 SHORT
166 }
167
168 /**
169 * Enum of the values on and off. Used for boolean arguments.
170 *
171 * @author Marius Gavrilescu <marius@ieval.ro>
172 */
173 @SuppressWarnings("javadoc")
174 private static enum OnOff{
175 ON, OFF
176 }
177
178 /**
179 * Enum of ongoing event types
180 *
181 * @author Marius Gavrilescu <marius@ieval.ro>
182 */
183 public static enum OngoingEvent{
184 /** Location tracking is active. Registered by {@link Command#LOCATION}, unregistered by {@link Command#NOLOCATION} */
185 LOCATION(location_tracking_is_active),
186 /** The phone is ringing. Registered/unregistered by {@link Command#RING} */
187 RING(ringing);
188
189 /** String resource: the event description */
190 public final int resource;
191
192 /**
193 * Constructs an OngoingEvent from its event description.
194 *
195 * @param resource the event description
196 */
197 private OngoingEvent(final int resource) {
198 this.resource=resource;
199 }
200 }
201
202 /** Confirmation string for the {@link Command#WIPE WIPE} command. */
203 public static final String WIPE_CONFIRM_STRING="I am aware this cannot be undone";
204
205 /**
206 * Converts a Nullable object into a NonNull one.
207 *
208 * @param object the Nullable object to convert
209 * @return a NonNull object equivalent to the Nullable parameter
210 * @throws AssertionError if the given object is null
211 */
212 public static <T> T toNonNull(@Nullable T object) throws AssertionError{
213 if(object==null){
214 Log.wtf(Utils.class.getName(), "toNonNull called with null");
215 throw new AssertionError("Log.wtf did not terminate the process");
216 }
217 return object;
218 }
219
220 /**
221 * Join an array of Objects with elements separated by a separator into a single string.
222 *
223 * @param separator the separator
224 * @param offset the offset into the array
225 * @param args the array of Objects to join
226 * @return the joined string
227 */
228 public static String join(final String separator,final int offset,final Object[] args){
229 final StringBuilder sb=new StringBuilder(240);
230 sb.append(args[offset]);
231 for (int i = offset+1; i < args.length; i++) {
232 sb.append(separator);
233 sb.append(args[i]);
234 }
235 return toNonNull(sb.toString());
236 }
237
238 /**
239 * Join an array of Objects with elements separated by a separator into a single string.
240 *
241 * @param separator the separator
242 * @param args the array of objects to join
243 * @return the joined string
244 */
245 public static String join(final String separator, final Object[] args){
246 return join(separator,0,args);
247 }
248
249 /**
250 * Send a notification to the user.
251 *
252 * @param context Context instance
253 * @param type notification type
254 * @param resource String resource for the message text
255 */
256 public static void sendMessage(final Context context, final MessageType type, final int resource){
257 sendMessage(context, type, toNonNull(context.getString(resource)));
258 }
259
260 /**
261 * Send a notification to the user.
262 *
263 * @param context Context instance
264 * @param type notification type
265 * @param resource String resource for the message text
266 * @param args format parameters for the resource
267 */
268 public static void sendMessage(final Context context, final MessageType type, final int resource, final Object... args){
269 sendMessage(context, type, toNonNull(context.getString(resource, args)));
270 }
271
272 /**
273 * Send a message to a certain Address.
274 *
275 * @param context Context instance
276 * @param address destination Address
277 * @param resource String resource for the message text
278 */
279 public static void sendMessage(final Context context, final Address address, final int resource){
280 sendMessage(context, address, toNonNull(context.getString(resource)));
281 }
282
283 /**
284 * Send a message to a certain Address.
285 *
286 * @param context Context instance
287 * @param address destination Address
288 * @param resource String resource for the message text
289 * @param args format parameters for the resource
290 */
291 public static void sendMessage(final Context context, final Address address, final int resource, final Object... args){
292 sendMessage(context, address, toNonNull(context.getString(resource, args)));
293 }
294
295 /**
296 * Send a notification to the user.
297 *
298 * @param context Context instance
299 * @param type notification type
300 * @param msg the notification text
301 */
302 public static void sendMessage(final Context context, final MessageType type,final String msg){
303 final SharedPreferences sp=PreferenceManager.getDefaultSharedPreferences(context);
304 final String address=sp.getString(type.toString(),null);
305 if(address==null)
306 return;
307 sendMessage(context, new Address(address), msg);
308 }
309
310 /**
311 * Send a message to a certain Address.
312 *
313 * @param context Context instance
314 * @param address destination Address
315 * @param message the message text
316 */
317 public static void sendMessage(final Context context, final Address address, final String message){
318 switch(address.protocol){
319 case HTTP:
320 new HttpCallExecutableRunnable("/send", toNonNull(Arrays.asList(
321 new Header("X-Destination", toNonNull(address.data)))), context, null, true, message).execute();
322 break;
323
324 case SMS:
325 SmsManager.getDefault().sendTextMessage(address.data, null, message, null, null);
326 break;
327
328 case LOCAL:
329 final Intent intent = new Intent(FonBotLocalActivity.RESPONSE_RECEIVED_ACTION);
330 intent.putExtra(FonBotLocalActivity.EXTRA_RESPONSE, message);
331 context.sendBroadcast(intent);
332 break;
333
334 case NULL:
335 break;//blackhole
336 }
337 }
338
339 /**
340 * Splits a string into words.
341 *
342 * @param string the string
343 * @return an array of words
344 */
345 public static String[] shellwords(final String string){
346 return toNonNull(string.split("[ ]+(?=([^\"]*\"[^\"]*\")*[^\"]*$)"));//TODO: Make this handle backslash escapes
347 }
348
349 /**
350 * Returns the name associated with a phone number.
351 *
352 * @param context Context instance
353 * @param number phone number to search for
354 * @return the name associated with this number, or null if the number was not found in the contacts.
355 */
356 public static @Nullable String callerId(final Context context, final String number){
357 final Cursor cursor=context.getContentResolver().query(
358 Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, Uri.encode(number)),
359 new String[]{PhoneLookup.DISPLAY_NAME},
360 null,
361 null,
362 null);
363
364 if(cursor.moveToFirst()){
365 final String name=cursor.getString(0);
366 cursor.close();
367 return name;
368 }
369 cursor.close();
370 return null;
371 }
372
373 /**
374 * Registers an ongoing event.
375 *
376 * @param context Context instance
377 * @param event event to register
378 */
379 public static void registerOngoing(final Context context, final OngoingEvent event){
380 final Intent intent=new Intent(context, FonBotMainService.class);
381 intent.setAction(FonBotMainService.ACTION_PUT_ONGOING);
382 intent.putExtra(FonBotMainService.EXTRA_ONGOING_ID, event.ordinal());
383 context.startService(intent);
384 }
385
386 /**
387 * Unregisters an ongoing event
388 *
389 * @param context Context instance
390 * @param event event to unregister
391 */
392 public static void unregisterOngoing(final Context context, final OngoingEvent event){
393 final Intent intent=new Intent(context, FonBotMainService.class);
394 intent.setAction(FonBotMainService.ACTION_DELETE_ONGOING);
395 intent.putExtra(FonBotMainService.EXTRA_ONGOING_ID, event.ordinal());
396 context.startService(intent);
397 }
398
399 /**
400 * Gets the server URL according to the user preferences.
401 *
402 * @param context Context instance
403 * @param path URL path
404 * @return the server URL
405 * @throws MalformedURLException if the user preferences create an invalid URL
406 */
407 public static URL getServerURL(final Context context, final String path) throws MalformedURLException{
408 final String hostname=PreferenceManager.getDefaultSharedPreferences(context).getString("hostname", "fonbot.ieval.ro");
409 final int port=Integer.parseInt(PreferenceManager.getDefaultSharedPreferences(context).getString("port", "443"));
410 final URL url=new URL("http", hostname, port, path);
411 return url;
412 }
413
414 /**
415 * Executes a given command
416 *
417 * @param context Context instance
418 * @param cmd Command to execute
419 * @param args arguments for the command
420 * @param replyTo Address to send replies to
421 */
422 private static void processCommand(final Context context, final Command cmd,final String[] args,final Address replyTo){
423 if(Heavy.isCommandDisabled(context, cmd)){
424 sendMessage(context, replyTo, command_disabled, cmd.toString());
425 return;
426 }
427
428 switch(cmd){
429 case TOAST:
430 if(args.length < 1 || args.length > 2){
431 Heavy.help(context, replyTo, toNonNull(Command.TOAST));
432 break;
433 }
434
435 if(args.length==1)
436 Heavy.toast(context, replyTo, toNonNull(args[0]));
437 else {
438 try {
439 switch(ToastLength.valueOf(args[1].toUpperCase(Locale.ENGLISH))){
440 case LONG:
441 Heavy.toast(context, replyTo, toNonNull(args[0]), Toast.LENGTH_LONG);
442 break;
443 case SHORT:
444 Heavy.toast(context, replyTo, toNonNull(args[0]), Toast.LENGTH_SHORT);
445 }
446 } catch(IllegalArgumentException e){
447 sendMessage(context, replyTo, invalid_length_allowed_values_are, join(", ",toNonNull(ToastLength.values())));
448 }
449 }
450 break;
451
452 case ECHO:
453 if(args.length==0){
454 Heavy.help(context, replyTo, toNonNull(Command.ECHO));
455 break;
456 }
457 sendMessage(context, replyTo, join(" ",args));
458 break;
459
460 case SMS:
461 if(args.length < 2){
462 Heavy.help(context, replyTo, toNonNull(Command.SMS));
463 break;
464 }
465 Heavy.sms(context, replyTo, toNonNull(args[0]), join(" ", 1, args));
466 break;
467
468 case FLASH:
469 if(args.length != 1){
470 Heavy.help(context, replyTo, toNonNull(Command.FLASH));
471 break;
472 }
473
474 try {
475 Heavy.flash(context, replyTo, OnOff.valueOf(args[0].toUpperCase(Locale.ENGLISH)) == OnOff.ON);
476 } catch(IllegalArgumentException e) {
477 sendMessage(context, replyTo, could_not_parse_argument_allowed_values_are, join(", ", toNonNull(OnOff.values())));
478 }
479 break;
480
481 case WIFI:
482 if(args.length>1){
483 Heavy.help(context, replyTo, toNonNull(Command.WIFI));
484 break;
485 }
486 if(args.length==0)
487 Heavy.wifi(context, replyTo);
488 else {
489 try {
490 Heavy.wifi(context, replyTo, OnOff.valueOf(args[0].toUpperCase(Locale.ENGLISH)) == OnOff.ON);
491 } catch(IllegalArgumentException e) {
492 sendMessage(context, replyTo, could_not_parse_argument_allowed_values_are, join(", ", toNonNull(OnOff.values())));
493 }
494 }
495 break;
496
497 case BLUETOOTH:
498 if(args.length>1){
499 Heavy.help(context, replyTo, toNonNull(Command.BLUETOOTH));
500 break;
501 }
502 if(args.length==0)
503 Heavy.bluetooth(context, replyTo);
504 else {
505 try {
506 Heavy.bluetooth(context, replyTo, OnOff.valueOf(args[0].toUpperCase(Locale.ENGLISH)) == OnOff.ON);
507 } catch(IllegalArgumentException e) {
508 sendMessage(context, replyTo, could_not_parse_argument_allowed_values_are, join(", ", toNonNull(OnOff.values())));
509 }
510 }
511 break;
512
513 case DIAL:
514 if(args.length!=1){
515 Heavy.help(context, replyTo, toNonNull(Command.DIAL));
516 break;
517 }
518 Heavy.dial(context, replyTo, toNonNull(args[0]));
519 break;
520
521 case RING:
522 if(args.length>1){
523 Heavy.help(context, replyTo, toNonNull(Command.RING));
524 break;
525 }
526 if(args.length==0)
527 Heavy.ring(context, replyTo);
528 else {
529 try {
530 Heavy.ring(context, replyTo, OnOff.valueOf(args[0].toUpperCase(Locale.ENGLISH)) == OnOff.ON);
531 } catch(IllegalArgumentException e){
532 sendMessage(context, replyTo, could_not_parse_argument_allowed_values_are, join(", ", toNonNull(OnOff.values())));
533 }
534 }
535 break;
536
537 case SPEAK:
538 if(args.length==0){
539 Heavy.help(context, replyTo, toNonNull(Command.SPEAK));
540 break;
541 }
542 Heavy.speak(context, replyTo, join(" ",args));
543 break;
544
545 case VIBRATE:
546 if(args.length!=1){
547 Heavy.help(context, replyTo, toNonNull(Command.VIBRATE));
548 break;
549 }
550 final long ms;
551 try{
552 ms=Long.parseLong(args[0]);
553 } catch(NumberFormatException e){
554 sendMessage(context, replyTo, could_not_parse_ms);
555 break;
556 }
557 Heavy.vibrate(context, replyTo, ms);
558 break;
559
560 case DIALOG://TODO: Should add an edittext
561 if(args.length<1){
562 Heavy.help(context, replyTo, toNonNull(Command.DIALOG));
563 break;
564 }
565 final String[] buttons=new String[args.length-1];
566 System.arraycopy(args,1,buttons,0,buttons.length);
567 Heavy.dialog(context, replyTo, toNonNull(args[0]), buttons);
568 break;
569
570 case LOCATION:
571 if(args.length>3||args.length<1){
572 Heavy.help(context, replyTo, toNonNull(Command.LOCATION));
573 break;
574 }
575
576 final @NonNull String provider;
577 try{
578 switch(LocationProvider.valueOf(args[0].toUpperCase(Locale.ENGLISH))){
579 case GPS:
580 provider=toNonNull(LocationManager.GPS_PROVIDER);
581 break;
582 case NETWORK:
583 default:
584 provider=toNonNull(LocationManager.NETWORK_PROVIDER);
585 break;
586 }
587 } catch(IllegalArgumentException e){
588 sendMessage(context, replyTo, cannot_parse_provider_allowed_values_are, join(", ",toNonNull(LocationProvider.values())));
589 break;
590 }
591
592 final long minTime;
593 final float minDistance;
594
595 if(args.length>1)
596 try{
597 minTime=Long.parseLong(args[1]);
598 } catch (NumberFormatException e){
599 sendMessage(context, replyTo, cannot_parse_min_time);
600 break;
601 }
602 else
603 minTime=500;
604
605 if(args.length>2)
606 try{
607 minDistance=Float.parseFloat(args[2]);
608 } catch (NumberFormatException e){
609 sendMessage(context, replyTo, cannot_parse_min_distance);
610 break;
611 }
612 else
613 minDistance=0;
614 Heavy.location(context, replyTo, provider, minTime, minDistance);
615 break;
616
617 case NOLOCATION:
618 Heavy.nolocation(context, replyTo);
619 break;
620
621 case RINGER:
622 if(args.length>1){
623 Heavy.help(context, replyTo, toNonNull(Command.RINGER));
624 break;
625 }
626 if(args.length==0)
627 Heavy.ringer(context, replyTo);
628 else{
629 try{
630 final RingerMode rm=RingerMode.valueOf(args[0].toUpperCase(Locale.ENGLISH));
631 switch(rm){
632 case NORMAL:
633 Heavy.ringer(context, replyTo, AudioManager.RINGER_MODE_NORMAL);
634 break;
635 case VIBRATE:
636 Heavy.ringer(context, replyTo, AudioManager.RINGER_MODE_VIBRATE);
637 break;
638 case SILENT:
639 Heavy.ringer(context, replyTo, AudioManager.RINGER_MODE_SILENT);
640 break;
641 }
642 } catch (IllegalArgumentException e){
643 Utils.sendMessage(context, replyTo, invalid_ringer_mode_valid_values_are, join(", ",toNonNull(RingerMode.values())));
644 }
645 }
646 break;
647
648 case NCFILE:
649 if(args.length!=3){
650 Heavy.help(context, replyTo, toNonNull(Command.NCFILE));
651 break;
652 }
653
654 final int ncfilePort;
655 try{
656 ncfilePort=Integer.parseInt(args[2]);
657 } catch (NumberFormatException e){
658 sendMessage(context, replyTo, cannot_parse_port);
659 break;
660 }
661 Heavy.ncfile(context, replyTo, toNonNull(args[0]), toNonNull(args[1]), ncfilePort);
662 break;
663
664 case PHOTO:
665 if(args.length!=2){
666 Heavy.help(context, replyTo, toNonNull(Command.PHOTO));
667 break;
668 }
669 final int photoPort;
670 try{
671 photoPort=Integer.parseInt(args[1]);
672 } catch (NumberFormatException e){
673 sendMessage(context, replyTo, cannot_parse_port);
674 break;
675 }
676 Heavy.photo(context, replyTo, toNonNull(args[0]), photoPort);
677 break;
678
679 case SETNOTIFICATION:
680 if(args.length!=1){
681 Heavy.help(context, replyTo, toNonNull(Command.SETNOTIFICATION));
682 break;
683 }
684
685 try{
686 PreferenceManager.getDefaultSharedPreferences(context).edit()
687 .putString(MessageType.valueOf(args[0].toUpperCase(Locale.ENGLISH)).toString(), replyTo.toString())
688 .commit();
689 sendMessage(context, replyTo, notification_enabled);
690 } catch (IllegalArgumentException e){
691 sendMessage(context, replyTo, messagetype_should_be_one_of, join(", ",toNonNull(MessageType.values())));
692 break;
693 }
694
695 break;
696
697 case DELNOTIFICATION:
698 if(args.length!=1){
699 Heavy.help(context, replyTo, toNonNull(Command.DELNOTIFICATION));
700 break;
701 }
702
703 try{
704 PreferenceManager.getDefaultSharedPreferences(context).edit()
705 .remove(MessageType.valueOf(args[0].toUpperCase(Locale.ENGLISH)).toString())
706 .commit();
707 sendMessage(context, replyTo, notification_disabled);
708 } catch (IllegalArgumentException e){
709 sendMessage(context, replyTo, messagetype_should_be_one_of, join(", ",toNonNull(MessageType.values())));
710 break;
711 }
712
713
714 break;
715 case SETPASSWORD:
716 if(args.length > 1){
717 Heavy.help(context, replyTo, toNonNull(Command.SETPASSWORD));
718 break;
719 }
720
721 try{
722 if(args.length==0)
723 Heavy.setPassword(context, replyTo);
724 else
725 Heavy.setPassword(context, replyTo, toNonNull(args[0]));
726 } catch (SecurityException e){
727 sendMessage(context, replyTo, security_exception+e.getMessage());
728 }
729 break;
730
731 case WIPE:
732 if(args.length!=2){
733 Heavy.help(context, replyTo, toNonNull(Command.WIPE));
734 break;
735 }
736
737 if(!args[1].equalsIgnoreCase(WIPE_CONFIRM_STRING)){
738 sendMessage(context, replyTo, the_second_argument_to_wipe_must_be, WIPE_CONFIRM_STRING);
739 break;
740 }
741
742 try{
743 Heavy.wipe(context, toNonNull(WipeType.valueOf(args[0].toUpperCase(Locale.ENGLISH))));
744 } catch (IllegalArgumentException e){
745 sendMessage(context, replyTo, wipetype_should_be_one_of, join (", ",toNonNull(WipeType.values())));
746 } catch (SecurityException e){
747 sendMessage(context, replyTo, security_exception, e.getMessage());
748 }
749 break;
750
751 case LOCK:
752 try{
753 Heavy.lock(context, replyTo);
754 } catch (SecurityException e){
755 sendMessage(context, replyTo, security_exception, e.getMessage());
756 }
757 break;
758
759 case VIEW:
760 if(args.length!=1){
761 Heavy.help(context, replyTo, toNonNull(Command.VIEW));
762 break;
763 }
764
765 Heavy.view(context, replyTo, toNonNull(Uri.parse(args[0])));
766 break;
767
768 case PLAY:
769 Heavy.musicPlayerCommand(context, replyTo, "play");
770 break;
771
772 case PAUSE:
773 Heavy.musicPlayerCommand(context, replyTo, "pause");
774 break;
775
776 case NEXT:
777 Heavy.musicPlayerCommand(context, replyTo, "next");
778 break;
779
780 case PREV:
781 Heavy.musicPlayerCommand(context, replyTo, "previous");
782 break;
783
784 case BATT:
785 Heavy.batt(context, replyTo);
786 break;
787
788 case CALLLOG:
789 if (args.length > 1) {
790 Heavy.help(context, replyTo, toNonNull(Command.CALLLOG));
791 break;
792 }
793
794 if (args.length == 0)
795 Heavy.calllog(context, replyTo, 5);
796 else {
797 try {
798 Heavy.calllog(context, replyTo, Integer.parseInt(args[0]));
799 } catch (IllegalArgumentException e){
800 sendMessage(context, replyTo, cannot_parse_count);
801 }
802 }
803 break;
804
805 case SMSLOG:
806 if (args.length > 1) {
807 Heavy.help(context, replyTo, toNonNull(Command.SMSLOG));
808 break;
809 }
810
811 if (args.length == 0)
812 Heavy.smslog(context, replyTo, 5);
813 else {
814 try {
815 Heavy.smslog(context, replyTo, Integer.parseInt(args[0]));
816 } catch (IllegalArgumentException e) {
817 sendMessage(context, replyTo, cannot_parse_count);
818 }
819 }
820 break;
821
822 case HELP:
823 if(args.length != 1){
824 Heavy.help(context, replyTo, toNonNull(Command.HELP));
825 break;
826 }
827
828 try {
829 Heavy.help(context, replyTo, toNonNull(Command.valueOf(args[0].toUpperCase(Locale.ENGLISH))));
830 } catch (IllegalArgumentException e) {
831 sendMessage(context, replyTo, no_such_command_command_list, join(", ", toNonNull(Command.values())));
832 }
833 break;
834
835 case LS:
836 if(args.length != 1){
837 Heavy.help(context, replyTo, toNonNull(Command.LS));
838 break;
839 }
840
841 Heavy.ls(context, replyTo, toNonNull(args[0]));
842 break;
843
844 case RM:
845 if(args.length != 1){
846 Heavy.help(context, replyTo, toNonNull(Command.RM));
847 break;
848 }
849
850 Heavy.rm(context, replyTo, toNonNull(args[0]));
851 break;
852
853 case CONTACTS:
854 if(args.length != 1){
855 Heavy.help(context, replyTo, toNonNull(Command.CONTACTS));
856 break;
857 }
858
859 Heavy.contacts(context, replyTo, toNonNull(args[0]));
860 break;
861
862 case DISABLE:
863 if(replyTo.protocol != Protocol.LOCAL || args.length != 1){
864 Heavy.help(context, replyTo, toNonNull(Command.DISABLE));
865 break;
866 }
867
868 try{
869 Heavy.disable(context, replyTo, toNonNull(Command.valueOf(args[0].toUpperCase(Locale.ENGLISH))));
870 } catch (IllegalArgumentException e){
871 sendMessage(context, replyTo, no_such_command_command_list, join(", ", toNonNull(Command.values())));
872 }
873 break;
874
875 case ENABLE:
876 if(replyTo.protocol != Protocol.LOCAL || args.length != 1){
877 Heavy.help(context, replyTo, toNonNull(Command.ENABLE));
878 break;
879 }
880
881 try{
882 Heavy.enable(context, replyTo, toNonNull(Command.valueOf(args[0].toUpperCase(Locale.ENGLISH))));
883 } catch (IllegalArgumentException e){
884 sendMessage(context, replyTo, no_such_command_command_list, join(", ", toNonNull(Command.values())));
885 }
886 break;
887
888 case POLL:
889 Heavy.poll(context, replyTo);
890 break;
891
892 case HANGUP:
893 Heavy.hangup(context, replyTo);
894 break;
895
896 case ANSWER:
897 Heavy.answer(context, replyTo);
898 break;
899
900 case LAUNCH:
901 if(args.length!=1){
902 Heavy.help(context, replyTo, toNonNull(Command.LAUNCH));
903 break;
904 }
905 Heavy.launch(context, replyTo, toNonNull(args[0]));
906 break;
907
908 case DATA:
909 if(args.length>1){
910 Heavy.help(context, replyTo, toNonNull(Command.DATA));
911 break;
912 }
913
914 if(args.length==0){
915 Heavy.data(context, replyTo);
916 break;
917 }
918 try {
919 Heavy.data(context, replyTo, OnOff.valueOf(args[0].toUpperCase(Locale.ENGLISH)) == OnOff.ON);
920 } catch(IllegalArgumentException e) {
921 sendMessage(context, replyTo, could_not_parse_argument_allowed_values_are, join(", ", toNonNull(OnOff.values())));
922 }
923 break;
924
925 case GPS:
926 if(args.length>1){
927 Heavy.help(context, replyTo, toNonNull(Command.GPS));
928 break;
929 }
930
931 if(args.length==0){
932 Heavy.gps(context, replyTo);
933 break;
934 }
935
936 try {
937 Heavy.gps(context, replyTo, OnOff.valueOf(args[0].toUpperCase(Locale.ENGLISH)) == OnOff.ON);
938 } catch(IllegalArgumentException e) {
939 sendMessage(context, replyTo, could_not_parse_argument_allowed_values_are, join(", ", toNonNull(OnOff.values())));
940 }
941 break;
942
943 case GLOCATION:
944 if(args.length>1){
945 Heavy.help(context, replyTo, toNonNull(Command.GLOCATION));
946 break;
947 }
948
949 if(args.length==0){
950 Heavy.glocation(context, replyTo);
951 break;
952 }
953
954 try {
955 Heavy.glocation(context, replyTo, OnOff.valueOf(args[0].toUpperCase(Locale.ENGLISH)) == OnOff.ON);
956 } catch(IllegalArgumentException e) {
957 sendMessage(context, replyTo, could_not_parse_argument_allowed_values_are, join(", ", toNonNull(OnOff.values())));
958 }
959 break;
960
961 case REBOOT:
962 if(args.length>1){
963 Heavy.help(context, replyTo, toNonNull(Command.REBOOT));
964 break;
965 }
966
967 Heavy.reboot(context, replyTo, args.length==0?null:args[0]);
968 break;
969
970 case NOTIFY:
971 if(args.length!=1 && args.length!=3){
972 Heavy.help(context, replyTo, toNonNull(Command.NOTIFY));
973 return;
974 }
975
976 final int id;
977 try{
978 id=Integer.parseInt(args[0]);
979 } catch (NumberFormatException e){
980 sendMessage(context, replyTo, R.string.could_not_parse_id);
981 break;
982 }
983
984 if(args.length==1)
985 Heavy.notify(context, replyTo, id);
986 else
987 Heavy.notify(context, replyTo, id, toNonNull(args[1]), toNonNull(args[2]));
988 break;
989
990 case SCREENCAP:
991 if(args.length != 1){
992 Heavy.help(context, replyTo, toNonNull(Command.SCREENCAP));
993 return;
994 }
995
996 Heavy.screencap(context, replyTo, args[0]);
997 break;
998
999 case TORCH:
1000 Heavy.torch(context, replyTo);
1001 break;
1002 }
1003
1004 }
1005
1006 /**
1007 * Executes a given command
1008 *
1009 * @param context Context instance
1010 * @param cmd Command to execute
1011 * @param args arguments for the command
1012 * @param replyTo Address to send replies to
1013 */
1014 public static void processCommand(final Context context, final String cmd,final String[] args,final Address replyTo){
1015 final @NonNull Command command;
1016 try{
1017 command=toNonNull(Command.valueOf(cmd.toUpperCase(Locale.ENGLISH)));
1018 } catch (IllegalArgumentException e){
1019 sendMessage(context, replyTo, unknown_command, cmd.toUpperCase(Locale.ENGLISH), e.getMessage());
1020 return;
1021 }
1022
1023 try{
1024 processCommand(context, command,args,replyTo);
1025 } catch(Exception e){
1026 sendMessage(context, replyTo, error_while_processing_command, e.getClass().getName(), e.getMessage());
1027 Log.w(Utils.class.getName(), "Error while processing command", e);
1028 }
1029 }
1030 }
This page took 0.051048 seconds and 4 git commands to generate.