-
Notifications
You must be signed in to change notification settings - Fork 199
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
added UCD data profiling library, not enabled yet.
- Loading branch information
Showing
68 changed files
with
14,405 additions
and
27 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
package edu.ucdavis.earlybird; | ||
|
||
import org.mariotaku.twidere.BuildConfig; | ||
import org.mariotaku.twidere.Constants; | ||
|
||
import java.io.BufferedWriter; | ||
import java.io.FileOutputStream; | ||
import java.io.OutputStreamWriter; | ||
|
||
import android.content.Context; | ||
import android.content.Intent; | ||
import android.content.IntentFilter; | ||
import android.content.SharedPreferences; | ||
import android.net.ConnectivityManager; | ||
import android.net.NetworkInfo; | ||
import android.os.BatteryManager; | ||
import android.util.Log; | ||
|
||
public class ProfilingUtil { | ||
static final boolean DEBUG = BuildConfig.DEBUG; | ||
|
||
public static final String FILE_NAME_PROFILE = "Profile"; | ||
public static final String FILE_NAME_LOCATION = "Location"; | ||
public static final String FILE_NAME_APP = "App"; | ||
|
||
public static boolean log(String msg) { | ||
if (DEBUG) { | ||
StackTraceElement ste = new Throwable().fillInStackTrace() | ||
.getStackTrace()[1]; | ||
String fullname = ste.getClassName(); | ||
String name = fullname.substring(fullname.lastIndexOf('.')); | ||
String tag = name + "." + ste.getMethodName(); | ||
Log.v(tag, msg); | ||
return true; | ||
} else | ||
return false; | ||
} | ||
|
||
|
||
public static void profiling(final Context context, final long accountID, final String text) { | ||
profiling(context, accountID + "_" + FILE_NAME_PROFILE, text); | ||
} | ||
|
||
public static void profiling(final Context context, final String name, final String text) { | ||
if (context == null) return; | ||
final SharedPreferences prefs = context.getSharedPreferences(Constants.SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE); | ||
if (!prefs.getBoolean(Constants.PREFERENCE_KEY_UCD_DATA_PROFILING, false)) return; | ||
final String filename = name + ".csv"; | ||
new Thread() { | ||
@Override | ||
public void run() { | ||
try { | ||
final FileOutputStream fos = context.openFileOutput(filename, Context.MODE_APPEND); | ||
if (fos == null) return; | ||
final BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(fos)); | ||
bw.write("[" + System.currentTimeMillis() + "], " + text | ||
+ "\n"); | ||
bw.flush(); | ||
fos.close(); | ||
} catch (Exception e) { | ||
e.printStackTrace(); | ||
} | ||
}; | ||
}.start(); | ||
} | ||
|
||
public static boolean isCharging(Context context) { | ||
if (context == null) return false; | ||
final Intent intent = context.registerReceiver(null, new IntentFilter( | ||
Intent.ACTION_BATTERY_CHANGED)); | ||
final int plugged = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1); | ||
return plugged == BatteryManager.BATTERY_PLUGGED_AC | ||
|| plugged == BatteryManager.BATTERY_PLUGGED_USB; | ||
} | ||
|
||
public static boolean isOnWifi(Context context) { | ||
if (context == null) return false; | ||
final ConnectivityManager conn = (ConnectivityManager) context | ||
.getSystemService(Context.CONNECTIVITY_SERVICE); | ||
final NetworkInfo networkInfo = conn.getActiveNetworkInfo(); | ||
|
||
return networkInfo != null && networkInfo.getType() == ConnectivityManager.TYPE_WIFI && | ||
networkInfo.isConnected(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
package edu.ucdavis.earlybird; | ||
|
||
import android.app.AlarmManager; | ||
import android.app.PendingIntent; | ||
import android.app.Service; | ||
import android.content.BroadcastReceiver; | ||
import android.content.Context; | ||
import android.content.Intent; | ||
import android.content.IntentFilter; | ||
import android.location.Criteria; | ||
import android.location.Location; | ||
import android.location.LocationListener; | ||
import android.location.LocationManager; | ||
import android.os.Bundle; | ||
import android.os.IBinder; | ||
|
||
/** | ||
* Request location ONCE per WAKE_PERIOD_IN_MILLI. | ||
*/ | ||
public class UCDService extends Service { | ||
|
||
public static final long LOCATION_PERIOD_IN_MILLI = 15 * 60 * 1000; | ||
public static final String ACTION_GET_LOCATION = "edu.ucdavis.earlybird.GET_LOCATION"; | ||
private LocationManager mLocationManager; | ||
private FineLocationListener mFineLocationListener; | ||
private AlarmManager mAlarmManager; | ||
private AlarmReceiver mAlarmReceiver; | ||
private PendingIntent StartIntent; | ||
|
||
@Override | ||
public void onCreate() { | ||
super.onCreate(); | ||
|
||
ProfilingUtil.log("onCreate"); | ||
mLocationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE); | ||
mFineLocationListener = new FineLocationListener(); | ||
mAlarmManager = (AlarmManager) getSystemService(Service.ALARM_SERVICE); | ||
|
||
mAlarmReceiver = new AlarmReceiver(); | ||
IntentFilter myFilter = new IntentFilter(); | ||
myFilter.addAction(ACTION_GET_LOCATION); | ||
registerReceiver(mAlarmReceiver, myFilter); | ||
|
||
Intent intent = new Intent(ACTION_GET_LOCATION); | ||
StartIntent = PendingIntent.getBroadcast(this, 0, intent, 0); | ||
mAlarmManager.setRepeating(AlarmManager.RTC_WAKEUP, | ||
System.currentTimeMillis(), LOCATION_PERIOD_IN_MILLI, | ||
StartIntent); | ||
|
||
// Upload Service | ||
Intent i = new Intent(UploadReceiver.ACTION_UPLOAD_PROFILE); | ||
PendingIntent pi = PendingIntent.getBroadcast(this, 0, i, 0); | ||
mAlarmManager.setRepeating(AlarmManager.RTC_WAKEUP, | ||
System.currentTimeMillis(), 12 * 60 * 60 * 1000, pi); | ||
} | ||
|
||
private final class AlarmReceiver extends BroadcastReceiver { | ||
|
||
@Override | ||
public void onReceive(Context context, Intent intent) { | ||
ProfilingUtil.log("AlarmReceiver"); | ||
final Criteria criteria = new Criteria(); | ||
criteria.setAccuracy(Criteria.ACCURACY_COARSE); | ||
final String provider = mLocationManager.getBestProvider(criteria, | ||
true); | ||
mLocationManager.requestLocationUpdates(provider, 0, 0, | ||
mFineLocationListener); | ||
} | ||
} | ||
|
||
private final class FineLocationListener implements LocationListener { | ||
|
||
@Override | ||
public void onLocationChanged(Location location) { | ||
ProfilingUtil.profiling(UCDService.this, ProfilingUtil.FILE_NAME_LOCATION, location.getTime() + "," | ||
+ location.getLatitude() + "," + location.getLongitude() + "," | ||
+ location.getProvider()); | ||
ProfilingUtil.log(location.getTime() + "," + location.getLatitude() + "," | ||
+ location.getLongitude() + "," + location.getProvider()); | ||
|
||
mLocationManager.removeUpdates(mFineLocationListener); | ||
} | ||
|
||
@Override | ||
public void onStatusChanged(String provider, int status, Bundle extras) { | ||
ProfilingUtil.log("onStatusChanged"); | ||
} | ||
|
||
@Override | ||
public void onProviderEnabled(String provider) { | ||
ProfilingUtil.log("onProviderEnabled"); | ||
} | ||
|
||
@Override | ||
public void onProviderDisabled(String provider) { | ||
ProfilingUtil.log("onProviderDisabled"); | ||
} | ||
} | ||
|
||
@Override | ||
public IBinder onBind(Intent intent) { | ||
throw new IllegalStateException("Not implemented."); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
package edu.ucdavis.earlybird; | ||
|
||
import android.content.BroadcastReceiver; | ||
import android.content.Context; | ||
import android.content.Intent; | ||
|
||
public class UploadReceiver extends BroadcastReceiver { | ||
public static boolean isWifi = false; | ||
public static boolean isCharging = false; | ||
|
||
public static final String ACTION_UPLOAD_PROFILE = "edu.ucdavis.earlybird.UPLOAD_PROFILE"; | ||
|
||
@Override | ||
public void onReceive(Context context, Intent intent) { | ||
isWifi = ProfilingUtil.isOnWifi(context.getApplicationContext()); | ||
isCharging = ProfilingUtil.isCharging(context.getApplicationContext()); | ||
|
||
if (isWifi && isCharging) { | ||
new UploadTask(context).execute(); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,126 @@ | ||
package edu.ucdavis.earlybird; | ||
|
||
import java.io.File; | ||
import java.io.FileInputStream; | ||
import java.io.IOException; | ||
import java.net.SocketException; | ||
import java.util.Calendar; | ||
|
||
import org.apache.commons.net.ftp.FTP; | ||
import org.apache.commons.net.ftp.FTPClient; | ||
import org.apache.commons.net.ftp.FTPConnectionClosedException; | ||
import org.apache.commons.net.ftp.FTPReply; | ||
|
||
import android.content.Context; | ||
import android.content.SharedPreferences; | ||
import android.os.AsyncTask; | ||
import android.preference.PreferenceManager; | ||
import android.provider.Settings.Secure; | ||
|
||
public class UploadTask extends AsyncTask<Void, Void, Void> { | ||
|
||
private static final String LAST_UPLOAD_DATE = "last_upload_time"; | ||
private static final double MILLSECS_HALF_DAY = 1000 * 60 * 60 * 12; | ||
|
||
private static final String FTP_PROFILE_SERVER = "earlybird_profile.metaisle.com"; | ||
private static final String FTP_USERNAME = "profile"; | ||
private static final String FTP_PASSWORD = "profile"; | ||
|
||
private final String device_id; | ||
private final Context context; | ||
|
||
public UploadTask(Context context) { | ||
this.context = context; | ||
device_id = Secure.getString(context.getContentResolver(), Secure.ANDROID_ID); | ||
} | ||
|
||
@Override | ||
protected Void doInBackground(Void... params) { | ||
final SharedPreferences prefs = context.getSharedPreferences("ucd_data_profiling", | ||
Context.MODE_PRIVATE); | ||
|
||
if (prefs.contains(LAST_UPLOAD_DATE)) { | ||
final long lastUpload = prefs.getLong(LAST_UPLOAD_DATE, System.currentTimeMillis()); | ||
final double deltaDays = ((double) (System.currentTimeMillis() - lastUpload)) | ||
/ (MILLSECS_HALF_DAY * 2); | ||
if (deltaDays < 1) { | ||
ProfilingUtil.log("Uploaded less than 1 day ago."); | ||
return null; | ||
} | ||
} | ||
|
||
final File root = context.getFileStreamPath(""); | ||
final File[] files = root.listFiles(); | ||
|
||
try { | ||
uploadToFTP(files); | ||
prefs.edit().putLong(LAST_UPLOAD_DATE, System.currentTimeMillis()).commit(); | ||
} catch (Exception ex) { | ||
} | ||
return null; | ||
} | ||
|
||
private boolean uploadToFTP(File... files) { | ||
|
||
final FTPClient ftp = new FTPClient(); | ||
|
||
ftp.setDefaultTimeout(30000); | ||
|
||
try { | ||
ftp.connect(FTP_PROFILE_SERVER, 21); | ||
int reply = ftp.getReplyCode(); | ||
if (!FTPReply.isPositiveCompletion(reply)) { | ||
ProfilingUtil.log("FTP connect fail"); | ||
ftp.disconnect(); | ||
} else { | ||
if (ftp.login(FTP_USERNAME, FTP_PASSWORD)) { | ||
ftp.enterLocalPassiveMode(); | ||
ProfilingUtil.log("FTP connect OK"); | ||
ftp.setFileType(FTP.BINARY_FILE_TYPE); | ||
Calendar now = Calendar.getInstance(); | ||
for (final File file : files) { | ||
if (!file.isFile() || file.length() <= 0) continue; | ||
final FileInputStream fis = new FileInputStream(file); | ||
final String filename = file.getName(); | ||
final String profile_type = filename.substring(0, filename.indexOf('.')); | ||
final String file_type = filename.substring(filename.indexOf('.')); | ||
final boolean working_dir_exists = ftp.changeWorkingDirectory("/profile/" + device_id + "/" + profile_type); | ||
if (!working_dir_exists) { | ||
ProfilingUtil.log("create user folder : " + "/profile/" | ||
+ device_id + "/" + profile_type); | ||
ftp.makeDirectory("/profile/" + device_id); | ||
ftp.makeDirectory("/profile/" + device_id + "/" | ||
+ profile_type); | ||
} | ||
final String upload_file_name = "/profile/" + device_id + "/" + profile_type | ||
+ "/" + now.getTimeInMillis() + file_type; | ||
|
||
ftp.setFileType(FTP.BINARY_FILE_TYPE); | ||
ftp.storeFile(upload_file_name, fis); | ||
ProfilingUtil.log("Upload File : " + upload_file_name); | ||
reply = ftp.getReplyCode(); | ||
ProfilingUtil.log("reply :" + reply); | ||
if (reply == FTPReply.CLOSING_DATA_CONNECTION) { | ||
ProfilingUtil.log("file upload success"); | ||
file.delete(); | ||
} | ||
} | ||
ftp.logout(); | ||
} | ||
} | ||
} catch (FTPConnectionClosedException e) { | ||
ProfilingUtil.log("ftp connect error!!"); | ||
e.printStackTrace(); | ||
return false; | ||
} catch (SocketException e) { | ||
e.printStackTrace(); | ||
return false; | ||
} catch (IOException e) { | ||
e.printStackTrace(); | ||
return false; | ||
} | ||
return false; | ||
|
||
} | ||
|
||
} |
56 changes: 56 additions & 0 deletions
56
src/org/apache/commons/net/MalformedServerReplyException.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
/* | ||
* Licensed to the Apache Software Foundation (ASF) under one or more | ||
* contributor license agreements. See the NOTICE file distributed with | ||
* this work for additional information regarding copyright ownership. | ||
* The ASF licenses this file to You under the Apache License, Version 2.0 | ||
* (the "License"); you may not use this file except in compliance with | ||
* the License. You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
package org.apache.commons.net; | ||
|
||
import java.io.IOException; | ||
|
||
/*** | ||
* This exception is used to indicate that the reply from a server | ||
* could not be interpreted. Most of the NetComponents classes attempt | ||
* to be as lenient as possible when receiving server replies. Many | ||
* server implementations deviate from IETF protocol specifications, making | ||
* it necessary to be as flexible as possible. However, there will be | ||
* certain situations where it is not possible to continue an operation | ||
* because the server reply could not be interpreted in a meaningful manner. | ||
* In these cases, a MalformedServerReplyException should be thrown. | ||
* <p> | ||
* <p> | ||
***/ | ||
|
||
public class MalformedServerReplyException extends IOException | ||
{ | ||
|
||
private static final long serialVersionUID = 6006765264250543945L; | ||
|
||
/*** Constructs a MalformedServerReplyException with no message ***/ | ||
public MalformedServerReplyException() | ||
{ | ||
super(); | ||
} | ||
|
||
/*** | ||
* Constructs a MalformedServerReplyException with a specified message. | ||
* <p> | ||
* @param message The message explaining the reason for the exception. | ||
***/ | ||
public MalformedServerReplyException(String message) | ||
{ | ||
super(message); | ||
} | ||
|
||
} |
Oops, something went wrong.