package com.malcom.library.android.module.campaign; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.os.AsyncTask; import android.util.Log; import com.malcom.library.android.MCMDefines; import com.malcom.library.android.exceptions.ApplicationConfigurationNotFoundException; import com.malcom.library.android.module.core.MCMCoreAdapter; import com.malcom.library.android.utils.HttpDateUtils; import com.malcom.library.android.utils.MCMUtils; import com.malcom.library.android.utils.MalcomHttpOperations; import com.malcom.library.android.utils.ToolBox; import com.malcom.library.android.utils.encoding.DigestUtils; import com.malcom.library.android.utils.encoding.base64.Base64; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import java.io.IOException; import java.io.InputStream; import java.io.UnsupportedEncodingException; import java.net.MalformedURLException; import java.net.URL; import java.net.URLEncoder; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.Map; /** * Created with IntelliJ IDEA. * User: PedroDuran * Date: 09/05/13 * Time: 13:02 * To change this template use File | Settings | File Templates. */ public class MCMCampaignAsyncTasks { /** * DownloadCampaignFile. * Async request campaigns data, and parse it to models. */ protected static class DownloadCampaignFile extends AsyncTask<String, Void, ArrayList<MCMCampaignDTO>> { private final static String kErrorCampaignRequestPrefix = "Error in campaign request: "; private MCMCampaignDTO.CampaignType campaignType; private MCMCampaignAdapter campaignAdapter; private String errorMessage = ""; public DownloadCampaignFile(MCMCampaignDTO.CampaignType campaignType, MCMCampaignAdapter campaignAdapter) { this.campaignType = campaignType; this.campaignAdapter = campaignAdapter; } protected void onPreExecute() { } protected ArrayList<MCMCampaignDTO> doInBackground(String... valores) { ArrayList<MCMCampaignDTO> receivedCampaignsArray = new ArrayList<MCMCampaignDTO>(); try { // Execute request to get JSON JSONObject objectJSON = getJSONfromURL(valores[0]); if (objectJSON != null) { Log.d(MCMDefines.LOG_TAG, "Received Campaigns JSON: " + objectJSON); // Parse JSON to obtain campaign data JSONArray campaignArray = (JSONArray) objectJSON.get(MCMCampaignDefines.ATTR_CAMPAIGNS_ARRAY); if (campaignArray != null) { for (int i = 0; i < campaignArray.length(); i++) { JSONObject campaignJSON = campaignArray.getJSONObject(i); receivedCampaignsArray.add(new MCMCampaignDTO(campaignJSON)); } } else { Log.e(MCMDefines.LOG_TAG, kErrorCampaignRequestPrefix + objectJSON.getString("description")); errorMessage = objectJSON.getString("description"); } } } catch (JSONException e) { Log.e(MCMDefines.LOG_TAG, kErrorCampaignRequestPrefix + e.getMessage()); errorMessage = kErrorCampaignRequestPrefix + e.getMessage(); } catch (Exception e) { Log.e(MCMDefines.LOG_TAG, kErrorCampaignRequestPrefix + e.getMessage()); errorMessage = kErrorCampaignRequestPrefix + e.getMessage(); } return receivedCampaignsArray; } protected void onPostExecute(ArrayList<MCMCampaignDTO> campaignsArray) { // After receiving campaign data, prepare banner if (campaignsArray.size() > 0) { campaignAdapter.processResponse(campaignsArray); } else { campaignAdapter.notifyCampaignDidFail(errorMessage); } } /** * Sends a GET request, obtains a response, and converts it to a JSON object. * * @param url - the destination of request * @return - the response JSON object * @throws ApplicationConfigurationNotFoundException * */ private JSONObject getJSONfromURL(String url) { String result = ""; JSONObject jObject = null; try { // Send request to Malcom and log it Log.d(MCMDefines.LOG_TAG, "Campaign request url: " + url); // TODO: Refactor this by extracting the headers build to a static helper class. This class should be used by all the methods connecting with Malcom Server String malcomDate = HttpDateUtils.formatDate(new Date()); String verb = "GET"; String contentType = "application/json"; String md5 = ToolBox.md5_calculateMD5(""); Map<String, String> headersData = new HashMap<String, String>(); headersData.put("Content-Type", "application/json"); headersData.put("content-md5", md5); headersData.put("x-mcm-date", malcomDate); String dataToSign = ToolBox.deliveries_getDataToSign(ToolBox.getCanonicalizedMalcomHeaders(headersData), contentType, null, verb, campaignAdapter.getCampaignResource(), md5); String secretKey = MCMCoreAdapter.getInstance().coreGetProperty(MCMCoreAdapter.PROPERTIES_MALCOM_APPSECRETKEY); String password = DigestUtils.calculateRFC2104HMAC(dataToSign, secretKey); // Complete headers with authorization headersData.put("Authorization", "basic " + new String(Base64.encode(campaignAdapter.getMalcomAppId() + ":" + password).getBytes())); // End of refactor result = ToolBox.net_httpclient_doAction(ToolBox.HTTP_METHOD.GET, url, "", headersData); Log.d(MCMCampaignDefines.LOG_TAG, "<<< getJSONfromURL result: " + result); // Try parse the string to a JSON object jObject = new JSONObject(result); } catch (Exception e) { Log.e(MCMCampaignDefines.LOG_TAG, "<<< getJSONfromURL ERROR: " + e.toString() + " - " + e.getMessage()); errorMessage = e.toString(); } return jObject; } } /** * NotifyServer * Async request to notify impressions and clicks to Malcom. * Needs the event type (CLICK or IMPRESSION) in first param. */ public static class NotifyServer extends AsyncTask<String, Float, Integer> { private Context context; public NotifyServer(Context context) { this.context = context; } protected Integer doInBackground(String... valores) { String url; try { // Get the connection params String malcomBaseUrl = MCMCoreAdapter.getInstance().coreGetProperty(MCMCoreAdapter.PROPERTIES_MALCOM_BASEURL); String appId = MCMUtils.getEncodedUDID(MCMCoreAdapter.getInstance().coreGetProperty(MCMCoreAdapter.PROPERTIES_MALCOM_APPID)); String deviceId = MCMUtils.getEncodedUDID(ToolBox.device_getId(context)); String secretKey = MCMCoreAdapter.getInstance().coreGetProperty(MCMCoreAdapter.PROPERTIES_MALCOM_APPSECRETKEY); // Get the service url String campaignHitService = MCMCampaignDefines.CAMPAIGN_HIT_URL .replace(MCMCampaignDefines.HIT_TYPE_TAG, valores[0]) // CLICK or IMPRESSION .replace(MCMCampaignDefines.CAMPAIGN_ID_TAG, valores[1]) .replace(MCMCampaignDefines.APP_ID_TAG, appId) .replace(MCMCampaignDefines.UDID_TAG, deviceId); url = malcomBaseUrl + campaignHitService; Log.i(MCMDefines.LOG_TAG,"Campaign notify url: "+url); // Send hit to Malcom MalcomHttpOperations.sendRequestToMalcom(url, campaignHitService, "", appId, secretKey, ToolBox.HTTP_METHOD.GET); } catch (UnsupportedEncodingException e1) { e1.printStackTrace(); } catch (Exception e) { e.printStackTrace(); }; return 0; } protected void onPostExecute(Integer bytes) { } } }