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