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.SystemProperties; 26 import android.util.Log; 27 28 import java.util.HashMap; 29 import java.util.Map; 30 31 /** 32 * Application class for SystemUI. 33 */ 34 public class SystemUIApplication extends Application { 35 36 private static final String TAG = "SystemUIService"; 37 private static final boolean DEBUG = false; 38 39 /** 40 * The classes of the stuff to start. 41 */ 42 private final Class<?>[] SERVICES = new Class[] { 43 com.android.systemui.tuner.TunerService.class, 44 com.android.systemui.keyguard.KeyguardViewMediator.class, 45 com.android.systemui.recents.Recents.class, 46 com.android.systemui.volume.VolumeUI.class, 47 com.android.systemui.statusbar.SystemBars.class, 48 com.android.systemui.usb.StorageNotification.class, 49 com.android.systemui.power.PowerUI.class, 50 com.android.systemui.media.RingtonePlayer.class, 51 }; 52 53 /** 54 * Hold a reference on the stuff we start. 55 */ 56 private final SystemUI[] mServices = new SystemUI[SERVICES.length]; 57 private boolean mServicesStarted; 58 private boolean mBootCompleted; 59 private final Map<Class<?>, Object> mComponents = new HashMap<Class<?>, Object>(); 60 61 @Override onCreate()62 public void onCreate() { 63 super.onCreate(); 64 // Set the application theme that is inherited by all services. Note that setting the 65 // application theme in the manifest does only work for activities. Keep this in sync with 66 // the theme set there. 67 setTheme(R.style.systemui_theme); 68 69 IntentFilter filter = new IntentFilter(Intent.ACTION_BOOT_COMPLETED); 70 filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY); 71 registerReceiver(new BroadcastReceiver() { 72 @Override 73 public void onReceive(Context context, Intent intent) { 74 if (mBootCompleted) return; 75 76 if (DEBUG) Log.v(TAG, "BOOT_COMPLETED received"); 77 unregisterReceiver(this); 78 mBootCompleted = true; 79 if (mServicesStarted) { 80 final int N = mServices.length; 81 for (int i = 0; i < N; i++) { 82 mServices[i].onBootCompleted(); 83 } 84 } 85 } 86 }, filter); 87 } 88 89 /** 90 * Makes sure that all the SystemUI services are running. If they are already running, this is a 91 * no-op. This is needed to conditinally start all the services, as we only need to have it in 92 * the main process. 93 * 94 * <p>This method must only be called from the main thread.</p> 95 */ startServicesIfNeeded()96 public void startServicesIfNeeded() { 97 if (mServicesStarted) { 98 return; 99 } 100 101 if (!mBootCompleted) { 102 // check to see if maybe it was already completed long before we began 103 // see ActivityManagerService.finishBooting() 104 if ("1".equals(SystemProperties.get("sys.boot_completed"))) { 105 mBootCompleted = true; 106 if (DEBUG) Log.v(TAG, "BOOT_COMPLETED was already sent"); 107 } 108 } 109 110 Log.v(TAG, "Starting SystemUI services."); 111 final int N = SERVICES.length; 112 for (int i=0; i<N; i++) { 113 Class<?> cl = SERVICES[i]; 114 if (DEBUG) Log.d(TAG, "loading: " + cl); 115 try { 116 mServices[i] = (SystemUI)cl.newInstance(); 117 } catch (IllegalAccessException ex) { 118 throw new RuntimeException(ex); 119 } catch (InstantiationException ex) { 120 throw new RuntimeException(ex); 121 } 122 mServices[i].mContext = this; 123 mServices[i].mComponents = mComponents; 124 if (DEBUG) Log.d(TAG, "running: " + mServices[i]); 125 mServices[i].start(); 126 127 if (mBootCompleted) { 128 mServices[i].onBootCompleted(); 129 } 130 } 131 mServicesStarted = true; 132 } 133 134 @Override onConfigurationChanged(Configuration newConfig)135 public void onConfigurationChanged(Configuration newConfig) { 136 if (mServicesStarted) { 137 int len = mServices.length; 138 for (int i = 0; i < len; i++) { 139 mServices[i].onConfigurationChanged(newConfig); 140 } 141 } 142 } 143 144 @SuppressWarnings("unchecked") getComponent(Class<T> interfaceType)145 public <T> T getComponent(Class<T> interfaceType) { 146 return (T) mComponents.get(interfaceType); 147 } 148 getServices()149 public SystemUI[] getServices() { 150 return mServices; 151 } 152 } 153