mirror of
https://github.com/beemdevelopment/Aegis.git
synced 2025-05-16 15:02:54 +00:00
Request root access from separate thread and don't use global Shell
This should help prevent some of the ANR's reported through Google Play
This commit is contained in:
parent
ac51996896
commit
69f0bb4fbc
8 changed files with 78 additions and 23 deletions
|
@ -39,8 +39,8 @@ public abstract class AegisApplicationBase extends Application {
|
|||
private VaultManager _vaultManager;
|
||||
|
||||
static {
|
||||
// to access other app's internal storage directory, run libsu commands inside the global mount namespace
|
||||
Shell.setDefaultBuilder(Shell.Builder.create().setFlags(Shell.FLAG_MOUNT_MASTER));
|
||||
// Enable verbose libsu logging in debug builds
|
||||
Shell.enableVerboseLogging = BuildConfig.DEBUG;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -16,6 +16,7 @@ import com.beemdevelopment.aegis.ui.dialogs.Dialogs;
|
|||
import com.beemdevelopment.aegis.util.JsonUtils;
|
||||
import com.beemdevelopment.aegis.util.PreferenceParser;
|
||||
import com.beemdevelopment.aegis.vault.VaultEntry;
|
||||
import com.topjohnwu.superuser.Shell;
|
||||
import com.topjohnwu.superuser.io.SuFile;
|
||||
import com.topjohnwu.superuser.io.SuFileInputStream;
|
||||
|
||||
|
@ -67,8 +68,9 @@ public class AuthyImporter extends DatabaseImporter {
|
|||
}
|
||||
|
||||
@Override
|
||||
public State readFromApp() throws PackageManager.NameNotFoundException, DatabaseImporterException {
|
||||
public State readFromApp(Shell shell) throws PackageManager.NameNotFoundException, DatabaseImporterException {
|
||||
SuFile path = getAppPath();
|
||||
path.setShell(shell);
|
||||
|
||||
JSONArray array;
|
||||
JSONArray authyArray;
|
||||
|
|
|
@ -8,6 +8,7 @@ import androidx.annotation.StringRes;
|
|||
import com.beemdevelopment.aegis.R;
|
||||
import com.beemdevelopment.aegis.util.UUIDMap;
|
||||
import com.beemdevelopment.aegis.vault.VaultEntry;
|
||||
import com.topjohnwu.superuser.Shell;
|
||||
import com.topjohnwu.superuser.io.SuFile;
|
||||
import com.topjohnwu.superuser.io.SuFileInputStream;
|
||||
|
||||
|
@ -70,8 +71,10 @@ public abstract class DatabaseImporter {
|
|||
return read(stream, false);
|
||||
}
|
||||
|
||||
public State readFromApp() throws PackageManager.NameNotFoundException, DatabaseImporterException {
|
||||
public State readFromApp(Shell shell) throws PackageManager.NameNotFoundException, DatabaseImporterException {
|
||||
SuFile file = getAppPath();
|
||||
file.setShell(shell);
|
||||
|
||||
try (InputStream stream = SuFileInputStream.open(file)) {
|
||||
return read(stream, true);
|
||||
} catch (IOException e) {
|
||||
|
|
|
@ -13,6 +13,7 @@ import com.beemdevelopment.aegis.otp.OtpInfo;
|
|||
import com.beemdevelopment.aegis.otp.OtpInfoException;
|
||||
import com.beemdevelopment.aegis.otp.TotpInfo;
|
||||
import com.beemdevelopment.aegis.vault.VaultEntry;
|
||||
import com.topjohnwu.superuser.Shell;
|
||||
import com.topjohnwu.superuser.io.SuFile;
|
||||
|
||||
import java.io.InputStream;
|
||||
|
@ -31,7 +32,8 @@ public class GoogleAuthImporter extends DatabaseImporter {
|
|||
|
||||
@Override
|
||||
protected SuFile getAppPath() throws PackageManager.NameNotFoundException {
|
||||
return getAppPath(_pkgName, _subPath);
|
||||
SuFile file = getAppPath(_pkgName, _subPath);
|
||||
return file;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -55,8 +57,10 @@ public class GoogleAuthImporter extends DatabaseImporter {
|
|||
}
|
||||
|
||||
@Override
|
||||
public DatabaseImporter.State readFromApp() throws PackageManager.NameNotFoundException, DatabaseImporterException {
|
||||
public DatabaseImporter.State readFromApp(Shell shell) throws PackageManager.NameNotFoundException, DatabaseImporterException {
|
||||
SuFile path = getAppPath();
|
||||
path.setShell(shell);
|
||||
|
||||
final Context context = requireContext();
|
||||
SqlImporterHelper helper = new SqlImporterHelper(context);
|
||||
List<Entry> entries = helper.read(Entry.class, path, "accounts");
|
||||
|
|
|
@ -11,6 +11,7 @@ import com.beemdevelopment.aegis.otp.OtpInfo;
|
|||
import com.beemdevelopment.aegis.otp.OtpInfoException;
|
||||
import com.beemdevelopment.aegis.otp.TotpInfo;
|
||||
import com.beemdevelopment.aegis.vault.VaultEntry;
|
||||
import com.topjohnwu.superuser.Shell;
|
||||
import com.topjohnwu.superuser.io.SuFile;
|
||||
|
||||
import java.io.InputStream;
|
||||
|
@ -40,8 +41,10 @@ public class MicrosoftAuthImporter extends DatabaseImporter {
|
|||
}
|
||||
|
||||
@Override
|
||||
public DatabaseImporter.State readFromApp() throws PackageManager.NameNotFoundException, DatabaseImporterException {
|
||||
public DatabaseImporter.State readFromApp(Shell shell) throws PackageManager.NameNotFoundException, DatabaseImporterException {
|
||||
SuFile path = getAppPath();
|
||||
path.setShell(shell);
|
||||
|
||||
SqlImporterHelper helper = new SqlImporterHelper(requireContext());
|
||||
List<Entry> entries = helper.read(Entry.class, path, "accounts");
|
||||
return new State(entries);
|
||||
|
|
|
@ -20,12 +20,12 @@ import com.beemdevelopment.aegis.importers.DatabaseImporterEntryException;
|
|||
import com.beemdevelopment.aegis.importers.DatabaseImporterException;
|
||||
import com.beemdevelopment.aegis.ui.dialogs.Dialogs;
|
||||
import com.beemdevelopment.aegis.ui.models.ImportEntry;
|
||||
import com.beemdevelopment.aegis.ui.tasks.RootShellTask;
|
||||
import com.beemdevelopment.aegis.ui.views.ImportEntriesAdapter;
|
||||
import com.beemdevelopment.aegis.util.UUIDMap;
|
||||
import com.beemdevelopment.aegis.vault.VaultEntry;
|
||||
import com.beemdevelopment.aegis.vault.VaultRepository;
|
||||
import com.google.android.material.floatingactionbutton.FloatingActionButton;
|
||||
import com.topjohnwu.superuser.Shell;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
|
@ -118,25 +118,36 @@ public class ImportEntriesActivity extends AegisActivity {
|
|||
}
|
||||
|
||||
private void startImportApp(@NonNull DatabaseImporter importer) {
|
||||
// obtain the global root shell and close it immediately after we're done
|
||||
// TODO: find a way to use SuFileInputStream with Shell.newInstance()
|
||||
try (Shell shell = Shell.getShell()) {
|
||||
if (!shell.isRoot()) {
|
||||
RootShellTask task = new RootShellTask(this, shell -> {
|
||||
if (isFinishing()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (shell == null || !shell.isRoot()) {
|
||||
Toast.makeText(this, R.string.root_error, Toast.LENGTH_SHORT).show();
|
||||
finish();
|
||||
return;
|
||||
}
|
||||
|
||||
DatabaseImporter.State state = importer.readFromApp();
|
||||
processImporterState(state);
|
||||
} catch (PackageManager.NameNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
Toast.makeText(this, R.string.app_lookup_error, Toast.LENGTH_SHORT).show();
|
||||
finish();
|
||||
} catch (IOException | DatabaseImporterException e) {
|
||||
e.printStackTrace();
|
||||
Dialogs.showErrorDialog(this, R.string.reading_file_error, e, (dialog, which) -> finish());
|
||||
}
|
||||
try {
|
||||
DatabaseImporter.State state = importer.readFromApp(shell);
|
||||
processImporterState(state);
|
||||
} catch (PackageManager.NameNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
Toast.makeText(this, R.string.app_lookup_error, Toast.LENGTH_SHORT).show();
|
||||
finish();
|
||||
} catch (DatabaseImporterException e) {
|
||||
e.printStackTrace();
|
||||
Dialogs.showErrorDialog(this, R.string.reading_file_error, e, (dialog, which) -> finish());
|
||||
} finally {
|
||||
try {
|
||||
shell.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
});
|
||||
task.execute(this);
|
||||
}
|
||||
|
||||
private void processImporterState(DatabaseImporter.State state) {
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
package com.beemdevelopment.aegis.ui.tasks;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import com.beemdevelopment.aegis.R;
|
||||
import com.topjohnwu.superuser.Shell;
|
||||
|
||||
public class RootShellTask extends ProgressDialogTask<Object, Shell> {
|
||||
private final Callback _cb;
|
||||
|
||||
public RootShellTask(Context context, Callback cb) {
|
||||
super(context, context.getString(R.string.requesting_root_access));
|
||||
_cb = cb;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Shell doInBackground(Object... params) {
|
||||
// To access other app's internal storage directory, run libsu commands inside the global mount namespace
|
||||
return Shell.Builder.create().setFlags(Shell.FLAG_MOUNT_MASTER).build();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(Shell shell) {
|
||||
super.onPostExecute(shell);
|
||||
_cb.onTaskFinished(shell);
|
||||
}
|
||||
|
||||
public interface Callback {
|
||||
void onTaskFinished(Shell shell);
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue