• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2017 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.states;
17 
18 import android.content.Intent;
19 import android.os.Binder;
20 import android.os.Bundle;
21 import android.os.IBinder;
22 
23 import com.android.launcher3.Launcher;
24 import com.android.launcher3.LauncherAppState;
25 import com.android.launcher3.LauncherModel.Callbacks;
26 import com.android.launcher3.MainThreadExecutor;
27 
28 import java.lang.ref.WeakReference;
29 
30 /**
31  * Utility class to sending state handling logic to Launcher from within the same process.
32  *
33  * Extending {@link Binder} ensures that the platform maintains a single instance of each object
34  * which allows this object to safely navigate the system process.
35  */
36 public abstract class InternalStateHandler extends Binder {
37 
38     public static final String EXTRA_STATE_HANDLER = "launcher.state_handler";
39 
40     private static final Scheduler sScheduler = new Scheduler();
41 
42     /**
43      * Initializes the handler when the launcher is ready.
44      * @return true if the handler wants to stay alive.
45      */
init(Launcher launcher, boolean alreadyOnHome)46     protected abstract boolean init(Launcher launcher, boolean alreadyOnHome);
47 
addToIntent(Intent intent)48     public final Intent addToIntent(Intent intent) {
49         Bundle extras = new Bundle();
50         extras.putBinder(EXTRA_STATE_HANDLER, this);
51         intent.putExtras(extras);
52         return intent;
53     }
54 
initWhenReady()55     public final void initWhenReady() {
56         sScheduler.schedule(this);
57     }
58 
clearReference()59     public boolean clearReference() {
60         return sScheduler.clearReference(this);
61     }
62 
hasPending()63     public static boolean hasPending() {
64         return sScheduler.hasPending();
65     }
66 
handleCreate(Launcher launcher, Intent intent)67     public static boolean handleCreate(Launcher launcher, Intent intent) {
68         return handleIntent(launcher, intent, false, false);
69     }
70 
handleNewIntent(Launcher launcher, Intent intent, boolean alreadyOnHome)71     public static boolean handleNewIntent(Launcher launcher, Intent intent, boolean alreadyOnHome) {
72         return handleIntent(launcher, intent, alreadyOnHome, true);
73     }
74 
handleIntent( Launcher launcher, Intent intent, boolean alreadyOnHome, boolean explicitIntent)75     private static boolean handleIntent(
76             Launcher launcher, Intent intent, boolean alreadyOnHome, boolean explicitIntent) {
77         boolean result = false;
78         if (intent != null && intent.getExtras() != null) {
79             IBinder stateBinder = intent.getExtras().getBinder(EXTRA_STATE_HANDLER);
80             if (stateBinder instanceof InternalStateHandler) {
81                 InternalStateHandler handler = (InternalStateHandler) stateBinder;
82                 if (!handler.init(launcher, alreadyOnHome)) {
83                     intent.getExtras().remove(EXTRA_STATE_HANDLER);
84                 }
85                 result = true;
86             }
87         }
88         if (!result && !explicitIntent) {
89             result = sScheduler.initIfPending(launcher, alreadyOnHome);
90         }
91         return result;
92     }
93 
94     private static class Scheduler implements Runnable {
95 
96         private WeakReference<InternalStateHandler> mPendingHandler = new WeakReference<>(null);
97         private MainThreadExecutor mMainThreadExecutor;
98 
schedule(InternalStateHandler handler)99         public void schedule(InternalStateHandler handler) {
100             synchronized (this) {
101                 mPendingHandler = new WeakReference<>(handler);
102                 if (mMainThreadExecutor == null) {
103                     mMainThreadExecutor = new MainThreadExecutor();
104                 }
105             }
106             mMainThreadExecutor.execute(this);
107         }
108 
109         @Override
run()110         public void run() {
111             LauncherAppState app = LauncherAppState.getInstanceNoCreate();
112             if (app == null) {
113                 return;
114             }
115             Callbacks cb = app.getModel().getCallback();
116             if (!(cb instanceof Launcher)) {
117                 return;
118             }
119             Launcher launcher = (Launcher) cb;
120             initIfPending(launcher, launcher.isStarted());
121         }
122 
initIfPending(Launcher launcher, boolean alreadyOnHome)123         public boolean initIfPending(Launcher launcher, boolean alreadyOnHome) {
124             InternalStateHandler pendingHandler = mPendingHandler.get();
125             if (pendingHandler != null) {
126                 if (!pendingHandler.init(launcher, alreadyOnHome)) {
127                     clearReference(pendingHandler);
128                 }
129                 return true;
130             }
131             return false;
132         }
133 
clearReference(InternalStateHandler handler)134         public boolean clearReference(InternalStateHandler handler) {
135             synchronized (this) {
136                 if (mPendingHandler.get() == handler) {
137                     mPendingHandler.clear();
138                     return true;
139                 }
140                 return false;
141             }
142         }
143 
hasPending()144         public boolean hasPending() {
145             return mPendingHandler.get() != null;
146         }
147     }
148 }