1bd91e2f3f6aca512a02be645b2515b5e3331e177Jeff Sharkey/* 2bd91e2f3f6aca512a02be645b2515b5e3331e177Jeff Sharkey * Copyright (C) 2016 The Android Open Source Project 3bd91e2f3f6aca512a02be645b2515b5e3331e177Jeff Sharkey * 4bd91e2f3f6aca512a02be645b2515b5e3331e177Jeff Sharkey * Licensed under the Apache License, Version 2.0 (the "License"); 5bd91e2f3f6aca512a02be645b2515b5e3331e177Jeff Sharkey * you may not use this file except in compliance with the License. 6bd91e2f3f6aca512a02be645b2515b5e3331e177Jeff Sharkey * You may obtain a copy of the License at 7bd91e2f3f6aca512a02be645b2515b5e3331e177Jeff Sharkey * 8bd91e2f3f6aca512a02be645b2515b5e3331e177Jeff Sharkey * http://www.apache.org/licenses/LICENSE-2.0 9bd91e2f3f6aca512a02be645b2515b5e3331e177Jeff Sharkey * 10bd91e2f3f6aca512a02be645b2515b5e3331e177Jeff Sharkey * Unless required by applicable law or agreed to in writing, software 11bd91e2f3f6aca512a02be645b2515b5e3331e177Jeff Sharkey * distributed under the License is distributed on an "AS IS" BASIS, 12bd91e2f3f6aca512a02be645b2515b5e3331e177Jeff Sharkey * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13bd91e2f3f6aca512a02be645b2515b5e3331e177Jeff Sharkey * See the License for the specific language governing permissions and 14bd91e2f3f6aca512a02be645b2515b5e3331e177Jeff Sharkey * limitations under the License. 15bd91e2f3f6aca512a02be645b2515b5e3331e177Jeff Sharkey */ 16bd91e2f3f6aca512a02be645b2515b5e3331e177Jeff Sharkey 17bd91e2f3f6aca512a02be645b2515b5e3331e177Jeff Sharkeypackage com.android.internal.util; 18bd91e2f3f6aca512a02be645b2515b5e3331e177Jeff Sharkey 19bd91e2f3f6aca512a02be645b2515b5e3331e177Jeff Sharkeyimport android.annotation.Nullable; 20bd91e2f3f6aca512a02be645b2515b5e3331e177Jeff Sharkeyimport android.content.Intent; 21bd91e2f3f6aca512a02be645b2515b5e3331e177Jeff Sharkeyimport android.os.Bundle; 22bd91e2f3f6aca512a02be645b2515b5e3331e177Jeff Sharkeyimport android.os.IProgressListener; 2384a4c971c484f05f2a2494d6353f36f4d954a5e0Jeff Sharkeyimport android.os.RemoteCallbackList; 24bd91e2f3f6aca512a02be645b2515b5e3331e177Jeff Sharkeyimport android.os.RemoteException; 25bd91e2f3f6aca512a02be645b2515b5e3331e177Jeff Sharkeyimport android.util.MathUtils; 26bd91e2f3f6aca512a02be645b2515b5e3331e177Jeff Sharkey 2784a4c971c484f05f2a2494d6353f36f4d954a5e0Jeff Sharkeyimport com.android.internal.annotations.GuardedBy; 2884a4c971c484f05f2a2494d6353f36f4d954a5e0Jeff Sharkey 29bd91e2f3f6aca512a02be645b2515b5e3331e177Jeff Sharkey/** 30bd91e2f3f6aca512a02be645b2515b5e3331e177Jeff Sharkey * Tracks and reports progress of a single task to a {@link IProgressListener}. 31bd91e2f3f6aca512a02be645b2515b5e3331e177Jeff Sharkey * The reported progress of a task ranges from 0-100, but the task can be 32bd91e2f3f6aca512a02be645b2515b5e3331e177Jeff Sharkey * segmented into smaller pieces using {@link #startSegment(int)} and 33bd91e2f3f6aca512a02be645b2515b5e3331e177Jeff Sharkey * {@link #endSegment(int[])}, and segments can be nested. 34bd91e2f3f6aca512a02be645b2515b5e3331e177Jeff Sharkey * <p> 35bd91e2f3f6aca512a02be645b2515b5e3331e177Jeff Sharkey * Here's an example in action; when finished the overall task progress will be 36bd91e2f3f6aca512a02be645b2515b5e3331e177Jeff Sharkey * at 60. 37bd91e2f3f6aca512a02be645b2515b5e3331e177Jeff Sharkey * 38bd91e2f3f6aca512a02be645b2515b5e3331e177Jeff Sharkey * <pre> 39bd91e2f3f6aca512a02be645b2515b5e3331e177Jeff Sharkey * prog.setProgress(20); 40bd91e2f3f6aca512a02be645b2515b5e3331e177Jeff Sharkey * { 41bd91e2f3f6aca512a02be645b2515b5e3331e177Jeff Sharkey * final int restore = prog.startSegment(40); 42bd91e2f3f6aca512a02be645b2515b5e3331e177Jeff Sharkey * for (int i = 0; i < N; i++) { 43bd91e2f3f6aca512a02be645b2515b5e3331e177Jeff Sharkey * prog.setProgress(i, N); 44bd91e2f3f6aca512a02be645b2515b5e3331e177Jeff Sharkey * ... 45bd91e2f3f6aca512a02be645b2515b5e3331e177Jeff Sharkey * } 46bd91e2f3f6aca512a02be645b2515b5e3331e177Jeff Sharkey * prog.endSegment(restore); 47bd91e2f3f6aca512a02be645b2515b5e3331e177Jeff Sharkey * } 48bd91e2f3f6aca512a02be645b2515b5e3331e177Jeff Sharkey * </pre> 49bd91e2f3f6aca512a02be645b2515b5e3331e177Jeff Sharkey * 50bd91e2f3f6aca512a02be645b2515b5e3331e177Jeff Sharkey * @hide 51bd91e2f3f6aca512a02be645b2515b5e3331e177Jeff Sharkey */ 52bd91e2f3f6aca512a02be645b2515b5e3331e177Jeff Sharkeypublic class ProgressReporter { 5384a4c971c484f05f2a2494d6353f36f4d954a5e0Jeff Sharkey private static final int STATE_INIT = 0; 5484a4c971c484f05f2a2494d6353f36f4d954a5e0Jeff Sharkey private static final int STATE_STARTED = 1; 5584a4c971c484f05f2a2494d6353f36f4d954a5e0Jeff Sharkey private static final int STATE_FINISHED = 2; 56bd91e2f3f6aca512a02be645b2515b5e3331e177Jeff Sharkey 57bd91e2f3f6aca512a02be645b2515b5e3331e177Jeff Sharkey private final int mId; 58bd91e2f3f6aca512a02be645b2515b5e3331e177Jeff Sharkey 5984a4c971c484f05f2a2494d6353f36f4d954a5e0Jeff Sharkey @GuardedBy("this") 6084a4c971c484f05f2a2494d6353f36f4d954a5e0Jeff Sharkey private final RemoteCallbackList<IProgressListener> mListeners = new RemoteCallbackList<>(); 61bd91e2f3f6aca512a02be645b2515b5e3331e177Jeff Sharkey 6284a4c971c484f05f2a2494d6353f36f4d954a5e0Jeff Sharkey @GuardedBy("this") 6384a4c971c484f05f2a2494d6353f36f4d954a5e0Jeff Sharkey private int mState = STATE_INIT; 6484a4c971c484f05f2a2494d6353f36f4d954a5e0Jeff Sharkey @GuardedBy("this") 65bd91e2f3f6aca512a02be645b2515b5e3331e177Jeff Sharkey private int mProgress = 0; 6684a4c971c484f05f2a2494d6353f36f4d954a5e0Jeff Sharkey @GuardedBy("this") 6784a4c971c484f05f2a2494d6353f36f4d954a5e0Jeff Sharkey private Bundle mExtras = new Bundle(); 68bd91e2f3f6aca512a02be645b2515b5e3331e177Jeff Sharkey 69bd91e2f3f6aca512a02be645b2515b5e3331e177Jeff Sharkey /** 70bd91e2f3f6aca512a02be645b2515b5e3331e177Jeff Sharkey * Current segment range: first element is starting progress of this 71bd91e2f3f6aca512a02be645b2515b5e3331e177Jeff Sharkey * segment, second element is length of segment. 72bd91e2f3f6aca512a02be645b2515b5e3331e177Jeff Sharkey */ 7384a4c971c484f05f2a2494d6353f36f4d954a5e0Jeff Sharkey @GuardedBy("this") 74bd91e2f3f6aca512a02be645b2515b5e3331e177Jeff Sharkey private int[] mSegmentRange = new int[] { 0, 100 }; 75bd91e2f3f6aca512a02be645b2515b5e3331e177Jeff Sharkey 76bd91e2f3f6aca512a02be645b2515b5e3331e177Jeff Sharkey /** 77bd91e2f3f6aca512a02be645b2515b5e3331e177Jeff Sharkey * Create a new task with the given identifier whose progress will be 78bd91e2f3f6aca512a02be645b2515b5e3331e177Jeff Sharkey * reported to the given listener. 79bd91e2f3f6aca512a02be645b2515b5e3331e177Jeff Sharkey */ 8084a4c971c484f05f2a2494d6353f36f4d954a5e0Jeff Sharkey public ProgressReporter(int id) { 81bd91e2f3f6aca512a02be645b2515b5e3331e177Jeff Sharkey mId = id; 8284a4c971c484f05f2a2494d6353f36f4d954a5e0Jeff Sharkey } 8384a4c971c484f05f2a2494d6353f36f4d954a5e0Jeff Sharkey 8484a4c971c484f05f2a2494d6353f36f4d954a5e0Jeff Sharkey /** 8584a4c971c484f05f2a2494d6353f36f4d954a5e0Jeff Sharkey * Add given listener to watch for progress events. The current state will 8684a4c971c484f05f2a2494d6353f36f4d954a5e0Jeff Sharkey * be immediately dispatched to the given listener. 8784a4c971c484f05f2a2494d6353f36f4d954a5e0Jeff Sharkey */ 8884a4c971c484f05f2a2494d6353f36f4d954a5e0Jeff Sharkey public void addListener(@Nullable IProgressListener listener) { 8984a4c971c484f05f2a2494d6353f36f4d954a5e0Jeff Sharkey if (listener == null) return; 9084a4c971c484f05f2a2494d6353f36f4d954a5e0Jeff Sharkey synchronized (this) { 9184a4c971c484f05f2a2494d6353f36f4d954a5e0Jeff Sharkey mListeners.register(listener); 9284a4c971c484f05f2a2494d6353f36f4d954a5e0Jeff Sharkey switch (mState) { 9384a4c971c484f05f2a2494d6353f36f4d954a5e0Jeff Sharkey case STATE_INIT: 9484a4c971c484f05f2a2494d6353f36f4d954a5e0Jeff Sharkey // Nothing has happened yet 9584a4c971c484f05f2a2494d6353f36f4d954a5e0Jeff Sharkey break; 9684a4c971c484f05f2a2494d6353f36f4d954a5e0Jeff Sharkey case STATE_STARTED: 9784a4c971c484f05f2a2494d6353f36f4d954a5e0Jeff Sharkey try { 9884a4c971c484f05f2a2494d6353f36f4d954a5e0Jeff Sharkey listener.onStarted(mId, null); 9984a4c971c484f05f2a2494d6353f36f4d954a5e0Jeff Sharkey listener.onProgress(mId, mProgress, mExtras); 10084a4c971c484f05f2a2494d6353f36f4d954a5e0Jeff Sharkey } catch (RemoteException ignored) { 10184a4c971c484f05f2a2494d6353f36f4d954a5e0Jeff Sharkey } 10284a4c971c484f05f2a2494d6353f36f4d954a5e0Jeff Sharkey break; 10384a4c971c484f05f2a2494d6353f36f4d954a5e0Jeff Sharkey case STATE_FINISHED: 10484a4c971c484f05f2a2494d6353f36f4d954a5e0Jeff Sharkey try { 10584a4c971c484f05f2a2494d6353f36f4d954a5e0Jeff Sharkey listener.onFinished(mId, null); 10684a4c971c484f05f2a2494d6353f36f4d954a5e0Jeff Sharkey } catch (RemoteException ignored) { 10784a4c971c484f05f2a2494d6353f36f4d954a5e0Jeff Sharkey } 10884a4c971c484f05f2a2494d6353f36f4d954a5e0Jeff Sharkey break; 10984a4c971c484f05f2a2494d6353f36f4d954a5e0Jeff Sharkey } 11084a4c971c484f05f2a2494d6353f36f4d954a5e0Jeff Sharkey } 111bd91e2f3f6aca512a02be645b2515b5e3331e177Jeff Sharkey } 112bd91e2f3f6aca512a02be645b2515b5e3331e177Jeff Sharkey 113bd91e2f3f6aca512a02be645b2515b5e3331e177Jeff Sharkey /** 114bd91e2f3f6aca512a02be645b2515b5e3331e177Jeff Sharkey * Set the progress of the currently active segment. 115bd91e2f3f6aca512a02be645b2515b5e3331e177Jeff Sharkey * 116bd91e2f3f6aca512a02be645b2515b5e3331e177Jeff Sharkey * @param progress Segment progress between 0-100. 117bd91e2f3f6aca512a02be645b2515b5e3331e177Jeff Sharkey */ 118bd91e2f3f6aca512a02be645b2515b5e3331e177Jeff Sharkey public void setProgress(int progress) { 119bd91e2f3f6aca512a02be645b2515b5e3331e177Jeff Sharkey setProgress(progress, 100, null); 120bd91e2f3f6aca512a02be645b2515b5e3331e177Jeff Sharkey } 121bd91e2f3f6aca512a02be645b2515b5e3331e177Jeff Sharkey 122bd91e2f3f6aca512a02be645b2515b5e3331e177Jeff Sharkey /** 123bd91e2f3f6aca512a02be645b2515b5e3331e177Jeff Sharkey * Set the progress of the currently active segment. 124bd91e2f3f6aca512a02be645b2515b5e3331e177Jeff Sharkey * 125bd91e2f3f6aca512a02be645b2515b5e3331e177Jeff Sharkey * @param progress Segment progress between 0-100. 126bd91e2f3f6aca512a02be645b2515b5e3331e177Jeff Sharkey */ 127bd91e2f3f6aca512a02be645b2515b5e3331e177Jeff Sharkey public void setProgress(int progress, @Nullable CharSequence title) { 128bd91e2f3f6aca512a02be645b2515b5e3331e177Jeff Sharkey setProgress(progress, 100, title); 129bd91e2f3f6aca512a02be645b2515b5e3331e177Jeff Sharkey } 130bd91e2f3f6aca512a02be645b2515b5e3331e177Jeff Sharkey 131bd91e2f3f6aca512a02be645b2515b5e3331e177Jeff Sharkey /** 132bd91e2f3f6aca512a02be645b2515b5e3331e177Jeff Sharkey * Set the fractional progress of the currently active segment. 133bd91e2f3f6aca512a02be645b2515b5e3331e177Jeff Sharkey */ 134bd91e2f3f6aca512a02be645b2515b5e3331e177Jeff Sharkey public void setProgress(int n, int m) { 135bd91e2f3f6aca512a02be645b2515b5e3331e177Jeff Sharkey setProgress(n, m, null); 136bd91e2f3f6aca512a02be645b2515b5e3331e177Jeff Sharkey } 137bd91e2f3f6aca512a02be645b2515b5e3331e177Jeff Sharkey 138bd91e2f3f6aca512a02be645b2515b5e3331e177Jeff Sharkey /** 139bd91e2f3f6aca512a02be645b2515b5e3331e177Jeff Sharkey * Set the fractional progress of the currently active segment. 140bd91e2f3f6aca512a02be645b2515b5e3331e177Jeff Sharkey */ 141bd91e2f3f6aca512a02be645b2515b5e3331e177Jeff Sharkey public void setProgress(int n, int m, @Nullable CharSequence title) { 14284a4c971c484f05f2a2494d6353f36f4d954a5e0Jeff Sharkey synchronized (this) { 14384a4c971c484f05f2a2494d6353f36f4d954a5e0Jeff Sharkey if (mState != STATE_STARTED) { 14484a4c971c484f05f2a2494d6353f36f4d954a5e0Jeff Sharkey throw new IllegalStateException("Must be started to change progress"); 14584a4c971c484f05f2a2494d6353f36f4d954a5e0Jeff Sharkey } 14684a4c971c484f05f2a2494d6353f36f4d954a5e0Jeff Sharkey mProgress = mSegmentRange[0] 14784a4c971c484f05f2a2494d6353f36f4d954a5e0Jeff Sharkey + MathUtils.constrain((n * mSegmentRange[1]) / m, 0, mSegmentRange[1]); 14884a4c971c484f05f2a2494d6353f36f4d954a5e0Jeff Sharkey if (title != null) { 14984a4c971c484f05f2a2494d6353f36f4d954a5e0Jeff Sharkey mExtras.putCharSequence(Intent.EXTRA_TITLE, title); 15084a4c971c484f05f2a2494d6353f36f4d954a5e0Jeff Sharkey } 15184a4c971c484f05f2a2494d6353f36f4d954a5e0Jeff Sharkey notifyProgress(mId, mProgress, mExtras); 152bd91e2f3f6aca512a02be645b2515b5e3331e177Jeff Sharkey } 153bd91e2f3f6aca512a02be645b2515b5e3331e177Jeff Sharkey } 154bd91e2f3f6aca512a02be645b2515b5e3331e177Jeff Sharkey 155bd91e2f3f6aca512a02be645b2515b5e3331e177Jeff Sharkey /** 156bd91e2f3f6aca512a02be645b2515b5e3331e177Jeff Sharkey * Start a new inner segment that will contribute the given range towards 157bd91e2f3f6aca512a02be645b2515b5e3331e177Jeff Sharkey * the currently active segment. You must pass the returned value to 158bd91e2f3f6aca512a02be645b2515b5e3331e177Jeff Sharkey * {@link #endSegment(int[])} when finished. 159bd91e2f3f6aca512a02be645b2515b5e3331e177Jeff Sharkey */ 160bd91e2f3f6aca512a02be645b2515b5e3331e177Jeff Sharkey public int[] startSegment(int size) { 16184a4c971c484f05f2a2494d6353f36f4d954a5e0Jeff Sharkey synchronized (this) { 16284a4c971c484f05f2a2494d6353f36f4d954a5e0Jeff Sharkey final int[] lastRange = mSegmentRange; 16384a4c971c484f05f2a2494d6353f36f4d954a5e0Jeff Sharkey mSegmentRange = new int[] { mProgress, (size * mSegmentRange[1] / 100) }; 16484a4c971c484f05f2a2494d6353f36f4d954a5e0Jeff Sharkey return lastRange; 16584a4c971c484f05f2a2494d6353f36f4d954a5e0Jeff Sharkey } 166bd91e2f3f6aca512a02be645b2515b5e3331e177Jeff Sharkey } 167bd91e2f3f6aca512a02be645b2515b5e3331e177Jeff Sharkey 168bd91e2f3f6aca512a02be645b2515b5e3331e177Jeff Sharkey /** 169bd91e2f3f6aca512a02be645b2515b5e3331e177Jeff Sharkey * End the current segment. 170bd91e2f3f6aca512a02be645b2515b5e3331e177Jeff Sharkey */ 171bd91e2f3f6aca512a02be645b2515b5e3331e177Jeff Sharkey public void endSegment(int[] lastRange) { 17284a4c971c484f05f2a2494d6353f36f4d954a5e0Jeff Sharkey synchronized (this) { 17384a4c971c484f05f2a2494d6353f36f4d954a5e0Jeff Sharkey mProgress = mSegmentRange[0] + mSegmentRange[1]; 17484a4c971c484f05f2a2494d6353f36f4d954a5e0Jeff Sharkey mSegmentRange = lastRange; 17584a4c971c484f05f2a2494d6353f36f4d954a5e0Jeff Sharkey } 176bd91e2f3f6aca512a02be645b2515b5e3331e177Jeff Sharkey } 177bd91e2f3f6aca512a02be645b2515b5e3331e177Jeff Sharkey 178bd91e2f3f6aca512a02be645b2515b5e3331e177Jeff Sharkey int getProgress() { 179bd91e2f3f6aca512a02be645b2515b5e3331e177Jeff Sharkey return mProgress; 180bd91e2f3f6aca512a02be645b2515b5e3331e177Jeff Sharkey } 181bd91e2f3f6aca512a02be645b2515b5e3331e177Jeff Sharkey 182bd91e2f3f6aca512a02be645b2515b5e3331e177Jeff Sharkey int[] getSegmentRange() { 183bd91e2f3f6aca512a02be645b2515b5e3331e177Jeff Sharkey return mSegmentRange; 184bd91e2f3f6aca512a02be645b2515b5e3331e177Jeff Sharkey } 185bd91e2f3f6aca512a02be645b2515b5e3331e177Jeff Sharkey 186bd91e2f3f6aca512a02be645b2515b5e3331e177Jeff Sharkey /** 18784a4c971c484f05f2a2494d6353f36f4d954a5e0Jeff Sharkey * Report this entire task as being started. 18884a4c971c484f05f2a2494d6353f36f4d954a5e0Jeff Sharkey */ 18984a4c971c484f05f2a2494d6353f36f4d954a5e0Jeff Sharkey public void start() { 19084a4c971c484f05f2a2494d6353f36f4d954a5e0Jeff Sharkey synchronized (this) { 19184a4c971c484f05f2a2494d6353f36f4d954a5e0Jeff Sharkey mState = STATE_STARTED; 19284a4c971c484f05f2a2494d6353f36f4d954a5e0Jeff Sharkey notifyStarted(mId, null); 19384a4c971c484f05f2a2494d6353f36f4d954a5e0Jeff Sharkey notifyProgress(mId, mProgress, mExtras); 19484a4c971c484f05f2a2494d6353f36f4d954a5e0Jeff Sharkey } 19584a4c971c484f05f2a2494d6353f36f4d954a5e0Jeff Sharkey } 19684a4c971c484f05f2a2494d6353f36f4d954a5e0Jeff Sharkey 19784a4c971c484f05f2a2494d6353f36f4d954a5e0Jeff Sharkey /** 198bd91e2f3f6aca512a02be645b2515b5e3331e177Jeff Sharkey * Report this entire task as being finished. 199bd91e2f3f6aca512a02be645b2515b5e3331e177Jeff Sharkey */ 200bd91e2f3f6aca512a02be645b2515b5e3331e177Jeff Sharkey public void finish() { 20184a4c971c484f05f2a2494d6353f36f4d954a5e0Jeff Sharkey synchronized (this) { 20284a4c971c484f05f2a2494d6353f36f4d954a5e0Jeff Sharkey mState = STATE_FINISHED; 20384a4c971c484f05f2a2494d6353f36f4d954a5e0Jeff Sharkey notifyFinished(mId, null); 20484a4c971c484f05f2a2494d6353f36f4d954a5e0Jeff Sharkey mListeners.kill(); 20584a4c971c484f05f2a2494d6353f36f4d954a5e0Jeff Sharkey } 20684a4c971c484f05f2a2494d6353f36f4d954a5e0Jeff Sharkey } 20784a4c971c484f05f2a2494d6353f36f4d954a5e0Jeff Sharkey 20884a4c971c484f05f2a2494d6353f36f4d954a5e0Jeff Sharkey private void notifyStarted(int id, Bundle extras) { 20984a4c971c484f05f2a2494d6353f36f4d954a5e0Jeff Sharkey for (int i = mListeners.beginBroadcast() - 1; i >= 0; i--) { 21084a4c971c484f05f2a2494d6353f36f4d954a5e0Jeff Sharkey try { 21184a4c971c484f05f2a2494d6353f36f4d954a5e0Jeff Sharkey mListeners.getBroadcastItem(i).onStarted(id, extras); 21284a4c971c484f05f2a2494d6353f36f4d954a5e0Jeff Sharkey } catch (RemoteException ignored) { 21384a4c971c484f05f2a2494d6353f36f4d954a5e0Jeff Sharkey } 21484a4c971c484f05f2a2494d6353f36f4d954a5e0Jeff Sharkey } 21584a4c971c484f05f2a2494d6353f36f4d954a5e0Jeff Sharkey mListeners.finishBroadcast(); 216bd91e2f3f6aca512a02be645b2515b5e3331e177Jeff Sharkey } 217bd91e2f3f6aca512a02be645b2515b5e3331e177Jeff Sharkey 218bd91e2f3f6aca512a02be645b2515b5e3331e177Jeff Sharkey private void notifyProgress(int id, int progress, Bundle extras) { 21984a4c971c484f05f2a2494d6353f36f4d954a5e0Jeff Sharkey for (int i = mListeners.beginBroadcast() - 1; i >= 0; i--) { 220bd91e2f3f6aca512a02be645b2515b5e3331e177Jeff Sharkey try { 22184a4c971c484f05f2a2494d6353f36f4d954a5e0Jeff Sharkey mListeners.getBroadcastItem(i).onProgress(id, progress, extras); 222bd91e2f3f6aca512a02be645b2515b5e3331e177Jeff Sharkey } catch (RemoteException ignored) { 223bd91e2f3f6aca512a02be645b2515b5e3331e177Jeff Sharkey } 224bd91e2f3f6aca512a02be645b2515b5e3331e177Jeff Sharkey } 22584a4c971c484f05f2a2494d6353f36f4d954a5e0Jeff Sharkey mListeners.finishBroadcast(); 226bd91e2f3f6aca512a02be645b2515b5e3331e177Jeff Sharkey } 227bd91e2f3f6aca512a02be645b2515b5e3331e177Jeff Sharkey 22884a4c971c484f05f2a2494d6353f36f4d954a5e0Jeff Sharkey private void notifyFinished(int id, Bundle extras) { 22984a4c971c484f05f2a2494d6353f36f4d954a5e0Jeff Sharkey for (int i = mListeners.beginBroadcast() - 1; i >= 0; i--) { 230bd91e2f3f6aca512a02be645b2515b5e3331e177Jeff Sharkey try { 23184a4c971c484f05f2a2494d6353f36f4d954a5e0Jeff Sharkey mListeners.getBroadcastItem(i).onFinished(id, extras); 232bd91e2f3f6aca512a02be645b2515b5e3331e177Jeff Sharkey } catch (RemoteException ignored) { 233bd91e2f3f6aca512a02be645b2515b5e3331e177Jeff Sharkey } 234bd91e2f3f6aca512a02be645b2515b5e3331e177Jeff Sharkey } 23584a4c971c484f05f2a2494d6353f36f4d954a5e0Jeff Sharkey mListeners.finishBroadcast(); 236bd91e2f3f6aca512a02be645b2515b5e3331e177Jeff Sharkey } 237bd91e2f3f6aca512a02be645b2515b5e3331e177Jeff Sharkey} 238