/**
* galaxy inc.
* meetup client for android
*/
package com.galaxy.meetup.client.android.iu;
import java.io.IOException;
import java.util.HashSet;
import android.accounts.AccountManager;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.SyncResult;
import android.content.SyncStats;
import android.database.ContentObserver;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.net.Uri;
import android.os.Environment;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
import android.os.Message;
import android.preference.PreferenceManager;
import android.util.Log;
import com.android.gallery3d.common.Utils;
import com.galaxy.meetup.client.android.EsMatrixCursor;
import com.galaxy.meetup.client.util.EsLog;
import com.galaxy.picasa.sync.PhotoEntry;
import com.galaxy.picasa.sync.PicasaDatabaseHelper;
import com.galaxy.picasa.sync.PicasaSyncHelper;
import com.galaxy.picasa.sync.SyncTask;
/**
*
* @author sihai
*
*/
public class UploadsManager {
private static final Uri EXTERNAL_STORAGE_FSID_URI = Uri.parse("content://media/external/fs_id");
private static final String MEDIA_RECORD_TABLE_NAME;
private static final String PHOTO_TABLE_NAME;
private static final String PROJECTION_DATA[] = {
"_data"
};
private static final String PROJECTION_FINGERPRINT[] = {
"fingerprint"
};
private static final String PROJECTION_QUOTA[] = {
"quota_limit", "quota_used"
};
private static UploadsManager sInstance;
private final AccountManager mAccountManager;
private final Context mContext;
private UploadTask mCurrent;
private int mExternalStorageFsId;
private final Handler mHandler;
private volatile boolean mIsExternalStorageFsIdReady;
private final PicasaDatabaseHelper mPicasaDbHelper;
private final SharedPreferences mPreferences;
private HashSet mProblematicAccounts;
private long mResetDelay;
private final UploadSettings mSettings;
private final PicasaSyncHelper mSyncHelper;
private HashSet mSyncedAccounts;
private final NewMediaTracker mToddsMediaTracker;
private String mUploadUrl;
private final UploadsDatabaseHelper mUploadsDbHelper;
static
{
MEDIA_RECORD_TABLE_NAME = MediaRecordEntry.SCHEMA.getTableName();
PHOTO_TABLE_NAME = PhotoEntry.SCHEMA.getTableName();
}
private static final class MessageHandler extends Handler {
MessageHandler(Looper looper)
{
super(looper);
}
public final void handleMessage(Message message) {
if(null == UploadsManager.sInstance) {
return;
}
switch(message.what)
{
case 4: // '\004'
default:
throw new AssertionError((new StringBuilder("unknown message: ")).append(message.what).toString());
case 6: // '\006'
if(message.obj instanceof Cursor)
UploadsManager.sInstance.mSettings.reloadSettings((Cursor)message.obj);
else
UploadsManager.sInstance.mSettings.reloadSettings(null);
break;
case 5: // '\005'
UploadsManager.sInstance.cancelTaskInternal(((Long)message.obj).longValue());
break;
case 1: // '\001'
UploadsManager.sInstance.sendUploadAllProgressBroadcast();
break;
case 2: // '\002'
UploadsManager.sInstance.uploadExistingPhotosInternal((String)message.obj);
break;
case 3: // '\003'
UploadsManager.sInstance.cancelUploadExistingPhotosInternal((String)message.obj);
break;
case 7: // '\007'
UploadsManager.sInstance.onFsIdChangedInternal();
break;
case 8: // '\b'
if(EsLog.isLoggable("iu.UploadsManager", 3))
Log.d("iu.UploadsManager", "Try to reset UploadsManager again!");
UploadsManager.sInstance.reset();
break;
}
}
}
private final class UploadTask extends SyncTask implements Uploader.UploadProgressListener {
protected UploadTaskEntry mCurrentTask;
private HashSet mFingerprintSet;
private final boolean mIsPhoto;
protected String mLogName;
protected volatile boolean mRunning;
private final String mStateSetting;
protected PicasaSyncHelper.SyncContext mSyncContext;
protected final int mUploadType;
private final ContentValues mValues;
protected UploadTask(String s, int i, boolean flag)
{
super(s);
int flag1 = 1;
mRunning = true;
mValues = new ContentValues(1);
mUploadType = i;
mIsPhoto = flag;
int j = i << 1;
if(flag)
flag1 = 0;
mPriority = flag1 | j;
switch(i) {
case 10:
mStateSetting = "manual_upload_state";
mLogName = "Manual";
break;
case 20:
mStateSetting = "instant_share_state";
mLogName = "InstantShare";
break;
case 30:
mStateSetting = "instant_upload_state";
mLogName = "InstantUpload";
break;
case 40:
mStateSetting = "upload_all_state";
mLogName = "UploadAll";
break;
default:
throw new IllegalArgumentException((new StringBuilder("unknown upload type: ")).append(i).toString());
}
}
private UploadTaskEntry getNextUpload() throws IOException {
// TODO
return null;
}
private boolean isOutOfQuota(UploadTaskEntry uploadtaskentry) {
// TODO
return false;
}
private boolean isUploadedBefore(UploadTaskEntry uploadtaskentry) {
// TODO
return false;
}
private boolean onIncompleteUpload(UploadTaskEntry uploadtaskentry, boolean flag) {
// TODO
return false;
}
private void onTaskDone(UploadTaskEntry uploadtaskentry) {
// TODO
}
private void performSyncInternal(SyncResult syncresult) throws IOException {
// TODO
}
private void skipTask(UploadTaskEntry uploadtaskentry, SyncStats syncstats, Throwable throwable)
{
setState(uploadtaskentry, 11, throwable);
syncstats.numSkippedEntries = 1L + syncstats.numSkippedEntries;
removeTaskFromDb(uploadtaskentry.id);
MediaRecordEntry mediarecordentry = MediaRecordEntry.fromId(mUploadsDbHelper.getReadableDatabase(), uploadtaskentry.getMediaRecordId());
if(mediarecordentry != null)
{
mediarecordentry.setState(400, 38);
MediaRecordEntry.SCHEMA.insertOrReplace(mUploadsDbHelper.getWritableDatabase(), mediarecordentry);
}
onTaskDone(uploadtaskentry);
}
private boolean syncCameraSyncStream(SyncResult syncresult, String s) {
// TODO
return false;
}
public final boolean cancelIfCurrentTaskMatches(long l) {
// TODO
return false;
}
public final void cancelSync()
{
synchronized(UploadsManager.this)
{
mRunning = false;
stopCurrentTask(6);
if(mSyncContext != null)
mSyncContext.stopSync();
if(EsLog.isLoggable("iu.UploadsManager", 4))
Log.i("iu.UploadsManager", (new StringBuilder("--- CANCEL sync ")).append(mLogName).toString());
}
}
public final boolean isBackgroundSync()
{
boolean flag;
if(mUploadType != 10)
flag = true;
else
flag = false;
return flag;
}
public final boolean isSyncOnBattery()
{
boolean flag;
if(mUploadType == 10 || mUploadType == 20 || mSettings.getSyncOnBattery())
flag = true;
else
flag = false;
return flag;
}
public final boolean isSyncOnRoaming()
{
boolean flag;
if(mUploadType == 10 || mUploadType == 20 || mSettings.getSyncOnRoaming())
flag = true;
else
flag = false;
return flag;
}
public final boolean isSyncOnWifiOnly()
{
// TODO
return false;
}
public final void onFileChanged(UploadTaskEntry uploadtaskentry)
{
FingerprintHelper.get(mContext).invalidate(uploadtaskentry.getContentUri().toString());
}
public final void onProgress(UploadTaskEntry uploadtaskentry)
{
synchronized(UploadsManager.this)
{
if(mRunning)
{
if(EsLog.isLoggable("iu.UploadsManager", 2))
Log.v("iu.UploadsManager", (new StringBuilder(" progress: ")).append(uploadtaskentry).toString());
updateTaskStateAndProgressInDb(uploadtaskentry);
if(mUploadType == 10)
{
notifyManualUploadDbChanges();
android.content.ComponentName componentname = uploadtaskentry.getComponentName();
}
}
}
}
public final void onRejected(int i)
{
if(EsLog.isLoggable("iu.UploadsManager", 4))
Log.i("iu.UploadsManager", (new StringBuilder("REJECT ")).append(mLogName).append(" due to ").append(InstantUploadFacade.stateToString(i)).toString());
onStateChanged(i);
if(mUploadType == 40)
requestUploadAllProgressBroadcast();
}
protected final void onStateChanged(int i)
{
mValues.clear();
mValues.put(mStateSetting, Integer.valueOf(i));
mContext.getContentResolver().update(InstantUploadFacade.SETTINGS_URI, mValues, null, null);
if(mUploadType == 40)
requestUploadAllProgressBroadcast();
}
public final void performSync(SyncResult syncresult)
throws IOException
{
// TODO
}
protected final void stopCurrentTask(int i)
{
UploadTaskEntry uploadtaskentry = mCurrentTask;
if(EsLog.isLoggable("iu.UploadsManager", 3))
Log.d("iu.UploadsManager", (new StringBuilder("stopCurrentTask: ")).append(uploadtaskentry).toString());
if(uploadtaskentry != null)
synchronized(UploadsManager.this)
{
if(uploadtaskentry.isCancellable())
{
setState(uploadtaskentry, i);
notify();
}
}
}
}
private final class UploadTaskProvider implements SyncTaskProvider {
public final SyncTask getNextTask(String s)
{
// TODO
return null;
}
public final void onSyncStart()
{
if(EsLog.isLoggable("iu.UploadsManager", 3))
Log.d("iu.UploadsManager", "onSyncStart");
mProblematicAccounts.clear();
mSyncedAccounts.clear();
}
}
private UploadsManager(Context context) {
mProblematicAccounts = new HashSet();
mSyncedAccounts = new HashSet();
mIsExternalStorageFsIdReady = false;
mResetDelay = 15000L;
mContext = context;
mAccountManager = AccountManager.get(context);
mUploadsDbHelper = UploadsDatabaseHelper.getInstance(context);
mPicasaDbHelper = PicasaDatabaseHelper.get(context);
mPreferences = PreferenceManager.getDefaultSharedPreferences(context);
mSyncHelper = PicasaSyncHelper.getInstance(context);
mSettings = UploadSettings.getInstance(context);
mToddsMediaTracker = NewMediaTracker.getInstance(context);
HandlerThread handlerthread = new HandlerThread("picasa-uploads-manager", 10);
handlerthread.start();
mHandler = new MessageHandler(handlerthread.getLooper());
String s = mSettings.getSyncAccount();
if(s != null && mToddsMediaTracker.getUploadProgress(s, 40) == 0)
requestUploadAllProgressBroadcast();
mIsExternalStorageFsIdReady = mPreferences.contains("external_storage_fsid");
if(mIsExternalStorageFsIdReady)
mExternalStorageFsId = mPreferences.getInt("external_storage_fsid", -1);
String s1 = mPreferences.getString("system_release", null);
boolean flag;
if(!android.os.Build.VERSION.RELEASE.equals(s1))
{
mPreferences.edit().putString("system_release", android.os.Build.VERSION.RELEASE).commit();
if(EsLog.isLoggable("iu.UploadsManager", 4))
Log.i("iu.UploadsManager", (new StringBuilder("System upgrade from ")).append(s1).append(" to ").append(android.os.Build.VERSION.RELEASE).toString());
flag = true;
} else
{
flag = false;
}
if(flag)
reset();
context.getContentResolver().registerContentObserver(EXTERNAL_STORAGE_FSID_URI, false, new ContentObserver(mHandler) {
public final void onChange(boolean flag1)
{
onFsIdChangedInternal();
}
});
Message.obtain(mHandler, 7).sendToTarget();
}
private synchronized void cancelTaskInternal(long l)
{
if(mCurrent == null || !mCurrent.cancelIfCurrentTaskMatches(l))
{
UploadTaskEntry uploadtaskentry = UploadTaskEntry.fromDb(mUploadsDbHelper.getWritableDatabase(), l);
if(uploadtaskentry != null)
{
removeTaskFromDb(l);
setState(uploadtaskentry, 8);
notifyManualUploadDbChanges();
if(EsLog.isLoggable("iu.UploadsManager", 4))
Log.i("iu.UploadsManager", (new StringBuilder("--- CANCEL task: ")).append(uploadtaskentry).toString());
}
}
}
private synchronized void cancelUploadExistingPhotosInternal(String s) {
if(EsLog.isLoggable("iu.UploadsManager", 4))
Log.i("iu.UploadsManager", "--- CANCEL upload all");
mToddsMediaTracker.cancelUpload(s, 40);
if(mCurrent != null && mCurrent.mUploadType == 40)
mCurrent.stopCurrentTask(7);
}
private synchronized MediaRecordEntry doUpload(UploadTaskEntry uploadtaskentry, Uploader.UploadProgressListener uploadprogresslistener, SyncResult syncresult)
{
// TODO
return null;
}
private static String getFilePath(Uri uri, ContentResolver contentresolver)
{
// TODO
return null;
}
private static int getFsId(Context context)
{
// TODO
return 0;
}
public static synchronized UploadsManager getInstance(Context context)
{
UploadsManager uploadsmanager;
if(sInstance == null)
sInstance = new UploadsManager(context);
uploadsmanager = sInstance;
return uploadsmanager;
}
private static boolean isExternalStorageMounted()
{
String s = Environment.getExternalStorageState();
boolean flag;
if(s.equals("mounted") || s.equals("mounted_ro"))
flag = true;
else
flag = false;
return flag;
}
private void notifyManualUploadDbChanges()
{
mContext.getContentResolver().notifyChange(InstantUploadFacade.UPLOADS_URI, null, false);
}
private synchronized void onFsIdChangedInternal()
{
// TODO
}
private boolean removeTaskFromDb(long l)
{
return UploadTaskEntry.SCHEMA.deleteWithId(mUploadsDbHelper.getWritableDatabase(), l);
}
private void requestUploadAllProgressBroadcast()
{
Message.obtain(mHandler, 1).sendToTarget();
}
private synchronized void reset()
{
// TODO
}
private void sendUploadAllProgressBroadcast()
{
// TODO
}
private synchronized void setCurrentUploadTask(UploadTask uploadtask)
{
mCurrent = uploadtask;
}
private void setMediaRecordStateAndProgress(long l, int i, Throwable throwable, boolean flag, long l1,
String s)
{
// TODO
}
private void updateTaskStateAndProgressInDb(UploadTaskEntry uploadtaskentry)
{
// TODO
}
private void uploadExistingPhotosInternal(String s)
{
// TODO
}
private boolean writeToPhotoTable(UploadTaskEntry uploadtaskentry, MediaRecordEntry mediarecordentry)
{
// TODO
return false;
}
public final long addManualUpload(ContentValues contentvalues)
{
SQLiteDatabase sqlitedatabase = mUploadsDbHelper.getWritableDatabase();
MediaRecordEntry mediarecordentry = MediaRecordEntry.createNew(contentvalues);
mediarecordentry.setUploadReason(10);
mediarecordentry.setState(100);
long l = MediaRecordEntry.SCHEMA.insertOrReplace(sqlitedatabase, mediarecordentry);
if(EsLog.isLoggable("iu.UploadsManager", 4))
Log.i("iu.UploadsManager", (new StringBuilder("+++ ADD record; manual upload: ")).append(mediarecordentry).toString());
InstantUploadSyncManager.getInstance(mContext).updateTasks(500L);
return l;
}
public final void cancelTask(long l)
{
Message.obtain(mHandler, 5, Long.valueOf(l)).sendToTarget();
}
public final void cancelUploadExistingPhotos(String s)
{
Message.obtain(mHandler, 3, s).sendToTarget();
}
public final Cursor getInstantUploadStatus()
{
String s = mSettings.getSyncAccount();
EsMatrixCursor esmatrixcursor = new EsMatrixCursor(new String[] {
"iu_pending_count"
});
int i = mToddsMediaTracker.getUploadProgress(s, 30);
esmatrixcursor.newRow().add(Integer.valueOf(i));
if(EsLog.isLoggable("iu.UploadsManager", 3))
Log.d("iu.UploadsManager", (new StringBuilder("get iu pending count for ")).append(Utils.maskDebugInfo(s)).append(":").append(i).toString());
return esmatrixcursor;
}
public final Cursor getUploadAllStatus(String s)
{
boolean flag = true;
String as[] = new String[4];
as[0] = "upload_all_account";
as[1] = "upload_all_progress";
as[2] = "upload_all_count";
as[3] = "upload_all_state";
EsMatrixCursor esmatrixcursor = new EsMatrixCursor(as);
if(s != null)
{
int i = mToddsMediaTracker.getUploadTotal(40);
int j = i - mToddsMediaTracker.getUploadProgress(s, 40);
if(EsLog.isLoggable("iu.UploadsManager", 3))
{
StringBuilder stringbuilder = (new StringBuilder("get upload-all status for ")).append(Utils.maskDebugInfo(s)).append(" allDone? ");
if(i != j)
flag = false;
Log.d("iu.UploadsManager", stringbuilder.append(flag).append(" current:").append(j).append(" total:").append(i).append(" state=0").toString());
}
esmatrixcursor.newRow().add(s).add(Integer.valueOf(j)).add(Integer.valueOf(i)).add(Integer.valueOf(0));
} else
{
esmatrixcursor.newRow().add(null).add(null).add(null).add(Integer.valueOf(0));
}
return esmatrixcursor;
}
public final SyncTaskProvider getUploadTaskProvider() {
return new UploadTaskProvider();
}
public final void reloadSystemSettings() {
Cursor cursor = mSettings.getSystemSettingsCursor();
Message.obtain(mHandler, 6, cursor).sendToTarget();
}
final HashSet retrieveAllFingerprints(String s) {
// TODO
return null;
}
final synchronized void setState(UploadTaskEntry uploadtaskentry, int i) {
uploadtaskentry.setState(i);
setMediaRecordStateAndProgress(uploadtaskentry.getMediaRecordId(), i, null, false, 0L, null);
}
final synchronized void setState(UploadTaskEntry uploadtaskentry, int i, Throwable throwable) {
uploadtaskentry.setState(i, throwable);
setMediaRecordStateAndProgress(uploadtaskentry.getMediaRecordId(), i, throwable, false, 0L, null);
}
public final void uploadExistingPhotos(String s)
{
Message.obtain(mHandler, 2, s).sendToTarget();
}
}