Merge branch '2633-hidden-apps-launch' into 'master'

Fix assorted ACRA crashes

Closes acra-crash-reports#547, acra-crash-reports#549, acra-crash-reports#574, #2632, #2631, and #2633

See merge request fdroid/fdroidclient!1242
This commit is contained in:
Torsten Grote
2023-06-14 18:23:02 +00:00
10 changed files with 50 additions and 11 deletions

View File

@@ -2,6 +2,7 @@ package org.fdroid.fdroid.nearby;
import static org.fdroid.fdroid.views.main.MainActivity.ACTION_REQUEST_SWAP;
import android.Manifest;
import android.bluetooth.BluetoothAdapter;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
@@ -9,6 +10,7 @@ import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.content.pm.PackageManager;
import android.graphics.LightingColorFilter;
import android.net.Uri;
import android.net.wifi.WifiManager;
@@ -33,6 +35,8 @@ import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.annotation.LayoutRes;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
@@ -133,6 +137,11 @@ public class SwapWorkflowActivity extends AppCompatActivity {
private final CompositeDisposable compositeDisposable = new CompositeDisposable();
private final ActivityResultLauncher<String> requestPermissionLauncher =
registerForActivityResult(new ActivityResultContracts.RequestPermission(), isGranted -> {
if (isGranted) sendFDroidBluetooth();
});
public static void requestSwap(Context context, String repo) {
requestSwap(context, Uri.parse(repo));
}
@@ -671,10 +680,14 @@ public class SwapWorkflowActivity extends AppCompatActivity {
public void sendFDroidBluetooth() {
if (bluetoothAdapter.isEnabled()) {
sendFDroidApk();
} else {
Intent discoverBt = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
discoverBt.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 120);
startActivityForResult(discoverBt, REQUEST_BLUETOOTH_ENABLE_FOR_SEND);
} else if (Build.VERSION.SDK_INT >= 31) {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.BLUETOOTH_CONNECT) == PackageManager.PERMISSION_GRANTED) {
Intent discoverBt = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
discoverBt.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 120);
startActivityForResult(discoverBt, REQUEST_BLUETOOTH_ENABLE_FOR_SEND);
} else {
requestPermissionLauncher.launch(Manifest.permission.BLUETOOTH_CONNECT);
}
}
}

View File

@@ -396,11 +396,14 @@ public final class AppUpdateStatusManager {
synchronized (appMapping) {
isBatchUpdating = true;
try {
int num = 0;
for (UpdatableApp app : canUpdate) {
Repository repo = FDroidApp.getRepoManager(context).getRepository(app.getUpdate().getRepoId());
if (repo == null) continue; // if repo is gone, it was just deleted, so skip app
addApk(new App(app), new Apk(app.getUpdate(), repo), Status.UpdateAvailable, null);
num++;
}
setNumUpdatableApps(canUpdate.size());
setNumUpdatableApps(num);
} finally {
isBatchUpdating = false;
}

View File

@@ -535,6 +535,7 @@ public class UpdateService extends JobIntentService {
return Single.fromCallable(() -> updateChecker.getUpdatableApps(releaseChannels))
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.doOnError(throwable -> Log.e(TAG, "Error auto-downloading updates: ", throwable))
.subscribe(updatableApps -> downloadUpdates(context, updatableApps));
}

View File

@@ -145,7 +145,12 @@ public abstract class Installer {
}
PackageManager pm = context.getPackageManager();
String installerPackageName = pm.getInstallerPackageName(apk.packageName);
String installerPackageName = null;
try {
installerPackageName = pm.getInstallerPackageName(apk.packageName);
} catch (IllegalArgumentException e) {
Log.e(TAG, "App not installed: " + apk.packageName, e);
}
if (Build.VERSION.SDK_INT >= 24 &&
("com.android.packageinstaller".equals(installerPackageName)
|| "com.google.android.packageinstaller".equals(installerPackageName))) {

View File

@@ -116,7 +116,11 @@ public class AppSecurityPermissions {
Drawable loadGroupIcon(Context context, PackageManager pm) {
Drawable iconDrawable;
if (icon != 0) {
iconDrawable = loadUnbadgedIcon(pm);
try {
iconDrawable = loadUnbadgedIcon(pm);
} catch (NullPointerException e) { // NOPMD
iconDrawable = ContextCompat.getDrawable(context, R.drawable.ic_perm_device_info);
}
} else {
iconDrawable = ContextCompat.getDrawable(context, R.drawable.ic_perm_device_info);
}

View File

@@ -23,6 +23,7 @@ import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.util.Log;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
@@ -59,7 +60,10 @@ public class UninstallDialogActivity extends FragmentActivity {
appInfo = pm.getApplicationInfo(apk.packageName,
PackageManager.GET_UNINSTALLED_PACKAGES);
} catch (PackageManager.NameNotFoundException e) {
throw new RuntimeException("Failed to get ApplicationInfo for uninstalling");
Log.e("UninstallDialogActivity", "Package to uninstall not found: " + apk.packageName, e);
// if it is not installed anymore, no work for us left to do.
finish();
return;
}
final boolean isSystem = (appInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0;

View File

@@ -359,6 +359,7 @@ public class AppDetailsActivity extends AppCompatActivity
break;
case REQUEST_PERMISSION_DIALOG:
if (resultCode == AppCompatActivity.RESULT_OK) {
App app = data.getParcelableExtra(Installer.EXTRA_APP);
Apk apk = data.getParcelableExtra(Installer.EXTRA_APK);
InstallManagerService.queue(this, app, apk);
}

View File

@@ -155,9 +155,9 @@ public class AppListActivity extends AppCompatActivity implements CategoryTextWa
hiddenAppNotice = findViewById(R.id.hiddenAppNotice);
hiddenAppNotice.setOnClickListener(v -> {
Intent intent = new Intent(getApplicationContext(), MainActivity.class);
Intent intent = new Intent(this, MainActivity.class);
intent.putExtra(MainActivity.EXTRA_VIEW_SETTINGS, true);
getApplicationContext().startActivity(intent);
startActivity(intent);
});
emptyState = findViewById(R.id.empty_state);

View File

@@ -18,6 +18,7 @@ import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
@@ -496,7 +497,13 @@ public abstract class AppListItemController extends RecyclerView.ViewHolder {
if (currentStatus != null && currentStatus.status == AppUpdateStatusManager.Status.Installed) {
Intent intent = activity.getPackageManager().getLaunchIntentForPackage(app.packageName);
if (intent != null) {
activity.startActivity(intent);
try {
activity.startActivity(intent);
} catch (SecurityException e) {
Log.e(TAG, "Error starting app launch intent: ", e);
// apps that don't export their launch activity cause this
Toast.makeText(activity, R.string.app_error_open, Toast.LENGTH_SHORT).show();
}
// Once it is explicitly launched by the user, then we can pretty much forget about
// any sort of notification that the app was successfully installed. It should be

View File

@@ -128,6 +128,7 @@ This often occurs with apps installed via Google Play or other sources, if they
<string name="app_permission_storage">F-Droid needs the storage permission to install this to storage. Please allow it on the next screen to proceed with installation.</string>
<string name="app_repository">Repository: %1$s</string>
<string name="app_size">Size: %1$s</string>
<string name="app_error_open">Could not launch app.</string>
<string name="app_list_results_hidden_antifeature_settings">Some results were hidden based on your antifeature settings.</string>
<string name="app_list__name__downloading_in_progress">Downloading %1$s</string>