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