Add SMSQ command that skips delivery reports
[fonbot.git] / src / ro / ieval / fonbot / Utils.java
CommitLineData
8dfb76c9
MG
1package ro.ieval.fonbot;
2
a646935d 3import static ro.ieval.fonbot.R.string.*;
8dfb76c9 4
a97d31fb
MG
5import java.net.MalformedURLException;
6import java.net.URL;
0bcf6b2e 7import java.util.ArrayList;
8dfb76c9
MG
8import java.util.Arrays;
9import java.util.Locale;
10
11import org.eclipse.jdt.annotation.NonNull;
12import org.eclipse.jdt.annotation.Nullable;
13
14import ro.ieval.fonbot.Address.Protocol;
15import android.content.Context;
16import android.content.Intent;
17import android.content.SharedPreferences;
18import android.database.Cursor;
19import android.location.LocationManager;
20import android.media.AudioManager;
21import android.net.Uri;
24ebe041
MG
22import android.os.Handler;
23import android.os.Looper;
8dfb76c9
MG
24import android.preference.PreferenceManager;
25import android.provider.ContactsContract.PhoneLookup;
26import android.telephony.SmsManager;
27import android.util.Log;
28import 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 */
54public 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{
96456689 62 TOAST, ECHO, SMS, SMSQ, FLASH, WIFI,
8dfb76c9
MG
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,
d87d24ba 70 GPS, GLOCATION, REBOOT, NOTIFY, SCREENCAP,
251aceaa 71 TORCH, GETFILE, SH, ROOTSH
8dfb76c9
MG
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 */
582cbf06
MG
94 HEADSET,
95 /** Phone booted notifications */
96 BOOT,
8dfb76c9
MG
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} */
ca40a5cc 168 RING(ringing);
8dfb76c9
MG
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{
dd779ac8
MG
194 if(object==null)
195 throw new NullPointerException();
8dfb76c9
MG
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:
10f7c6fc 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();
8dfb76c9
MG
300 break;
301
302 case SMS:
24ebe041
MG
303 new Handler(Looper.getMainLooper()).post(new Runnable(){
304 @Override
305 public void run(){
0bcf6b2e
MG
306 final ArrayList<String> parts = SmsManager.getDefault().divideMessage(message);
307 SmsManager.getDefault().sendMultipartTextMessage(address.data, null, parts, null, null);
24ebe041
MG
308 }
309 });
8dfb76c9
MG
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
8dfb76c9
MG
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
a97d31fb
MG
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{
1443a929 392 final String protocol=PreferenceManager.getDefaultSharedPreferences(context).getString("protocol", "https");
9717b83e 393 final String hostname=PreferenceManager.getDefaultSharedPreferences(context).getString("hostname", "fonbot.ieval.ro");
29db9532 394 final int port=Integer.parseInt(PreferenceManager.getDefaultSharedPreferences(context).getString("port", "443"));
1443a929 395 final URL url=new URL(protocol, hostname, port, path);
a97d31fb
MG
396 return url;
397 }
398
8dfb76c9
MG
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)){
06a86a92 409 sendMessage(context, replyTo, command_disabled, cmd.toString());
8dfb76c9
MG
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 }
96456689
MG
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);
8dfb76c9
MG
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:
a646935d 658 if(args.length!=3){
8dfb76c9
MG
659 Heavy.help(context, replyTo, toNonNull(Command.PHOTO));
660 break;
661 }
a646935d
MG
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
8dfb76c9
MG
671 final int photoPort;
672 try{
a646935d 673 photoPort=Integer.parseInt(args[2]);
8dfb76c9
MG
674 } catch (NumberFormatException e){
675 sendMessage(context, replyTo, cannot_parse_port);
676 break;
677 }
a646935d 678 Heavy.photo(context, replyTo, cameraNumber, toNonNull(args[1]), photoPort);
8dfb76c9
MG
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:
ca40a5cc 891 Heavy.poll(context, replyTo);
8dfb76c9
MG
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
8dfb76c9
MG
972 case NOTIFY:
973 if(args.length!=1 && args.length!=3){
974 Heavy.help(context, replyTo, toNonNull(Command.NOTIFY));
02c042b0 975 return;
8dfb76c9
MG
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;
0f74646f
MG
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;
d87d24ba
MG
1000
1001 case TORCH:
1002 Heavy.torch(context, replyTo);
1003 break;
740a6fa5
MG
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;
251aceaa
MG
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;
8dfb76c9
MG
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.076951 seconds and 4 git commands to generate.