1cff0acb6b1eea23c3f44a078a0a5e81c11faea35Jorim Jaggi/* 2cff0acb6b1eea23c3f44a078a0a5e81c11faea35Jorim Jaggi * Copyright (C) 2014 The Android Open Source Project 3cff0acb6b1eea23c3f44a078a0a5e81c11faea35Jorim Jaggi * 4cff0acb6b1eea23c3f44a078a0a5e81c11faea35Jorim Jaggi * Licensed under the Apache License, Version 2.0 (the "License"); 5cff0acb6b1eea23c3f44a078a0a5e81c11faea35Jorim Jaggi * you may not use this file except in compliance with the License. 6cff0acb6b1eea23c3f44a078a0a5e81c11faea35Jorim Jaggi * You may obtain a copy of the License at 7cff0acb6b1eea23c3f44a078a0a5e81c11faea35Jorim Jaggi * 8cff0acb6b1eea23c3f44a078a0a5e81c11faea35Jorim Jaggi * http://www.apache.org/licenses/LICENSE-2.0 9cff0acb6b1eea23c3f44a078a0a5e81c11faea35Jorim Jaggi * 10cff0acb6b1eea23c3f44a078a0a5e81c11faea35Jorim Jaggi * Unless required by applicable law or agreed to in writing, software 11cff0acb6b1eea23c3f44a078a0a5e81c11faea35Jorim Jaggi * distributed under the License is distributed on an "AS IS" BASIS, 12cff0acb6b1eea23c3f44a078a0a5e81c11faea35Jorim Jaggi * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13cff0acb6b1eea23c3f44a078a0a5e81c11faea35Jorim Jaggi * See the License for the specific language governing permissions and 14cff0acb6b1eea23c3f44a078a0a5e81c11faea35Jorim Jaggi * limitations under the License 15cff0acb6b1eea23c3f44a078a0a5e81c11faea35Jorim Jaggi */ 16cff0acb6b1eea23c3f44a078a0a5e81c11faea35Jorim Jaggi 17cff0acb6b1eea23c3f44a078a0a5e81c11faea35Jorim Jaggipackage com.android.systemui; 18cff0acb6b1eea23c3f44a078a0a5e81c11faea35Jorim Jaggi 19b647984f04a8cff6f98ee9654336854ddf872278dooyoung.hwangimport android.app.ActivityThread; 20cff0acb6b1eea23c3f44a078a0a5e81c11faea35Jorim Jaggiimport android.app.Application; 21dc5f16bf096796d2f822bce8a720fc26e898da5eDan Sandlerimport android.content.BroadcastReceiver; 22dc5f16bf096796d2f822bce8a720fc26e898da5eDan Sandlerimport android.content.Context; 23dc5f16bf096796d2f822bce8a720fc26e898da5eDan Sandlerimport android.content.Intent; 24dc5f16bf096796d2f822bce8a720fc26e898da5eDan Sandlerimport android.content.IntentFilter; 25b647984f04a8cff6f98ee9654336854ddf872278dooyoung.hwangimport android.content.pm.ApplicationInfo; 26cff0acb6b1eea23c3f44a078a0a5e81c11faea35Jorim Jaggiimport android.content.res.Configuration; 27fe67abac68d628043604e8f24fb1915aca298e0cWinsonimport android.os.Process; 28dc5f16bf096796d2f822bce8a720fc26e898da5eDan Sandlerimport android.os.SystemProperties; 29f3591359b9841a1571545a39b038802ce7ed77bbFyodor Kupolovimport android.os.Trace; 30fe67abac68d628043604e8f24fb1915aca298e0cWinsonimport android.os.UserHandle; 31421a9410b462770544c6ae9a554542fa2fe1acb1Jason Monkimport android.util.ArraySet; 32cff0acb6b1eea23c3f44a078a0a5e81c11faea35Jorim Jaggiimport android.util.Log; 3370dcd00d4a8dd3fa52983121a8052c99e66368bfBeverlyimport android.util.TimingsTraceLog; 34cff0acb6b1eea23c3f44a078a0a5e81c11faea35Jorim Jaggi 3586bc33188948e7b6beb07dbb5ddba59b5ea3c1fcJason Monkimport com.android.systemui.plugins.OverlayPlugin; 3686bc33188948e7b6beb07dbb5ddba59b5ea3c1fcJason Monkimport com.android.systemui.plugins.PluginListener; 3786bc33188948e7b6beb07dbb5ddba59b5ea3c1fcJason Monkimport com.android.systemui.plugins.PluginManager; 382a6ea9c2a1b52b0386270ec73e1e6d6a9b614a34Jason Monkimport com.android.systemui.statusbar.phone.StatusBar; 39421a9410b462770544c6ae9a554542fa2fe1acb1Jason Monkimport com.android.systemui.statusbar.phone.StatusBarWindowManager; 408e032e15e6b1b6a2f44fd3d5063ee83f45d71189Dan Sandlerimport com.android.systemui.util.NotificationChannels; 4161f39a7b988f6a22681a3f9e0bf8121f72ff88c4Jorim Jaggi 42cff0acb6b1eea23c3f44a078a0a5e81c11faea35Jorim Jaggiimport java.util.HashMap; 43cff0acb6b1eea23c3f44a078a0a5e81c11faea35Jorim Jaggiimport java.util.Map; 44cff0acb6b1eea23c3f44a078a0a5e81c11faea35Jorim Jaggi 45cff0acb6b1eea23c3f44a078a0a5e81c11faea35Jorim Jaggi/** 46cff0acb6b1eea23c3f44a078a0a5e81c11faea35Jorim Jaggi * Application class for SystemUI. 47cff0acb6b1eea23c3f44a078a0a5e81c11faea35Jorim Jaggi */ 4849fa016a98cef9940c883b3f620a0e90537a204eJason Monkpublic class SystemUIApplication extends Application implements SysUiServiceProvider { 49cff0acb6b1eea23c3f44a078a0a5e81c11faea35Jorim Jaggi 50dc2ddd7e3e1b6a4f3ecc24a0a05d17a4e89cef28Dan Sandler public static final String TAG = "SystemUIService"; 51cff0acb6b1eea23c3f44a078a0a5e81c11faea35Jorim Jaggi private static final boolean DEBUG = false; 52cff0acb6b1eea23c3f44a078a0a5e81c11faea35Jorim Jaggi 53cff0acb6b1eea23c3f44a078a0a5e81c11faea35Jorim Jaggi /** 54cff0acb6b1eea23c3f44a078a0a5e81c11faea35Jorim Jaggi * Hold a reference on the stuff we start. 55cff0acb6b1eea23c3f44a078a0a5e81c11faea35Jorim Jaggi */ 5661b37088337753a7e631579829040c5cae9d72c4yoshiki iguchi private SystemUI[] mServices; 573beffdf4a0081a97356f46d50e10541b1a213153Jorim Jaggi private boolean mServicesStarted; 58dc5f16bf096796d2f822bce8a720fc26e898da5eDan Sandler private boolean mBootCompleted; 59fe67abac68d628043604e8f24fb1915aca298e0cWinson private final Map<Class<?>, Object> mComponents = new HashMap<>(); 60cff0acb6b1eea23c3f44a078a0a5e81c11faea35Jorim Jaggi 61070a0b61cd416b9d54d57bf52ba6583f9b111ee6Adrian Roos @Override 62070a0b61cd416b9d54d57bf52ba6583f9b111ee6Adrian Roos public void onCreate() { 63070a0b61cd416b9d54d57bf52ba6583f9b111ee6Adrian Roos super.onCreate(); 64070a0b61cd416b9d54d57bf52ba6583f9b111ee6Adrian Roos // Set the application theme that is inherited by all services. Note that setting the 65070a0b61cd416b9d54d57bf52ba6583f9b111ee6Adrian Roos // application theme in the manifest does only work for activities. Keep this in sync with 66070a0b61cd416b9d54d57bf52ba6583f9b111ee6Adrian Roos // the theme set there. 67e17ce5286f2c25c2ce440b30f476e9e88a6d1e8eLucas Dupin setTheme(R.style.Theme_SystemUI); 68dc5f16bf096796d2f822bce8a720fc26e898da5eDan Sandler 691b30f79cffbe9e0c2b974fa3ee48001edcdd6c05Xiyuan Xia SystemUIFactory.createFromConfig(this); 701b30f79cffbe9e0c2b974fa3ee48001edcdd6c05Xiyuan Xia 71fe67abac68d628043604e8f24fb1915aca298e0cWinson if (Process.myUserHandle().equals(UserHandle.SYSTEM)) { 726ea063eb5f1d4d7c6242915f378e68048ea51d70Beverly IntentFilter bootCompletedFilter = new IntentFilter(Intent.ACTION_BOOT_COMPLETED); 736ea063eb5f1d4d7c6242915f378e68048ea51d70Beverly bootCompletedFilter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY); 74fe67abac68d628043604e8f24fb1915aca298e0cWinson registerReceiver(new BroadcastReceiver() { 75fe67abac68d628043604e8f24fb1915aca298e0cWinson @Override 76fe67abac68d628043604e8f24fb1915aca298e0cWinson public void onReceive(Context context, Intent intent) { 77fe67abac68d628043604e8f24fb1915aca298e0cWinson if (mBootCompleted) return; 78dc5f16bf096796d2f822bce8a720fc26e898da5eDan Sandler 79fe67abac68d628043604e8f24fb1915aca298e0cWinson if (DEBUG) Log.v(TAG, "BOOT_COMPLETED received"); 80fe67abac68d628043604e8f24fb1915aca298e0cWinson unregisterReceiver(this); 81fe67abac68d628043604e8f24fb1915aca298e0cWinson mBootCompleted = true; 82fe67abac68d628043604e8f24fb1915aca298e0cWinson if (mServicesStarted) { 83fe67abac68d628043604e8f24fb1915aca298e0cWinson final int N = mServices.length; 84fe67abac68d628043604e8f24fb1915aca298e0cWinson for (int i = 0; i < N; i++) { 85fe67abac68d628043604e8f24fb1915aca298e0cWinson mServices[i].onBootCompleted(); 86fe67abac68d628043604e8f24fb1915aca298e0cWinson } 87dc5f16bf096796d2f822bce8a720fc26e898da5eDan Sandler } 8870dcd00d4a8dd3fa52983121a8052c99e66368bfBeverly 896ea063eb5f1d4d7c6242915f378e68048ea51d70Beverly 906ea063eb5f1d4d7c6242915f378e68048ea51d70Beverly } 916ea063eb5f1d4d7c6242915f378e68048ea51d70Beverly }, bootCompletedFilter); 926ea063eb5f1d4d7c6242915f378e68048ea51d70Beverly 936ea063eb5f1d4d7c6242915f378e68048ea51d70Beverly IntentFilter localeChangedFilter = new IntentFilter(Intent.ACTION_LOCALE_CHANGED); 946ea063eb5f1d4d7c6242915f378e68048ea51d70Beverly registerReceiver(new BroadcastReceiver() { 956ea063eb5f1d4d7c6242915f378e68048ea51d70Beverly @Override 966ea063eb5f1d4d7c6242915f378e68048ea51d70Beverly public void onReceive(Context context, Intent intent) { 976ea063eb5f1d4d7c6242915f378e68048ea51d70Beverly if (Intent.ACTION_LOCALE_CHANGED.equals(intent.getAction())) { 986ea063eb5f1d4d7c6242915f378e68048ea51d70Beverly if (!mBootCompleted) return; 996ea063eb5f1d4d7c6242915f378e68048ea51d70Beverly // Update names of SystemUi notification channels 1006ea063eb5f1d4d7c6242915f378e68048ea51d70Beverly NotificationChannels.createAll(context); 1016ea063eb5f1d4d7c6242915f378e68048ea51d70Beverly } 102dc5f16bf096796d2f822bce8a720fc26e898da5eDan Sandler } 1036ea063eb5f1d4d7c6242915f378e68048ea51d70Beverly }, localeChangedFilter); 104fe67abac68d628043604e8f24fb1915aca298e0cWinson } else { 105b647984f04a8cff6f98ee9654336854ddf872278dooyoung.hwang // We don't need to startServices for sub-process that is doing some tasks. 106b647984f04a8cff6f98ee9654336854ddf872278dooyoung.hwang // (screenshots, sweetsweetdesserts or tuner ..) 107b647984f04a8cff6f98ee9654336854ddf872278dooyoung.hwang String processName = ActivityThread.currentProcessName(); 108b647984f04a8cff6f98ee9654336854ddf872278dooyoung.hwang ApplicationInfo info = getApplicationInfo(); 109b647984f04a8cff6f98ee9654336854ddf872278dooyoung.hwang if (processName != null && processName.startsWith(info.processName + ":")) { 110b647984f04a8cff6f98ee9654336854ddf872278dooyoung.hwang return; 111b647984f04a8cff6f98ee9654336854ddf872278dooyoung.hwang } 112fe67abac68d628043604e8f24fb1915aca298e0cWinson // For a secondary user, boot-completed will never be called because it has already 113fe67abac68d628043604e8f24fb1915aca298e0cWinson // been broadcasted on startup for the primary SystemUI process. Instead, for 114fe67abac68d628043604e8f24fb1915aca298e0cWinson // components which require the SystemUI component to be initialized per-user, we 115fe67abac68d628043604e8f24fb1915aca298e0cWinson // start those components now for the current non-system user. 11661b37088337753a7e631579829040c5cae9d72c4yoshiki iguchi startSecondaryUserServicesIfNeeded(); 117fe67abac68d628043604e8f24fb1915aca298e0cWinson } 118070a0b61cd416b9d54d57bf52ba6583f9b111ee6Adrian Roos } 119070a0b61cd416b9d54d57bf52ba6583f9b111ee6Adrian Roos 1203beffdf4a0081a97356f46d50e10541b1a213153Jorim Jaggi /** 1213beffdf4a0081a97356f46d50e10541b1a213153Jorim Jaggi * Makes sure that all the SystemUI services are running. If they are already running, this is a 1223beffdf4a0081a97356f46d50e10541b1a213153Jorim Jaggi * no-op. This is needed to conditinally start all the services, as we only need to have it in 1233beffdf4a0081a97356f46d50e10541b1a213153Jorim Jaggi * the main process. 1243beffdf4a0081a97356f46d50e10541b1a213153Jorim Jaggi * <p>This method must only be called from the main thread.</p> 1253beffdf4a0081a97356f46d50e10541b1a213153Jorim Jaggi */ 126be3235abcddbcab63e60184de416c6243697abb7Jason Monk 1273beffdf4a0081a97356f46d50e10541b1a213153Jorim Jaggi public void startServicesIfNeeded() { 12861b37088337753a7e631579829040c5cae9d72c4yoshiki iguchi String[] names = getResources().getStringArray(R.array.config_systemUIServiceComponents); 12961b37088337753a7e631579829040c5cae9d72c4yoshiki iguchi startServicesIfNeeded(names); 130fe67abac68d628043604e8f24fb1915aca298e0cWinson } 131fe67abac68d628043604e8f24fb1915aca298e0cWinson 1323c2c34bb039e92d68f466b7d194cbbe8241d8d60Winson /** 1333c2c34bb039e92d68f466b7d194cbbe8241d8d60Winson * Ensures that all the Secondary user SystemUI services are running. If they are already 1343c2c34bb039e92d68f466b7d194cbbe8241d8d60Winson * running, this is a no-op. This is needed to conditinally start all the services, as we only 1353c2c34bb039e92d68f466b7d194cbbe8241d8d60Winson * need to have it in the main process. 1363c2c34bb039e92d68f466b7d194cbbe8241d8d60Winson * <p>This method must only be called from the main thread.</p> 1373c2c34bb039e92d68f466b7d194cbbe8241d8d60Winson */ 1383c2c34bb039e92d68f466b7d194cbbe8241d8d60Winson void startSecondaryUserServicesIfNeeded() { 13961b37088337753a7e631579829040c5cae9d72c4yoshiki iguchi String[] names = 14061b37088337753a7e631579829040c5cae9d72c4yoshiki iguchi getResources().getStringArray(R.array.config_systemUIServiceComponentsPerUser); 14161b37088337753a7e631579829040c5cae9d72c4yoshiki iguchi startServicesIfNeeded(names); 1423c2c34bb039e92d68f466b7d194cbbe8241d8d60Winson } 1433c2c34bb039e92d68f466b7d194cbbe8241d8d60Winson 14461b37088337753a7e631579829040c5cae9d72c4yoshiki iguchi private void startServicesIfNeeded(String[] services) { 1453beffdf4a0081a97356f46d50e10541b1a213153Jorim Jaggi if (mServicesStarted) { 1463beffdf4a0081a97356f46d50e10541b1a213153Jorim Jaggi return; 1473beffdf4a0081a97356f46d50e10541b1a213153Jorim Jaggi } 14861b37088337753a7e631579829040c5cae9d72c4yoshiki iguchi mServices = new SystemUI[services.length]; 149dc5f16bf096796d2f822bce8a720fc26e898da5eDan Sandler 150dc5f16bf096796d2f822bce8a720fc26e898da5eDan Sandler if (!mBootCompleted) { 151dc5f16bf096796d2f822bce8a720fc26e898da5eDan Sandler // check to see if maybe it was already completed long before we began 152dc5f16bf096796d2f822bce8a720fc26e898da5eDan Sandler // see ActivityManagerService.finishBooting() 153dc5f16bf096796d2f822bce8a720fc26e898da5eDan Sandler if ("1".equals(SystemProperties.get("sys.boot_completed"))) { 154dc5f16bf096796d2f822bce8a720fc26e898da5eDan Sandler mBootCompleted = true; 155dc5f16bf096796d2f822bce8a720fc26e898da5eDan Sandler if (DEBUG) Log.v(TAG, "BOOT_COMPLETED was already sent"); 156dc5f16bf096796d2f822bce8a720fc26e898da5eDan Sandler } 157dc5f16bf096796d2f822bce8a720fc26e898da5eDan Sandler } 158dc5f16bf096796d2f822bce8a720fc26e898da5eDan Sandler 159fe67abac68d628043604e8f24fb1915aca298e0cWinson Log.v(TAG, "Starting SystemUI services for user " + 160fe67abac68d628043604e8f24fb1915aca298e0cWinson Process.myUserHandle().getIdentifier() + "."); 1616e3461b67cae27a42a4d77fa277ba2d844ea0cdeFyodor Kupolov TimingsTraceLog log = new TimingsTraceLog("SystemUIBootTiming", 162f3591359b9841a1571545a39b038802ce7ed77bbFyodor Kupolov Trace.TRACE_TAG_APP); 163f3591359b9841a1571545a39b038802ce7ed77bbFyodor Kupolov log.traceBegin("StartServices"); 164fe67abac68d628043604e8f24fb1915aca298e0cWinson final int N = services.length; 165421a9410b462770544c6ae9a554542fa2fe1acb1Jason Monk for (int i = 0; i < N; i++) { 16661b37088337753a7e631579829040c5cae9d72c4yoshiki iguchi String clsName = services[i]; 16761b37088337753a7e631579829040c5cae9d72c4yoshiki iguchi if (DEBUG) Log.d(TAG, "loading: " + clsName); 16861b37088337753a7e631579829040c5cae9d72c4yoshiki iguchi log.traceBegin("StartServices" + clsName); 169f3591359b9841a1571545a39b038802ce7ed77bbFyodor Kupolov long ti = System.currentTimeMillis(); 17061b37088337753a7e631579829040c5cae9d72c4yoshiki iguchi Class cls; 171cff0acb6b1eea23c3f44a078a0a5e81c11faea35Jorim Jaggi try { 17261b37088337753a7e631579829040c5cae9d72c4yoshiki iguchi cls = Class.forName(clsName); 17361b37088337753a7e631579829040c5cae9d72c4yoshiki iguchi mServices[i] = (SystemUI) cls.newInstance(); 17461b37088337753a7e631579829040c5cae9d72c4yoshiki iguchi } catch(ClassNotFoundException ex){ 17561b37088337753a7e631579829040c5cae9d72c4yoshiki iguchi throw new RuntimeException(ex); 176cff0acb6b1eea23c3f44a078a0a5e81c11faea35Jorim Jaggi } catch (IllegalAccessException ex) { 177cff0acb6b1eea23c3f44a078a0a5e81c11faea35Jorim Jaggi throw new RuntimeException(ex); 178cff0acb6b1eea23c3f44a078a0a5e81c11faea35Jorim Jaggi } catch (InstantiationException ex) { 179cff0acb6b1eea23c3f44a078a0a5e81c11faea35Jorim Jaggi throw new RuntimeException(ex); 180cff0acb6b1eea23c3f44a078a0a5e81c11faea35Jorim Jaggi } 18194ce94e96069ab6c2ece4864ba4c7692f3168352Muyuan Li 182cff0acb6b1eea23c3f44a078a0a5e81c11faea35Jorim Jaggi mServices[i].mContext = this; 183cff0acb6b1eea23c3f44a078a0a5e81c11faea35Jorim Jaggi mServices[i].mComponents = mComponents; 184cff0acb6b1eea23c3f44a078a0a5e81c11faea35Jorim Jaggi if (DEBUG) Log.d(TAG, "running: " + mServices[i]); 185cff0acb6b1eea23c3f44a078a0a5e81c11faea35Jorim Jaggi mServices[i].start(); 186f3591359b9841a1571545a39b038802ce7ed77bbFyodor Kupolov log.traceEnd(); 187dc5f16bf096796d2f822bce8a720fc26e898da5eDan Sandler 188f3591359b9841a1571545a39b038802ce7ed77bbFyodor Kupolov // Warn if initialization of component takes too long 189f3591359b9841a1571545a39b038802ce7ed77bbFyodor Kupolov ti = System.currentTimeMillis() - ti; 190f3591359b9841a1571545a39b038802ce7ed77bbFyodor Kupolov if (ti > 1000) { 19161b37088337753a7e631579829040c5cae9d72c4yoshiki iguchi Log.w(TAG, "Initialization of " + cls.getName() + " took " + ti + " ms"); 192f3591359b9841a1571545a39b038802ce7ed77bbFyodor Kupolov } 193dc5f16bf096796d2f822bce8a720fc26e898da5eDan Sandler if (mBootCompleted) { 194dc5f16bf096796d2f822bce8a720fc26e898da5eDan Sandler mServices[i].onBootCompleted(); 195dc5f16bf096796d2f822bce8a720fc26e898da5eDan Sandler } 196cff0acb6b1eea23c3f44a078a0a5e81c11faea35Jorim Jaggi } 197f3591359b9841a1571545a39b038802ce7ed77bbFyodor Kupolov log.traceEnd(); 1985bec68fbea1a02d7debc2eeeaf01b9478de216e5Jason Monk Dependency.get(PluginManager.class).addPluginListener( 19986bc33188948e7b6beb07dbb5ddba59b5ea3c1fcJason Monk new PluginListener<OverlayPlugin>() { 200421a9410b462770544c6ae9a554542fa2fe1acb1Jason Monk private ArraySet<OverlayPlugin> mOverlays; 201421a9410b462770544c6ae9a554542fa2fe1acb1Jason Monk 202421a9410b462770544c6ae9a554542fa2fe1acb1Jason Monk @Override 203421a9410b462770544c6ae9a554542fa2fe1acb1Jason Monk public void onPluginConnected(OverlayPlugin plugin, Context pluginContext) { 204421a9410b462770544c6ae9a554542fa2fe1acb1Jason Monk StatusBar statusBar = getComponent(StatusBar.class); 205421a9410b462770544c6ae9a554542fa2fe1acb1Jason Monk if (statusBar != null) { 206421a9410b462770544c6ae9a554542fa2fe1acb1Jason Monk plugin.setup(statusBar.getStatusBarWindow(), 207421a9410b462770544c6ae9a554542fa2fe1acb1Jason Monk statusBar.getNavigationBarView()); 208421a9410b462770544c6ae9a554542fa2fe1acb1Jason Monk } 209421a9410b462770544c6ae9a554542fa2fe1acb1Jason Monk // Lazy init. 210421a9410b462770544c6ae9a554542fa2fe1acb1Jason Monk if (mOverlays == null) mOverlays = new ArraySet<>(); 211421a9410b462770544c6ae9a554542fa2fe1acb1Jason Monk if (plugin.holdStatusBarOpen()) { 212421a9410b462770544c6ae9a554542fa2fe1acb1Jason Monk mOverlays.add(plugin); 213421a9410b462770544c6ae9a554542fa2fe1acb1Jason Monk Dependency.get(StatusBarWindowManager.class).setStateListener(b -> 214421a9410b462770544c6ae9a554542fa2fe1acb1Jason Monk mOverlays.forEach(o -> o.setCollapseDesired(b))); 215421a9410b462770544c6ae9a554542fa2fe1acb1Jason Monk Dependency.get(StatusBarWindowManager.class).setForcePluginOpen( 216421a9410b462770544c6ae9a554542fa2fe1acb1Jason Monk mOverlays.size() != 0); 217421a9410b462770544c6ae9a554542fa2fe1acb1Jason Monk 218421a9410b462770544c6ae9a554542fa2fe1acb1Jason Monk } 219421a9410b462770544c6ae9a554542fa2fe1acb1Jason Monk } 220421a9410b462770544c6ae9a554542fa2fe1acb1Jason Monk 221421a9410b462770544c6ae9a554542fa2fe1acb1Jason Monk @Override 222421a9410b462770544c6ae9a554542fa2fe1acb1Jason Monk public void onPluginDisconnected(OverlayPlugin plugin) { 223421a9410b462770544c6ae9a554542fa2fe1acb1Jason Monk mOverlays.remove(plugin); 224421a9410b462770544c6ae9a554542fa2fe1acb1Jason Monk Dependency.get(StatusBarWindowManager.class).setForcePluginOpen( 225421a9410b462770544c6ae9a554542fa2fe1acb1Jason Monk mOverlays.size() != 0); 226421a9410b462770544c6ae9a554542fa2fe1acb1Jason Monk } 2275bec68fbea1a02d7debc2eeeaf01b9478de216e5Jason Monk }, OverlayPlugin.class, true /* Allow multiple plugins */); 22886bc33188948e7b6beb07dbb5ddba59b5ea3c1fcJason Monk 2293beffdf4a0081a97356f46d50e10541b1a213153Jorim Jaggi mServicesStarted = true; 230cff0acb6b1eea23c3f44a078a0a5e81c11faea35Jorim Jaggi } 231cff0acb6b1eea23c3f44a078a0a5e81c11faea35Jorim Jaggi 232cff0acb6b1eea23c3f44a078a0a5e81c11faea35Jorim Jaggi @Override 233cff0acb6b1eea23c3f44a078a0a5e81c11faea35Jorim Jaggi public void onConfigurationChanged(Configuration newConfig) { 2343beffdf4a0081a97356f46d50e10541b1a213153Jorim Jaggi if (mServicesStarted) { 2353beffdf4a0081a97356f46d50e10541b1a213153Jorim Jaggi int len = mServices.length; 2363beffdf4a0081a97356f46d50e10541b1a213153Jorim Jaggi for (int i = 0; i < len; i++) { 23794a148594d56e87920c3771ab630a5337612bd52Winson if (mServices[i] != null) { 23894a148594d56e87920c3771ab630a5337612bd52Winson mServices[i].onConfigurationChanged(newConfig); 23994a148594d56e87920c3771ab630a5337612bd52Winson } 2403beffdf4a0081a97356f46d50e10541b1a213153Jorim Jaggi } 241cff0acb6b1eea23c3f44a078a0a5e81c11faea35Jorim Jaggi } 242cff0acb6b1eea23c3f44a078a0a5e81c11faea35Jorim Jaggi } 243cff0acb6b1eea23c3f44a078a0a5e81c11faea35Jorim Jaggi 244cff0acb6b1eea23c3f44a078a0a5e81c11faea35Jorim Jaggi @SuppressWarnings("unchecked") 245cff0acb6b1eea23c3f44a078a0a5e81c11faea35Jorim Jaggi public <T> T getComponent(Class<T> interfaceType) { 246cff0acb6b1eea23c3f44a078a0a5e81c11faea35Jorim Jaggi return (T) mComponents.get(interfaceType); 247cff0acb6b1eea23c3f44a078a0a5e81c11faea35Jorim Jaggi } 248cff0acb6b1eea23c3f44a078a0a5e81c11faea35Jorim Jaggi 249cff0acb6b1eea23c3f44a078a0a5e81c11faea35Jorim Jaggi public SystemUI[] getServices() { 250cff0acb6b1eea23c3f44a078a0a5e81c11faea35Jorim Jaggi return mServices; 251cff0acb6b1eea23c3f44a078a0a5e81c11faea35Jorim Jaggi } 252cff0acb6b1eea23c3f44a078a0a5e81c11faea35Jorim Jaggi} 253