• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2014 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.systemui;
18 
19 import android.app.Application;
20 import android.content.BroadcastReceiver;
21 import android.content.Context;
22 import android.content.Intent;
23 import android.content.IntentFilter;
24 import android.content.res.Configuration;
25 import android.os.Process;
26 import android.os.SystemProperties;
27 import android.os.UserHandle;
28 import android.util.Log;
29 
30 import com.android.systemui.stackdivider.Divider;
31 
32 import java.util.HashMap;
33 import java.util.Map;
34 
35 /**
36  * Application class for SystemUI.
37  */
38 public class SystemUIApplication extends Application {
39 
40     private static final String TAG = "SystemUIService";
41     private static final boolean DEBUG = false;
42 
43     /**
44      * The classes of the stuff to start.
45      */
46     private final Class<?>[] SERVICES = new Class[] {
47             com.android.systemui.tuner.TunerService.class,
48             com.android.systemui.keyguard.KeyguardViewMediator.class,
49             com.android.systemui.recents.Recents.class,
50             com.android.systemui.volume.VolumeUI.class,
51             Divider.class,
52             com.android.systemui.statusbar.SystemBars.class,
53             com.android.systemui.usb.StorageNotification.class,
54             com.android.systemui.power.PowerUI.class,
55             com.android.systemui.media.RingtonePlayer.class,
56             com.android.systemui.keyboard.KeyboardUI.class,
57             com.android.systemui.tv.pip.PipUI.class,
58             com.android.systemui.shortcut.ShortcutKeyDispatcher.class,
59             com.android.systemui.VendorServices.class
60     };
61 
62     /**
63      * The classes of the stuff to start for each user.  This is a subset of the services listed
64      * above.
65      */
66     private final Class<?>[] SERVICES_PER_USER = new Class[] {
67             com.android.systemui.recents.Recents.class,
68             com.android.systemui.tv.pip.PipUI.class
69     };
70 
71     /**
72      * Hold a reference on the stuff we start.
73      */
74     private final SystemUI[] mServices = new SystemUI[SERVICES.length];
75     private boolean mServicesStarted;
76     private boolean mBootCompleted;
77     private final Map<Class<?>, Object> mComponents = new HashMap<>();
78 
79     @Override
onCreate()80     public void onCreate() {
81         super.onCreate();
82         // Set the application theme that is inherited by all services. Note that setting the
83         // application theme in the manifest does only work for activities. Keep this in sync with
84         // the theme set there.
85         setTheme(R.style.systemui_theme);
86 
87         SystemUIFactory.createFromConfig(this);
88 
89         if (Process.myUserHandle().equals(UserHandle.SYSTEM)) {
90             IntentFilter filter = new IntentFilter(Intent.ACTION_BOOT_COMPLETED);
91             filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
92             registerReceiver(new BroadcastReceiver() {
93                 @Override
94                 public void onReceive(Context context, Intent intent) {
95                     if (mBootCompleted) return;
96 
97                     if (DEBUG) Log.v(TAG, "BOOT_COMPLETED received");
98                     unregisterReceiver(this);
99                     mBootCompleted = true;
100                     if (mServicesStarted) {
101                         final int N = mServices.length;
102                         for (int i = 0; i < N; i++) {
103                             mServices[i].onBootCompleted();
104                         }
105                     }
106                 }
107             }, filter);
108         } else {
109             // For a secondary user, boot-completed will never be called because it has already
110             // been broadcasted on startup for the primary SystemUI process.  Instead, for
111             // components which require the SystemUI component to be initialized per-user, we
112             // start those components now for the current non-system user.
113             startServicesIfNeeded(SERVICES_PER_USER);
114         }
115     }
116 
117     /**
118      * Makes sure that all the SystemUI services are running. If they are already running, this is a
119      * no-op. This is needed to conditinally start all the services, as we only need to have it in
120      * the main process.
121      *
122      * <p>This method must only be called from the main thread.</p>
123      */
startServicesIfNeeded()124     public void startServicesIfNeeded() {
125         startServicesIfNeeded(SERVICES);
126     }
127 
128     /**
129      * Ensures that all the Secondary user SystemUI services are running. If they are already
130      * running, this is a no-op. This is needed to conditinally start all the services, as we only
131      * need to have it in the main process.
132      *
133      * <p>This method must only be called from the main thread.</p>
134      */
startSecondaryUserServicesIfNeeded()135     void startSecondaryUserServicesIfNeeded() {
136         startServicesIfNeeded(SERVICES_PER_USER);
137     }
138 
startServicesIfNeeded(Class<?>[] services)139     private void startServicesIfNeeded(Class<?>[] services) {
140         if (mServicesStarted) {
141             return;
142         }
143 
144         if (!mBootCompleted) {
145             // check to see if maybe it was already completed long before we began
146             // see ActivityManagerService.finishBooting()
147             if ("1".equals(SystemProperties.get("sys.boot_completed"))) {
148                 mBootCompleted = true;
149                 if (DEBUG) Log.v(TAG, "BOOT_COMPLETED was already sent");
150             }
151         }
152 
153         Log.v(TAG, "Starting SystemUI services for user " +
154                 Process.myUserHandle().getIdentifier() + ".");
155         final int N = services.length;
156         for (int i=0; i<N; i++) {
157             Class<?> cl = services[i];
158             if (DEBUG) Log.d(TAG, "loading: " + cl);
159             try {
160                 Object newService = SystemUIFactory.getInstance().createInstance(cl);
161                 mServices[i] = (SystemUI) ((newService == null) ? cl.newInstance() : newService);
162             } catch (IllegalAccessException ex) {
163                 throw new RuntimeException(ex);
164             } catch (InstantiationException ex) {
165                 throw new RuntimeException(ex);
166             }
167 
168             mServices[i].mContext = this;
169             mServices[i].mComponents = mComponents;
170             if (DEBUG) Log.d(TAG, "running: " + mServices[i]);
171             mServices[i].start();
172 
173             if (mBootCompleted) {
174                 mServices[i].onBootCompleted();
175             }
176         }
177         mServicesStarted = true;
178     }
179 
180     @Override
onConfigurationChanged(Configuration newConfig)181     public void onConfigurationChanged(Configuration newConfig) {
182         if (mServicesStarted) {
183             int len = mServices.length;
184             for (int i = 0; i < len; i++) {
185                 if (mServices[i] != null) {
186                     mServices[i].onConfigurationChanged(newConfig);
187                 }
188             }
189         }
190     }
191 
192     @SuppressWarnings("unchecked")
getComponent(Class<T> interfaceType)193     public <T> T getComponent(Class<T> interfaceType) {
194         return (T) mComponents.get(interfaceType);
195     }
196 
getServices()197     public SystemUI[] getServices() {
198         return mServices;
199     }
200 }
201