package au.id.teda.broadband.usage.util; import java.io.BufferedInputStream; import java.io.IOException; import java.io.InputStream; import java.net.HttpURLConnection; import java.net.URL; import java.util.Calendar; import java.util.List; import au.id.teda.broadband.usage.authenticator.AccountAuthenticator; import au.id.teda.broadband.usage.database.DailyDataTableAdapter; import au.id.teda.broadband.usage.helper.AccountInfoHelper; import au.id.teda.broadband.usage.helper.AccountStatusHelper; import au.id.teda.broadband.usage.parser.AccountInfoParser; import au.id.teda.broadband.usage.parser.AccountStatusParser; import au.id.teda.broadband.usage.parser.ErrorParser; import au.id.teda.broadband.usage.parser.VolumeUsageParser; import org.xmlpull.v1.XmlPullParserException; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; import android.preference.PreferenceManager; import au.id.teda.broadband.usage.R; import au.id.teda.broadband.usage.helper.NotificationHelper; /** * Class for downloading XML data. * Authenticate * Account Information * Account Status * Volume Usage * * @author iteda * */ public class NetworkUtilities { //private static final String DEBUG_TAG = BaseActivity.DEBUG_TAG; /** Activity context **/ private Context mContext; /** Activity shared preferences **/ SharedPreferences sharedPrefs; // Used for testing public static final boolean weTesting = false; private static int RAW_XML_TESTING_FILE = R.raw.naked_dsl_home_5; public static final String PERIOD_STRING = "200903"; private AccountAuthenticator mAccountAuthenticator; private static String mUsername; // Error texts from XML private static final String AUTHENTICATION_FAILURE = "Authentication failure"; public final static String PREF_LAST_SYNC_KEY = "last_sync_timestamp"; /** * Class constructor * @param context */ public NetworkUtilities(Context context) { // Set context based on activity context passed to constructor mContext = context; mAccountAuthenticator = new AccountAuthenticator(mContext); } /** * Setup progress dialog and then start download task */ public void syncXmlData(){ mUsername = mAccountAuthenticator.getUsername(); SyncXmlThread mSyncThread = new SyncXmlThread(); mSyncThread.run(); } /** * Get xml buffered input stream * @return * @throws IOException */ private UnclosableBufferedInputStream getXmlBufferedInputStream() throws IOException { InputStream stream; if (weTesting){ stream = mContext.getResources().openRawResource(RAW_XML_TESTING_FILE); } else { stream = getUrlInputStream(urlBuilder(mUsername, mAccountAuthenticator.getPassword())); } UnclosableBufferedInputStream bis = new UnclosableBufferedInputStream (stream); return bis; } /** * Url builder for downloading XML * @param username * @param password * @return */ private String urlBuilder(String username, String password){ String urlString = "https://toolbox.iinet.net.au/cgi-bin/new/volume_usage_xml.cgi?" + "username=" + username + "&action=login" + "&password=" + password; return urlString; } /** * Get URL input stream for string representation of URL * @param urlString * @return * @throws IOException */ private InputStream getUrlInputStream(String urlString) throws IOException { URL url = new URL(urlString); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setReadTimeout(10000 /* milliseconds */); conn.setConnectTimeout(15000 /* milliseconds */); conn.setRequestMethod("GET"); conn.setDoInput(true); // Starts the query conn.connect(); InputStream stream = conn.getInputStream(); return stream; } /** * Parse XML based on username and password, for authentication failure error. * * @param username * @param password * @return boolean false if error tag found in XML parse */ public Boolean authenticate(String username, String password){ String errorString = null; ErrorParser mErrorParser = new ErrorParser(); try { InputStream stream; if (weTesting){ stream = mContext.getResources().openRawResource(RAW_XML_TESTING_FILE); } else { stream = getUrlInputStream(urlBuilder(username, password)); } errorString = mErrorParser.parse(stream); } catch (XmlPullParserException e) { e.printStackTrace(); return false; } catch (IOException e) { e.printStackTrace(); return false; } if (errorString != null && errorString.equals(AUTHENTICATION_FAILURE)){ return false; } else { return true; } } /** * Parse XML input stream for account information and then set shared prefs * @param stream */ private void setAccountInfo(UnclosableBufferedInputStream stream) { AccountInfoParser mAccountInfoParser = new AccountInfoParser(); List<AccountInfoParser.AccountInfo> account = null; try { account = mAccountInfoParser.parse(stream); } catch (XmlPullParserException e) { //Log.e(DEBUG_TAG, "XmlPullParserException: " + e); } catch (IOException e) { //Log.e(DEBUG_TAG, "IOException: " + e); } AccountInfoHelper mAccountInfoHelper = new AccountInfoHelper(mContext); String plan = null; String product = null; boolean isAnyTime = false; long offpeakStartTime; long offpeakEndTime; long anyTimeQuota; long peakQuota; long offpeakQuota; for (AccountInfoParser.AccountInfo accountInfo : account) { plan = accountInfo.plan; product = accountInfo.product; isAnyTime = accountInfo.isAnyTime; offpeakStartTime = accountInfo.offpeakStartTime; offpeakEndTime = accountInfo.offpeakEndTime; anyTimeQuota = accountInfo.anytimeQuota; peakQuota = accountInfo.offpeakQuota; offpeakQuota = accountInfo.offpeakQuota; //Log.d(DEBUG_TAG, "isAnyTime:" + isAnyTime); //Log.d(DEBUG_TAG, "anyTimeQuota:" + anyTimeQuota); mAccountInfoHelper.setAccountInfo(mUsername, plan, product, isAnyTime, offpeakStartTime, offpeakEndTime, anyTimeQuota, peakQuota, offpeakQuota); } } /** * Parse XML input stream for account status and then set shared prefs * @param stream */ private void setAccountStatus(UnclosableBufferedInputStream stream){ AccountStatusParser mAccountStatusParser= new AccountStatusParser(); List<AccountStatusParser.AccountStatus> status = null; try { status = mAccountStatusParser.parse(stream); } catch (XmlPullParserException e) { //Log.e(DEBUG_TAG, "XmlPullParserException: " + e); } catch (IOException e) { //Log.e(DEBUG_TAG, "IOException: " + e); } AccountStatusHelper mAccountStatusHelper = new AccountStatusHelper(mContext); long quotaResetDate; long quotaStartDate; long anyTimeDateUsed; boolean anyTimeIsShaped; long anyTimeSpeed; long peakDataUsed; long offpeakDataUsed; long uploadsDataUsed; long freezoneDataUsed; int peakSpeed; boolean peakIsShaped; int offpeakSpeed; boolean offpeakIsShaped; String ipAddress; long upTimeDate; for (AccountStatusParser.AccountStatus accountStatus : status) { quotaResetDate = accountStatus.quotaResetDate; quotaStartDate = accountStatus.quotaStartDate; anyTimeDateUsed = accountStatus.anyTimeDataUsed; anyTimeSpeed = accountStatus.anyTimeSpeed; anyTimeIsShaped = accountStatus.anyTimeIsShaped; peakDataUsed = accountStatus.peakDataUsed; offpeakDataUsed = accountStatus.offpeakDataUsed; uploadsDataUsed = accountStatus.uploadsDataUsed; freezoneDataUsed = accountStatus.freezoneDataUsed; peakSpeed = accountStatus.peakSpeed; peakIsShaped = accountStatus.peakIsShaped; offpeakSpeed = accountStatus.offpeakSpeed; offpeakIsShaped = accountStatus.offpeakIsShaped; ipAddress = accountStatus.ipAddress; upTimeDate = accountStatus.upTimeDate; /** Log.d(DEBUG_TAG, "quotaResetDate: " + quotaResetDate + " | quotaStartDate: " + quotaStartDate); Log.d(DEBUG_TAG, "anyTimeDateUsed: " + anyTimeDateUsed + " | anyTimeIsShaped: " + anyTimeIsShaped + " | anyTimeSpeed: " + anyTimeSpeed); Log.d(DEBUG_TAG, "peakDataUsed: " + peakDataUsed + " | peakIsShaped: " + peakIsShaped + " | peakSpeed: " + peakSpeed); Log.d(DEBUG_TAG, "offpeakDataUsed: " + offpeakDataUsed + " | offpeakIsShaped: " + offpeakIsShaped + " | offpeakSpeed: " + offpeakSpeed); Log.d(DEBUG_TAG, "uploadsDataUsed: " + uploadsDataUsed + " | freezoneDataUsed: " + freezoneDataUsed + " | ipAddress: " + ipAddress + " | upTimeDate: " + upTimeDate); **/ mAccountStatusHelper.setAccoutStatus(mUsername , quotaResetDate, quotaStartDate , anyTimeDateUsed, anyTimeIsShaped, anyTimeSpeed , peakDataUsed, peakIsShaped, peakSpeed , offpeakDataUsed, offpeakIsShaped, offpeakSpeed , uploadsDataUsed, freezoneDataUsed , ipAddress, upTimeDate); } } /** * Parse XML input stream for volume dev and then added to database * @param stream */ private void setVolumeUsage(UnclosableBufferedInputStream stream) { VolumeUsageParser mVolumeUsageParser = new VolumeUsageParser(); List<DailyVolumeUsage> usage = null; try { usage = mVolumeUsageParser.parse(stream); } catch (XmlPullParserException e) { //Log.e(DEBUG_TAG, "XmlPullParserException: " + e); } catch (IOException e) { //Log.e(DEBUG_TAG, "IOException: " + e); } // Initiate database DailyDataTableAdapter mDatabase = new DailyDataTableAdapter(mContext); mDatabase.open(); for (DailyVolumeUsage volumeUsage : usage) { Long day = volumeUsage.day; String month = volumeUsage.month; Long anytime = volumeUsage.anytime; Long peak = volumeUsage.peak; Long offpeak = volumeUsage.offpeak; Long uploads = volumeUsage.uploads; Long freezone = volumeUsage.freezone; /** Log.d(DEBUG_TAG, "day: " + day + " | month" + month + " | anytime: " + anytime + " | peak: " + peak + " | offpeak: " + offpeak + " | uploads: " + uploads + " | freezone: " + freezone); **/ mDatabase.addReplaceEntry(mUsername, month, day, anytime, peak, offpeak, uploads, freezone); } mDatabase.close(); } private class SyncXmlThread implements Runnable{ @Override public void run() { String start = mContext.getString(R.string.sync_broadcast_start); sendBroadcastMessage(start); UnclosableBufferedInputStream stream; try { stream = getXmlBufferedInputStream(); setAccountInfo(stream); setAccountStatus(stream); setVolumeUsage(stream); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } String complete = mContext.getString(R.string.sync_broadcast_complete); sendBroadcastMessage(complete); NotificationHelper mNotificationHelper = new NotificationHelper(mContext); mNotificationHelper.checkStatus(); setSyncTimeStamp(); } } private void sendBroadcastMessage(String msg){ String BROADCAST = mContext.getString(R.string.sync_broadcast_action); String MESSAGE = mContext.getString(R.string.sync_broadcast_message); Intent i = new Intent(BROADCAST); i.putExtra(MESSAGE, msg); mContext.sendBroadcast(i); } private void setSyncTimeStamp(){ SharedPreferences mSettings = PreferenceManager.getDefaultSharedPreferences(mContext); SharedPreferences.Editor mEditor = mSettings.edit(); // Get current date/time Calendar now = Calendar.getInstance(); long nowInMillis = now.getTimeInMillis(); // Put into shared prefferences mEditor.putLong(PREF_LAST_SYNC_KEY, nowInMillis); mEditor.commit(); } /** * Class of buffer input stream * @author iteda * */ private class UnclosableBufferedInputStream extends BufferedInputStream { public UnclosableBufferedInputStream(InputStream in) { super(in); super.mark(Integer.MAX_VALUE); } @Override public void close() throws IOException { super.reset(); } } }