diff options
author | 2025-03-06 13:25:12 -0800 | |
---|---|---|
committer | 2025-03-06 13:25:12 -0800 | |
commit | b6d83baa452320fa5c2d35afb8bd31785041574e (patch) | |
tree | 98fbaa038938bcd35f1d235efa9bd3f9a0654098 /src/com | |
parent | 800e5f08ccdde397b2ae935e3b176c6b88a46ed6 (diff) | |
parent | 9d5b960f0229d9a0e10bcca4851073bce2ead0eb (diff) |
Merge "Broadcast the progress of Jobs" into main
Diffstat (limited to 'src/com')
-rw-r--r-- | src/com/android/documentsui/services/FileOperationService.java | 76 | ||||
-rw-r--r-- | src/com/android/documentsui/util/FlagUtils.kt | 5 |
2 files changed, 79 insertions, 2 deletions
diff --git a/src/com/android/documentsui/services/FileOperationService.java b/src/com/android/documentsui/services/FileOperationService.java index c7be5f4fc..dcb2c1db4 100644 --- a/src/com/android/documentsui/services/FileOperationService.java +++ b/src/com/android/documentsui/services/FileOperationService.java @@ -17,6 +17,7 @@ package com.android.documentsui.services; import static com.android.documentsui.base.SharedMinimal.DEBUG; +import static com.android.documentsui.util.FlagUtils.isVisualSignalsFlagEnabled; import android.app.Notification; import android.app.NotificationChannel; @@ -126,9 +127,15 @@ public class FileOperationService extends Service implements Job.Listener { // Use a features to determine if notification channel is enabled. @VisibleForTesting Features features; + // Used so tests can force the state of visual signals. + @VisibleForTesting Boolean mVisualSignalsEnabled = isVisualSignalsFlagEnabled(); + @GuardedBy("mJobs") private final Map<String, JobRecord> mJobs = new LinkedHashMap<>(); + // Used to send periodic broadcasts for job progress. + private GlobalJobMonitor mJobMonitor; + // The job whose notification is used to keep the service in foreground mode. @GuardedBy("mJobs") private Job mForegroundJob; @@ -162,6 +169,10 @@ public class FileOperationService extends Service implements Job.Listener { notificationManager = getSystemService(NotificationManager.class); } + if (mVisualSignalsEnabled && mJobMonitor == null) { + mJobMonitor = new GlobalJobMonitor(); + } + UserManager userManager = (UserManager) getSystemService(Context.USER_SERVICE); features = new Features.RuntimeFeatures(getResources(), userManager); setUpNotificationChannel(); @@ -188,6 +199,10 @@ public class FileOperationService extends Service implements Job.Listener { Log.d(TAG, "Shutting down executor."); } + if (mJobMonitor != null) { + mJobMonitor.stop(); + } + List<Runnable> unfinishedCopies = executor.shutdownNow(); List<Runnable> unfinishedDeletions = deletionExecutor.shutdownNow(); List<Runnable> unfinished = @@ -330,6 +345,10 @@ public class FileOperationService extends Service implements Job.Listener { assert(record != null); record.job.cleanup(); + if (mVisualSignalsEnabled && mJobs.isEmpty()) { + mJobMonitor.stop(); + } + // Delay the shutdown until we've cleaned up all notifications. shutdown() is now posted in // onFinished(Job job) to main thread. } @@ -389,8 +408,12 @@ public class FileOperationService extends Service implements Job.Listener { } // Set up related monitor - JobMonitor monitor = new JobMonitor(job); - monitor.start(); + if (mVisualSignalsEnabled) { + mJobMonitor.start(); + } else { + JobMonitor monitor = new JobMonitor(job); + monitor.start(); + } } @Override @@ -399,6 +422,9 @@ public class FileOperationService extends Service implements Job.Listener { if (DEBUG) { Log.d(TAG, "onFinished: " + job.id); } + if (mVisualSignalsEnabled) { + mJobMonitor.sendProgress(); + } synchronized (mJobs) { // Delete the job from mJobs first to avoid this job being selected as the foreground @@ -545,6 +571,52 @@ public class FileOperationService extends Service implements Job.Listener { } } + /** + * A class used to periodically poll the state of every running job. + * + * We need to be sending the progress of every job, so rather than having a single monitor per + * job, have one for the whole service. + */ + private final class GlobalJobMonitor implements Runnable { + private static final long PROGRESS_INTERVAL_MILLIS = 500L; + private boolean mRunning = false; + + private void start() { + if (!mRunning) { + handler.post(this); + } + mRunning = true; + } + + private void stop() { + mRunning = false; + handler.removeCallbacks(this); + } + + private void sendProgress() { + var progress = new ArrayList<JobProgress>(); + synchronized (mJobs) { + for (JobRecord rec : mJobs.values()) { + progress.add(rec.job.getJobProgress()); + } + } + Intent intent = new Intent(); + intent.setPackage(getPackageName()); + intent.setAction("com.android.documentsui.PROGRESS"); + intent.putExtra("id", 0); + intent.putParcelableArrayListExtra("progress", progress); + sendBroadcast(intent); + } + + @Override + public void run() { + sendProgress(); + if (mRunning) { + handler.postDelayed(this, PROGRESS_INTERVAL_MILLIS); + } + } + } + @Override public IBinder onBind(Intent intent) { return null; // Boilerplate. See super#onBind diff --git a/src/com/android/documentsui/util/FlagUtils.kt b/src/com/android/documentsui/util/FlagUtils.kt index 606f071f2..eee51be89 100644 --- a/src/com/android/documentsui/util/FlagUtils.kt +++ b/src/com/android/documentsui/util/FlagUtils.kt @@ -45,6 +45,11 @@ class FlagUtils { } @JvmStatic + fun isVisualSignalsFlagEnabled(): Boolean { + return Flags.visualSignalsRo() && isUseMaterial3FlagEnabled() + } + + @JvmStatic fun isHideRootsOnDesktopFlagEnabled(): Boolean { return Flags.hideRootsOnDesktopRo() } |