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