Merge pull request #474 from Luca1991/master

CloudVMU tool added
This commit is contained in:
TwistedUmbrella 2014-05-13 19:03:57 -04:00
commit ebeef1ddaf
16 changed files with 481 additions and 1 deletions

View File

@ -2,8 +2,8 @@
<classpath>
<classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
<classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.LIBRARIES"/>
<classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.DEPENDENCIES"/>
<classpathentry kind="src" path="src"/>
<classpathentry kind="src" path="gen"/>
<classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.DEPENDENCIES"/>
<classpathentry kind="output" path="bin/classes"/>
</classpath>

View File

@ -13,6 +13,8 @@
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-feature
android:glEsVersion="0x00020000"
@ -101,6 +103,19 @@
android:name="android.app.lib_name"
android:value="sexplay" />
</activity>
<activity
android:name="com.dropbox.client2.android.AuthActivity"
android:configChanges="orientation|keyboard"
android:launchMode="singleTask" >
<intent-filter>
<data android:scheme="db-7d7tw1t57sbzrj5" />
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.BROWSABLE" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<activity
android:name=".config.EditVJoyActivity"
android:configChanges="orientation|screenSize|screenLayout|uiMode|keyboard|keyboardHidden"

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

View File

@ -0,0 +1,48 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:orientation="vertical" >
<TextView
android:id="@+id/about_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:layout_marginTop="10dp"
android:ems="12"
android:gravity="center"
android:text="@string/cloud" />
<TextView
android:id="@+id/CloudInfos"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="50dp"
android:text="@string/cloudInfos"
android:textAppearance="?android:attr/textAppearanceSmall" />
<Button
android:id="@+id/uploadBtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="35dp"
android:text="@string/uploadVMU" />
<Button
android:id="@+id/downloadBtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="35dp"
android:text="@string/downloadVMU" />
<ImageView
android:id="@+id/imageView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription="cloudImg"
android:src="@drawable/cloud_big" />
</LinearLayout>

View File

@ -227,6 +227,37 @@
android:textAppearance="@style/BaseText"
android:textSize="28dp" />
</LinearLayout>
<LinearLayout
android:id="@+id/cloud_menu"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="4dp"
android:layout_marginTop="10dp"
android:background="@drawable/game_selector"
android:focusable="true"
android:gravity="center_vertical|left"
android:orientation="horizontal" >
<ImageView
android:id="@+id/cloud"
android:layout_width="52dp"
android:layout_height="match_parent"
android:layout_margin="2dp"
android:gravity="center_vertical|left"
android:scaleType="fitCenter"
android:src="@drawable/cloud" />
<TextView
android:id="@+id/cloud_title"
style="@android:style/TextAppearance.Large"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:text="@string/cloud"
android:textAppearance="@style/BaseText"
android:textSize="28dp" />
</LinearLayout>
</LinearLayout>
</ScrollView>

View File

@ -94,6 +94,7 @@
<string name="about">About</string>
<string name="rateme">Rate Me</string>
<string name="messages">Test Suite</string>
<string name="cloud">Cloud VMU</string>
<string name="textOn">ON</string>
<string name="textOff">OFF</string>
@ -102,4 +103,11 @@
<string name="dismiss">Dismiss</string>
<string name="manual">Manual</string>
<string name="options">Options</string>
<string name="cloudInfos">With this tool you can upload/download your VMUs to/from Dropbox, in order to sync them with all your devices!</string>
<string name="uploadWarning">ATTENTION: You are about to upload your VMUs to Dropbox, please notice that this will OVERWRITE your last upload!!</string>
<string name="downloadWarning">ATTENTION: You are about to download your VMUs from Dropbox, please notice that this will OVERWRITE your currently VMUs!! By the way a backup copy will
be created in VmuBackups folder!</string>
<string name="uploadVMU">Upload VMU</string>
<string name="downloadVMU">Download VMU</string>
</resources>

View File

@ -0,0 +1,347 @@
package com.reicast.emulator;
/*
* File: CloudFragment.java
* Author: Luca D'Amico (Luca91)
* Last Edit: 11 May 2014
*
* Reference: http://forums.reicast.com/index.php?topic=160.msg422
*/
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.concurrent.ExecutionException;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.Toast;
import com.dropbox.client2.DropboxAPI;
import com.dropbox.client2.DropboxAPI.Entry;
import com.dropbox.client2.android.AndroidAuthSession;
import com.dropbox.client2.exception.DropboxException;
import com.dropbox.client2.session.AccessTokenPair;
import com.dropbox.client2.session.AppKeyPair;
import com.dropbox.client2.session.TokenPair;
public class CloudFragment extends Fragment {
Button uploadBtn;
Button downloadBtn;
AlertDialog.Builder confirmDialog = null;
boolean actionRequired=false;
public String task = "";
DropBoxClient client = null;
String[] vmus = {"vmu_save_A1.bin","vmu_save_A2.bin",
"vmu_save_B1.bin","vmu_save_B2.bin",
"vmu_save_C1.bin","vmu_save_C2.bin",
"vmu_save_D1.bin","vmu_save_D2.bin"};
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.cloud_fragment, container, false);
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
buttonListener();
confirmDialog = new AlertDialog.Builder(getActivity());
setClient();
}
public void setClient(){
if(client==null)
client = new DropBoxClient(getActivity());
}
public void buttonListener() {
uploadBtn = (Button) getView().findViewById(R.id.uploadBtn);
uploadBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
confirmDialog.setMessage(R.string.uploadWarning);
confirmDialog.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
setClient();
task = "Upload";
client.startLogin();
actionRequired = true;
}
});
confirmDialog.setNegativeButton(R.string.cancel, null);
confirmDialog.show();
}
});
downloadBtn = (Button) getView().findViewById(R.id.downloadBtn);
downloadBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
confirmDialog.setMessage(R.string.downloadWarning);
confirmDialog.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
setClient();
task = "Download";
client.startLogin();
actionRequired = true;
}
});
confirmDialog.setNegativeButton(R.string.cancel, null);
confirmDialog.show();
}
});
}
@Override
public void onResume(){
super.onResume();
if (client.mDBApi != null) {
if (client.mDBApi.getSession().authenticationSuccessful()) {
try {
client.mDBApi.getSession().finishAuthentication();
TokenPair tokens = client.mDBApi.getSession(). getAccessTokenPair();
if(tokens == null)
Toast.makeText(getActivity(), "Failed to save session token!", Toast.LENGTH_SHORT).show();
else
client.storeKeys(tokens.key, tokens.secret);
} catch (IllegalStateException e) {
Log.i("Dropbox", "Error authenticating", e);
}
}
if(actionRequired){
for(int k=0;k<vmus.length;k++){
String result = "";
try {
String vmuPath = MainActivity.home_directory+"/"+vmus[k];
File vmu = new File(vmuPath);
if(vmu.exists() || task.equals("Download") ){
result = new netOperation(client).execute(task,vmuPath,vmus[k]).get();
}
else{
result = "Ok"; // The result is still ok, because the vmu bin doesn't exist ;)
Toast.makeText(getActivity(), vmus[k]+" doesn't exist, skipping it!", Toast.LENGTH_SHORT).show();
}
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
if(result.equals("Ok"))
Toast.makeText(getActivity(), "Task Completed!", Toast.LENGTH_SHORT).show();
else
Toast.makeText(getActivity(), "Task Failed!", Toast.LENGTH_SHORT).show();
}
}
actionRequired = false;
}
}
}
class DropBoxClient {
Context context;
final static private String APP_KEY = "7d7tw1t57sbzrj5";
final static private String APP_SECRET = "5xxqa2uctousyi2";
public DropboxAPI<AndroidAuthSession> mDBApi;
AndroidAuthSession session;
public DropBoxClient(Context context){
this.context = context;
session = buildSession();
mDBApi = new DropboxAPI<AndroidAuthSession>(session);
}
public void startLogin(){
mDBApi.getSession().startOAuth2Authentication(context);
}
public String[] getKeys() {
SharedPreferences prefs = context.getSharedPreferences("ReicastVMUUploader", 0);
String key = prefs.getString("DBoxKey", null);
String secret = prefs.getString("DBoxSecret", null);
if (key != null && secret != null) {
String[] ret = new String[2];
ret[0] = key;
ret[1] = secret;
return ret;
} else {
return null;
}
}
public void storeKeys(String key, String secret) {
SharedPreferences prefs = context.getSharedPreferences("ReicastVMUUploader", 0);
Editor edit = prefs.edit();
edit.putString("DBoxKey", key);
edit.putString("DBoxSecret", secret);
edit.commit();
}
private AndroidAuthSession buildSession() {
AppKeyPair appKeyPair = new AppKeyPair(APP_KEY, APP_SECRET);
AndroidAuthSession session;
String[] stored = getKeys();
if (stored != null) {
AccessTokenPair accessToken = new AccessTokenPair(stored[0], stored[1]);
session = new AndroidAuthSession(appKeyPair, accessToken);
} else {
session = new AndroidAuthSession(appKeyPair);
}
return session;
}
}
class netOperation extends AsyncTask<String, Void, String> {
DropBoxClient client = null;
public netOperation(DropBoxClient client){
this.client = client;
}
public boolean uploadFile(String filePath, String fileName) {
File file = new File(filePath);
FileInputStream inputStream = null;
try {
inputStream = new FileInputStream(file);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
DropboxAPI.Entry response = null;
try {
response = client.mDBApi.putFileOverwrite("/"+fileName, inputStream, file.length(), null);
} catch (DropboxException e) {
e.printStackTrace();
}
Log.i("FileInfos", "The uploaded file's rev is: "+ response);
return true;
}
public boolean downloadFile(String filePath, String fileName) {
DropboxAPI.DropboxFileInfo info = null;
try {
Entry remoteFile = client.mDBApi.metadata("/"+fileName, 1, null, false, null);
if((remoteFile.rev != null) && (remoteFile.bytes > 0)){ // Avoid to download 0 bytes vmus!
File file = new File(filePath);
if(file.exists())
createBackupOfVmu(fileName);
FileOutputStream out = null;
try {
out = new FileOutputStream(file);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
info = client.mDBApi.getFile("/"+fileName,null,out,null);
}
} catch (DropboxException e) {
e.printStackTrace();
}
Log.i("FileInfos", "The downloaded file's rev is: "+ info);
return true;
}
@Override
protected void onPostExecute(String result) {
}
@Override
protected String doInBackground(String... strings) {
if(strings[0].equals("Upload")){
if(uploadFile(strings[1],strings[2]))
return "Ok";
else
return "No";
}
else if(strings[0].equals("Download")){
if(downloadFile(strings[1],strings[2]))
return "Ok";
else
return "No";
}
else
return "Unknown";
}
@Override
protected void onPreExecute() {}
@Override
protected void onProgressUpdate(Void... values) {}
void createBackupOfVmu(String vmuName){
File backupDir = new File(MainActivity.home_directory+"/VmuBackups/");
if(!backupDir.exists()) {
backupDir.mkdirs();
}
File source = new File(MainActivity.home_directory+"/"+vmuName);
File destination = new File(MainActivity.home_directory+"/VmuBackups/"+vmuName);
if(!destination.exists()) {
try {
destination.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
try {
InputStream in = new FileInputStream(source);
OutputStream out = new FileOutputStream(destination);
byte[] buffer = new byte[1024];
int length;
while ((length = in.read(buffer)) > 0){
out.write(buffer, 0, length);
}
in.close();
out.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}

View File

@ -270,6 +270,27 @@ public class MainActivity extends SlidingFragmentActivity implements
}
});
findViewById(R.id.cloud_menu).setOnClickListener(new OnClickListener() {
public void onClick(View view) {
CloudFragment cloudFrag = (CloudFragment) getSupportFragmentManager()
.findFragmentByTag("CLOUD_FRAG");
if (cloudFrag != null) {
if (cloudFrag.isVisible()) {
return;
}
}
cloudFrag = new CloudFragment();
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.fragment_container,
cloudFrag, "CLOUD_FRAG")
.addToBackStack(null).commit();
setTitle(R.string.cloud);
sm.toggle(true);
}
});
View rateMe = findViewById(R.id.rateme_menu);
if (!hasAndroidMarket) {
@ -290,6 +311,8 @@ public class MainActivity extends SlidingFragmentActivity implements
}
});
}
View messages = findViewById(R.id.message_menu);
if (MainActivity.debugUser) {
@ -567,6 +590,14 @@ public class MainActivity extends SlidingFragmentActivity implements
fragment.moga.onResume();
}
}
CloudFragment cloudfragment = (CloudFragment) getSupportFragmentManager()
.findFragmentByTag("CLOUD_FRAG");
if (cloudfragment != null && cloudfragment.isVisible()) {
if (cloudfragment != null) {
cloudfragment.onResume();
}
}
}
public boolean isCallable(Intent intent) {