From a2c7e291d8eff5d667bf33adb9028e8994dec980 Mon Sep 17 00:00:00 2001 From: Sergey Eremin Date: Sat, 29 Jul 2017 18:09:41 +0300 Subject: [PATCH] "Update all" and "Check for updates" buttons will now be disabled while processing --- .../BackgroundUpdatableAppsTask.java | 89 +++++++++++++++++++ .../yalpstore/GlobalDownloadReceiver.java | 1 + .../yalpstore/GlobalInstallReceiver.java | 4 +- .../yeriomin/yalpstore/InstallerAbstract.java | 1 + .../yalpstore/InstallerBackground.java | 1 + .../yalpstore/UpdatableAppsActivity.java | 40 ++++++++- .../yeriomin/yalpstore/UpdateAllReceiver.java | 33 +++++++ .../yeriomin/yalpstore/UpdateChecker.java | 83 +---------------- .../yalpstore/YalpStoreApplication.java | 31 +++++++ app/src/main/res/values-ru/strings.xml | 1 + app/src/main/res/values/strings.xml | 1 + 11 files changed, 200 insertions(+), 85 deletions(-) create mode 100644 app/src/main/java/com/github/yeriomin/yalpstore/BackgroundUpdatableAppsTask.java create mode 100644 app/src/main/java/com/github/yeriomin/yalpstore/UpdateAllReceiver.java diff --git a/app/src/main/java/com/github/yeriomin/yalpstore/BackgroundUpdatableAppsTask.java b/app/src/main/java/com/github/yeriomin/yalpstore/BackgroundUpdatableAppsTask.java new file mode 100644 index 000000000..4c1f4c78e --- /dev/null +++ b/app/src/main/java/com/github/yeriomin/yalpstore/BackgroundUpdatableAppsTask.java @@ -0,0 +1,89 @@ +package com.github.yeriomin.yalpstore; + +import android.app.Activity; +import android.content.Context; +import android.content.Intent; +import android.util.Log; + +import com.github.yeriomin.yalpstore.model.App; +import com.github.yeriomin.yalpstore.notification.NotificationManagerWrapper; + +import java.util.List; + +class BackgroundUpdatableAppsTask extends UpdatableAppsTask { + + @Override + protected void onPostExecute(Throwable e) { + super.onPostExecute(e); + if (null != e) { + return; + } + int updatesCount = this.updatableApps.size(); + Log.i(this.getClass().getName(), "Found updates for " + updatesCount + " apps"); + if (updatesCount == 0) { + return; + } + if (canUpdate()) { + process(context, updatableApps); + } else { + createNotification(context, updatesCount); + } + } + + private boolean canUpdate() { + return explicitCheck || + (PreferenceActivity.getBoolean(context, PreferenceActivity.PREFERENCE_BACKGROUND_UPDATE_DOWNLOAD) + && (DownloadManagerFactory.get(context) instanceof DownloadManagerAdapter + || !PreferenceActivity.getBoolean(context, PreferenceActivity.PREFERENCE_BACKGROUND_UPDATE_WIFI_ONLY) + || NetworkState.isWifi() + ) + ) + ; + } + + private void process(Context context, List apps) { + boolean canInstallInBackground = PreferenceActivity.canInstallInBackground(context); + YalpStoreApplication application = (YalpStoreApplication) context.getApplicationContext(); + application.clearPendingUpdates(); + for (App app: apps) { + application.addPendingUpdate(app.getPackageName()); + if (!Paths.getApkPath(app.getPackageName(), app.getVersionCode()).exists()) { + download(context, app); + } else if (canInstallInBackground) { + // Not passing context because it might be an activity + // and we want it to run in background + InstallerFactory.get(context.getApplicationContext()).verifyAndInstall(app); + } else { + application.removePendingUpdate(app.getPackageName()); + } + } + } + + private void download(Context context, App app) { + Log.i(getClass().getName(), "Starting download of update for " + app.getPackageName()); + DownloadState state = DownloadState.get(app.getPackageName()); + state.setApp(app); + getPurchaseTask(context, app).execute(); + } + + private PurchaseTask getPurchaseTask(Context context, App app) { + PurchaseTask task = new PurchaseTask(); + task.setApp(app); + task.setContext(context); + task.setTriggeredBy(context instanceof Activity + ? DownloadState.TriggeredBy.UPDATE_ALL_BUTTON + : DownloadState.TriggeredBy.SCHEDULED_UPDATE + ); + return task; + } + + private void createNotification(Context context, int updatesCount) { + Intent i = new Intent(context, UpdatableAppsActivity.class); + i.setAction(Intent.ACTION_VIEW); + new NotificationManagerWrapper(context).show( + i, + context.getString(R.string.notification_updates_available_title), + context.getString(R.string.notification_updates_available_message, updatesCount) + ); + } +} diff --git a/app/src/main/java/com/github/yeriomin/yalpstore/GlobalDownloadReceiver.java b/app/src/main/java/com/github/yeriomin/yalpstore/GlobalDownloadReceiver.java index eb13c0f45..66fc08193 100644 --- a/app/src/main/java/com/github/yeriomin/yalpstore/GlobalDownloadReceiver.java +++ b/app/src/main/java/com/github/yeriomin/yalpstore/GlobalDownloadReceiver.java @@ -79,6 +79,7 @@ public class GlobalDownloadReceiver extends BroadcastReceiver { installer.verifyAndInstall(app); } else { notifyDownloadComplete(app); + ((YalpStoreApplication) context.getApplicationContext()).removePendingUpdate(app.getPackageName()); } } diff --git a/app/src/main/java/com/github/yeriomin/yalpstore/GlobalInstallReceiver.java b/app/src/main/java/com/github/yeriomin/yalpstore/GlobalInstallReceiver.java index 1c536c967..4607f58de 100644 --- a/app/src/main/java/com/github/yeriomin/yalpstore/GlobalInstallReceiver.java +++ b/app/src/main/java/com/github/yeriomin/yalpstore/GlobalInstallReceiver.java @@ -22,8 +22,10 @@ public class GlobalInstallReceiver extends BroadcastReceiver { } updateDetails(intent); UpdatableAppsActivity.setNeedsUpdate(true); + String packageName = intent.getData().getSchemeSpecificPart(); + ((YalpStoreApplication) context.getApplicationContext()).removePendingUpdate(packageName); if (needToRemoveApk(context) && action.equals(Intent.ACTION_PACKAGE_ADDED)) { - App app = getApp(context, intent.getData().getSchemeSpecificPart()); + App app = getApp(context, packageName); File apkPath = Paths.getApkPath(app.getPackageName(), app.getVersionCode()); boolean deleted = apkPath.delete(); Log.i(getClass().getName(), "Removed " + apkPath + " successfully: " + deleted); diff --git a/app/src/main/java/com/github/yeriomin/yalpstore/InstallerAbstract.java b/app/src/main/java/com/github/yeriomin/yalpstore/InstallerAbstract.java index 135c89da3..721704e86 100644 --- a/app/src/main/java/com/github/yeriomin/yalpstore/InstallerAbstract.java +++ b/app/src/main/java/com/github/yeriomin/yalpstore/InstallerAbstract.java @@ -64,6 +64,7 @@ public abstract class InstallerAbstract { Paths.getApkPath(app.getPackageName(), app.getVersionCode()) )) { Log.i(getClass().getName(), "Signature mismatch for " + app.getPackageName()); + ((YalpStoreApplication) context.getApplicationContext()).removePendingUpdate(app.getPackageName()); if (Util.isContextUiCapable(context)) { getSignatureMismatchDialog(app).show(); } else { diff --git a/app/src/main/java/com/github/yeriomin/yalpstore/InstallerBackground.java b/app/src/main/java/com/github/yeriomin/yalpstore/InstallerBackground.java index ae1dd0ddb..2c00b743c 100644 --- a/app/src/main/java/com/github/yeriomin/yalpstore/InstallerBackground.java +++ b/app/src/main/java/com/github/yeriomin/yalpstore/InstallerBackground.java @@ -22,6 +22,7 @@ abstract public class InstallerBackground extends InstallerAbstract { } if (background && !new PermissionsComparator(context).isSame(app)) { Log.i(getClass().getName(), "New permissions for " + app.getPackageName()); + ((YalpStoreApplication) context.getApplicationContext()).removePendingUpdate(app.getPackageName()); notifyNewPermissions(app); return false; } diff --git a/app/src/main/java/com/github/yeriomin/yalpstore/UpdatableAppsActivity.java b/app/src/main/java/com/github/yeriomin/yalpstore/UpdatableAppsActivity.java index 98394bd48..ef84e9e3b 100644 --- a/app/src/main/java/com/github/yeriomin/yalpstore/UpdatableAppsActivity.java +++ b/app/src/main/java/com/github/yeriomin/yalpstore/UpdatableAppsActivity.java @@ -23,6 +23,8 @@ public class UpdatableAppsActivity extends AppListActivity { static private boolean needsUpdate; + private UpdateAllReceiver updateAllReceiver; + static public void setNeedsUpdate(boolean needsUpdate) { UpdatableAppsActivity.needsUpdate = needsUpdate; } @@ -62,6 +64,15 @@ public class UpdatableAppsActivity extends AppListActivity { } }); } + updateAllReceiver = new UpdateAllReceiver(this); + } + + @Override + protected void onPause() { + super.onPause(); + if (null != updateAllReceiver) { + unregisterReceiver(updateAllReceiver); + } } @Override @@ -85,7 +96,7 @@ public class UpdatableAppsActivity extends AppListActivity { if (requestCode == PERMISSIONS_REQUEST_CODE && grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED ) { - new UpdateChecker().onReceive(this, getIntent()); + launchUpdateAll(); } } @@ -117,13 +128,17 @@ public class UpdatableAppsActivity extends AppListActivity { } private void toggleUpdateAll(boolean enable) { - Button button = (Button) findViewById(R.id.update_all); + Button button = findViewById(R.id.update_all); button.setVisibility(enable ? View.VISIBLE : View.GONE); + if (((YalpStoreApplication) getApplication()).isBackgroundUpdating()) { + button.setEnabled(false); + button.setText(R.string.list_updating); + } button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (checkPermission()) { - new UpdateChecker().onReceive(UpdatableAppsActivity.this, getIntent()); + launchUpdateAll(); } else { requestPermission(); } @@ -131,6 +146,14 @@ public class UpdatableAppsActivity extends AppListActivity { }); } + private void launchUpdateAll() { + ((YalpStoreApplication) getApplicationContext()).setBackgroundUpdating(true); + new UpdateChecker().onReceive(UpdatableAppsActivity.this, getIntent()); + Button button = findViewById(R.id.update_all); + button.setEnabled(false); + button.setText(R.string.list_updating); + } + private boolean checkPermission() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { return checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED; @@ -172,6 +195,14 @@ public class UpdatableAppsActivity extends AppListActivity { return result; } + @Override + protected void onPreExecute() { + super.onPreExecute(); + Button button = activity.findViewById(R.id.check_updates); + button.setEnabled(false); + button.setText(R.string.details_download_checking); + } + @Override protected void onPostExecute(Throwable e) { super.onPostExecute(e); @@ -191,6 +222,9 @@ public class UpdatableAppsActivity extends AppListActivity { } activity.toggleUpdateAll(this.updatableApps.size() > 0); new CategoryManager(activity).downloadCategoryNames(); + Button button = activity.findViewById(R.id.check_updates); + button.setEnabled(true); + button.setText(R.string.list_check_updates); } } } diff --git a/app/src/main/java/com/github/yeriomin/yalpstore/UpdateAllReceiver.java b/app/src/main/java/com/github/yeriomin/yalpstore/UpdateAllReceiver.java new file mode 100644 index 000000000..f583c441b --- /dev/null +++ b/app/src/main/java/com/github/yeriomin/yalpstore/UpdateAllReceiver.java @@ -0,0 +1,33 @@ +package com.github.yeriomin.yalpstore; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.widget.Button; +import android.widget.Toast; + +public class UpdateAllReceiver extends BroadcastReceiver { + + static public final String ACTION_UPDATE_COMPLETE = "ACTION_UPDATE_COMPLETE"; + + private Button button; + + public UpdateAllReceiver(UpdatableAppsActivity activity) { + button = activity.findViewById(R.id.update_all); + IntentFilter filter = new IntentFilter(); + filter.addAction(UpdateAllReceiver.ACTION_UPDATE_COMPLETE); + activity.registerReceiver(this, filter); + if (!((YalpStoreApplication) activity.getApplication()).isBackgroundUpdating()) { + onReceive(activity, new Intent()); + } + } + + @Override + public void onReceive(Context context, Intent intent) { + if (null != button) { + button.setEnabled(true); + button.setText(R.string.list_update_all); + } + } +} diff --git a/app/src/main/java/com/github/yeriomin/yalpstore/UpdateChecker.java b/app/src/main/java/com/github/yeriomin/yalpstore/UpdateChecker.java index 6df37406a..b49094579 100644 --- a/app/src/main/java/com/github/yeriomin/yalpstore/UpdateChecker.java +++ b/app/src/main/java/com/github/yeriomin/yalpstore/UpdateChecker.java @@ -8,11 +8,6 @@ import android.content.Context; import android.content.Intent; import android.util.Log; -import com.github.yeriomin.yalpstore.model.App; -import com.github.yeriomin.yalpstore.notification.NotificationManagerWrapper; - -import java.util.List; - public class UpdateChecker extends BroadcastReceiver { static public void enable(Context context, int interval) { @@ -34,83 +29,9 @@ public class UpdateChecker extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { Log.i(getClass().getName(), "Started"); - getTask(context).execute(); - } - - private UpdatableAppsTask getTask(Context context) { - UpdatableAppsTask task = new UpdatableAppsTask() { - @Override - protected void onPostExecute(Throwable e) { - super.onPostExecute(e); - if (null != e) { - return; - } - int updatesCount = this.updatableApps.size(); - Log.i(this.getClass().getName(), "Found updates for " + updatesCount + " apps"); - if (updatesCount == 0) { - return; - } - if (canUpdate()) { - process(context, updatableApps); - } else { - createNotification(context, updatesCount); - } - } - - private boolean canUpdate() { - return explicitCheck || - (PreferenceActivity.getBoolean(context, PreferenceActivity.PREFERENCE_BACKGROUND_UPDATE_DOWNLOAD) - && (DownloadManagerFactory.get(context) instanceof DownloadManagerAdapter - || !PreferenceActivity.getBoolean(context, PreferenceActivity.PREFERENCE_BACKGROUND_UPDATE_WIFI_ONLY) - || NetworkState.isWifi() - ) - ) - ; - } - }; + UpdatableAppsTask task = new BackgroundUpdatableAppsTask(); task.setExplicitCheck(context instanceof Activity); task.setContext(context); - return task; - } - - private void process(Context context, List apps) { - boolean canInstallInBackground = PreferenceActivity.canInstallInBackground(context); - for (App app: apps) { - if (!Paths.getApkPath(app.getPackageName(), app.getVersionCode()).exists()) { - download(context, app); - } else if (canInstallInBackground) { - // Not passing context because it might be an activity - // and we want it to run in background - InstallerFactory.get(context.getApplicationContext()).verifyAndInstall(app); - } - } - } - - private void download(Context context, App app) { - Log.i(getClass().getName(), "Starting download of update for " + app.getPackageName()); - DownloadState state = DownloadState.get(app.getPackageName()); - state.setApp(app); - getPurchaseTask(context, app).execute(); - } - - private PurchaseTask getPurchaseTask(Context context, App app) { - PurchaseTask task = new PurchaseTask(); - task.setApp(app); - task.setContext(context); - task.setTriggeredBy(context instanceof Activity - ? DownloadState.TriggeredBy.UPDATE_ALL_BUTTON - : DownloadState.TriggeredBy.SCHEDULED_UPDATE - ); - return task; - } - - private void createNotification(Context context, int updatesCount) { - Intent i = new Intent(context, UpdatableAppsActivity.class); - i.setAction(Intent.ACTION_VIEW); - new NotificationManagerWrapper(context).show( - i, - context.getString(R.string.notification_updates_available_title), - context.getString(R.string.notification_updates_available_message, updatesCount) - ); + task.execute(); } } diff --git a/app/src/main/java/com/github/yeriomin/yalpstore/YalpStoreApplication.java b/app/src/main/java/com/github/yeriomin/yalpstore/YalpStoreApplication.java index 270dd0da7..2dfe05e25 100644 --- a/app/src/main/java/com/github/yeriomin/yalpstore/YalpStoreApplication.java +++ b/app/src/main/java/com/github/yeriomin/yalpstore/YalpStoreApplication.java @@ -8,9 +8,40 @@ import android.os.Build; import android.os.Handler; import android.os.HandlerThread; import android.preference.PreferenceManager; +import android.util.Log; + +import java.util.ArrayList; +import java.util.List; public class YalpStoreApplication extends Application { + private boolean isBackgroundUpdating = false; + private List pendingUpdates = new ArrayList<>(); + + public boolean isBackgroundUpdating() { + return isBackgroundUpdating; + } + + public void setBackgroundUpdating(boolean backgroundUpdating) { + isBackgroundUpdating = backgroundUpdating; + } + + public void addPendingUpdate(String packageName) { + pendingUpdates.add(packageName); + } + + public void removePendingUpdate(String packageName) { + pendingUpdates.remove(packageName); + if (pendingUpdates.isEmpty()) { + isBackgroundUpdating = false; + sendBroadcast(new Intent(UpdateAllReceiver.ACTION_UPDATE_COMPLETE)); + } + } + + public void clearPendingUpdates() { + pendingUpdates.clear(); + } + @Override public void onCreate() { super.onCreate(); diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index 8aff11646..887b96ff9 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -17,6 +17,7 @@ несовместимо Проверить обновления Обновить всё + Обновляем… есть реклама нет рекламы зависит от GSF diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index f6c067538..e04939285 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -16,6 +16,7 @@ incompatible Check for updates Update all + Updating… has ads no ads depends on GSF