ToolsInstaller: Propagate NoRootException properly

Signed-off-by: Samuel Holland <samuel@sholland.org>
This commit is contained in:
Samuel Holland 2018-01-09 08:13:32 -06:00
parent 52e8eef9ce
commit 426fa7d50b
2 changed files with 34 additions and 32 deletions

View File

@ -34,15 +34,6 @@ public class ToolsInstallerPreference extends Preference {
this(context, null); this(context, null);
} }
private static State mapResultToState(final int scriptResult) {
if (scriptResult == OsConstants.EXIT_SUCCESS)
return State.SUCCESS;
else if (scriptResult == OsConstants.EALREADY)
return State.ALREADY;
else
return State.FAILURE;
}
@Override @Override
public CharSequence getSummary() { public CharSequence getSummary() {
return getContext().getString(state.messageResourceId); return getContext().getString(state.messageResourceId);
@ -61,16 +52,31 @@ public class ToolsInstallerPreference extends Preference {
@Override @Override
protected void onAttachedToActivity() { protected void onAttachedToActivity() {
super.onAttachedToActivity(); super.onAttachedToActivity();
asyncWorker.supplyAsync(toolsInstaller::areInstalled) asyncWorker.supplyAsync(toolsInstaller::areInstalled).whenComplete(this::onCheckResult);
.thenAccept(installed -> setState(installed ? State.ALREADY : State.INITIAL)); }
private void onCheckResult(final Integer result, final Throwable throwable) {
setState(throwable == null && result == OsConstants.EALREADY ?
State.ALREADY : State.INITIAL);
} }
@Override @Override
protected void onClick() { protected void onClick() {
setState(State.WORKING); setState(State.WORKING);
asyncWorker.supplyAsync(toolsInstaller::install) asyncWorker.supplyAsync(toolsInstaller::install).whenComplete(this::onInstallResult);
.thenApply(ToolsInstallerPreference::mapResultToState) }
.thenAccept(this::setState);
private void onInstallResult(final Integer result, final Throwable throwable) {
final State nextState;
if (throwable != null)
nextState = State.FAILURE;
else if (result == OsConstants.EXIT_SUCCESS)
nextState = State.SUCCESS;
else if (result == OsConstants.EALREADY)
nextState = State.ALREADY;
else
nextState = State.FAILURE;
setState(nextState);
} }
private void setState(@NonNull final State state) { private void setState(@NonNull final State state) {

View File

@ -56,9 +56,9 @@ public final class ToolsInstaller {
return null; return null;
} }
public boolean areInstalled() { public int areInstalled() throws NoRootException {
if (INSTALL_DIR == null) if (INSTALL_DIR == null)
return false; return OsConstants.ENOENT;
final StringBuilder script = new StringBuilder(); final StringBuilder script = new StringBuilder();
for (final String[] names : EXECUTABLES) { for (final String[] names : EXECUTABLES) {
script.append(String.format("cmp -s '%s' '%s' && ", script.append(String.format("cmp -s '%s' '%s' && ",
@ -67,13 +67,13 @@ public final class ToolsInstaller {
} }
script.append("exit ").append(OsConstants.EALREADY).append(';'); script.append("exit ").append(OsConstants.EALREADY).append(';');
try { try {
return rootShell.run(null, script.toString()) == OsConstants.EALREADY; return rootShell.run(null, script.toString());
} catch (final IOException | NoRootException ignored) { } catch (final IOException ignored) {
return false; return OsConstants.EXIT_FAILURE;
} }
} }
public boolean areSymlinked() { public int areSymlinked() throws NoRootException {
final StringBuilder script = new StringBuilder(); final StringBuilder script = new StringBuilder();
for (final String[] names : EXECUTABLES) { for (final String[] names : EXECUTABLES) {
script.append(String.format("test '%s' -ef '%s' && ", script.append(String.format("test '%s' -ef '%s' && ",
@ -82,20 +82,20 @@ public final class ToolsInstaller {
} }
script.append("exit ").append(OsConstants.EALREADY).append(';'); script.append("exit ").append(OsConstants.EALREADY).append(';');
try { try {
return rootShell.run(null, script.toString()) == OsConstants.EALREADY; return rootShell.run(null, script.toString());
} catch (final IOException | NoRootException ignored) { } catch (final IOException ignored) {
return false; return OsConstants.EXIT_FAILURE;
} }
} }
public void ensureToolsAvailable() throws FileNotFoundException { public void ensureToolsAvailable() throws FileNotFoundException, NoRootException {
if (areToolsAvailable == null) { if (areToolsAvailable == null) {
synchronized (this) { synchronized (this) {
if (areToolsAvailable == null) { if (areToolsAvailable == null) {
if (areInstalled()) { if (areInstalled() == OsConstants.EALREADY) {
Log.d(TAG, "Tools are installed to /system"); Log.d(TAG, "Tools are installed to /system");
areToolsAvailable = true; areToolsAvailable = true;
} else if (areSymlinked()) { } else if (areSymlinked() == OsConstants.EALREADY) {
Log.d(TAG, "Tools were already symlinked into our private binary dir"); Log.d(TAG, "Tools were already symlinked into our private binary dir");
areToolsAvailable = true; areToolsAvailable = true;
} else if (symlink() == OsConstants.EXIT_SUCCESS) { } else if (symlink() == OsConstants.EXIT_SUCCESS) {
@ -112,7 +112,7 @@ public final class ToolsInstaller {
throw new FileNotFoundException("Required tools unavailable"); throw new FileNotFoundException("Required tools unavailable");
} }
public int install() { public int install() throws NoRootException {
if (INSTALL_DIR == null) if (INSTALL_DIR == null)
return OsConstants.ENOENT; return OsConstants.ENOENT;
final StringBuilder script = new StringBuilder("set -ex;"); final StringBuilder script = new StringBuilder("set -ex;");
@ -126,12 +126,10 @@ public final class ToolsInstaller {
return rootShell.run(null, script.toString()); return rootShell.run(null, script.toString());
} catch (final IOException ignored) { } catch (final IOException ignored) {
return OsConstants.EXIT_FAILURE; return OsConstants.EXIT_FAILURE;
} catch (final NoRootException ignored) {
return OsConstants.EACCES;
} }
} }
public int symlink() { public int symlink() throws NoRootException {
final StringBuilder script = new StringBuilder("set -ex;"); final StringBuilder script = new StringBuilder("set -ex;");
for (final String[] names : EXECUTABLES) { for (final String[] names : EXECUTABLES) {
script.append(String.format("ln -fns '%s' '%s'; ", script.append(String.format("ln -fns '%s' '%s'; ",
@ -142,8 +140,6 @@ public final class ToolsInstaller {
return rootShell.run(null, script.toString()); return rootShell.run(null, script.toString());
} catch (final IOException ignored) { } catch (final IOException ignored) {
return OsConstants.EXIT_FAILURE; return OsConstants.EXIT_FAILURE;
} catch (final NoRootException ignored) {
return OsConstants.EACCES;
} }
} }
} }