• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2019 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.android.launcher3.util;
17 
18 import androidx.annotation.Nullable;
19 
20 import com.android.launcher3.BaseActivity;
21 
22 import java.lang.ref.WeakReference;
23 import java.util.ArrayList;
24 import java.util.HashSet;
25 import java.util.concurrent.CopyOnWriteArrayList;
26 
27 /**
28  * Helper class to statically track activity creation
29  * @param <T> The activity type to track
30  */
31 public final class ActivityTracker<T extends BaseActivity> {
32 
33     private WeakReference<T> mCurrentActivity = new WeakReference<>(null);
34     private CopyOnWriteArrayList<SchedulerCallback<T>> mCallbacks = new CopyOnWriteArrayList<>();
35 
36     @Nullable
getCreatedActivity()37     public <R extends T> R getCreatedActivity() {
38         return (R) mCurrentActivity.get();
39     }
40 
onActivityDestroyed(T activity)41     public void onActivityDestroyed(T activity) {
42         if (mCurrentActivity.get() == activity) {
43             mCurrentActivity.clear();
44         }
45     }
46 
47     /**
48      * Call {@link SchedulerCallback#init(BaseActivity, boolean)} when the
49      * activity is ready. If the activity is already created, this is called immediately.
50      *
51      * The tracker maintains a strong ref to the callback, so it is up to the caller to return
52      * {@code false} in the callback OR to unregister the callback explicitly.
53      *
54      * @param callback The callback to call init() on when the activity is ready.
55      */
registerCallback(SchedulerCallback<T> callback)56     public void registerCallback(SchedulerCallback<T> callback) {
57         T activity = mCurrentActivity.get();
58         mCallbacks.add(callback);
59         if (activity != null) {
60             if (!callback.init(activity, activity.isStarted())) {
61                 unregisterCallback(callback);
62             }
63         }
64     }
65 
66     /**
67      * Unregisters a registered callback.
68      */
unregisterCallback(SchedulerCallback<T> callback)69     public void unregisterCallback(SchedulerCallback<T> callback) {
70         mCallbacks.remove(callback);
71     }
72 
handleCreate(T activity)73     public boolean handleCreate(T activity) {
74         mCurrentActivity = new WeakReference<>(activity);
75         return handleIntent(activity, false /* alreadyOnHome */);
76     }
77 
handleNewIntent(T activity)78     public boolean handleNewIntent(T activity) {
79         return handleIntent(activity, activity.isStarted());
80     }
81 
handleIntent(T activity, boolean alreadyOnHome)82     private boolean handleIntent(T activity, boolean alreadyOnHome) {
83         boolean handled = false;
84         for (SchedulerCallback<T> cb : mCallbacks) {
85             if (!cb.init(activity, alreadyOnHome)) {
86                 // Callback doesn't want any more updates
87                 unregisterCallback(cb);
88             }
89             handled = true;
90         }
91         return handled;
92     }
93 
94     public interface SchedulerCallback<T extends BaseActivity> {
95 
96         /**
97          * Called when the activity is ready.
98          * @param alreadyOnHome Whether the activity is already started.
99          * @return Whether to continue receiving callbacks (i.e. if the activity is recreated).
100          */
init(T activity, boolean alreadyOnHome)101         boolean init(T activity, boolean alreadyOnHome);
102     }
103 }
104