• 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 
17 package com.android.wm.shell.sysui;
18 
19 import static com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_INIT;
20 
21 import android.os.Build;
22 import android.os.SystemClock;
23 import android.util.Pair;
24 
25 import androidx.annotation.VisibleForTesting;
26 
27 import com.android.internal.protolog.common.ProtoLog;
28 import com.android.wm.shell.common.ShellExecutor;
29 
30 import java.util.ArrayList;
31 
32 /**
33  * The entry point implementation into the shell for initializing shell internal state.  Classes
34  * which need to initialize on start of the host SysUI should inject an instance of this class and
35  * add an init callback.
36  */
37 public class ShellInit {
38     private static final String TAG = ShellInit.class.getSimpleName();
39 
40     private final ShellExecutor mMainExecutor;
41 
42     // An ordered list of init callbacks to be made once shell is first started
43     private final ArrayList<Pair<String, Runnable>> mInitCallbacks = new ArrayList<>();
44     private boolean mHasInitialized;
45 
46 
ShellInit(ShellExecutor mainExecutor)47     public ShellInit(ShellExecutor mainExecutor) {
48         mMainExecutor = mainExecutor;
49     }
50 
51     /**
52      * Adds a callback to the ordered list of callbacks be made when Shell is first started.  This
53      * can be used in class constructors when dagger is used to ensure that the initialization order
54      * matches the dependency order.
55      *
56      * @param r the callback to be made when Shell is initialized
57      * @param instance used for debugging only
58      */
addInitCallback(Runnable r, T instance)59     public <T extends Object> void addInitCallback(Runnable r, T instance) {
60         if (mHasInitialized) {
61             if (Build.isDebuggable()) {
62                 // All callbacks must be added prior to the Shell being initialized
63                 throw new IllegalArgumentException("Can not add callback after init");
64             }
65             return;
66         }
67         final String className = instance.getClass().getSimpleName();
68         mInitCallbacks.add(new Pair<>(className, r));
69         ProtoLog.v(WM_SHELL_INIT, "Adding init callback for %s", className);
70     }
71 
72     /**
73      * Calls all the init callbacks when the Shell is first starting.
74      */
75     @VisibleForTesting
init()76     public void init() {
77         ProtoLog.v(WM_SHELL_INIT, "Initializing Shell Components: %d", mInitCallbacks.size());
78         // Init in order of registration
79         for (int i = 0; i < mInitCallbacks.size(); i++) {
80             final Pair<String, Runnable> info = mInitCallbacks.get(i);
81             final long t1 = SystemClock.uptimeMillis();
82             info.second.run();
83             final long t2 = SystemClock.uptimeMillis();
84             ProtoLog.v(WM_SHELL_INIT, "\t%s init took %dms", info.first, (t2 - t1));
85         }
86         mInitCallbacks.clear();
87         mHasInitialized = true;
88     }
89 }
90