package roman10.http;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.RandomAccessFile;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.HttpVersion;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.FileEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.params.CoreProtocolPNames;
import roman10.media.dash.VideoBrowser;
import roman10.utils.FileUtilsStatic;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.IBinder;
import android.os.PowerManager;
import android.util.Log;
public class UploadService extends Service {
private Context mContext;
private PowerManager.WakeLock wl; //lock used when uploading is on-going
private static Queue<String> mUploadFileQueue = new LinkedList<String>();
private final static ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock();
private final static Lock readLock = readWriteLock.readLock();
private final static Lock writeLock = readWriteLock.writeLock();
public static void addUploadFile(String _task) {
writeLock.lock();
try {
mUploadFileQueue.add(_task);
} finally {
writeLock.unlock();
}
}
public static String removeUploadFile() {
writeLock.lock();
try {
if (!mUploadFileQueue.isEmpty()) {
return mUploadFileQueue.remove();
} else {
return null;
}
} finally {
writeLock.unlock();
}
}
public static String topUploadFile() {
readLock.lock();
try {
if (!mUploadFileQueue.isEmpty()) {
return mUploadFileQueue.peek();
} else {
return null;
}
} finally {
readLock.unlock();
}
}
public static boolean noFileToUpload() {
return mUploadFileQueue.isEmpty();
}
@Override
public void onCreate() {
mContext = this.getApplicationContext();
}
UploadFileTask uploadFileTask = null;
@Override
public void onStart(Intent intent, int startid) {
Log.i("onStart", "start upload files");
if (uploadFileTask == null || uploadFileTask.isCancelled()) {
uploadFileTask = new UploadFileTask();
uploadFileTask.execute();
}
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
private void stopService() {
this.stopSelf();
}
@Override
public void onDestroy() {
super.onDestroy();
if (wl != null) {
wl.release();
}
}
//TODO: to make it more efficient, don't create http client every time
public void uploadFile(String pFileFullPathName) throws ClientProtocolException, IOException {
HttpClient httpClient = new DefaultHttpClient();
try {
httpClient.getParams().setParameter(CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP_1_1);
httpClient.getParams().setParameter("http.socket.timeout", new Integer(90000)); // 90 second
HttpPost httpPost = new HttpPost("http://cervino.ddns.comp.nus.edu.sg/~a0075306/receivefinal.php");
// File lFile = new File(pFileFullPathName);
// FileEntity lEntity;
// lEntity = new FileEntity(lFile, "binary/octet-stream");
// lEntity.setChunked(true);
SimpleMultipartEntity mpEntity = new SimpleMultipartEntity();
File vFile = new File(pFileFullPathName);
mpEntity.addPart("myfile", pFileFullPathName.substring(pFileFullPathName.lastIndexOf("/")+1), new FileInputStream(vFile), "video/" + pFileFullPathName.substring(pFileFullPathName.lastIndexOf(".") + 1));
httpPost.setEntity(mpEntity);
HttpResponse lResponse = httpClient.execute(httpPost);
if (lResponse.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
Log.e("UploadService-uploadFile","Response Status line code:"+ lResponse.getStatusLine());
}
HttpEntity resEntity = lResponse.getEntity();
if (resEntity == null) {
Log.e("UploadService-uploadFile", "No Response!");
}
} finally {
httpClient.getConnectionManager().shutdown();
}
}
public int requestFileStatus(String filePath) {
int status = 0;
// Create a new HttpClient
HttpClient httpclient = new DefaultHttpClient();
try {
//Post Header
HttpPost httppost = new HttpPost("http://cervino.ddns.comp.nus.edu.sg/~a0075306/startupload.php");
// HttpGet httpget = new HttpGet("http://cervino.ddns.comp.nus.edu.sg/~a0075306/startupload.php");
// Add data
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(1);
String lFileName = filePath.substring(filePath.lastIndexOf("/")+1);
nameValuePairs.add(new BasicNameValuePair("filename[" + 0 + "]", lFileName));
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
// HttpParams params = new BasicHttpParams();
// params.setParameter(name, value);
// httpget.setParams(params);
// Execute HTTP Post Request
HttpResponse response = httpclient.execute(httppost);
if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
Log.e("queryHttp","Response Status line code:"+ response.getStatusLine());
}
HttpEntity resEntity = response.getEntity();
if (resEntity == null) {
Log.e("queryHttp", "No Response!");
} else {
BufferedReader br = new BufferedReader(new InputStreamReader(resEntity.getContent()));
String line = br.readLine();
Log.i("http reply", line);
status = Integer.valueOf(line);
br.close();
}
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
} catch (IOException e) {
// TODO Auto-generated catch block
} finally {
httpclient.getConnectionManager().shutdown();
}
return status;
}
private class UploadFileTask extends AsyncTask<Object, Integer, Object> {
@Override
protected void onPreExecute() {
/*acquire PARTIAL_WAKE_LOCK WakeLock, so that the processing can continue even when screen is off*/
PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
"generateStreamletTask");
wl.acquire();
}
@Override
protected Object doInBackground(Object... arg0) {
try {
//VideoBrowser.mCurrUploadFileNum = 0;
for (int fi = 0; fi < VideoBrowser.mUploadFileNameList.size(); ++fi) {
String lFileFullPathName = topUploadFile();
Log.i("UploadFileTask-doInBackground", "upload file " + lFileFullPathName);
int status = requestFileStatus(lFileFullPathName);
Log.i("status", status + ":");
if (status == 1) {
//TODO: file already uploaded, we still send, as server
//side might not have done transcoding and other stuff yet
//this should be improved in future release
uploadFile(lFileFullPathName);
} else if (status == 0) {
//file not uploaded, upload it
uploadFile(lFileFullPathName);
} else {
//file partially uploaded, upload the rest
InputStream myInput = new FileInputStream(lFileFullPathName);
String tmpFile = FileUtilsStatic.DEFAULT_TMP_DIR + lFileFullPathName.substring(lFileFullPathName.lastIndexOf("/")+1);
FileOutputStream myOutput = new FileOutputStream(tmpFile);
byte[] buffer = new byte[1024];
int length;
myInput.skip(status);
while ((length = myInput.read(buffer)) > 0) {
myOutput.write(buffer, 0, length);
}
myOutput.flush();
myOutput.close();
myInput.close();
uploadFile(tmpFile);
Log.i("file size", new File(lFileFullPathName).length() + ":" + new File(tmpFile).length() + ":" + status);
}
removeUploadFile(); //after upload is done, we then remove the item from the queue
++VideoBrowser.mCurrUploadFileNum;
this.publishProgress();
}
} catch (Exception e) {
Log.i("UploadFileTask-doInBackground", "exception");
if (!mUploadFileQueue.isEmpty()) {
Log.i("UploadServer", "queue not empty, check if we can resume upload every 10 seconds");
Intent intent = new Intent();
intent.setAction(Intent.ACTION_ATTACH_DATA);
intent.putExtra("action", VideoBrowser.upladInterruptedReceiver_ACTION);
mContext.sendBroadcast(intent);
}
}
return null;
}
@Override
protected void onProgressUpdate(Integer... progress) {
VideoBrowser.updateUploadFilesProgress();
}
@Override
protected void onPostExecute(Object res) {
VideoBrowser.finishUploadFiles();
uploadFileTask = null;
stopService(); //finish the service
}
}
}