diff --git a/app/build.gradle b/app/build.gradle index b791376..f4726fd 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -338,7 +338,7 @@ dependencies { implementation 'com.jakewharton.timber:timber:5.0.1' // ksp - implementation "com.google.devtools.ksp:symbol-processing-api:1.8.0-1.0.8" + implementation "com.google.devtools.ksp:symbol-processing-api:1.8.0-1.0.9" implementation "androidx.security:security-crypto:1.1.0-alpha04" } @@ -364,7 +364,6 @@ android { } buildFeatures { viewBinding true - compose true } kotlinOptions { diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index cc96551..12021d1 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -20,6 +20,7 @@ + { + // Now, parse the intent + String extras = getIntent().getAction(); + // if extras is null, then we are in a bad state or user launched the activity manually + if (extras == null) { + runOnUiThread(() -> { + // set status text to error + statusTextView.setText(R.string.error_no_extras); + // set progress bar to error + progressIndicator.setIndeterminate(false); + progressIndicator.setProgressCompat(0, false); + }); return; } - File file = new File(path); - if (!file.exists()) { - // set status text to error - statusTextView.setText(R.string.no_file_found); - // set progress bar to error - progressIndicator.setIndeterminate(false); - progressIndicator.setProgressCompat(0, false); + + // get action + ACTIONS action = ACTIONS.valueOf(extras); + // if action is null, then we are in a bad state or user launched the activity manually + if (Objects.isNull(action)) { + runOnUiThread(() -> { + // set status text to error + statusTextView.setText(R.string.error_no_action); + // set progress bar to error + progressIndicator.setIndeterminate(false); + progressIndicator.setProgressCompat(0, false); + }); // return return; } - if (!Objects.equals(file.getParentFile(), getCacheDir())) { - // set status text to error - statusTextView.setText(R.string.no_file_found); - // set progress bar to error - progressIndicator.setIndeterminate(false); - progressIndicator.setProgressCompat(0, false); - // return - return; + + // For check action, we need to check if there is an update using the AppUpdateManager.peekShouldUpdate() + if (action == ACTIONS.CHECK) { + checkForUpdate(); + } else if (action == ACTIONS.DOWNLOAD) { + try { + downloadUpdate(); + } catch ( + JSONException e) { + e.printStackTrace(); + runOnUiThread(() -> { + // set status text to error + statusTextView.setText(R.string.error_download_update); + // set progress bar to error + progressIndicator.setIndeterminate(false); + progressIndicator.setProgressCompat(100, false); + }); + } + } else if (action == ACTIONS.INSTALL) { + // ensure path was passed and points to a file within our cache directory + String path = getIntent().getStringExtra("path"); + if (path == null) { + runOnUiThread(() -> { + // set status text to error + statusTextView.setText(R.string.no_file_found); + // set progress bar to error + progressIndicator.setIndeterminate(false); + progressIndicator.setProgressCompat(0, false); + }); + return; + } + File file = new File(path); + if (!file.exists()) { + runOnUiThread(() -> { + // set status text to error + statusTextView.setText(R.string.no_file_found); + // set progress bar to error + progressIndicator.setIndeterminate(false); + progressIndicator.setProgressCompat(0, false); + }); + // return + return; + } + if (!Objects.equals(file.getParentFile(), getCacheDir())) { + // set status text to error + runOnUiThread(() -> { + statusTextView.setText(R.string.no_file_found); + // set progress bar to error + progressIndicator.setIndeterminate(false); + progressIndicator.setProgressCompat(0, false); + }); + // return + return; + } + // set status text to installing + statusTextView.setText(R.string.installing_update); + // set progress bar to indeterminate + progressIndicator.setIndeterminate(true); + // install update + installUpdate(file); } - // set status text to installing - statusTextView.setText(R.string.installing_update); - // set progress bar to indeterminate - progressIndicator.setIndeterminate(true); - // install update - installUpdate(file); - } + + }).start(); } public void checkForUpdate() { @@ -163,7 +182,11 @@ public class UpdateActivity extends AppCompatActivity { lastestJSON = Http.doHttpGet(AppUpdateManager.RELEASES_API_URL, false); } catch ( Exception e) { - e.printStackTrace(); + // when logging, REMOVE the json from the log + String msg = e.getMessage(); + // remove everything from the first { to the last } + msg = Objects.requireNonNull(msg).substring(0, msg.indexOf("{")) + msg.substring(msg.lastIndexOf("}") + 1); + Timber.e(msg); progressIndicator.setIndeterminate(false); progressIndicator.setProgressCompat(100, false); statusTextView.setText(R.string.error_download_update); @@ -174,11 +197,14 @@ public class UpdateActivity extends AppCompatActivity { JSONArray assets = latestJSON.getJSONArray("assets"); // get the asset we want JSONObject asset = null; - for (int i = 0; i < assets.length(); i++) { - JSONObject asset1 = assets.getJSONObject(i); - if (asset1.getString("name").contains(Build.SUPPORTED_ABIS[0])) { - asset = asset1; - break; + // iterate through assets until we find the one that contains Build.SUPPORTED_ABIS[0] + while (Objects.isNull(asset)) { + for (int i = 0; i < assets.length(); i++) { + JSONObject asset1 = assets.getJSONObject(i); + if (asset1.getString("name").contains(Build.SUPPORTED_ABIS[0])) { + asset = asset1; + break; + } } } // if asset is null, then we are in a bad state @@ -195,52 +221,62 @@ public class UpdateActivity extends AppCompatActivity { String downloadUrl = Objects.requireNonNull(asset).getString("browser_download_url"); // get the download size long downloadSize = asset.getLong("size"); - // set status text to downloading update - statusTextView.setText(getString(R.string.downloading_update, 0)); - // set progress bar to 0 - progressIndicator.setIndeterminate(false); - progressIndicator.setProgressCompat(0, false); + runOnUiThread(() -> { + // set status text to downloading update + statusTextView.setText(getString(R.string.downloading_update, 0)); + // set progress bar to 0 + progressIndicator.setIndeterminate(false); + progressIndicator.setProgressCompat(0, false); + }); // download the update byte[] update = new byte[0]; try { - update = Http.doHttpGet(downloadUrl, (downloaded, total, done) -> { + update = Http.doHttpGet(downloadUrl, (downloaded, total, done) -> runOnUiThread(() -> { // update progress bar progressIndicator.setProgressCompat((int) (((float) downloaded / (float) total) * 100), true); // update status text statusTextView.setText(getString(R.string.downloading_update, (int) (((float) downloaded / (float) total) * 100))); - }); + })); } catch ( Exception e) { e.printStackTrace(); - progressIndicator.setIndeterminate(false); - progressIndicator.setProgressCompat(100, false); - statusTextView.setText(R.string.error_download_update); + runOnUiThread(() -> { + progressIndicator.setIndeterminate(false); + progressIndicator.setProgressCompat(100, false); + statusTextView.setText(R.string.error_download_update); + }); } // if update is null, then we are in a bad state if (Objects.isNull(update)) { - // set status text to error - statusTextView.setText(R.string.error_download_update); - // set progress bar to error - progressIndicator.setIndeterminate(false); - progressIndicator.setProgressCompat(100, false); + runOnUiThread(() -> { + // set status text to error + statusTextView.setText(R.string.error_download_update); + // set progress bar to error + progressIndicator.setIndeterminate(false); + progressIndicator.setProgressCompat(100, false); + }); // return return; } // if update is not the same size as the download size, then we are in a bad state if (update.length != downloadSize) { - // set status text to error - statusTextView.setText(R.string.error_download_update); - // set progress bar to error - progressIndicator.setIndeterminate(false); - progressIndicator.setProgressCompat(100, false); + runOnUiThread(() -> { + // set status text to error + statusTextView.setText(R.string.error_download_update); + // set progress bar to error + progressIndicator.setIndeterminate(false); + progressIndicator.setProgressCompat(100, false); + }); // return return; } // set status text to installing update - statusTextView.setText(R.string.installing_update); - // set progress bar to 100 - progressIndicator.setIndeterminate(true); - progressIndicator.setProgressCompat(100, false); + runOnUiThread(() -> { + statusTextView.setText(R.string.installing_update); + // set progress bar to 100 + progressIndicator.setIndeterminate(true); + progressIndicator.setProgressCompat(100, false); + }); // save the update to the cache File updateFile = null; try { @@ -251,9 +287,11 @@ public class UpdateActivity extends AppCompatActivity { } catch ( IOException e) { e.printStackTrace(); - progressIndicator.setIndeterminate(false); - progressIndicator.setProgressCompat(100, false); - statusTextView.setText(R.string.error_download_update); + runOnUiThread(() -> { + progressIndicator.setIndeterminate(false); + progressIndicator.setProgressCompat(100, false); + statusTextView.setText(R.string.error_download_update); + }); } // install the update installUpdate(updateFile); @@ -261,19 +299,25 @@ public class UpdateActivity extends AppCompatActivity { return; } + @SuppressLint("RestrictedApi") private void installUpdate(File updateFile) { // get status text view - MaterialTextView statusTextView = findViewById(R.id.update_progress_text); - // set status text to installing update - statusTextView.setText(R.string.installing_update); - // set progress bar to 100 - LinearProgressIndicator progressIndicator = findViewById(R.id.update_progress); - progressIndicator.setIndeterminate(true); - progressIndicator.setProgressCompat(100, false); - // install the update - Intent intent = new Intent(Intent.ACTION_VIEW); - intent.setDataAndType(Uri.fromFile(updateFile), "application/vnd.android.package-archive"); - intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + runOnUiThread(() -> { + MaterialTextView statusTextView = findViewById(R.id.update_progress_text); + // set status text to installing update + statusTextView.setText(R.string.installing_update); + // set progress bar to 100 + LinearProgressIndicator progressIndicator = findViewById(R.id.update_progress); + progressIndicator.setIndeterminate(true); + progressIndicator.setProgressCompat(100, false); + }); + // request install permissions + Intent intent = new Intent(Intent.ACTION_INSTALL_PACKAGE); + Context context = getApplicationContext(); + Uri uri = FileProvider.getUriForFile(context, context.getPackageName() + ".file-provider", updateFile); + intent.setData(uri); + intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); startActivity(intent); // return return; diff --git a/app/src/main/java/com/fox2code/mmm/background/BackgroundUpdateChecker.java b/app/src/main/java/com/fox2code/mmm/background/BackgroundUpdateChecker.java index a7821ef..94ab973 100644 --- a/app/src/main/java/com/fox2code/mmm/background/BackgroundUpdateChecker.java +++ b/app/src/main/java/com/fox2code/mmm/background/BackgroundUpdateChecker.java @@ -53,8 +53,11 @@ public class BackgroundUpdateChecker extends Worker { if ("twrp-keep".equals(localModuleInfo.id)) continue; // exclude all modules with id's stored in the pref pref_background_update_check_excludes - if (MainApplication.getSharedPreferences().getStringSet("pref_background_update_check_excludes", null).contains(localModuleInfo.id)) - continue; + try { + if (MainApplication.getSharedPreferences().getStringSet("pref_background_update_check_excludes", null).contains(localModuleInfo.id)) + continue; + } catch (Exception ignored) { + } RepoModule repoModule = repoModules.get(localModuleInfo.id); localModuleInfo.checkModuleUpdate(); if (localModuleInfo.updateVersionCode > localModuleInfo.versionCode && !PropUtils.isNullString(localModuleInfo.updateVersion)) { diff --git a/app/src/main/java/com/fox2code/mmm/settings/SettingsActivity.java b/app/src/main/java/com/fox2code/mmm/settings/SettingsActivity.java index 548b642..ed675ad 100644 --- a/app/src/main/java/com/fox2code/mmm/settings/SettingsActivity.java +++ b/app/src/main/java/com/fox2code/mmm/settings/SettingsActivity.java @@ -504,6 +504,16 @@ public class SettingsActivity extends FoxActivity implements LanguageActivity { Toast.makeText(requireContext(), toastText, Toast.LENGTH_SHORT).show(); return true; }); + // for pref_background_update_check_debug_download, do the same as pref_update except with DOWNLOAD action + Preference debugDownload = findPreference("pref_background_update_check_debug_download"); + debugDownload.setVisible(MainApplication.isDeveloper() && MainApplication.isBackgroundUpdateCheckEnabled() && !MainApplication.isWrapped()); + debugDownload.setOnPreferenceClickListener(p -> { + devModeStep = 0; + Intent intent = new Intent(requireContext(), UpdateActivity.class); + intent.setAction(UpdateActivity.ACTIONS.DOWNLOAD.name()); + startActivity(intent); + return true; + }); if (BuildConfig.DEBUG || BuildConfig.ENABLE_AUTO_UPDATER) { linkClickable = findPreference("pref_report_bug"); linkClickable.setOnPreferenceClickListener(p -> { diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 25c3b4f..9d0030f 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -298,7 +298,7 @@ Could not save logs Share FoxMMM logs This app is an unofficial FoxMMM build. - Uh-oh, we hit a snag!= + Uh-oh, we hit a snag! Give us more details about what you were doing when this happened. The more, the merrier! Submit and restart Please help us out by telling us what you were trying to do when this happened. @@ -330,7 +330,8 @@ In-app Updater Update app An update may be available for FoxMMM. Please wait while we download and install it. - Please wait...ERROR: Invalid data received + Please wait... + ERROR: Invalid data received on launch You appear to be running a debug build. Debug builds must be updated manually, and do not support in-app updates ERROR: Invalid action specified. Refusing to continue.Update found Checking for updates… @@ -338,5 +339,6 @@ Download update An error occurred downloading the update information. ERROR: Failed to parse update information - Downloading update… %1$d\%Installing update…ERROR: Could not find update package.Check for app updates + Downloading update… %1$d%% + Installing update…ERROR: Could not find update package.Check for app updatesTest update download mechanism diff --git a/app/src/main/res/xml/root_preferences.xml b/app/src/main/res/xml/root_preferences.xml index 175daf9..d9ac262 100644 --- a/app/src/main/res/xml/root_preferences.xml +++ b/app/src/main/res/xml/root_preferences.xml @@ -57,6 +57,12 @@ app:icon="@drawable/baseline_notification_important_24" app:title="@string/notification_update_debug_pref" /> + +