Merge pull request #1425 from reicast/ac/dropbox

Update Dropbox API from 1.6 to 3.0
This commit is contained in:
Abandoned Cart 2018-10-02 23:21:55 -04:00 committed by GitHub
commit d436c30f3b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 577 additions and 402 deletions

View File

@ -39,8 +39,6 @@ android {
ndk { ndk {
moduleName "dc" moduleName "dc"
abiFilters 'armeabi-v7a', 'x86' abiFilters 'armeabi-v7a', 'x86'
moduleName "sexplay"
abiFilters 'armeabi-v7a', 'x86'
} }
} }
@ -56,11 +54,13 @@ android {
buildTypes { buildTypes {
debug { debug {
debuggable true debuggable true
minifyEnabled true
zipAlignEnabled true zipAlignEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
} }
release { release {
debuggable false debuggable false
minifyEnabled false minifyEnabled true
zipAlignEnabled true zipAlignEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt' proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
signingConfig signingConfigs.release signingConfig signingConfigs.release
@ -101,6 +101,7 @@ dependencies {
implementation 'org.bouncycastle:bcprov-jdk16:1.46' implementation 'org.bouncycastle:bcprov-jdk16:1.46'
implementation 'commons-io:commons-io:2.6' implementation 'commons-io:commons-io:2.6'
implementation 'org.apache.commons:commons-lang3:3.7' implementation 'org.apache.commons:commons-lang3:3.7'
implementation 'com.dropbox.core:dropbox-core-sdk:3.0.9'
implementation ('com.googlecode.json-simple:json-simple:1.1.1') { implementation ('com.googlecode.json-simple:json-simple:1.1.1') {
exclude module: 'junit' exclude module: 'junit'
} }

View File

@ -0,0 +1,69 @@
# This is a configuration file for ProGuard.
# http://proguard.sourceforge.net/index.html#manual/usage.html
# Optimizations: If you don't want to optimize, use the
# proguard-android.txt configuration file instead of this one, which
# turns off the optimization flags. Adding optimization introduces
# certain risks, since for example not all optimizations performed by
# ProGuard works on all versions of Dalvik. The following flags turn
# off various optimizations known to have issues, but the list may not
# be complete or up to date. (The "arithmetic" optimization can be
# used if you are only targeting Android 2.0 or later.) Make sure you
# test thoroughly if you go this route.
-optimizations !code/simplification/arithmetic,!code/simplification/cast,!field/*,!class/merging/*
-optimizationpasses 5
-allowaccessmodification
-dontpreverify
# The remainder of this file is identical to the non-optimized version
# of the Proguard configuration file (except that the other file has
# flags to turn off optimization).
-dontusemixedcaseclassnames
-dontskipnonpubliclibraryclasses
-verbose
-keepattributes *Annotation*
# For native methods, see http://proguard.sourceforge.net/manual/examples.html#native
-keepclasseswithmembernames class * {
native <methods>;
}
# keep setters in Views so that animations can still work.
# see http://proguard.sourceforge.net/manual/examples.html#beans
-keepclassmembers public class * extends android.view.View {
void set*(***);
*** get*();
}
# We want to keep methods in Activity that could be used in the XML attribute onClick
-keepclassmembers class * extends android.app.Activity {
public void *(android.view.View);
}
# For enumeration classes, see http://proguard.sourceforge.net/manual/examples.html#enumerations
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
-keepclassmembers class * implements android.os.Parcelable {
public static final android.os.Parcelable$Creator CREATOR;
}
-keepclassmembers class **.R$* {
public static <fields>;
}
-keep class com.reicast.** {*;}
-keepclassmembers class com.reicast.** {*;}
# The support library contains references to newer platform versions.
# Don't warn about those in case this app is linking against an older
# platform version. We know about them, and they are safe.
-dontwarn android.support.**
-dontwarn okio.**
-dontwarn okhttp3.**
-dontwarn com.squareup.okhttp.**
-dontwarn com.google.appengine.**
-dontwarn java.io.**
-dontwarn java.nio.file.**
-dontwarn javax.naming.**
-dontwarn javax.servlet.**
-dontwarn junit.textui.**
-keepattributes Signature
-keepattributes InnerClasses
-keepattributes Exceptions,SourceFile,LineNumberTable

View File

@ -101,11 +101,11 @@
android:theme="@android:style/Theme.NoTitleBar.Fullscreen" > android:theme="@android:style/Theme.NoTitleBar.Fullscreen" >
</activity> </activity>
<activity <activity
android:name="com.dropbox.client2.android.AuthActivity" android:name="com.dropbox.core.android.AuthActivity"
android:configChanges="orientation|keyboard" android:configChanges="orientation|keyboard"
android:launchMode="singleTask" > android:launchMode="singleTask">
<intent-filter> <intent-filter>
<data android:scheme="db-7d7tw1t57sbzrj5" /> <data android:scheme="db-lowa9ps6h5k7zbo" />
<action android:name="android.intent.action.VIEW" /> <action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.BROWSABLE" /> <category android:name="android.intent.category.BROWSABLE" />
<category android:name="android.intent.category.DEFAULT" /> <category android:name="android.intent.category.DEFAULT" />

View File

@ -1,350 +0,0 @@
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 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.os.Environment;
import android.preference.PreferenceManager;
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;
import com.reicast.emulator.config.Config;
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;
public class CloudFragment extends Fragment {
Button uploadBtn;
Button downloadBtn;
AlertDialog.Builder confirmDialog = null;
boolean actionRequired=false;
public String task = "";
DropBoxClient client = null;
private String home_directory;
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) {
SharedPreferences mPrefs = PreferenceManager.getDefaultSharedPreferences(getActivity());
home_directory = mPrefs.getString(Config.pref_home,
Environment.getExternalStorageDirectory().getAbsolutePath());
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 = home_directory+"/"+vmus[k];
File vmu = new File(vmuPath);
if(vmu.exists() || task.equals("Download") ){
result = new netOperation(client, home_directory).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.apply();
}
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;
private String home_directory;
public netOperation(DropBoxClient client, String home_directory){
this.client = client;
this.home_directory = home_directory;
}
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(home_directory+"/VmuBackups/");
if(!backupDir.exists()) {
backupDir.mkdirs();
}
File source = new File(home_directory+"/"+vmuName);
File destination = new File(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

@ -194,6 +194,11 @@ public class FileBrowser extends Fragment {
if (buttons != null && buttons.exists()) { if (buttons != null && buttons.exists()) {
in = new FileInputStream(buttons); in = new FileInputStream(buttons);
} else if (!file.exists() || file.length() == 0) { } else if (!file.exists() || file.length() == 0) {
try {
file.createNewFile();
} catch (Exception e) {
// N+ files be broken
}
in = getActivity().getAssets().open("buttons.png"); in = getActivity().getAssets().open("buttons.png");
} }
if (in != null) { if (in != null) {
@ -321,17 +326,7 @@ public class FileBrowser extends Fragment {
((TextView) childview.findViewById(R.id.item_name)).setText(R.string.boot_bios); ((TextView) childview.findViewById(R.id.item_name)).setText(R.string.boot_bios);
ImageView icon = (ImageView) childview.findViewById(R.id.item_icon); ImageView icon = (ImageView) childview.findViewById(R.id.item_icon);
icon.setImageResource(R.mipmap.disk_bios); icon.setImageResource(R.mipmap.disk_bios);
int app_theme = mPrefs.getInt(Config.pref_app_theme, 0); configureTheme(childview, true);
if (app_theme == 7) {
ImageViewCompat.setImageTintList(icon, ColorStateList.valueOf(
ContextCompat.getColor(getActivity(), R.color.colorDreamTint)));
} else if (app_theme == 1) {
ImageViewCompat.setImageTintList(icon, ColorStateList.valueOf(
ContextCompat.getColor(getActivity(), R.color.colorBlueTint)));
} else {
ImageViewCompat.setImageTintList(icon, ColorStateList.valueOf(
ContextCompat.getColor(getActivity(), R.color.colorDarkTint)));
}
childview.setTag(null); childview.setTag(null);
@ -352,17 +347,7 @@ public class FileBrowser extends Fragment {
((TextView) childview.findViewById(R.id.item_name)).setText(R.string.clear_search); ((TextView) childview.findViewById(R.id.item_name)).setText(R.string.clear_search);
ImageView icon = (ImageView) childview.findViewById(R.id.item_icon); ImageView icon = (ImageView) childview.findViewById(R.id.item_icon);
icon.setImageResource(R.mipmap.disk_unknown); icon.setImageResource(R.mipmap.disk_unknown);
int app_theme = mPrefs.getInt(Config.pref_app_theme, 0); configureTheme(childview, true);
if (app_theme == 7) {
ImageViewCompat.setImageTintList(icon, ColorStateList.valueOf(
ContextCompat.getColor(getActivity(), R.color.colorDreamTint)));
} else if (app_theme == 1) {
ImageViewCompat.setImageTintList(icon, ColorStateList.valueOf(
ContextCompat.getColor(getActivity(), R.color.colorBlueTint)));
} else {
ImageViewCompat.setImageTintList(icon, ColorStateList.valueOf(
ContextCompat.getColor(getActivity(), R.color.colorDarkTint)));
}
childview.setTag(null); childview.setTag(null);
@ -433,6 +418,7 @@ public class FileBrowser extends Fragment {
} }
} }
}); });
configureTheme(childview, false);
list.addView(childview); list.addView(childview);
xmlParser.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, game.getName()); xmlParser.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, game.getName());
} }
@ -499,18 +485,6 @@ public class FileBrowser extends Fragment {
final View childview = browser.get().getActivity().getLayoutInflater().inflate( final View childview = browser.get().getActivity().getLayoutInflater().inflate(
R.layout.browser_fragment_item, null, false); R.layout.browser_fragment_item, null, false);
int app_theme = browser.get().mPrefs.getInt(Config.pref_app_theme, 0);
if (app_theme == 7) {
childview.findViewById(R.id.childview)
.setBackgroundResource(R.drawable.game_selector_dream);
} else if (app_theme == 1) {
childview.findViewById(R.id.childview)
.setBackgroundResource(R.drawable.game_selector_blue);
} else {
childview.findViewById(R.id.childview)
.setBackgroundResource(R.drawable.game_selector_dark);
}
if (file == null) { if (file == null) {
((TextView) childview.findViewById(R.id.item_name)).setText(R.string.folder_select); ((TextView) childview.findViewById(R.id.item_name)).setText(R.string.folder_select);
} else if (file == parent) } else if (file == parent)
@ -522,17 +496,7 @@ public class FileBrowser extends Fragment {
icon.setImageResource(file == null icon.setImageResource(file == null
? R.drawable.ic_settings: file.isDirectory() ? R.drawable.ic_settings: file.isDirectory()
? R.drawable.ic_folder_black_24dp : R.drawable.disk_unknown); ? R.drawable.ic_folder_black_24dp : R.drawable.disk_unknown);
browser.get().configureTheme(childview, true);
if (app_theme == 7) {
ImageViewCompat.setImageTintList(icon, ColorStateList.valueOf(
ContextCompat.getColor(browser.get().getActivity(), R.color.colorDreamTint)));
} else if (app_theme == 1) {
ImageViewCompat.setImageTintList(icon, ColorStateList.valueOf(
ContextCompat.getColor(browser.get().getActivity(), R.color.colorBlueTint)));
} else {
ImageViewCompat.setImageTintList(icon, ColorStateList.valueOf(
ContextCompat.getColor(browser.get().getActivity(), R.color.colorDarkTint)));
}
childview.setTag(file); childview.setTag(file);
@ -616,6 +580,30 @@ public class FileBrowser extends Fragment {
} }
} }
private void configureTheme(View childview, boolean useTint) {
int app_theme = mPrefs.getInt(Config.pref_app_theme, 0);
ImageView icon = (ImageView) childview.findViewById(R.id.item_icon);
if (app_theme == 7) {
childview.findViewById(R.id.childview)
.setBackgroundResource(R.drawable.game_selector_dream);
if (useTint)
ImageViewCompat.setImageTintList(icon, ColorStateList.valueOf(
ContextCompat.getColor(getActivity(), R.color.colorDreamTint)));
} else if (app_theme == 1) {
childview.findViewById(R.id.childview)
.setBackgroundResource(R.drawable.game_selector_blue);
if (useTint)
ImageViewCompat.setImageTintList(icon, ColorStateList.valueOf(
ContextCompat.getColor(getActivity(), R.color.colorBlueTint)));
} else {
childview.findViewById(R.id.childview)
.setBackgroundResource(R.drawable.game_selector_dark);
if (useTint)
ImageViewCompat.setImageTintList(icon, ColorStateList.valueOf(
ContextCompat.getColor(getActivity(), R.color.colorDarkTint)));
}
}
private void showToastMessage(String message, int duration) { private void showToastMessage(String message, int duration) {
ConstraintLayout layout = (ConstraintLayout) getActivity().findViewById(R.id.mainui_layout); ConstraintLayout layout = (ConstraintLayout) getActivity().findViewById(R.id.mainui_layout);
Snackbar snackbar = Snackbar.make(layout, message, duration); Snackbar snackbar = Snackbar.make(layout, message, duration);

View File

@ -20,7 +20,6 @@ import android.support.design.widget.NavigationView;
import android.support.design.widget.Snackbar; import android.support.design.widget.Snackbar;
import android.support.v4.app.ActivityCompat; import android.support.v4.app.ActivityCompat;
import android.support.v4.app.Fragment; import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.view.GravityCompat; import android.support.v4.view.GravityCompat;
import android.support.v4.widget.DrawerLayout; import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.AppCompatActivity; import android.support.v7.app.AppCompatActivity;
@ -41,6 +40,7 @@ import com.reicast.emulator.config.InputFragment;
import com.reicast.emulator.config.OptionsFragment; import com.reicast.emulator.config.OptionsFragment;
import com.reicast.emulator.config.PGConfigFragment; import com.reicast.emulator.config.PGConfigFragment;
import com.reicast.emulator.debug.GenerateLogs; import com.reicast.emulator.debug.GenerateLogs;
import com.reicast.emulator.cloud.CloudFragment;
import com.reicast.emulator.emu.JNIdc; import com.reicast.emulator.emu.JNIdc;
import java.lang.Thread.UncaughtExceptionHandler; import java.lang.Thread.UncaughtExceptionHandler;

View File

@ -227,12 +227,15 @@ public class XMLParser extends AsyncTask<String, Integer, String> {
icon.setImageDrawable(game_icon); icon.setImageDrawable(game_icon);
int app_theme = mPrefs.getInt(Config.pref_app_theme, 0); int app_theme = mPrefs.getInt(Config.pref_app_theme, 0);
if (app_theme == 7) { if (app_theme == 7) {
childview.get().setBackgroundResource(R.drawable.game_selector_dream);
ImageViewCompat.setImageTintList(icon, ColorStateList.valueOf( ImageViewCompat.setImageTintList(icon, ColorStateList.valueOf(
ContextCompat.getColor(mContext.get(), R.color.colorDreamTint))); ContextCompat.getColor(mContext.get(), R.color.colorDreamTint)));
} else if (app_theme == 1) { } else if (app_theme == 1) {
childview.get().setBackgroundResource(R.drawable.game_selector_blue);
ImageViewCompat.setImageTintList(icon, ColorStateList.valueOf( ImageViewCompat.setImageTintList(icon, ColorStateList.valueOf(
ContextCompat.getColor(mContext.get(), R.color.colorBlueTint))); ContextCompat.getColor(mContext.get(), R.color.colorBlueTint)));
} else { } else {
childview.get().setBackgroundResource(R.drawable.game_selector_dark);
ImageViewCompat.setImageTintList(icon, ColorStateList.valueOf( ImageViewCompat.setImageTintList(icon, ColorStateList.valueOf(
ContextCompat.getColor(mContext.get(), R.color.colorDarkTint))); ContextCompat.getColor(mContext.get(), R.color.colorDarkTint)));
} }

View File

@ -0,0 +1,432 @@
package com.reicast.emulator.cloud;
/*
* Author: Luca D'Amico (Luca91)
* Rewrite: AbandonedCart
* Last Edit: 02 Oct 2018
* Reference: http://forums.reicast.com/index.php?topic=160.msg422
*/
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.preference.PreferenceManager;
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.core.DbxException;
import com.dropbox.core.android.Auth;
import com.dropbox.core.v2.DbxClientV2;
import com.dropbox.core.v2.files.FileMetadata;
import com.dropbox.core.v2.files.ListFolderResult;
import com.dropbox.core.v2.files.Metadata;
import com.dropbox.core.v2.files.WriteMode;
import com.reicast.emulator.R;
import com.reicast.emulator.config.Config;
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.lang.ref.WeakReference;
public class CloudFragment extends Fragment {
private final static String APP_KEY = "lowa9ps6h5k7zbo";
private String mPath = ""; // Dropbox folder
Button uploadBtn;
Button downloadBtn;
AlertDialog.Builder confirmDialog = null;
private String home_directory;
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) {
SharedPreferences mPrefs = PreferenceManager.getDefaultSharedPreferences(getActivity());
home_directory = mPrefs.getString(Config.pref_home,
Environment.getExternalStorageDirectory().getAbsolutePath());
buttonListener();
confirmDialog = new AlertDialog.Builder(getActivity());
}
@Override
public void onResume() {
super.onResume();
SharedPreferences mPrefs = PreferenceManager.getDefaultSharedPreferences(getActivity());
String accessToken = mPrefs.getString("access-token", null);
if (accessToken == null) {
accessToken = Auth.getOAuth2Token();
if (accessToken != null) {
mPrefs.edit().putString("access-token", accessToken).apply();
DbxClientFactory.init(accessToken);
}
} else {
DbxClientFactory.init(accessToken);
}
}
public void buttonListener() {
Auth.startOAuth2Authentication(getActivity(), APP_KEY);
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) {
getPathForFiles("Upload");
}
});
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) {
getPathForFiles("Download");
}
});
confirmDialog.setNegativeButton(R.string.cancel, null);
confirmDialog.show();
}
});
}
private void uploadFile(String filePath) {
final ProgressDialog dialog = new ProgressDialog(getActivity());
dialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
dialog.setCancelable(false);
dialog.setMessage("Uploading");
dialog.show();
try {
new UploadFileTask(getActivity(), DbxClientFactory.getClient(), new UploadFileTask.Callback() {
@Override
public void onUploadComplete(FileMetadata result) {
dialog.dismiss();
}
@Override
public void onError(Exception e) {
dialog.dismiss();
Log.e(getActivity().getLocalClassName(), "Failed to upload file.", e);
Toast.makeText(getActivity(),
"Failed to upload file", Toast.LENGTH_SHORT).show();
}
}).execute(filePath, mPath);
} catch (IllegalStateException s) {
dialog.dismiss();
Log.e(getActivity().getLocalClassName(), "Failed to upload file.", s);
Toast.makeText(getActivity(),
"Failed to upload file", Toast.LENGTH_SHORT).show();
}
}
private void retrieveFiles(final String vmu) {
final ProgressDialog dialog = new ProgressDialog(getActivity());
dialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
dialog.setCancelable(false);
dialog.setMessage("Loading");
dialog.show();
try {
new ListFolderTask(DbxClientFactory.getClient(), new ListFolderTask.Callback() {
@Override
public void onDataLoaded(ListFolderResult result) {
dialog.dismiss();
for (Metadata item : result.getEntries()) {
if (item.getName().equals(vmu)) {
if (item instanceof FileMetadata) {
downloadFile((FileMetadata) item);
}
}
}
}
@Override
public void onError(Exception e) {
dialog.dismiss();
Log.e(getActivity().getLocalClassName(), "Failed to list folder.", e);
Toast.makeText(getActivity(),
"Failed to list folder", Toast.LENGTH_SHORT).show();
}
}).execute(mPath);
} catch (IllegalStateException s) {
dialog.dismiss();
Log.e(getActivity().getLocalClassName(), "Failed to list folder.", s);
Toast.makeText(getActivity(),
"Failed to list folder", Toast.LENGTH_SHORT).show();
}
}
private void downloadFile(FileMetadata file) {
final ProgressDialog dialog = new ProgressDialog(getActivity());
dialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
dialog.setCancelable(false);
dialog.setMessage("Downloading");
dialog.show();
try {
new DownloadFileTask(this, DbxClientFactory.getClient(), new DownloadFileTask.Callback() {
@Override
public void onDownloadComplete(File result) {
dialog.dismiss();
}
@Override
public void onError(Exception e) {
dialog.dismiss();
Log.e(getActivity().getLocalClassName(), "Failed to download file.", e);
Toast.makeText(getActivity(),
"Failed to download file\n" + e, Toast.LENGTH_SHORT).show();
}
}).execute(file);
} catch (IllegalStateException s) {
dialog.dismiss();
Log.e(getActivity().getLocalClassName(), "Failed to download file.", s);
Toast.makeText(getActivity(),
"Failed to download file", Toast.LENGTH_SHORT).show();
}
}
static class UploadFileTask extends AsyncTask<String, Void, FileMetadata> {
private WeakReference<Context> mContext;
private final DbxClientV2 mDbxClient;
private final Callback mCallback;
private Exception mException;
public interface Callback {
void onUploadComplete(FileMetadata result);
void onError(Exception e);
}
UploadFileTask(Context context, DbxClientV2 dbxClient, Callback callback) {
mContext = new WeakReference<>(context);
mDbxClient = dbxClient;
mCallback = callback;
}
@Override
protected void onPostExecute(FileMetadata result) {
super.onPostExecute(result);
if (mException != null) {
mCallback.onError(mException);
} else if (result == null) {
mCallback.onError(null);
} else {
mCallback.onUploadComplete(result);
}
}
@Override
protected FileMetadata doInBackground(String... params) {
File localFile = new File(params[0]);
String remoteFolderPath = params[1];
// Note - does not verify a valid dropbox file name
String remoteFileName = localFile.getName();
try {
InputStream inputStream = new FileInputStream(localFile);
return mDbxClient.files().uploadBuilder(
remoteFolderPath + "/" + remoteFileName)
.withMode(WriteMode.OVERWRITE)
.uploadAndFinish(inputStream);
} catch (DbxException | IOException e) {
mException = e;
}
return null;
}
}
static class ListFolderTask extends AsyncTask<String, Void, ListFolderResult> {
private final DbxClientV2 mDbxClient;
private final Callback mCallback;
private Exception mException;
public interface Callback {
void onDataLoaded(ListFolderResult result);
void onError(Exception e);
}
ListFolderTask(DbxClientV2 dbxClient, Callback callback) {
mDbxClient = dbxClient;
mCallback = callback;
}
@Override
protected void onPostExecute(ListFolderResult result) {
super.onPostExecute(result);
if (mException != null) {
mCallback.onError(mException);
} else {
mCallback.onDataLoaded(result);
}
}
@Override
protected ListFolderResult doInBackground(String... params) {
try {
return mDbxClient.files().listFolder(params[0]);
} catch (DbxException e) {
mException = e;
}
return null;
}
}
static class DownloadFileTask extends AsyncTask<FileMetadata, Void, File> {
private WeakReference<CloudFragment> mCloud;
private final DbxClientV2 mDbxClient;
private final Callback mCallback;
private Exception mException;
public interface Callback {
void onDownloadComplete(File result);
void onError(Exception e);
}
DownloadFileTask(CloudFragment context, DbxClientV2 dbxClient, Callback callback) {
mCloud = new WeakReference<>(context);
mDbxClient = dbxClient;
mCallback = callback;
}
@Override
protected void onPostExecute(File result) {
super.onPostExecute(result);
if (mException != null) {
mCallback.onError(mException);
} else {
mCallback.onDownloadComplete(result);
}
}
@Override
protected File doInBackground(FileMetadata... params) {
FileMetadata metadata = params[0];
try {
File path = new File(mCloud.get().home_directory);
File file = new File(path, metadata.getName());
// Make sure the Downloads directory exists.
if (!path.exists()) {
if (!path.mkdirs()) {
mException = new RuntimeException("Unable to create directory: " + path);
}
} else if (!path.isDirectory()) {
mException = new IllegalStateException("Download path is not a directory: " + path);
return null;
}
// Download the file.
OutputStream outputStream = new FileOutputStream(file);
mDbxClient.files().download(metadata.getPathLower(), metadata.getRev())
.download(outputStream);
// Tell android about the file
Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
intent.setData(Uri.fromFile(file));
mCloud.get().getActivity().sendBroadcast(intent);
return file;
} catch (DbxException | IOException e) {
mException = e;
}
return null;
}
}
private void getPathForFiles(String task) {
for (String vmu : vmus) {
File vmuFile = new File(home_directory, vmu);
if (task.equals("Download")) {
if (vmuFile.exists())
createBackupOfVmu(vmuFile.getName());
else
retrieveFiles(vmuFile.getName());
}
if (task.equals("Upload")) {
if (vmuFile.exists())
uploadFile(vmuFile.toString());
}
}
}
void createBackupOfVmu(String vmuName) {
File backupDir = new File(home_directory, "vmu_backup");
if (!backupDir.exists()) {
backupDir.mkdirs();
}
File source = new File(home_directory, vmuName);
File destination = new File(home_directory, "vmu_backup/" + 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();
}
retrieveFiles(vmuName);
}
}

View File

@ -0,0 +1,32 @@
package com.reicast.emulator.cloud;
import com.dropbox.core.DbxRequestConfig;
import com.dropbox.core.http.StandardHttpRequestor;
import com.dropbox.core.v2.DbxClientV2;
/**
* Singleton instance of {@link DbxClientV2} and friends
*/
public class DbxClientFactory {
private static DbxClientV2 sDbxClient;
public static void init(String accessToken) {
if (sDbxClient == null) {
StandardHttpRequestor requestor = new StandardHttpRequestor(
StandardHttpRequestor.Config.DEFAULT_INSTANCE);
DbxRequestConfig requestConfig = DbxRequestConfig
.newBuilder("ReicastCloud")
.withHttpRequestor(requestor).build();
sDbxClient = new DbxClientV2(requestConfig, accessToken);
}
}
public static DbxClientV2 getClient() {
if (sDbxClient == null) {
throw new IllegalStateException("Client not initialized.");
}
return sDbxClient;
}
}