Merge SendHttpMessageAsyncTask and PollServerAsyncTask
authorMarius Gavrilescu <marius@ieval.ro>
Tue, 12 Mar 2013 16:27:54 +0000 (18:27 +0200)
committerMarius Gavrilescu <marius@ieval.ro>
Tue, 12 Mar 2013 16:27:54 +0000 (18:27 +0200)
The resulting class is named HttpCallExxecutableRunnable. It uses
the new ExecutableRunnable class and lets the users make a HTTP
call to a server URL and pass in a callback to use the response.

12 files changed:
src/ro/ieval/fonbot/DynamicEventReceiver.java
src/ro/ieval/fonbot/FonBotApplication.java
src/ro/ieval/fonbot/FonBotMainActivity.java
src/ro/ieval/fonbot/GCMIntentService.java
src/ro/ieval/fonbot/Heavy.java
src/ro/ieval/fonbot/HttpCallExecutableRunnable.java [new file with mode: 0644]
src/ro/ieval/fonbot/LocalBroadcastReceiver.java
src/ro/ieval/fonbot/PollResultCallback.java [new file with mode: 0644]
src/ro/ieval/fonbot/PollServerAsyncTask.java [deleted file]
src/ro/ieval/fonbot/RemoteCrashdumpHandler.java
src/ro/ieval/fonbot/SendHttpMessageAsyncTask.java [deleted file]
src/ro/ieval/fonbot/Utils.java

index d7acf5467da3ba0b9873cffa05d55076ac16484a..0912e8834f022709cbf082527bdef0609e801e52 100644 (file)
@@ -47,7 +47,7 @@ public final class DynamicEventReceiver extends BroadcastReceiver {
 
                if(action.equals(Intent.ACTION_SCREEN_ON)){
                        if(PreferenceManager.getDefaultSharedPreferences(context).getBoolean("poll_on_screen_on", false))
-                               new PollServerAsyncTask(context).execute();
+                               Utils.pollServer(context);
                } else if(action.equals(Intent.ACTION_BATTERY_CHANGED))
                        Heavy.describeBatteryLevel(context, null, toNonNull(MessageType.BATTERY_CHANGED));
                else if(action.equals(Intent.ACTION_HEADSET_PLUG)){
index be774ce6b15d8367801c850f0a514184efc3044f..af5a70c2ac69c236d22c5a4351bf38f6277f687b 100644 (file)
@@ -48,7 +48,7 @@ public final class FonBotApplication extends Application {
                final TelephonyManager tman=(TelephonyManager) getSystemService(TELEPHONY_SERVICE);
                tman.listen(new FonBotPhoneStateListener(this), PhoneStateListener.LISTEN_CALL_STATE);
 
-               new PollServerAsyncTask(this).execute();
+               Utils.pollServer(this);
 
                startService(new Intent(this, FonBotMainService.class));
 
index 7ef45b849c485400cfc83276141a1fdb382ab67a..2ec56e2442d1e960378f9869a1b339f9c3b8a12e 100644 (file)
@@ -3,11 +3,11 @@ package ro.ieval.fonbot;
 import static ro.ieval.fonbot.R.string.logging_in;
 import static ro.ieval.fonbot.Utils.toNonNull;
 
-import java.util.Collections;
-
+import java.io.InputStream;
 import org.eclipse.jdt.annotation.Nullable;
 
 import ro.ieval.fonbot.FonBotMainService.Binder;
+import ro.ieval.fonbot.HttpCallExecutableRunnable.ResultCallback;
 import ro.ieval.fonbot.Utils.OngoingEvent;
 import android.app.ListActivity;
 import android.content.BroadcastReceiver;
@@ -150,8 +150,8 @@ public final class FonBotMainActivity extends ListActivity {
                public void onReceive(@Nullable final Context context, @Nullable final Intent intent) {
                        if(intent==null)
                                return;
-                       resultTextView.setText(intent.getStringExtra(SendHttpMessageAsyncTask.EXTRA_RESPONSE_MESSAGE));
-                       final int responseCode=intent.getIntExtra(SendHttpMessageAsyncTask.EXTRA_RESPONSE_CODE, 0);
+                       resultTextView.setText(intent.getStringExtra(BroadcastResultCallback.EXTRA_RESPONSE_MESSAGE));
+                       final int responseCode=intent.getIntExtra(BroadcastResultCallback.EXTRA_RESPONSE_CODE, 0);
                        if(responseCode>=200&&responseCode<300)
                                resultTextView.setCompoundDrawablesWithIntrinsicBounds(0, R.drawable.tick, 0, 0);
                        else
@@ -159,6 +159,37 @@ public final class FonBotMainActivity extends ListActivity {
                }
        }
 
+       /**
+        * Implementation of <code>ResultCallback</code> that broadcasts a {@link #LOGIN_BROADCAST}
+        *
+        * @author Marius Gavrilescu
+        */
+       public final class BroadcastResultCallback implements ResultCallback{
+               /**
+                * Extra: the response message
+                */
+               public static final String EXTRA_RESPONSE_MESSAGE="response_message";
+               /**
+                * Extra: the response code
+                */
+               public static final String EXTRA_RESPONSE_CODE="response_code";
+
+               @Override
+               public void onResult(final int responseCode, final String responseMessage, final InputStream inputStream) {
+                       final Intent intent=new Intent(LOGIN_BROADCAST);
+                       intent.putExtra(EXTRA_RESPONSE_MESSAGE, responseMessage);
+                       intent.putExtra(EXTRA_RESPONSE_CODE, responseCode);
+                       sendBroadcast(intent);
+               }
+
+               @Override
+               public void onError(final String error) {
+                       final Intent intent=new Intent(LOGIN_BROADCAST);
+                       intent.putExtra(EXTRA_RESPONSE_MESSAGE, error);
+                       sendBroadcast(intent);
+               }
+       }
+
        /**
         * The one instance of {@link OngoingUpdateReceiver}
         */
@@ -172,13 +203,17 @@ public final class FonBotMainActivity extends ListActivity {
         */
        private final BroadcastReceiver loginReceiver=new LoginReceiver();
        /**
-        * The broadcast sent by {@link SendHttpMessageAsyncTask} when logging in. 
+        * The broadcast sent by {@link HttpCallExecutableRunnable} when logging in.
         */
        private static final String LOGIN_BROADCAST="ro.ieval.fonbot.LOGIN_RESULT";
        /**
         * IntentFilter for {@link #loginReceiver}
         */
        private static final IntentFilter LOGIN_FILTER=new IntentFilter(LOGIN_BROADCAST);
+       /**
+        * The one instance of {@link BroadcastResultCallback}
+        */
+       private final BroadcastResultCallback broadcastResultCallback=new BroadcastResultCallback();
        /**
         * The one instance of {@link ServiceConnection}
         */
@@ -202,8 +237,8 @@ public final class FonBotMainActivity extends ListActivity {
        protected void onStart() {
                super.onStart();
                resultTextView.setText(logging_in);
-               new SendHttpMessageAsyncTask("/ok", toNonNull(Collections.<Header>emptySet()),
-                               LOGIN_BROADCAST,this).execute();
+               new HttpCallExecutableRunnable("/ok", null,
+                               toNonNull(getApplicationContext()), toNonNull(broadcastResultCallback)).execute();
                connection.refreshAdapter();
        }
 
index bf17e5ffa83076f3ebd346bc56884cf48bbfdce8..84a3c7903268c8656f3790dd406db5712000260f 100644 (file)
@@ -4,9 +4,6 @@ import org.eclipse.jdt.annotation.Nullable;
 
 import android.content.Context;
 import android.content.Intent;
-import android.os.Handler;
-import android.os.Looper;
-
 import com.google.android.gcm.GCMBaseIntentService;
 
 /*
@@ -34,9 +31,6 @@ import com.google.android.gcm.GCMBaseIntentService;
  * @author Marius Gavrilescu <marius@ieval.ro>
  */
 public class GCMIntentService extends GCMBaseIntentService {
-       /** Handler instance */
-       private final Handler handler=new Handler(Looper.getMainLooper());
-
        /**
         * Constructs a GCMIntentService with the iEval sender id
         */
@@ -54,12 +48,7 @@ public class GCMIntentService extends GCMBaseIntentService {
                if(context==null)
                        return;
 
-               handler.post(new Runnable(){
-                       @Override
-                       public void run() {
-                               new PollServerAsyncTask(context).execute();     
-                       }
-               });
+               Utils.pollServer(context);
        }
 
        @Override
index 905b577d34ac187de0bac36072e5f564a84cafdb..6e91f2f1fbbd61c173ad4105ffb48cd1189b9909 100644 (file)
@@ -1507,7 +1507,7 @@ final class Heavy {
         */
        public static void poll(final Context context, final Address replyTo) {
                Utils.sendMessage(context, replyTo, polling_server);
-               new PollServerAsyncTask(context).execute();
+               Utils.pollServer(context);
        }
 
        /**
diff --git a/src/ro/ieval/fonbot/HttpCallExecutableRunnable.java b/src/ro/ieval/fonbot/HttpCallExecutableRunnable.java
new file mode 100644 (file)
index 0000000..621f0bc
--- /dev/null
@@ -0,0 +1,168 @@
+package ro.ieval.fonbot;
+
+import static ro.ieval.fonbot.R.string.*;
+import static ro.ieval.fonbot.Utils.toNonNull;
+
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.util.Collection;
+
+import org.eclipse.jdt.annotation.Nullable;
+
+import android.content.Context;
+import android.preference.PreferenceManager;
+import android.util.Base64;
+import android.util.Log;
+
+import com.google.android.gcm.GCMRegistrar;
+
+/*
+ * Copyright © 2013 Marius Gavrilescu
+ * 
+ * This file is part of FonBot.
+ *
+ * FonBot is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * FonBot is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with FonBot.  If not, see <http://www.gnu.org/licenses/>. 
+ */
+
+/**
+ * ExecutableRunnable that makes a HTTP call to the server and hands the response to a callback
+ *
+ * @author Marius Gavrilescu <marius@ieval.ro>
+ */
+public final class HttpCallExecutableRunnable extends ExecutableRunnable{
+       /**
+        * Callback which is run after a HTTP call.
+        *
+        * @author Marius Gavrilescu
+        */
+       public static interface ResultCallback{
+               /**
+                * Callback invoked if the HTTP call is successful.
+                *
+                * @param responseCode HTTP response code
+                * @param responseMessage HTTP response message
+                * @param inputStream HTTP content InputStream
+                */
+               public void onResult(final int responseCode, final String responseMessage, final InputStream inputStream);
+               /**
+                * Callback invoked if the HTTP call is unsuccessful.
+                *
+                * @param error localized error message
+                */
+               public void onError(final String error);
+       }
+
+       /**
+        * List of extra request headers.
+        */
+       private final Collection<Header> headers;
+       /**
+        * Context instance used by this class
+        */
+       private final Context context;
+       /**
+        * Data to send to the server
+        */
+       private final byte[] data;
+       /**
+        * Server URL path
+        */
+       private final String path;
+       /**
+        * Callback to run after the request returns
+        */
+       private final ResultCallback callback;
+
+       /**
+        * Constructs a SendHttpMessageAsyncTask which sends a binary message.
+        *
+        * @param path URL path
+        * @param headers the extra headers
+        * @param context the context instance
+        * @param resultCallback {@link ResultCallback} instance
+        * @param data the message to send
+        */
+       public HttpCallExecutableRunnable(final String path, final @Nullable Collection<Header> headers, final Context context, final @Nullable ResultCallback resultCallback, final byte[] data){//NOPMD array is supposed to be immutable.
+               this.path=path;
+               this.headers=headers;
+               this.context=context;
+               this.callback=resultCallback;
+               this.data=data;
+       }
+
+       /**
+        * Constructs a SendHttpMessageAsyncTask which sends a text message.
+        *
+        * @param path URL path
+        * @param headers the extra headers
+        * @param context the context instance
+        * @param resultCallback {@link ResultCallback} instance
+        * @param message message to send
+        */
+       public HttpCallExecutableRunnable(final String path, final @Nullable Collection<Header> headers, final Context context, final @Nullable ResultCallback resultCallback, final String... message){
+               this.path=path;
+               this.headers=headers;
+               this.context=context;
+               this.callback=resultCallback;
+               if(message.length == 0)
+                       this.data=null;//NOPMD final field
+               else
+                       this.data=Utils.join(" ", message).getBytes();
+       }
+
+       @Override
+       public void run() {
+               try {
+                       final URL url=Utils.getServerURL(toNonNull(context),toNonNull(path));
+                       final HttpURLConnection conn=(HttpURLConnection) url.openConnection();
+                       if(data!=null){
+                               conn.setDoOutput(true);
+                               conn.setFixedLengthStreamingMode(data.length);
+                       }
+                       conn.setRequestProperty("X-ID", GCMRegistrar.getRegistrationId(context));
+                       final String user=PreferenceManager.getDefaultSharedPreferences(context).getString("username", null);
+                       final String password=PreferenceManager.getDefaultSharedPreferences(context).getString("password", null);
+                       if(user == null || password == null){
+                               if(callback!=null)
+                                       callback.onError(toNonNull(context.getString(user_or_password_not_set)));
+                               return;
+                       }
+
+                       conn.setRequestProperty("Authorization", "Basic "+Base64.encodeToString(
+                                       (user+':'+password).getBytes(), Base64.NO_WRAP));
+                       if(headers != null)
+                               for (final Header header : headers)
+                                       conn.setRequestProperty(header.name, header.value);
+                       conn.connect();
+                       if(data!=null){
+                               final OutputStream stream=conn.getOutputStream();
+                               stream.write(data);
+                               stream.close();
+                       }
+                       Log.d(getClass().getName(),"HTTP Response: "+conn.getResponseCode()+" "+conn.getResponseMessage());
+                       final String message=conn.getResponseMessage();
+                       if(message==null && callback != null)
+                               callback.onError(toNonNull(context.getString(no_response_returned_from_server)));
+                       else if(message != null && callback != null)
+                               callback.onResult(conn.getResponseCode(), Utils.parseHttpMessage(message),
+                                               toNonNull(conn.getInputStream()));
+                       conn.disconnect();
+               } catch (Exception e) {
+                       e.printStackTrace();
+                       callback.onError(toNonNull(context.getString(connection_error)));
+               }
+       }
+}
index 88cf462b776d93cc0bf3e6f0d45d3fbb924b7c30..2aade7fac5755300213b04fb3693f7e99d4f6f1f 100644 (file)
@@ -43,7 +43,7 @@ public final class LocalBroadcastReceiver extends BroadcastReceiver {
 
                final String action=intent.getAction();
                if(action.equals(LocalBroadcastReceiver.ACTION_POLL_ALARM))
-                       new PollServerAsyncTask(context).execute();
+                       Utils.pollServer(context);
        }
 
 }
diff --git a/src/ro/ieval/fonbot/PollResultCallback.java b/src/ro/ieval/fonbot/PollResultCallback.java
new file mode 100644 (file)
index 0000000..2517fce
--- /dev/null
@@ -0,0 +1,104 @@
+package ro.ieval.fonbot;
+
+import static ro.ieval.fonbot.Utils.toNonNull;
+
+import java.io.InputStream;
+
+import org.json.JSONArray;
+import org.json.JSONObject;
+
+import android.content.Context;
+import android.os.Handler;
+import android.os.Looper;
+import android.util.Log;
+
+import ro.ieval.fonbot.Address.Protocol;
+import ro.ieval.fonbot.HttpCallExecutableRunnable.ResultCallback;
+
+/*
+* Copyright © 2013 Marius Gavrilescu
+* 
+* This file is part of FonBot.
+*
+* FonBot is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* FonBot is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with FonBot.  If not, see <http://www.gnu.org/licenses/>. 
+*/
+
+/**
+ * ResultCallback implementation that polls the server for pending commands.
+ *
+ * @author Marius Gavrilescu <marius@ieval.ro>
+ */
+final class PollResultCallback implements ResultCallback {
+       /** Context instance */
+       private final Context context;
+
+       /**
+        * Construct a <code>PollResultCallback</code> with a Context.
+        *
+        * @param context Context instance
+        */
+       public PollResultCallback(final Context context) {
+               this.context=context;
+       }
+
+       @Override
+       public void onResult(int responseCode, String responseMessage,
+                       InputStream inputStream) {
+               if(responseCode!=200)
+                       return;
+
+               final Handler handler=new Handler(Looper.getMainLooper());
+
+               try{
+                       final JSONArray array;
+                       {
+                               final byte[] buf=new byte[4096*1024];
+                               inputStream.read(buf);
+                               array=new JSONArray(new String(buf));
+                       }
+
+                       for(int i=0;i<array.length();i++){
+                               final JSONObject object=array.getJSONObject(i);
+
+                               final JSONArray jsonargs=object.getJSONArray("args");
+                               final String command=object.getString("command");
+                               final Address replyTo=new Address(toNonNull(Protocol.HTTP), object.getString("replyto"));//NOPMD address depends on command
+                               final String[] args=new String[jsonargs.length()];
+                               for(int j=0;j<args.length;j++)
+                                       args[j]=jsonargs.getString(j);
+
+                               Log.d(getClass().getName(), "Poll got command "+command+" with "+((args.length==0)?"no args":"args "+Utils.join(
+                                               " ",toNonNull(args))));
+
+                               handler.post(new Runnable() {
+                                       @Override
+                                       public void run() {
+                                               Utils.processCommand(
+                                                               toNonNull(context),
+                                                               toNonNull(command),
+                                                               args, replyTo);
+                                       }
+                               });
+                       }
+               }catch(Exception ex){
+                       ex.printStackTrace();
+               }
+       }
+
+       @Override
+       public void onError(final String error) {
+               Log.e("PollResultCallback", "onError: "+error);
+       }
+
+}
diff --git a/src/ro/ieval/fonbot/PollServerAsyncTask.java b/src/ro/ieval/fonbot/PollServerAsyncTask.java
deleted file mode 100644 (file)
index 07c014b..0000000
+++ /dev/null
@@ -1,162 +0,0 @@
-package ro.ieval.fonbot;
-
-import static ro.ieval.fonbot.Utils.toNonNull;
-
-import java.io.IOException;
-import java.net.HttpURLConnection;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.List;
-
-import org.eclipse.jdt.annotation.Nullable;
-import org.json.JSONArray;
-import org.json.JSONException;
-import org.json.JSONObject;
-
-import ro.ieval.fonbot.Address.Protocol;
-import android.content.Context;
-import android.os.AsyncTask;
-import android.preference.PreferenceManager;
-import android.util.Base64;
-import android.util.Log;
-
-import com.google.android.gcm.GCMRegistrar;
-
-/*
- * Copyright © 2013 Marius Gavrilescu
- * 
- * This file is part of FonBot.
- *
- * FonBot is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * FonBot is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with FonBot.  If not, see <http://www.gnu.org/licenses/>. 
- */
-
-/**
- * AsyncTask that polls the server for pending commands and executes any commands found.
- *
- * @author Marius Gavrilescu <marius@ieval.ro>
- */
-public final class PollServerAsyncTask extends AsyncTask<Void, Void, List<PollServerAsyncTask.Command>> {
-       /**
-        * POJO that represents a command in a basic form: a command name, a list of arguments and a reply address, all of them being strings
-        *
-        * @author Marius Gavrilescu <marius@ieval.ro>
-        */
-       final class Command{
-               /**
-                * The command name
-                */
-               final String command;//NOPMD no confusion here
-               /**
-                * The list of command arguments
-                */
-               final String[] args;
-               /**
-                * The reply address, excluding the protocol
-                */
-               final String replyto;
-
-               /**
-                * Construct a Command from its three parts
-                *
-                * @param command the command name
-                * @param args the command arguments
-                * @param replyto the reply address
-                */
-               Command(final String command, final String[] args, final String replyto) {//NOPMD array is immutable
-                       this.command=command;
-                       this.args=args;
-                       this.replyto=replyto;
-               }
-       }
-
-       /** Context instance */
-       private final Context context;
-
-       /**
-        * Constructs a PollServerAsyncTask.
-        *
-        * @param context Context instance
-        */
-       public PollServerAsyncTask(final Context context) {
-               this.context=context;
-       }
-
-       @Override
-       protected List<Command> doInBackground(final @Nullable Void... params) {
-               Log.d(getClass().getName(), "Polling server");
-               final List<Command> commands=new ArrayList<Command>(10);
-               try {
-                       final URL url=Utils.getServerURL(toNonNull(context),"/get");
-                       final HttpURLConnection conn=(HttpURLConnection) url.openConnection();
-                       conn.setRequestProperty("X-ID", GCMRegistrar.getRegistrationId(context));
-                       final String user=PreferenceManager.getDefaultSharedPreferences(context).getString("username", null);
-                       final String password=PreferenceManager.getDefaultSharedPreferences(context).getString("password", null);
-                       if(user == null || password == null)
-                               return commands;
-
-                       conn.setRequestProperty("Authorization", "Basic "+Base64.encodeToString(
-                                       (user+':'+password).getBytes(), Base64.NO_WRAP));
-                       conn.connect();
-                       Log.d(getClass().getName(), "Server poll got response code "+conn.getResponseCode()+" and message "+conn.getResponseMessage());
-                       if(conn.getResponseCode()!=200)
-                               return commands;
-
-                       final JSONArray array;
-                       {
-                               final byte[] buf=new byte[4096*1024];
-                               conn.getInputStream().read(buf);
-                               array=new JSONArray(new String(buf));
-                       }
-
-                       for(int i=0;i<array.length();i++){
-                               final JSONObject object=array.getJSONObject(i);
-
-                               final JSONArray jsonargs=object.getJSONArray("args");
-                               final String[] args=new String[jsonargs.length()];
-                               for(int j=0;j<args.length;j++)
-                                       args[j]=jsonargs.getString(j);
-
-                               commands.add(new Command(//NOPMD command changes for each JSON object
-                                               toNonNull(object.getString("command")),
-                                               args,
-                                               toNonNull(object.getString("replyto"))));
-                       }
-               } catch (MalformedURLException e) {
-                       e.printStackTrace();
-               } catch (IOException e) {
-                       e.printStackTrace();
-               } catch (JSONException e) {
-                       e.printStackTrace();
-               }
-               if(commands==null)
-                       throw new AssertionError("commands is null in PollServerAsyncTask#doInBackground");//silence Eclipse bug
-               return commands;
-       }
-
-       @Override
-       protected void onPostExecute(final @Nullable List<Command> commands) {
-               if(commands==null)
-                       return;
-               for (Command command : commands) {
-                       Log.d(getClass().getName(), "Poll got command "+command.command+" with "+((command.args.length==0)?"no args":"args "+Utils.join(
-                                       " ",toNonNull(command.args))));
-                       Utils.processCommand(
-                                       toNonNull(context),
-                                       toNonNull(command.command),
-                                       toNonNull(command.args),
-                                       new Address(toNonNull(Protocol.HTTP), command.replyto));//NOPMD address depends on command
-               }
-       }
-}
index e228869a5fde4180acd597ab348daf8d1980f52d..e09e31e36f1e7325109174a1ec8d4bcb4aa68d74 100644 (file)
@@ -59,8 +59,8 @@ final class RemoteCrashdumpHandler implements UncaughtExceptionHandler {
                ex.printStackTrace(pw);
                pw.close();
 
-               new SendHttpMessageAsyncTask("/crashdump", toNonNull(Collections.<Header>emptyList()),
-                               toNonNull(context), toNonNull(baos.toByteArray())).execute();
+               new HttpCallExecutableRunnable("/crashdump", toNonNull(Collections.<Header>emptyList()),
+                               toNonNull(context), null, toNonNull(baos.toByteArray())).execute();
 
                try {
                        baos.close();
diff --git a/src/ro/ieval/fonbot/SendHttpMessageAsyncTask.java b/src/ro/ieval/fonbot/SendHttpMessageAsyncTask.java
deleted file mode 100644 (file)
index 68f7319..0000000
+++ /dev/null
@@ -1,190 +0,0 @@
-package ro.ieval.fonbot;
-
-import static ro.ieval.fonbot.R.string.*;
-import static ro.ieval.fonbot.Utils.toNonNull;
-
-import java.io.OutputStream;
-import java.net.HttpURLConnection;
-import java.net.URL;
-import java.util.Collection;
-
-import org.eclipse.jdt.annotation.Nullable;
-
-import android.content.Context;
-import android.content.Intent;
-import android.os.AsyncTask;
-import android.preference.PreferenceManager;
-import android.util.Base64;
-import android.util.Log;
-
-import com.google.android.gcm.GCMRegistrar;
-
-/*
- * Copyright © 2013 Marius Gavrilescu
- * 
- * This file is part of FonBot.
- *
- * FonBot is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * FonBot is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with FonBot.  If not, see <http://www.gnu.org/licenses/>. 
- */
-
-/**
- * AsyncTask that sends a HTTP request to the server and broadcasts back the response message & response code
- *
- * @author Marius Gavrilescu <marius@ieval.ro>
- */
-public final class SendHttpMessageAsyncTask extends AsyncTask<String, Void, String> {
-       /**
-        * Extra: the response message 
-        */
-       public static final String EXTRA_RESPONSE_MESSAGE="response_message";
-       /**
-        * Extra: the response code
-        */
-       public static final String EXTRA_RESPONSE_CODE="response_code";
-
-       /**
-        * List of extra request headers.
-        */
-       private final Collection<Header> headers;
-       /**
-        * Action to send back in the response broadcast
-        */
-       private final String broadcast;
-       /**
-        * Context instance used by this class
-        */
-       private final Context context;
-       /**
-        * Data to send to the server
-        */
-       private final byte[] data;
-       /**
-        * Server URL path
-        */
-       private final String path;
-       /**
-        * Response code from the server
-        */
-       private int responseCode=0;
-
-       /**
-        * Constructs a SendHttpMessageAsyncTask which sends a string-based message and does not broadcast the response. 
-        *
-        * @param path URL path
-        * @param headers the extra headers
-        * @param context the context instance
-        */
-       public SendHttpMessageAsyncTask(final String path, final Collection<Header> headers, final Context context){
-               super();
-               this.path=path;
-               this.headers=headers;
-               this.broadcast=null;//NOPMD final field
-               this.context=context;
-               this.data=null;//NOPMD final field
-       }
-
-       /**
-        * Constructs a SendHttpMessageAsyncTask which sends a binary message and does not broadcast the response.
-        *
-        * @param path URL path
-        * @param headers the extra headers
-        * @param context the context instance
-        * @param data the message to send
-        */
-       public SendHttpMessageAsyncTask(final String path, final Collection<Header> headers, final Context context, final byte[] data){//NOPMD array is supposed to be immutable.
-               super();
-               this.path=path;
-               this.headers=headers;
-               this.broadcast=null;//NOPMD final field
-               this.context=context;
-               this.data=data;
-       }
-
-       /**
-        * Constructs a SendHttpMessageAsyncTask which sends a string-based message and broadcasts the response.
-        *
-        * @param path URL path
-        * @param headers the extra headers
-        * @param broadcast the broadcast to send
-        * @param context the context instance
-        */
-       public SendHttpMessageAsyncTask(final String path, final Collection<Header> headers, final String broadcast, final Context context){
-               super();
-               this.path=path;
-               this.headers=headers;
-               this.broadcast=broadcast;
-               this.context=context;
-               this.data=null;//NOPMD final field
-       }
-
-       @Override
-       protected String doInBackground(final @Nullable String... args) {
-               if(args==null)
-                       return "";
-
-               final byte[] msg;
-               if(data==null && args.length > 0)
-                       msg=Utils.join(" ", args).getBytes();
-               else if(data!=null)
-                       msg=data;
-               else
-                       msg=null;
-
-               try {
-                       final URL url=Utils.getServerURL(toNonNull(context),toNonNull(path));
-                       final HttpURLConnection conn=(HttpURLConnection) url.openConnection();
-                       if(msg!=null){
-                               conn.setDoOutput(true);
-                               conn.setFixedLengthStreamingMode(msg.length);
-                       }
-                       conn.setRequestProperty("X-ID", GCMRegistrar.getRegistrationId(context));
-                       final String user=PreferenceManager.getDefaultSharedPreferences(context).getString("username", null);
-                       final String password=PreferenceManager.getDefaultSharedPreferences(context).getString("password", null);
-                       if(user == null || password == null)
-                               return toNonNull(context.getString(user_or_password_not_set));
-
-                       conn.setRequestProperty("Authorization", "Basic "+Base64.encodeToString(
-                                       (user+':'+password).getBytes(), Base64.NO_WRAP));
-                       for (Header header : headers)
-                               conn.setRequestProperty(header.name, header.value);
-                       conn.connect();
-                       if(msg!=null){
-                               final OutputStream stream=conn.getOutputStream();
-                               stream.write(msg);
-                               stream.close();
-                       }
-                       Log.d(getClass().getName(),"HTTP Response: "+conn.getResponseCode()+" "+conn.getResponseMessage());
-                       conn.disconnect();
-                       final String message=conn.getResponseMessage();
-                       responseCode=conn.getResponseCode();
-                       if(message==null)
-                               return toNonNull(context.getString(no_response_returned_from_server));
-                       return Utils.parseHttpMessage(message);
-               } catch (Exception e) {
-                       e.printStackTrace();
-                       return toNonNull(context.getString(connection_error));
-               }
-       }
-
-       @Override
-       protected void onPostExecute(final @Nullable String result) {
-               super.onPostExecute(result);
-               if(broadcast!=null){
-                       final Intent intent=new Intent(broadcast);
-                       intent.putExtra(EXTRA_RESPONSE_MESSAGE, result);
-                       intent.putExtra(EXTRA_RESPONSE_CODE, responseCode);
-                       context.sendBroadcast(intent);
-               }
-       }
-}
index d9060eb662734475026200ef84587260ef931794..e14095ea4695e4301b33215e64731786b77a561c 100644 (file)
@@ -316,8 +316,8 @@ public final class Utils {
        public static void sendMessage(final Context context, final Address address, final String message){
                switch(address.protocol){
                case HTTP:
-                       new SendHttpMessageAsyncTask("/send", toNonNull(Arrays.asList(
-                                       new Header("X-Destination", toNonNull(address.data)))), context).execute(message);
+                       new HttpCallExecutableRunnable("/send", toNonNull(Arrays.asList(
+                                       new Header("X-Destination", toNonNull(address.data)))), context, null, message).execute();
                        break;
 
                case SMS:
@@ -425,6 +425,15 @@ public final class Utils {
                return url;
        }
 
+       /**
+        * Poll the server for pending commands.
+        *
+        * @param context Context instance
+        */
+       public static void pollServer(final Context context){
+               new HttpCallExecutableRunnable("/get", null, context, new PollResultCallback(context)).execute();
+       }
+
        /**
         * Executes a given command
         *
This page took 0.029332 seconds and 4 git commands to generate.