15c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock/*
25c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock * Copyright (C) 2013 The Android Open Source Project
35c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock *
45c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock * Licensed under the Apache License, Version 2.0 (the "License");
55c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock * you may not use this file except in compliance with the License.
65c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock * You may obtain a copy of the License at
75c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock *
85c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock *      http://www.apache.org/licenses/LICENSE-2.0
95c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock *
105c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock * Unless required by applicable law or agreed to in writing, software
115c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock * distributed under the License is distributed on an "AS IS" BASIS,
125c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
135c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock * See the License for the specific language governing permissions and
145c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock * limitations under the License.
155c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock */
165c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock
175c4541246c6a70f53552423dc35940386788bd5fJohn Spurlockpackage com.android.systemui.statusbar;
185c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock
19777dcdeeb67c570168e04d5096d2a7a9eb408ceaDaniel Sandlerimport android.content.res.Configuration;
205c4541246c6a70f53552423dc35940386788bd5fJohn Spurlockimport android.provider.Settings;
215c4541246c6a70f53552423dc35940386788bd5fJohn Spurlockimport android.util.Log;
225c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock
235c4541246c6a70f53552423dc35940386788bd5fJohn Spurlockimport com.android.systemui.R;
245c4541246c6a70f53552423dc35940386788bd5fJohn Spurlockimport com.android.systemui.SystemUI;
255c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock
260ec64c65fb7fbfd89556bc33f5caab4ef0937fd4John Spurlockimport java.io.FileDescriptor;
270ec64c65fb7fbfd89556bc33f5caab4ef0937fd4John Spurlockimport java.io.PrintWriter;
280ec64c65fb7fbfd89556bc33f5caab4ef0937fd4John Spurlock
295c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock/**
305c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock * Ensure a single status bar service implementation is running at all times.
315c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock *
325c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock * <p>The implementation either comes from a service component running in a remote process (defined
335c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock * using a secure setting), else falls back to using the in-process implementation according
345c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock * to the product config.
355c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock */
365c4541246c6a70f53552423dc35940386788bd5fJohn Spurlockpublic class SystemBars extends SystemUI implements ServiceMonitor.Callbacks {
375c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock    private static final String TAG = "SystemBars";
38342cad772be1973875dea6a31ceb04bc72e7a6b5John Spurlock    private static final boolean DEBUG = false;
395c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock    private static final int WAIT_FOR_BARS_TO_DIE = 500;
405c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock
415c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock    // manages the implementation coming from the remote process
425c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock    private ServiceMonitor mServiceMonitor;
435c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock
445c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock    // in-process fallback implementation, per the product config
455c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock    private BaseStatusBar mStatusBar;
465c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock
475c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock    @Override
485c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock    public void start() {
495c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock        if (DEBUG) Log.d(TAG, "start");
505c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock        mServiceMonitor = new ServiceMonitor(TAG, DEBUG,
515c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock                mContext, Settings.Secure.BAR_SERVICE_COMPONENT, this);
525c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock        mServiceMonitor.start();  // will call onNoService if no remote service is found
535c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock    }
545c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock
555c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock    @Override
565c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock    public void onNoService() {
575c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock        if (DEBUG) Log.d(TAG, "onNoService");
585c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock        createStatusBarFromConfig();  // fallback to using an in-process implementation
595c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock    }
605c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock
615c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock    @Override
625c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock    public long onServiceStartAttempt() {
635c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock        if (DEBUG) Log.d(TAG, "onServiceStartAttempt mStatusBar="+mStatusBar);
645c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock        if (mStatusBar != null) {
655c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock            // tear down the in-process version, we'll recreate it again if needed
665c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock            mStatusBar.destroy();
675c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock            mStatusBar = null;
685c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock            return WAIT_FOR_BARS_TO_DIE;
695c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock        }
705c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock        return 0;
715c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock    }
725c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock
730ec64c65fb7fbfd89556bc33f5caab4ef0937fd4John Spurlock    @Override
74777dcdeeb67c570168e04d5096d2a7a9eb408ceaDaniel Sandler    protected void onConfigurationChanged(Configuration newConfig) {
75777dcdeeb67c570168e04d5096d2a7a9eb408ceaDaniel Sandler        if (mStatusBar != null) {
76777dcdeeb67c570168e04d5096d2a7a9eb408ceaDaniel Sandler            mStatusBar.onConfigurationChanged(newConfig);
77777dcdeeb67c570168e04d5096d2a7a9eb408ceaDaniel Sandler        }
78777dcdeeb67c570168e04d5096d2a7a9eb408ceaDaniel Sandler    }
79777dcdeeb67c570168e04d5096d2a7a9eb408ceaDaniel Sandler
80777dcdeeb67c570168e04d5096d2a7a9eb408ceaDaniel Sandler    @Override
810ec64c65fb7fbfd89556bc33f5caab4ef0937fd4John Spurlock    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
820ec64c65fb7fbfd89556bc33f5caab4ef0937fd4John Spurlock        if (mStatusBar != null) {
830ec64c65fb7fbfd89556bc33f5caab4ef0937fd4John Spurlock            mStatusBar.dump(fd, pw, args);
840ec64c65fb7fbfd89556bc33f5caab4ef0937fd4John Spurlock        }
850ec64c65fb7fbfd89556bc33f5caab4ef0937fd4John Spurlock    }
860ec64c65fb7fbfd89556bc33f5caab4ef0937fd4John Spurlock
875c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock    private void createStatusBarFromConfig() {
885c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock        if (DEBUG) Log.d(TAG, "createStatusBarFromConfig");
895c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock        final String clsName = mContext.getString(R.string.config_statusBarComponent);
905c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock        if (clsName == null || clsName.length() == 0) {
915c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock            throw andLog("No status bar component configured", null);
925c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock        }
935c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock        Class<?> cls = null;
945c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock        try {
955c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock            cls = mContext.getClassLoader().loadClass(clsName);
965c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock        } catch (Throwable t) {
975c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock            throw andLog("Error loading status bar component: " + clsName, t);
985c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock        }
995c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock        try {
1005c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock            mStatusBar = (BaseStatusBar) cls.newInstance();
1015c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock        } catch (Throwable t) {
1025c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock            throw andLog("Error creating status bar component: " + clsName, t);
1035c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock        }
1045c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock        mStatusBar.mContext = mContext;
105d08de37a2223d5183620098737eb93907a4ba92cJohn Spurlock        mStatusBar.mComponents = mComponents;
1065c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock        mStatusBar.start();
1075c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock        if (DEBUG) Log.d(TAG, "started " + mStatusBar.getClass().getSimpleName());
1085c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock    }
1095c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock
1105c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock    private RuntimeException andLog(String msg, Throwable t) {
1115c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock        Log.w(TAG, msg, t);
1125c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock        throw new RuntimeException(msg, t);
1135c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock    }
1145c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock}
115