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