summaryrefslogtreecommitdiffstats
path: root/packages/SystemUI/src/com/android/systemui/statusbar/SystemBars.java
diff options
context:
space:
mode:
authorJohn Spurlock <jspurlock@google.com>2013-06-17 07:35:46 -0400
committerJohn Spurlock <jspurlock@google.com>2013-06-21 17:31:25 -0400
commit5c4541246c6a70f53552423dc35940386788bd5f (patch)
tree046c57c05b972b2a5e8929fd9cd748d365a592e9 /packages/SystemUI/src/com/android/systemui/statusbar/SystemBars.java
parente36b93575f14239ff38ea8b71e39e41b0312326b (diff)
downloadframeworks_base-5c4541246c6a70f53552423dc35940386788bd5f.zip
frameworks_base-5c4541246c6a70f53552423dc35940386788bd5f.tar.gz
frameworks_base-5c4541246c6a70f53552423dc35940386788bd5f.tar.bz2
Introduce SystemUI-managed alternative system bars.
If a service component is defined in a new secure setting, SystemUI will attempt to use that service as the status bar provider. Falls back to the existing in-process implementation configured in the product config if the setting is missing or invalid. Nothing changes yet from a permission point of view. Alternative system bar implementations still require the status bar permission. Also nothing changes from an api point of view. Alternative system bar implementations use the existing IStatusBar interface. This simply enables testing alternative system bar implementations installed from other trusted, platform-signed packages. Known caveat: the setting is stored per user, multi-user changes will be handled in a future CL. Change-Id: I0413df185f7e75f77ad2ae1bc3689306d5e6e0fb
Diffstat (limited to 'packages/SystemUI/src/com/android/systemui/statusbar/SystemBars.java')
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/SystemBars.java95
1 files changed, 95 insertions, 0 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/SystemBars.java b/packages/SystemUI/src/com/android/systemui/statusbar/SystemBars.java
new file mode 100644
index 0000000..847bf96
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/SystemBars.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar;
+
+import android.provider.Settings;
+import android.util.Log;
+
+import com.android.systemui.R;
+import com.android.systemui.SystemUI;
+
+/**
+ * Ensure a single status bar service implementation is running at all times.
+ *
+ * <p>The implementation either comes from a service component running in a remote process (defined
+ * using a secure setting), else falls back to using the in-process implementation according
+ * to the product config.
+ */
+public class SystemBars extends SystemUI implements ServiceMonitor.Callbacks {
+ private static final String TAG = "SystemBars";
+ private static final boolean DEBUG = true;
+ private static final int WAIT_FOR_BARS_TO_DIE = 500;
+
+ // manages the implementation coming from the remote process
+ private ServiceMonitor mServiceMonitor;
+
+ // in-process fallback implementation, per the product config
+ private BaseStatusBar mStatusBar;
+
+ @Override
+ public void start() {
+ if (DEBUG) Log.d(TAG, "start");
+ mServiceMonitor = new ServiceMonitor(TAG, DEBUG,
+ mContext, Settings.Secure.BAR_SERVICE_COMPONENT, this);
+ mServiceMonitor.start(); // will call onNoService if no remote service is found
+ }
+
+ @Override
+ public void onNoService() {
+ if (DEBUG) Log.d(TAG, "onNoService");
+ createStatusBarFromConfig(); // fallback to using an in-process implementation
+ }
+
+ @Override
+ public long onServiceStartAttempt() {
+ if (DEBUG) Log.d(TAG, "onServiceStartAttempt mStatusBar="+mStatusBar);
+ if (mStatusBar != null) {
+ // tear down the in-process version, we'll recreate it again if needed
+ mStatusBar.destroy();
+ mStatusBar = null;
+ return WAIT_FOR_BARS_TO_DIE;
+ }
+ return 0;
+ }
+
+ private void createStatusBarFromConfig() {
+ if (DEBUG) Log.d(TAG, "createStatusBarFromConfig");
+ final String clsName = mContext.getString(R.string.config_statusBarComponent);
+ if (clsName == null || clsName.length() == 0) {
+ throw andLog("No status bar component configured", null);
+ }
+ Class<?> cls = null;
+ try {
+ cls = mContext.getClassLoader().loadClass(clsName);
+ } catch (Throwable t) {
+ throw andLog("Error loading status bar component: " + clsName, t);
+ }
+ try {
+ mStatusBar = (BaseStatusBar) cls.newInstance();
+ } catch (Throwable t) {
+ throw andLog("Error creating status bar component: " + clsName, t);
+ }
+ mStatusBar.mContext = mContext;
+ mStatusBar.start();
+ if (DEBUG) Log.d(TAG, "started " + mStatusBar.getClass().getSimpleName());
+ }
+
+ private RuntimeException andLog(String msg, Throwable t) {
+ Log.w(TAG, msg, t);
+ throw new RuntimeException(msg, t);
+ }
+}