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