Skip to content

Commit

Permalink
Refactoring (split code into packages / add custom exception handling)
Browse files Browse the repository at this point in the history
  • Loading branch information
David-Development committed Jun 15, 2018
1 parent 8676b56 commit 70831be
Show file tree
Hide file tree
Showing 17 changed files with 324 additions and 35 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
More information here: https://github.com/abeluck/android-streams-ipc
*/

package de.luhmer.owncloud.accountimporter.helper;
package de.luhmer.owncloud.accountimporter.aidl;

interface IInputStreamService {
ParcelFileDescriptor performNextcloudRequest(in ParcelFileDescriptor input);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
package de.luhmer.owncloud.accountimporter.helper;
package de.luhmer.owncloud.accountimporter;

import android.accounts.Account;
import android.accounts.AccountManager;
import android.accounts.AuthenticatorException;
import android.accounts.OperationCanceledException;
import android.app.Activity;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.RequiresApi;
import android.widget.Toast;

import java.io.IOException;
import java.util.ArrayList;
Expand All @@ -20,7 +22,9 @@
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

import static android.content.Context.MODE_PRIVATE;
import de.luhmer.owncloud.accountimporter.exceptions.NextcloudFilesAppNotInstalledException;
import de.luhmer.owncloud.accountimporter.helper.AsyncTaskHelper;
import de.luhmer.owncloud.accountimporter.model.SingleSignOnAccount;

/**
* Nextcloud SingleSignOn
Expand All @@ -47,29 +51,35 @@ public class AccountImporter {
private static final String PREF_FILE_NAME = "PrefNextcloudAccount";
private static final String PREF_ACCOUNT_STRING = "PREF_ACCOUNT_STRING";

private static final String AUTH_TOKEN = "NextcloudSSO";

public static final int CHOOSE_ACCOUNT_SSO = 4242;

public static boolean AccountsToImportAvailable(Context context) {
return FindAccounts(context).size() > 0;
}

//TODO add multi account support
public static Account GetCurrentAccount(Context context) {
SharedPreferences preferences = context.getSharedPreferences(PREF_FILE_NAME, MODE_PRIVATE);
String accountName = preferences.getString(PREF_ACCOUNT_STRING, "");
return GetAccountForName(context, accountName);
}

//TODO add multi account support
public static SingleSignOnAccount GetCurrentSingleAccount(Context context) throws AuthenticatorException, OperationCanceledException, IOException {
return GetAuthToken(context, GetCurrentAccount(context));
public static void PickNewAccount(android.support.v4.app.Fragment fragment) throws NextcloudFilesAppNotInstalledException {
if(AppInstalledOrNot(fragment.getContext(), "com.nextcloud.client")) {
Intent intent = AccountManager.newChooseAccountIntent(null, null, new String[]{"nextcloud"},
true, null, null, null, null);
fragment.startActivityForResult(intent, CHOOSE_ACCOUNT_SSO);
} else {
throw new NextcloudFilesAppNotInstalledException();
}
}

//TODO add multi account support
public static void SetCurrentAccount(Context context, Account account) {
SharedPreferences preferences = context.getSharedPreferences(PREF_FILE_NAME, MODE_PRIVATE);
preferences.edit().putString(PREF_ACCOUNT_STRING, account.name).commit();
private static boolean AppInstalledOrNot(Context context, String uri) {
PackageManager pm = context.getPackageManager();
try {
pm.getPackageInfo(uri, PackageManager.GET_ACTIVITIES);
return true;
} catch (PackageManager.NameNotFoundException e) {
}
return false;
}


// Find all currently installed nextcloud accounts on the phone
private static List<Account> FindAccounts(Context context) {
final AccountManager accMgr = AccountManager.get(context);
Expand All @@ -84,7 +94,7 @@ private static List<Account> FindAccounts(Context context) {
return accountsAvailable;
}

private static final String AUTH_TOKEN = "NextcloudSSO";



public static Account GetAccountForName(Context context, String name) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package de.luhmer.owncloud.accountimporter.helper;
package de.luhmer.owncloud.accountimporter.aidl;

/**
* Nextcloud SingleSignOn
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package de.luhmer.owncloud.accountimporter.helper;
package de.luhmer.owncloud.accountimporter.aidl;

import java.io.Serializable;
import java.util.HashMap;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package de.luhmer.owncloud.accountimporter.helper;
package de.luhmer.owncloud.accountimporter.aidl;

import android.os.ParcelFileDescriptor;
import android.util.Log;
Expand All @@ -7,6 +7,8 @@
import java.io.InputStream;
import java.io.OutputStream;

import de.luhmer.owncloud.accountimporter.aidl.IThreadListener;

/**
* Nextcloud SingleSignOn
*
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package de.luhmer.owncloud.accountimporter.helper;
package de.luhmer.owncloud.accountimporter.api;

import android.content.ComponentName;
import android.content.Context;
Expand All @@ -11,6 +11,9 @@

import com.google.gson.Gson;

import org.reactivestreams.Publisher;
import org.reactivestreams.Subscriber;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
Expand All @@ -20,8 +23,14 @@
import java.io.ObjectOutputStream;
import java.io.Reader;
import java.lang.reflect.Type;
import java.util.concurrent.Callable;

import de.luhmer.owncloud.accountimporter.aidl.IInputStreamService;
import de.luhmer.owncloud.accountimporter.aidl.IThreadListener;
import de.luhmer.owncloud.accountimporter.aidl.ParcelFileDescriptorUtil;
import de.luhmer.owncloud.accountimporter.aidl.NextcloudRequest;
import de.luhmer.owncloud.accountimporter.exceptions.NextcloudFilesAppAccountNotFoundException;
import de.luhmer.owncloud.accountimporter.exceptions.TokenMismatchException;
import de.luhmer.owncloud.accountimporter.model.SingleSignOnAccount;
import io.reactivex.Observable;
import io.reactivex.annotations.NonNull;

Expand Down Expand Up @@ -122,12 +131,16 @@ public void onServiceDisconnected(ComponentName className) {


public <T> Observable<T> performRequestObservable(final Type type, final NextcloudRequest request) {
return Observable.fromCallable(new Callable<T>() {
return Observable.fromPublisher(new Publisher<T>() {
@Override
public T call() throws Exception {
T result = performRequest(type, request);
Log.d(TAG, "Wrapping result object in Observable: " + result);
return result;
public void subscribe(Subscriber<? super T> s) {
try {
s.onNext((T) performRequest(type, request));
s.onComplete();
} catch (Exception e) {
e.printStackTrace();
s.onError(e);
}
}
});
}
Expand All @@ -136,8 +149,8 @@ public <T> T performRequest(final @NonNull Type type, NextcloudRequest request)
Log.d(TAG, "performRequest() called with: type = [" + type + "], request = [" + request + "]");

InputStream os = performNetworkRequest(request);

Reader targetReader = new InputStreamReader(os);

T result = null;
if (type != Void.class) {
result = gson.fromJson(targetReader, type);
Expand Down Expand Up @@ -173,24 +186,38 @@ public InputStream performNetworkRequest(NextcloudRequest request) throws Except
ParcelFileDescriptor output = performAidlNetworkRequest(request);
os = new ParcelFileDescriptor.AutoCloseInputStream(output);
exception = deserializeObject(os);
} catch (RemoteException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}

// Handle Remote Exceptions
if(exception != null) {
if(exception.getMessage() != null) {
switch (exception.getMessage()) {
case "CE_1":
throw new TokenMismatchException();
case "CE_2":
throw new NextcloudFilesAppAccountNotFoundException();
default:
throw exception;
}
}
throw exception;
}
return os;
}

/**
* DO NOT CALL THIS METHOD DIRECTLY - use "performNetworkRequest(...)" instead
* @param request
* @return
* @throws IOException
*/
private ParcelFileDescriptor performAidlNetworkRequest(NextcloudRequest request) throws IOException, RemoteException {
// Log.d(TAG, request.url);
request.accountName = getAccountName();
request.token = getAccountToken();


ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(request);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package de.luhmer.owncloud.accountimporter.exceptions;

import android.content.Context;

public class CurrentAccountNotFoundException extends SSOException {

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package de.luhmer.owncloud.accountimporter.exceptions;

public class NextcloudFilesAppAccountNotFoundException extends SSOException {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package de.luhmer.owncloud.accountimporter.exceptions;

public class NextcloudFilesAppNotInstalledException extends SSOException {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package de.luhmer.owncloud.accountimporter.exceptions;

import android.content.Context;

public class NoCurrentAccountSelectedException extends SSOException {

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
package de.luhmer.owncloud.accountimporter.exceptions;

import android.app.Application;
import android.content.Context;
import android.util.Log;

import java.lang.reflect.InvocationTargetException;

import de.luhmer.owncloud.accountimporter.R;
import de.luhmer.owncloud.accountimporter.model.ExceptionMessage;

public class SSOException extends Exception {

private ExceptionMessage em;

public SSOException() {
super("Single Sign On Exception (use getMessage(context) for more information)");
}

private void loadExceptionMessage(Context context) {
em = new ExceptionMessage();

Log.d("AAAAAA", "this.getClass(): " + this.getClass());

if(this instanceof CurrentAccountNotFoundException) {
em.title = context.getString(R.string.current_account_not_found_exception_title);
em.message = context.getString(R.string.current_account_not_found_exception_message);
} else if(this instanceof NoCurrentAccountSelectedException) {
em.title = context.getString(R.string.no_current_account_selected_exception_title);
em.message = context.getString(R.string.no_current_account_selected_exception_message);
} else if(this instanceof TokenMismatchException) {
em.title = context.getString(R.string.token_mismatch_title);
em.message = context.getString(R.string.token_mismatch_message);
} else if(this instanceof NextcloudFilesAppNotInstalledException) {
em.title = context.getString(R.string.nextcloud_files_app_not_installed_title);
em.message = context.getString(R.string.nextcloud_files_app_not_installed_message);
} else if(this instanceof NextcloudFilesAppAccountNotFoundException) {
em.title = context.getString(R.string.nextcloud_files_app_account_not_found_title);
em.message = context.getString(R.string.nextcloud_files_app_account_not_found_message);
} else {
em.title = "Unknown error";
em.message = "Unknown error..";
}
}

public String getTitle(Context context) {
if(em == null) {
loadExceptionMessage(context);
}
return em.title;
}

public String getMessage(Context context) {
if(em == null) {
loadExceptionMessage(context);
}
return em.message;
}

@Override
public String getMessage() {
// If already loaded.. return it
if(em != null) {
return em.message;
}

// Otherwise try to get the application via reflection
Application app = getApplication();
if(app != null) {
loadExceptionMessage(app);
return em.message;
}

// If that didn't work.. well return the "generic" base message
return super.getMessage();
}

private Application getApplication() {
try {
return (Application) Class.forName("android.app.ActivityThread")
.getMethod("currentApplication").invoke(null, (Object[]) null);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return null;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package de.luhmer.owncloud.accountimporter.exceptions;

public class TokenMismatchException extends SSOException {

}
Loading

0 comments on commit 70831be

Please sign in to comment.