Let users disable command confirmations over SMS
[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
a5259b32
MG
274 /**
275 * Send a confirmation message to a certain Address. A confirm message is a message that:
276 * 1) Confers no information (except for confirming that the command was executed).
277 * 2) May be dropped if the user asked so.
278 *
279 * @param context Context instance
280 * @param address destination Address
281 * @param resource String resource for the message text
282 * @param args format parameters for the resource
283 */
284 public static void sendConfirmMessage(final Context context, final Address address, final int resource, final Object... args){
285 final SharedPreferences sp=PreferenceManager.getDefaultSharedPreferences(context);
286 if(address.protocol != Protocol.SMS || !sp.getBoolean("expensive_sms", false))
287 sendMessage(context, address, resource, args);
288 }
289
8dfb76c9
MG
290 /**
291 * Send a notification to the user.
292 *
293 * @param context Context instance
294 * @param type notification type
295 * @param msg the notification text
296 */
297 public static void sendMessage(final Context context, final MessageType type,final String msg){
298 final SharedPreferences sp=PreferenceManager.getDefaultSharedPreferences(context);
299 final String address=sp.getString(type.toString(),null);
300 if(address==null)
301 return;
302 sendMessage(context, new Address(address), msg);
303 }
304
305 /**
306 * Send a message to a certain Address.
307 *
308 * @param context Context instance
309 * @param address destination Address
310 * @param message the message text
311 */
312 public static void sendMessage(final Context context, final Address address, final String message){
313 switch(address.protocol){
314 case HTTP:
10f7c6fc 315 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
316 break;
317
318 case SMS:
24ebe041
MG
319 new Handler(Looper.getMainLooper()).post(new Runnable(){
320 @Override
321 public void run(){
0bcf6b2e
MG
322 final ArrayList<String> parts = SmsManager.getDefault().divideMessage(message);
323 SmsManager.getDefault().sendMultipartTextMessage(address.data, null, parts, null, null);
24ebe041
MG
324 }
325 });
8dfb76c9
MG
326 break;
327
328 case LOCAL:
329 final Intent intent = new Intent(FonBotLocalActivity.RESPONSE_RECEIVED_ACTION);
330 intent.putExtra(FonBotLocalActivity.EXTRA_RESPONSE, message);
331 context.sendBroadcast(intent);
332 break;
333
334 case NULL:
335 break;//blackhole
336 }
337 }
338
8dfb76c9
MG
339 /**
340 * Splits a string into words.
341 *
342 * @param string the string
343 * @return an array of words
344 */
345 public static String[] shellwords(final String string){
346 return toNonNull(string.split("[ ]+(?=([^\"]*\"[^\"]*\")*[^\"]*$)"));//TODO: Make this handle backslash escapes
347 }
348
349 /**
350 * Returns the name associated with a phone number.
351 *
352 * @param context Context instance
353 * @param number phone number to search for
354 * @return the name associated with this number, or null if the number was not found in the contacts.
355 */
356 public static @Nullable String callerId(final Context context, final String number){
357 final Cursor cursor=context.getContentResolver().query(
358 Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, Uri.encode(number)),
359 new String[]{PhoneLookup.DISPLAY_NAME},
360 null,
361 null,
362 null);
363
364 if(cursor.moveToFirst()){
365 final String name=cursor.getString(0);
366 cursor.close();
367 return name;
368 }
369 cursor.close();
370 return null;
371 }
372
373 /**
374 * Registers an ongoing event.
375 *
376 * @param context Context instance
377 * @param event event to register
378 */
379 public static void registerOngoing(final Context context, final OngoingEvent event){
380 final Intent intent=new Intent(context, FonBotMainService.class);
381 intent.setAction(FonBotMainService.ACTION_PUT_ONGOING);
382 intent.putExtra(FonBotMainService.EXTRA_ONGOING_ID, event.ordinal());
383 context.startService(intent);
384 }
385
386 /**
387 * Unregisters an ongoing event
388 *
389 * @param context Context instance
390 * @param event event to unregister
391 */
392 public static void unregisterOngoing(final Context context, final OngoingEvent event){
393 final Intent intent=new Intent(context, FonBotMainService.class);
394 intent.setAction(FonBotMainService.ACTION_DELETE_ONGOING);
395 intent.putExtra(FonBotMainService.EXTRA_ONGOING_ID, event.ordinal());
396 context.startService(intent);
397 }
398
a97d31fb
MG
399 /**
400 * Gets the server URL according to the user preferences.
401 *
402 * @param context Context instance
403 * @param path URL path
404 * @return the server URL
405 * @throws MalformedURLException if the user preferences create an invalid URL
406 */
407 public static URL getServerURL(final Context context, final String path) throws MalformedURLException{
1443a929 408 final String protocol=PreferenceManager.getDefaultSharedPreferences(context).getString("protocol", "https");
9717b83e 409 final String hostname=PreferenceManager.getDefaultSharedPreferences(context).getString("hostname", "fonbot.ieval.ro");
29db9532 410 final int port=Integer.parseInt(PreferenceManager.getDefaultSharedPreferences(context).getString("port", "443"));
1443a929 411 final URL url=new URL(protocol, hostname, port, path);
a97d31fb
MG
412 return url;
413 }
414
8dfb76c9
MG
415 /**
416 * Executes a given command
417 *
418 * @param context Context instance
419 * @param cmd Command to execute
420 * @param args arguments for the command
421 * @param replyTo Address to send replies to
422 */
423 private static void processCommand(final Context context, final Command cmd,final String[] args,final Address replyTo){
424 if(Heavy.isCommandDisabled(context, cmd)){
06a86a92 425 sendMessage(context, replyTo, command_disabled, cmd.toString());
8dfb76c9
MG
426 return;
427 }
428
429 switch(cmd){
430 case TOAST:
431 if(args.length < 1 || args.length > 2){
432 Heavy.help(context, replyTo, toNonNull(Command.TOAST));
433 break;
434 }
435
436 if(args.length==1)
437 Heavy.toast(context, replyTo, toNonNull(args[0]));
438 else {
439 try {
440 switch(ToastLength.valueOf(args[1].toUpperCase(Locale.ENGLISH))){
441 case LONG:
442 Heavy.toast(context, replyTo, toNonNull(args[0]), Toast.LENGTH_LONG);
443 break;
444 case SHORT:
445 Heavy.toast(context, replyTo, toNonNull(args[0]), Toast.LENGTH_SHORT);
446 }
447 } catch(IllegalArgumentException e){
448 sendMessage(context, replyTo, invalid_length_allowed_values_are, join(", ",toNonNull(ToastLength.values())));
449 }
450 }
451 break;
452
453 case ECHO:
454 if(args.length==0){
455 Heavy.help(context, replyTo, toNonNull(Command.ECHO));
456 break;
457 }
458 sendMessage(context, replyTo, join(" ",args));
459 break;
460
461 case SMS:
462 if(args.length < 2){
463 Heavy.help(context, replyTo, toNonNull(Command.SMS));
464 break;
465 }
96456689
MG
466 Heavy.sms(context, replyTo, toNonNull(args[0]), join(" ", 1, args), false);
467 break;
468
469 case SMSQ:
470 if(args.length < 2){
471 Heavy.help(context, replyTo, toNonNull(Command.SMSQ));
472 break;
473 }
474 Heavy.sms(context, replyTo, toNonNull(args[0]), join(" ", 1, args), true);
8dfb76c9
MG
475 break;
476
477 case FLASH:
478 if(args.length != 1){
479 Heavy.help(context, replyTo, toNonNull(Command.FLASH));
480 break;
481 }
482
483 try {
484 Heavy.flash(context, replyTo, OnOff.valueOf(args[0].toUpperCase(Locale.ENGLISH)) == OnOff.ON);
485 } catch(IllegalArgumentException e) {
486 sendMessage(context, replyTo, could_not_parse_argument_allowed_values_are, join(", ", toNonNull(OnOff.values())));
487 }
488 break;
489
490 case WIFI:
491 if(args.length>1){
492 Heavy.help(context, replyTo, toNonNull(Command.WIFI));
493 break;
494 }
495 if(args.length==0)
496 Heavy.wifi(context, replyTo);
497 else {
498 try {
499 Heavy.wifi(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 BLUETOOTH:
507 if(args.length>1){
508 Heavy.help(context, replyTo, toNonNull(Command.BLUETOOTH));
509 break;
510 }
511 if(args.length==0)
512 Heavy.bluetooth(context, replyTo);
513 else {
514 try {
515 Heavy.bluetooth(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 DIAL:
523 if(args.length!=1){
524 Heavy.help(context, replyTo, toNonNull(Command.DIAL));
525 break;
526 }
527 Heavy.dial(context, replyTo, toNonNull(args[0]));
528 break;
529
530 case RING:
531 if(args.length>1){
532 Heavy.help(context, replyTo, toNonNull(Command.RING));
533 break;
534 }
535 if(args.length==0)
536 Heavy.ring(context, replyTo);
537 else {
538 try {
539 Heavy.ring(context, replyTo, OnOff.valueOf(args[0].toUpperCase(Locale.ENGLISH)) == OnOff.ON);
540 } catch(IllegalArgumentException e){
541 sendMessage(context, replyTo, could_not_parse_argument_allowed_values_are, join(", ", toNonNull(OnOff.values())));
542 }
543 }
544 break;
545
546 case SPEAK:
547 if(args.length==0){
548 Heavy.help(context, replyTo, toNonNull(Command.SPEAK));
549 break;
550 }
551 Heavy.speak(context, replyTo, join(" ",args));
552 break;
553
554 case VIBRATE:
555 if(args.length!=1){
556 Heavy.help(context, replyTo, toNonNull(Command.VIBRATE));
557 break;
558 }
559 final long ms;
560 try{
561 ms=Long.parseLong(args[0]);
562 } catch(NumberFormatException e){
563 sendMessage(context, replyTo, could_not_parse_ms);
564 break;
565 }
566 Heavy.vibrate(context, replyTo, ms);
567 break;
568
569 case DIALOG://TODO: Should add an edittext
570 if(args.length<1){
571 Heavy.help(context, replyTo, toNonNull(Command.DIALOG));
572 break;
573 }
574 final String[] buttons=new String[args.length-1];
575 System.arraycopy(args,1,buttons,0,buttons.length);
576 Heavy.dialog(context, replyTo, toNonNull(args[0]), buttons);
577 break;
578
579 case LOCATION:
580 if(args.length>3||args.length<1){
581 Heavy.help(context, replyTo, toNonNull(Command.LOCATION));
582 break;
583 }
584
585 final @NonNull String provider;
586 try{
587 switch(LocationProvider.valueOf(args[0].toUpperCase(Locale.ENGLISH))){
588 case GPS:
589 provider=toNonNull(LocationManager.GPS_PROVIDER);
590 break;
591 case NETWORK:
592 default:
593 provider=toNonNull(LocationManager.NETWORK_PROVIDER);
594 break;
595 }
596 } catch(IllegalArgumentException e){
597 sendMessage(context, replyTo, cannot_parse_provider_allowed_values_are, join(", ",toNonNull(LocationProvider.values())));
598 break;
599 }
600
601 final long minTime;
602 final float minDistance;
603
604 if(args.length>1)
605 try{
606 minTime=Long.parseLong(args[1]);
607 } catch (NumberFormatException e){
608 sendMessage(context, replyTo, cannot_parse_min_time);
609 break;
610 }
611 else
612 minTime=500;
613
614 if(args.length>2)
615 try{
616 minDistance=Float.parseFloat(args[2]);
617 } catch (NumberFormatException e){
618 sendMessage(context, replyTo, cannot_parse_min_distance);
619 break;
620 }
621 else
622 minDistance=0;
623 Heavy.location(context, replyTo, provider, minTime, minDistance);
624 break;
625
626 case NOLOCATION:
627 Heavy.nolocation(context, replyTo);
628 break;
629
630 case RINGER:
631 if(args.length>1){
632 Heavy.help(context, replyTo, toNonNull(Command.RINGER));
633 break;
634 }
635 if(args.length==0)
636 Heavy.ringer(context, replyTo);
637 else{
638 try{
639 final RingerMode rm=RingerMode.valueOf(args[0].toUpperCase(Locale.ENGLISH));
640 switch(rm){
641 case NORMAL:
642 Heavy.ringer(context, replyTo, AudioManager.RINGER_MODE_NORMAL);
643 break;
644 case VIBRATE:
645 Heavy.ringer(context, replyTo, AudioManager.RINGER_MODE_VIBRATE);
646 break;
647 case SILENT:
648 Heavy.ringer(context, replyTo, AudioManager.RINGER_MODE_SILENT);
649 break;
650 }
651 } catch (IllegalArgumentException e){
652 Utils.sendMessage(context, replyTo, invalid_ringer_mode_valid_values_are, join(", ",toNonNull(RingerMode.values())));
653 }
654 }
655 break;
656
657 case NCFILE:
658 if(args.length!=3){
659 Heavy.help(context, replyTo, toNonNull(Command.NCFILE));
660 break;
661 }
662
663 final int ncfilePort;
664 try{
665 ncfilePort=Integer.parseInt(args[2]);
666 } catch (NumberFormatException e){
667 sendMessage(context, replyTo, cannot_parse_port);
668 break;
669 }
670 Heavy.ncfile(context, replyTo, toNonNull(args[0]), toNonNull(args[1]), ncfilePort);
671 break;
672
673 case PHOTO:
a646935d 674 if(args.length!=3){
8dfb76c9
MG
675 Heavy.help(context, replyTo, toNonNull(Command.PHOTO));
676 break;
677 }
a646935d
MG
678
679 final int cameraNumber;
680 try{
681 cameraNumber=Integer.parseInt(args[0]);
682 } catch (NumberFormatException e){
683 sendMessage(context, replyTo, cannot_parse_camera_number);
684 break;
685 }
686
8dfb76c9
MG
687 final int photoPort;
688 try{
a646935d 689 photoPort=Integer.parseInt(args[2]);
8dfb76c9
MG
690 } catch (NumberFormatException e){
691 sendMessage(context, replyTo, cannot_parse_port);
692 break;
693 }
a646935d 694 Heavy.photo(context, replyTo, cameraNumber, toNonNull(args[1]), photoPort);
8dfb76c9
MG
695 break;
696
697 case SETNOTIFICATION:
698 if(args.length!=1){
699 Heavy.help(context, replyTo, toNonNull(Command.SETNOTIFICATION));
700 break;
701 }
702
703 try{
704 PreferenceManager.getDefaultSharedPreferences(context).edit()
705 .putString(MessageType.valueOf(args[0].toUpperCase(Locale.ENGLISH)).toString(), replyTo.toString())
706 .commit();
a5259b32 707 sendConfirmMessage(context, replyTo, notification_enabled);
8dfb76c9
MG
708 } catch (IllegalArgumentException e){
709 sendMessage(context, replyTo, messagetype_should_be_one_of, join(", ",toNonNull(MessageType.values())));
710 break;
711 }
712
713 break;
714
715 case DELNOTIFICATION:
716 if(args.length!=1){
717 Heavy.help(context, replyTo, toNonNull(Command.DELNOTIFICATION));
718 break;
719 }
720
721 try{
722 PreferenceManager.getDefaultSharedPreferences(context).edit()
723 .remove(MessageType.valueOf(args[0].toUpperCase(Locale.ENGLISH)).toString())
724 .commit();
a5259b32 725 sendConfirmMessage(context, replyTo, notification_disabled);
8dfb76c9
MG
726 } catch (IllegalArgumentException e){
727 sendMessage(context, replyTo, messagetype_should_be_one_of, join(", ",toNonNull(MessageType.values())));
728 break;
729 }
730
731
732 break;
733 case SETPASSWORD:
734 if(args.length > 1){
735 Heavy.help(context, replyTo, toNonNull(Command.SETPASSWORD));
736 break;
737 }
738
739 try{
740 if(args.length==0)
741 Heavy.setPassword(context, replyTo);
742 else
743 Heavy.setPassword(context, replyTo, toNonNull(args[0]));
744 } catch (SecurityException e){
a5259b32 745 sendMessage(context, replyTo, security_exception, e.getMessage());
8dfb76c9
MG
746 }
747 break;
748
749 case WIPE:
750 if(args.length!=2){
751 Heavy.help(context, replyTo, toNonNull(Command.WIPE));
752 break;
753 }
754
755 if(!args[1].equalsIgnoreCase(WIPE_CONFIRM_STRING)){
756 sendMessage(context, replyTo, the_second_argument_to_wipe_must_be, WIPE_CONFIRM_STRING);
757 break;
758 }
759
760 try{
761 Heavy.wipe(context, toNonNull(WipeType.valueOf(args[0].toUpperCase(Locale.ENGLISH))));
762 } catch (IllegalArgumentException e){
763 sendMessage(context, replyTo, wipetype_should_be_one_of, join (", ",toNonNull(WipeType.values())));
764 } catch (SecurityException e){
765 sendMessage(context, replyTo, security_exception, e.getMessage());
766 }
767 break;
768
769 case LOCK:
770 try{
771 Heavy.lock(context, replyTo);
772 } catch (SecurityException e){
773 sendMessage(context, replyTo, security_exception, e.getMessage());
774 }
775 break;
776
777 case VIEW:
778 if(args.length!=1){
779 Heavy.help(context, replyTo, toNonNull(Command.VIEW));
780 break;
781 }
782
783 Heavy.view(context, replyTo, toNonNull(Uri.parse(args[0])));
784 break;
785
786 case PLAY:
787 Heavy.musicPlayerCommand(context, replyTo, "play");
788 break;
789
790 case PAUSE:
791 Heavy.musicPlayerCommand(context, replyTo, "pause");
792 break;
793
794 case NEXT:
795 Heavy.musicPlayerCommand(context, replyTo, "next");
796 break;
797
798 case PREV:
799 Heavy.musicPlayerCommand(context, replyTo, "previous");
800 break;
801
802 case BATT:
803 Heavy.batt(context, replyTo);
804 break;
805
806 case CALLLOG:
807 if (args.length > 1) {
808 Heavy.help(context, replyTo, toNonNull(Command.CALLLOG));
809 break;
810 }
811
812 if (args.length == 0)
813 Heavy.calllog(context, replyTo, 5);
814 else {
815 try {
816 Heavy.calllog(context, replyTo, Integer.parseInt(args[0]));
817 } catch (IllegalArgumentException e){
818 sendMessage(context, replyTo, cannot_parse_count);
819 }
820 }
821 break;
822
823 case SMSLOG:
824 if (args.length > 1) {
825 Heavy.help(context, replyTo, toNonNull(Command.SMSLOG));
826 break;
827 }
828
829 if (args.length == 0)
830 Heavy.smslog(context, replyTo, 5);
831 else {
832 try {
833 Heavy.smslog(context, replyTo, Integer.parseInt(args[0]));
834 } catch (IllegalArgumentException e) {
835 sendMessage(context, replyTo, cannot_parse_count);
836 }
837 }
838 break;
839
840 case HELP:
841 if(args.length != 1){
842 Heavy.help(context, replyTo, toNonNull(Command.HELP));
843 break;
844 }
845
846 try {
847 Heavy.help(context, replyTo, toNonNull(Command.valueOf(args[0].toUpperCase(Locale.ENGLISH))));
848 } catch (IllegalArgumentException e) {
849 sendMessage(context, replyTo, no_such_command_command_list, join(", ", toNonNull(Command.values())));
850 }
851 break;
852
853 case LS:
854 if(args.length != 1){
855 Heavy.help(context, replyTo, toNonNull(Command.LS));
856 break;
857 }
858
859 Heavy.ls(context, replyTo, toNonNull(args[0]));
860 break;
861
862 case RM:
863 if(args.length != 1){
864 Heavy.help(context, replyTo, toNonNull(Command.RM));
865 break;
866 }
867
868 Heavy.rm(context, replyTo, toNonNull(args[0]));
869 break;
870
871 case CONTACTS:
872 if(args.length != 1){
873 Heavy.help(context, replyTo, toNonNull(Command.CONTACTS));
874 break;
875 }
876
877 Heavy.contacts(context, replyTo, toNonNull(args[0]));
878 break;
879
880 case DISABLE:
881 if(replyTo.protocol != Protocol.LOCAL || args.length != 1){
882 Heavy.help(context, replyTo, toNonNull(Command.DISABLE));
883 break;
884 }
885
886 try{
887 Heavy.disable(context, replyTo, toNonNull(Command.valueOf(args[0].toUpperCase(Locale.ENGLISH))));
888 } catch (IllegalArgumentException e){
889 sendMessage(context, replyTo, no_such_command_command_list, join(", ", toNonNull(Command.values())));
890 }
891 break;
892
893 case ENABLE:
894 if(replyTo.protocol != Protocol.LOCAL || args.length != 1){
895 Heavy.help(context, replyTo, toNonNull(Command.ENABLE));
896 break;
897 }
898
899 try{
900 Heavy.enable(context, replyTo, toNonNull(Command.valueOf(args[0].toUpperCase(Locale.ENGLISH))));
901 } catch (IllegalArgumentException e){
902 sendMessage(context, replyTo, no_such_command_command_list, join(", ", toNonNull(Command.values())));
903 }
904 break;
905
906 case POLL:
ca40a5cc 907 Heavy.poll(context, replyTo);
8dfb76c9
MG
908 break;
909
910 case HANGUP:
911 Heavy.hangup(context, replyTo);
912 break;
913
914 case ANSWER:
915 Heavy.answer(context, replyTo);
916 break;
917
918 case LAUNCH:
919 if(args.length!=1){
920 Heavy.help(context, replyTo, toNonNull(Command.LAUNCH));
921 break;
922 }
923 Heavy.launch(context, replyTo, toNonNull(args[0]));
924 break;
925
926 case DATA:
927 if(args.length>1){
928 Heavy.help(context, replyTo, toNonNull(Command.DATA));
929 break;
930 }
931
932 if(args.length==0){
933 Heavy.data(context, replyTo);
934 break;
935 }
936 try {
937 Heavy.data(context, replyTo, OnOff.valueOf(args[0].toUpperCase(Locale.ENGLISH)) == OnOff.ON);
938 } catch(IllegalArgumentException e) {
939 sendMessage(context, replyTo, could_not_parse_argument_allowed_values_are, join(", ", toNonNull(OnOff.values())));
940 }
941 break;
942
943 case GPS:
944 if(args.length>1){
945 Heavy.help(context, replyTo, toNonNull(Command.GPS));
946 break;
947 }
948
949 if(args.length==0){
950 Heavy.gps(context, replyTo);
951 break;
952 }
953
954 try {
955 Heavy.gps(context, replyTo, OnOff.valueOf(args[0].toUpperCase(Locale.ENGLISH)) == OnOff.ON);
956 } catch(IllegalArgumentException e) {
957 sendMessage(context, replyTo, could_not_parse_argument_allowed_values_are, join(", ", toNonNull(OnOff.values())));
958 }
959 break;
960
961 case GLOCATION:
962 if(args.length>1){
963 Heavy.help(context, replyTo, toNonNull(Command.GLOCATION));
964 break;
965 }
966
967 if(args.length==0){
968 Heavy.glocation(context, replyTo);
969 break;
970 }
971
972 try {
973 Heavy.glocation(context, replyTo, OnOff.valueOf(args[0].toUpperCase(Locale.ENGLISH)) == OnOff.ON);
974 } catch(IllegalArgumentException e) {
975 sendMessage(context, replyTo, could_not_parse_argument_allowed_values_are, join(", ", toNonNull(OnOff.values())));
976 }
977 break;
978
979 case REBOOT:
980 if(args.length>1){
981 Heavy.help(context, replyTo, toNonNull(Command.REBOOT));
982 break;
983 }
984
985 Heavy.reboot(context, replyTo, args.length==0?null:args[0]);
986 break;
987
8dfb76c9
MG
988 case NOTIFY:
989 if(args.length!=1 && args.length!=3){
990 Heavy.help(context, replyTo, toNonNull(Command.NOTIFY));
02c042b0 991 return;
8dfb76c9
MG
992 }
993
994 final int id;
995 try{
996 id=Integer.parseInt(args[0]);
997 } catch (NumberFormatException e){
998 sendMessage(context, replyTo, R.string.could_not_parse_id);
999 break;
1000 }
1001
1002 if(args.length==1)
1003 Heavy.notify(context, replyTo, id);
1004 else
1005 Heavy.notify(context, replyTo, id, toNonNull(args[1]), toNonNull(args[2]));
1006 break;
0f74646f
MG
1007
1008 case SCREENCAP:
1009 if(args.length != 1){
1010 Heavy.help(context, replyTo, toNonNull(Command.SCREENCAP));
1011 return;
1012 }
1013
1014 Heavy.screencap(context, replyTo, args[0]);
1015 break;
d87d24ba
MG
1016
1017 case TORCH:
1018 Heavy.torch(context, replyTo);
1019 break;
740a6fa5
MG
1020
1021 case GETFILE:
1022 if(args.length != 3){
1023 Heavy.help(context, replyTo, toNonNull(Command.GETFILE));
1024 return;
1025 }
1026
1027 final int getfilePort;
1028 try{
1029 getfilePort=Integer.parseInt(args[2]);
1030 } catch (NumberFormatException e){
1031 sendMessage(context, replyTo, cannot_parse_port);
1032 break;
1033 }
1034 Heavy.getfile(context, replyTo, toNonNull(args[0]), toNonNull(args[1]), getfilePort);
1035 break;
251aceaa
MG
1036
1037 case SH:
1038 if(args.length == 0){
1039 Heavy.help(context, replyTo, toNonNull(Command.SH));
1040 return;
1041 }
1042
1043 Heavy.execute(context, replyTo, "sh", join(" ", args));
1044 break;
1045
1046 case ROOTSH:
1047 if(args.length == 0){
1048 Heavy.help(context, replyTo, toNonNull(Command.ROOTSH));
1049 return;
1050 }
1051
1052 Heavy.execute(context, replyTo, "su", join(" ", args));
1053 break;
8dfb76c9
MG
1054 }
1055
1056 }
1057
1058 /**
1059 * Executes a given command
1060 *
1061 * @param context Context instance
1062 * @param cmd Command to execute
1063 * @param args arguments for the command
1064 * @param replyTo Address to send replies to
1065 */
1066 public static void processCommand(final Context context, final String cmd,final String[] args,final Address replyTo){
1067 final @NonNull Command command;
1068 try{
1069 command=toNonNull(Command.valueOf(cmd.toUpperCase(Locale.ENGLISH)));
1070 } catch (IllegalArgumentException e){
1071 sendMessage(context, replyTo, unknown_command, cmd.toUpperCase(Locale.ENGLISH), e.getMessage());
1072 return;
1073 }
1074
1075 try{
1076 processCommand(context, command,args,replyTo);
1077 } catch(Exception e){
1078 sendMessage(context, replyTo, error_while_processing_command, e.getClass().getName(), e.getMessage());
1079 Log.w(Utils.class.getName(), "Error while processing command", e);
1080 }
1081 }
1082}
This page took 0.079386 seconds and 4 git commands to generate.