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