Installer: Starting with better error handling, new callback design
This commit is contained in:
parent
fbc47c1428
commit
2399f954ed
@ -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,7 +261,8 @@ 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?!
|
|
||||||
if (downloadHandler != null) {
|
|
||||||
downloadHandler = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
PackageManagerCompat.setInstaller(mPm, app.id);
|
|
||||||
resetRequired = true;
|
resetRequired = true;
|
||||||
|
|
||||||
// if unattended, onResume is not execute automatically
|
if (operation == Installer.InstallerCallback.OPERATION_INSTALL) {
|
||||||
if (unattended) {
|
if (downloadHandler != null) {
|
||||||
runOnUiThread(new Runnable() {
|
downloadHandler = null;
|
||||||
@Override
|
}
|
||||||
public void run() {
|
|
||||||
onResume();
|
PackageManagerCompat.setInstaller(mPm, app.id);
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// if unattended, onResume is not execute automatically
|
||||||
|
// if (unattended) {
|
||||||
|
runOnUiThread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
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?!
|
runOnUiThread(new Runnable() {
|
||||||
resetRequired = true;
|
@Override
|
||||||
|
public void run() {
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// if unattended, onResume is not execute automatically
|
|
||||||
if (unattended) {
|
|
||||||
runOnUiThread(new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
onResume();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
@ -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)
|
||||||
|
@ -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();
|
||||||
|
@ -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");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user