Installer: Starting with better error handling, new callback design

This commit is contained in:
Dominik Schürmann 2014-04-27 20:42:45 +02:00
parent fbc47c1428
commit 2399f954ed
6 changed files with 69 additions and 56 deletions

View File

@ -57,6 +57,7 @@ import android.view.MenuItem;
import android.view.SubMenu; import android.view.SubMenu;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.view.Window;
import android.graphics.Bitmap; import android.graphics.Bitmap;
import com.nostra13.universalimageloader.core.DisplayImageOptions; import com.nostra13.universalimageloader.core.DisplayImageOptions;
@ -260,6 +261,7 @@ public class AppDetails extends ListActivity {
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
fdroidApp = ((FDroidApp) getApplication()); fdroidApp = ((FDroidApp) getApplication());
fdroidApp.applyTheme(this); fdroidApp.applyTheme(this);
@ -353,6 +355,7 @@ public class AppDetails extends ListActivity {
@Override @Override
protected void onResume() { protected void onResume() {
Log.d(TAG, "onresume");
super.onResume(); super.onResume();
if (resetRequired) { if (resetRequired) {
if (!reset()) { if (!reset()) {
@ -930,6 +933,8 @@ public class AppDetails extends ListActivity {
} }
private void installApk(File file, String packageName) { private void installApk(File file, String packageName) {
setProgressBarIndeterminateVisibility(true);
try { try {
installer.installPackage(file); installer.installPackage(file);
} catch (AndroidNotCompatibleException e) { } catch (AndroidNotCompatibleException e) {
@ -940,6 +945,8 @@ public class AppDetails extends ListActivity {
} }
private void removeApk(String packageName) { private void removeApk(String packageName) {
setProgressBarIndeterminateVisibility(true);
try { try {
installer.deletePackage(packageName); installer.deletePackage(packageName);
} catch (AndroidNotCompatibleException e) { } catch (AndroidNotCompatibleException e) {
@ -960,40 +967,46 @@ public class AppDetails extends ListActivity {
private Installer.InstallerCallback myInstallerCallback = new Installer.InstallerCallback() { private Installer.InstallerCallback myInstallerCallback = new Installer.InstallerCallback() {
@Override @Override
public void onPackageInstalled(int returnCode, boolean unattended) { public void onSuccess(int operation, boolean unattended) {
// TODO: check return code?! resetRequired = true;
if (operation == Installer.InstallerCallback.OPERATION_INSTALL) {
if (downloadHandler != null) { if (downloadHandler != null) {
downloadHandler = null; downloadHandler = null;
} }
PackageManagerCompat.setInstaller(mPm, app.id); PackageManagerCompat.setInstaller(mPm, app.id);
resetRequired = true; }
// if unattended, onResume is not execute automatically // if unattended, onResume is not execute automatically
if (unattended) { // if (unattended) {
runOnUiThread(new Runnable() { runOnUiThread(new Runnable() {
@Override @Override
public void run() { public void run() {
onResume(); onResume();
setProgressBarIndeterminateVisibility(false);
} }
}); });
} // }
} }
@Override @Override
public void onPackageDeleted(int returnCode, boolean unattended) { public void onError(int operation, boolean unattended, final String reason) {
// TODO: check return code?!
resetRequired = true;
// if unattended, onResume is not execute automatically
if (unattended) {
runOnUiThread(new Runnable() { runOnUiThread(new Runnable() {
@Override @Override
public void run() { public void run() {
onResume(); setProgressBarIndeterminateVisibility(false);
// TODO
AlertDialog.Builder alertBuilder = new AlertDialog.Builder(AppDetails.this);
alertBuilder.setTitle("Error");
alertBuilder.setMessage(reason);
alertBuilder.setNeutralButton(android.R.string.ok, null);
alertBuilder.create().show();
} }
}); });
}
} }
}; };

View File

@ -26,7 +26,6 @@ import android.preference.CheckBoxPreference;
import android.preference.EditTextPreference; import android.preference.EditTextPreference;
import android.preference.ListPreference; import android.preference.ListPreference;
import android.app.AlertDialog; import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener; import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.view.MenuItem; import android.view.MenuItem;

View File

@ -98,17 +98,17 @@ public class DefaultInstaller extends Installer {
switch (requestCode) { switch (requestCode) {
case REQUEST_CODE_INSTALL: case REQUEST_CODE_INSTALL:
if (resultCode == Activity.RESULT_OK) { if (resultCode == Activity.RESULT_OK) {
mCallback.onPackageInstalled(InstallerCallback.RETURN_SUCCESS, false); mCallback.onSuccess(InstallerCallback.OPERATION_INSTALL, false);
} else { } else {
mCallback.onPackageInstalled(InstallerCallback.RETURN_CANCEL, false); mCallback.onError(InstallerCallback.OPERATION_INSTALL, false, "todo");
} }
return true; return true;
case REQUEST_CODE_DELETE: case REQUEST_CODE_DELETE:
if (resultCode == Activity.RESULT_OK) { if (resultCode == Activity.RESULT_OK) {
mCallback.onPackageDeleted(InstallerCallback.RETURN_SUCCESS, false); mCallback.onSuccess(InstallerCallback.OPERATION_DELETE, false);
} else { } else {
mCallback.onPackageDeleted(InstallerCallback.RETURN_CANCEL, false); mCallback.onError(InstallerCallback.OPERATION_DELETE, false, "todo");
} }
return true; return true;

View File

@ -74,12 +74,13 @@ abstract public class Installer {
*/ */
public interface InstallerCallback { public interface InstallerCallback {
public static final int RETURN_SUCCESS = 1; public static final int OPERATION_GENERIC_ERROR = 0;
public static final int RETURN_CANCEL = 0; public static final int OPERATION_INSTALL = 1;
public static final int OPERATION_DELETE = 2;
public void onPackageInstalled(int returnCode, boolean unattended); public void onSuccess(int operation, boolean unattended);
public void onPackageDeleted(int returnCode, boolean unattended); public void onError(int operation, boolean unattended, String reason);
} }
public Installer(Context context, PackageManager pm, InstallerCallback callback) public Installer(Context context, PackageManager pm, InstallerCallback callback)

View File

@ -62,8 +62,9 @@ public class RootInstaller extends Installer {
// exec failed // exec failed
// Shell.OnCommandResultListener.SHELL_EXEC_FAILED // Shell.OnCommandResultListener.SHELL_EXEC_FAILED
// reportError("Error opening root shell: exitCode " + // TODO
// exitCode); mCallback.onError(InstallerCallback.OPERATION_GENERIC_ERROR, true,
"Error opening root shell with exitCode " + exitCode);
} else { } else {
// Shell is up: send our first request // Shell is up: send our first request
sendInstallCommand(apkFile); sendInstallCommand(apkFile);
@ -95,8 +96,9 @@ public class RootInstaller extends Installer {
// exec failed // exec failed
// Shell.OnCommandResultListener.SHELL_EXEC_FAILED // Shell.OnCommandResultListener.SHELL_EXEC_FAILED
// reportError("Error opening root shell: exitCode " + // TODO
// exitCode); mCallback.onError(InstallerCallback.OPERATION_GENERIC_ERROR, true,
"Error opening root shell with exitCode " + exitCode);
} else { } else {
// Shell is up: send our first request // Shell is up: send our first request
sendDeleteCommand(packageName); sendDeleteCommand(packageName);
@ -120,9 +122,9 @@ public class RootInstaller extends Installer {
rootSession.close(); rootSession.close();
if (exitCode < 0) { if (exitCode < 0) {
// reportError("Error executing commands: exitCode " // TODO
// + exitCode); mCallback.onError(InstallerCallback.OPERATION_INSTALL, true,
mCallback.onPackageInstalled(InstallerCallback.RETURN_CANCEL, true); "Install failed with exit code " + exitCode);
} else { } else {
// wait until Android's internal PackageManger has // wait until Android's internal PackageManger has
// received the new package state // received the new package state
@ -134,8 +136,7 @@ public class RootInstaller extends Installer {
} catch (InterruptedException e) { } catch (InterruptedException e) {
} }
mCallback.onPackageInstalled(InstallerCallback.RETURN_SUCCESS, mCallback.onSuccess(InstallerCallback.OPERATION_INSTALL, true);
true);
} }
}); });
wait.start(); wait.start();
@ -152,9 +153,9 @@ public class RootInstaller extends Installer {
rootSession.close(); rootSession.close();
if (exitCode < 0) { if (exitCode < 0) {
// reportError("Error executing commands: exitCode " // TODO
// + exitCode); mCallback.onError(InstallerCallback.OPERATION_DELETE, true,
mCallback.onPackageDeleted(InstallerCallback.RETURN_CANCEL, true); "Delete failed with exit code " + exitCode);
} else { } else {
// wait until Android's internal PackageManger has // wait until Android's internal PackageManger has
// received the new package state // received the new package state
@ -166,8 +167,7 @@ public class RootInstaller extends Installer {
} catch (InterruptedException e) { } catch (InterruptedException e) {
} }
mCallback.onPackageDeleted(InstallerCallback.RETURN_SUCCESS, mCallback.onSuccess(InstallerCallback.OPERATION_DELETE, true);
true);
} }
}); });
wait.start(); wait.start();

View File

@ -93,13 +93,13 @@ public class SystemPermissionInstaller extends Installer {
} catch (InterruptedException e) { } catch (InterruptedException e) {
} }
mCallback.onPackageInstalled(InstallerCallback.RETURN_SUCCESS, true); mCallback.onSuccess(InstallerCallback.OPERATION_INSTALL, true);
} }
}); });
wait.start(); wait.start();
} else { } else {
Log.d(TAG, "Install failed: " + returnCode); Log.d(TAG, "Install failed: " + returnCode);
mCallback.onPackageInstalled(InstallerCallback.RETURN_CANCEL, true); mCallback.onError(InstallerCallback.OPERATION_INSTALL, true, "todo");
} }
} }
} }
@ -123,13 +123,13 @@ public class SystemPermissionInstaller extends Installer {
} catch (InterruptedException e) { } catch (InterruptedException e) {
} }
mCallback.onPackageDeleted(InstallerCallback.RETURN_SUCCESS, true); mCallback.onSuccess(InstallerCallback.OPERATION_DELETE, true);
} }
}); });
wait.start(); wait.start();
} else { } else {
Log.d(TAG, "Delete failed: " + returnCode); Log.d(TAG, "Delete failed: " + returnCode);
mCallback.onPackageDeleted(InstallerCallback.RETURN_CANCEL, true); mCallback.onError(InstallerCallback.OPERATION_DELETE, true, "todo");
} }
} }
} }