Change callback

This commit is contained in:
Dominik Schürmann 2014-05-11 00:03:26 +02:00
parent 0887da72ed
commit c48dcdc785
7 changed files with 156 additions and 106 deletions

View File

@ -25,6 +25,7 @@ import android.widget.*;
import org.fdroid.fdroid.data.*; import org.fdroid.fdroid.data.*;
import org.fdroid.fdroid.installer.Installer; import org.fdroid.fdroid.installer.Installer;
import org.fdroid.fdroid.installer.Installer.AndroidNotCompatibleException; import org.fdroid.fdroid.installer.Installer.AndroidNotCompatibleException;
import org.fdroid.fdroid.installer.Installer.InstallerCallback;
import org.xml.sax.XMLReader; import org.xml.sax.XMLReader;
import android.app.AlertDialog; import android.app.AlertDialog;
@ -310,7 +311,8 @@ public class AppDetails extends ListActivity {
} }
mPm = getPackageManager(); mPm = getPackageManager();
installer = Installer.getActivityInstaller(this, mPm, myInstallerCallback); installer = Installer.getActivityInstaller(this, mPm,
myInstallerCallback);
// Get the preferences we're going to use in this Activity... // Get the preferences we're going to use in this Activity...
AppDetails old = (AppDetails) getLastNonConfigurationInstance(); AppDetails old = (AppDetails) getLastNonConfigurationInstance();
@ -929,7 +931,6 @@ public class AppDetails extends ListActivity {
downloadHandler = new DownloadHandler(apk, repoaddress, downloadHandler = new DownloadHandler(apk, repoaddress,
Utils.getApkCacheDir(getBaseContext())); Utils.getApkCacheDir(getBaseContext()));
} }
private void installApk(File file, String packageName) { private void installApk(File file, String packageName) {
setProgressBarIndeterminateVisibility(true); setProgressBarIndeterminateVisibility(true);
@ -938,8 +939,6 @@ public class AppDetails extends ListActivity {
} catch (AndroidNotCompatibleException e) { } catch (AndroidNotCompatibleException e) {
Log.e(TAG, "Android not compatible with this Installer!", e); Log.e(TAG, "Android not compatible with this Installer!", e);
} }
notifyAppChanged(packageName);
} }
private void removeApk(String packageName) { private void removeApk(String packageName) {
@ -950,22 +949,28 @@ public class AppDetails extends ListActivity {
} catch (AndroidNotCompatibleException e) { } catch (AndroidNotCompatibleException e) {
Log.e(TAG, "Android not compatible with this Installer!", e); Log.e(TAG, "Android not compatible with this Installer!", e);
} }
notifyAppChanged(packageName);
} }
/** /**
* We could probably drop this, and let the PackageReceiver take care of notifications * We could probably drop this, and let the PackageReceiver take care of
* for us, but I don't think the package receiver notifications are very instantaneous. * notifications for us, but I don't think the package receiver
* notifications are very instantaneous.
*/ */
private void notifyAppChanged(String id) { private void notifyAppChanged(String id) {
getContentResolver().notifyChange(AppProvider.getContentUri(id), null); getContentResolver().notifyChange(AppProvider.getContentUri(id), null);
} }
private Installer.InstallerCallback myInstallerCallback = new Installer.InstallerCallback() { Installer.InstallerCallback myInstallerCallback = new Installer.InstallerCallback() {
@Override @Override
public void onSuccess(int operation, boolean unattended) { public void onSuccess(final int operation) {
runOnUiThread(new Runnable() {
@Override
public void run() {
Log.d(TAG, "handling installer onSuccess");
notifyAppChanged(app.id);
resetRequired = true; resetRequired = true;
if (operation == Installer.InstallerCallback.OPERATION_INSTALL) { if (operation == Installer.InstallerCallback.OPERATION_INSTALL) {
@ -976,21 +981,16 @@ public class AppDetails extends ListActivity {
PackageManagerCompat.setInstaller(mPm, app.id); PackageManagerCompat.setInstaller(mPm, app.id);
} }
// if unattended, onResume is not execute automatically // TODO: whole onResume?
// if (unattended) {
runOnUiThread(new Runnable() {
@Override
public void run() {
onResume(); onResume();
setProgressBarIndeterminateVisibility(false); setProgressBarIndeterminateVisibility(false);
} }
}); });
// }
} }
@Override @Override
public void onError(int operation, boolean unattended, final String reason) { public void onError(int operation, final int errorCode) {
if (errorCode != InstallerCallback.ERROR_CODE_CANCELED) {
runOnUiThread(new Runnable() { runOnUiThread(new Runnable() {
@Override @Override
public void run() { public void run() {
@ -999,12 +999,12 @@ public class AppDetails extends ListActivity {
// TODO // TODO
AlertDialog.Builder alertBuilder = new AlertDialog.Builder(AppDetails.this); AlertDialog.Builder alertBuilder = new AlertDialog.Builder(AppDetails.this);
alertBuilder.setTitle("Error"); alertBuilder.setTitle("Error");
alertBuilder.setMessage(reason); alertBuilder.setMessage("errorCode: " + errorCode);
alertBuilder.setNeutralButton(android.R.string.ok, null); alertBuilder.setNeutralButton(android.R.string.ok, null);
alertBuilder.create().show(); alertBuilder.create().show();
} }
}); });
}
} }
}; };

View File

@ -9,12 +9,12 @@ import android.util.Log;
public class PackageManagerCompat extends Compatibility { public class PackageManagerCompat extends Compatibility {
@TargetApi(11) @TargetApi(11)
public static void setInstaller(PackageManager mPm, String app_id) { public static void setInstaller(PackageManager mPm, String packageName) {
if (!hasApi(11)) return; if (!hasApi(11)) return;
try { try {
mPm.setInstallerPackageName(app_id, "org.fdroid.fdroid"); mPm.setInstallerPackageName(packageName, "org.fdroid.fdroid");
Log.d("FDroid", "Installer package name for " + Log.d("FDroid", "Installer package name for " +
app_id + " set successfully"); packageName + " set successfully");
} catch (Exception e) { } catch (Exception e) {
// Many problems can occur: // Many problems can occur:
// * App wasn't installed due to incompatibility // * App wasn't installed due to incompatibility
@ -22,8 +22,8 @@ public class PackageManagerCompat extends Compatibility {
// * Another app interfered in the process // * Another app interfered in the process
// * Another app already set the target's installer package // * Another app already set the target's installer package
// * ... // * ...
Log.d("FDroid", "Could not set installer package name for " + Log.e("FDroid", "Could not set installer package name for " +
app_id + ": " + e.getMessage()); packageName, e);
} }
} }

View File

@ -104,11 +104,11 @@ public class DefaultInstaller extends Installer {
*/ */
switch (requestCode) { switch (requestCode) {
case REQUEST_CODE_INSTALL: case REQUEST_CODE_INSTALL:
mCallback.onSuccess(InstallerCallback.OPERATION_INSTALL, false); mCallback.onSuccess(InstallerCallback.OPERATION_INSTALL);
return true; return true;
case REQUEST_CODE_DELETE: case REQUEST_CODE_DELETE:
mCallback.onSuccess(InstallerCallback.OPERATION_DELETE, false); mCallback.onSuccess(InstallerCallback.OPERATION_DELETE);
return true; return true;
default: default:

View File

@ -21,6 +21,8 @@ package org.fdroid.fdroid.installer;
import java.io.File; import java.io.File;
import org.fdroid.fdroid.installer.Installer.InstallerCallback;
import android.annotation.TargetApi; import android.annotation.TargetApi;
import android.app.Activity; import android.app.Activity;
import android.content.ActivityNotFoundException; import android.content.ActivityNotFoundException;
@ -97,39 +99,83 @@ public class DefaultInstallerSdk14 extends Installer {
} }
@Override @Override
public boolean handleOnActivityResult(int requestCode, int resultCode, Intent data) { public boolean handleOnActivityResult(final int requestCode, final int resultCode, Intent data) {
/** /**
* resultCode is always 0 on Android < 4.0. See * resultCode is always 0 on Android < 4.0. See
* com.android.packageinstaller.PackageInstallerActivity: setResult is * com.android.packageinstaller.PackageInstallerActivity: setResult is
* never executed! * never executed!
*/ */
// wait until Android's internal PackageManger has
// received the new package state
Thread wait = new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
}
switch (requestCode) { switch (requestCode) {
case REQUEST_CODE_INSTALL: case REQUEST_CODE_INSTALL:
if (resultCode == Activity.RESULT_OK) { if (resultCode == Activity.RESULT_OK) {
mCallback.onSuccess(InstallerCallback.OPERATION_INSTALL, false); mCallback.onSuccess(InstallerCallback.OPERATION_INSTALL);
} else if (resultCode == Activity.RESULT_CANCELED) { } else if (resultCode == Activity.RESULT_CANCELED) {
// TODO mCallback.onError(InstallerCallback.OPERATION_INSTALL,
mCallback.onError(InstallerCallback.OPERATION_INSTALL, false, "canceled"); InstallerCallback.ERROR_CODE_CANCELED);
} else { } else {
mCallback.onError(InstallerCallback.OPERATION_INSTALL, false, "todo"); mCallback.onError(InstallerCallback.OPERATION_INSTALL,
InstallerCallback.ERROR_CODE_OTHER);
} }
return true; // return true;
case REQUEST_CODE_DELETE: case REQUEST_CODE_DELETE:
if (resultCode == Activity.RESULT_OK) { if (resultCode == Activity.RESULT_OK) {
mCallback.onSuccess(InstallerCallback.OPERATION_DELETE, false); mCallback.onSuccess(InstallerCallback.OPERATION_DELETE);
} else if (resultCode == Activity.RESULT_CANCELED) { } else if (resultCode == Activity.RESULT_CANCELED) {
// TODO mCallback.onError(InstallerCallback.OPERATION_DELETE,
mCallback.onError(InstallerCallback.OPERATION_DELETE, false, "canceled"); InstallerCallback.ERROR_CODE_CANCELED);
} else { } else {
mCallback.onError(InstallerCallback.OPERATION_DELETE, false, "todo"); mCallback.onError(InstallerCallback.OPERATION_DELETE,
InstallerCallback.ERROR_CODE_OTHER);
} }
return true; // return true;
default: default:
return false; // return false;
} }
} }
});
wait.start();
return true;
// case REQUEST_CODE_INSTALL:
// if (resultCode == Activity.RESULT_OK) {
// mCallback.onSuccess(InstallerCallback.OPERATION_INSTALL);
// } else if (resultCode == Activity.RESULT_CANCELED) {
// mCallback.onError(InstallerCallback.OPERATION_INSTALL,
// InstallerCallback.ERROR_CODE_CANCELED);
// } else {
// mCallback.onError(InstallerCallback.OPERATION_INSTALL,
// InstallerCallback.ERROR_CODE_OTHER);
// }
//
// return true;
// case REQUEST_CODE_DELETE:
// if (resultCode == Activity.RESULT_OK) {
// mCallback.onSuccess(InstallerCallback.OPERATION_DELETE);
// } else if (resultCode == Activity.RESULT_CANCELED) {
// mCallback.onError(InstallerCallback.OPERATION_DELETE,
// InstallerCallback.ERROR_CODE_CANCELED);
// } else {
// mCallback.onError(InstallerCallback.OPERATION_DELETE,
// InstallerCallback.ERROR_CODE_OTHER);
// }
//
// return true;
// default:
// return false;
// }
}
@Override @Override
public boolean supportsUnattendedOperations() { public boolean supportsUnattendedOperations() {

View File

@ -78,9 +78,12 @@ abstract public class Installer {
public static final int OPERATION_INSTALL = 1; public static final int OPERATION_INSTALL = 1;
public static final int OPERATION_DELETE = 2; public static final int OPERATION_DELETE = 2;
public void onSuccess(int operation, boolean unattended); public static final int ERROR_CODE_CANCELED = 1;
public static final int ERROR_CODE_OTHER = 2;
public void onError(int operation, boolean unattended, String reason); public void onSuccess(int operation);
public void onError(int operation, int errorCode);
} }
public Installer(Context context, PackageManager pm, InstallerCallback callback) public Installer(Context context, PackageManager pm, InstallerCallback callback)

View File

@ -27,6 +27,7 @@ import eu.chainfire.libsuperuser.Shell;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.util.Log;
/** /**
* Installer using a root shell and "pm install", "pm uninstall" commands * Installer using a root shell and "pm install", "pm uninstall" commands
@ -67,9 +68,9 @@ public class RootInstaller extends Installer {
// exec failed // exec failed
// Shell.OnCommandResultListener.SHELL_EXEC_FAILED // Shell.OnCommandResultListener.SHELL_EXEC_FAILED
// TODO Log.e(TAG, "Error opening root shell with exitCode " + exitCode);
mCallback.onError(InstallerCallback.OPERATION_INSTALL, true, mCallback.onError(InstallerCallback.OPERATION_INSTALL,
"Error opening root shell with exitCode " + exitCode); InstallerCallback.ERROR_CODE_OTHER);
} else { } else {
addInstallCommand(apkFile); addInstallCommand(apkFile);
} }
@ -94,9 +95,9 @@ public class RootInstaller extends Installer {
// exec failed // exec failed
// Shell.OnCommandResultListener.SHELL_EXEC_FAILED // Shell.OnCommandResultListener.SHELL_EXEC_FAILED
// TODO Log.e(TAG, "Error opening root shell with exitCode " + exitCode);
mCallback.onError(InstallerCallback.OPERATION_INSTALL, true, mCallback.onError(InstallerCallback.OPERATION_INSTALL,
"Error opening root shell with exitCode " + exitCode); InstallerCallback.ERROR_CODE_OTHER);
} else { } else {
addInstallCommand(apkFiles); addInstallCommand(apkFiles);
} }
@ -121,9 +122,9 @@ public class RootInstaller extends Installer {
// exec failed // exec failed
// Shell.OnCommandResultListener.SHELL_EXEC_FAILED // Shell.OnCommandResultListener.SHELL_EXEC_FAILED
// TODO Log.e(TAG, "Error opening root shell with exitCode " + exitCode);
mCallback.onError(InstallerCallback.OPERATION_DELETE, true, mCallback.onError(InstallerCallback.OPERATION_DELETE,
"Error opening root shell with exitCode " + exitCode); InstallerCallback.ERROR_CODE_OTHER);
} else { } else {
addDeleteCommand(packageName); addDeleteCommand(packageName);
} }
@ -153,9 +154,9 @@ public class RootInstaller extends Installer {
rootSession.close(); rootSession.close();
if (exitCode < 0) { if (exitCode < 0) {
// TODO Log.e(TAG, "Install failed with exit code " + exitCode);
mCallback.onError(InstallerCallback.OPERATION_INSTALL, true, mCallback.onError(InstallerCallback.OPERATION_INSTALL,
"Install failed with exit code " + exitCode); InstallerCallback.ERROR_CODE_OTHER);
} else { } else {
// wait until Android's internal PackageManger // wait until Android's internal PackageManger
// has received the new package state // has received the new package state
@ -167,9 +168,7 @@ public class RootInstaller extends Installer {
} catch (InterruptedException e) { } catch (InterruptedException e) {
} }
mCallback.onSuccess( mCallback.onSuccess(InstallerCallback.OPERATION_INSTALL);
InstallerCallback.OPERATION_INSTALL,
true);
} }
}); });
wait.start(); wait.start();
@ -187,9 +186,9 @@ public class RootInstaller extends Installer {
rootSession.close(); rootSession.close();
if (exitCode < 0) { if (exitCode < 0) {
// TODO Log.e(TAG, "Install failed with exit code " + exitCode);
mCallback.onError(InstallerCallback.OPERATION_INSTALL, true, mCallback.onError(InstallerCallback.OPERATION_INSTALL,
"Install failed with exit code " + exitCode); InstallerCallback.ERROR_CODE_OTHER);
} 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
@ -201,7 +200,7 @@ public class RootInstaller extends Installer {
} catch (InterruptedException e) { } catch (InterruptedException e) {
} }
mCallback.onSuccess(InstallerCallback.OPERATION_INSTALL, true); mCallback.onSuccess(InstallerCallback.OPERATION_INSTALL);
} }
}); });
wait.start(); wait.start();
@ -218,9 +217,9 @@ public class RootInstaller extends Installer {
rootSession.close(); rootSession.close();
if (exitCode < 0) { if (exitCode < 0) {
// TODO Log.e(TAG, "Delete failed with exit code " + exitCode);
mCallback.onError(InstallerCallback.OPERATION_DELETE, true, mCallback.onError(InstallerCallback.OPERATION_DELETE,
"Delete failed with exit code " + exitCode); InstallerCallback.ERROR_CODE_OTHER);
} 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
@ -232,7 +231,7 @@ public class RootInstaller extends Installer {
} catch (InterruptedException e) { } catch (InterruptedException e) {
} }
mCallback.onSuccess(InstallerCallback.OPERATION_DELETE, true); mCallback.onSuccess(InstallerCallback.OPERATION_DELETE);
} }
}); });
wait.start(); wait.start();

View File

@ -106,13 +106,14 @@ public class SystemPermissionInstaller extends Installer {
} catch (InterruptedException e) { } catch (InterruptedException e) {
} }
mCallback.onSuccess(InstallerCallback.OPERATION_INSTALL, true); mCallback.onSuccess(InstallerCallback.OPERATION_INSTALL);
} }
}); });
wait.start(); wait.start();
} else { } else {
Log.d(TAG, "Install failed: " + returnCode); Log.e(TAG, "Install failed with returnCode " + returnCode);
mCallback.onError(InstallerCallback.OPERATION_INSTALL, true, "todo"); mCallback.onError(InstallerCallback.OPERATION_INSTALL,
InstallerCallback.ERROR_CODE_OTHER);
} }
} }
} }
@ -136,13 +137,14 @@ public class SystemPermissionInstaller extends Installer {
} catch (InterruptedException e) { } catch (InterruptedException e) {
} }
mCallback.onSuccess(InstallerCallback.OPERATION_DELETE, true); mCallback.onSuccess(InstallerCallback.OPERATION_DELETE);
} }
}); });
wait.start(); wait.start();
} else { } else {
Log.d(TAG, "Delete failed: " + returnCode); Log.e(TAG, "Delete failed with returnCode " + returnCode);
mCallback.onError(InstallerCallback.OPERATION_DELETE, true, "todo"); mCallback.onError(InstallerCallback.OPERATION_DELETE,
InstallerCallback.ERROR_CODE_OTHER);
} }
} }
} }