diff options
Diffstat (limited to 'packages/SystemUI/src')
9 files changed, 188 insertions, 17 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/SystemUI.java b/packages/SystemUI/src/com/android/systemui/SystemUI.java index 2110483..14f6345 100644 --- a/packages/SystemUI/src/com/android/systemui/SystemUI.java +++ b/packages/SystemUI/src/com/android/systemui/SystemUI.java @@ -26,7 +26,7 @@ public abstract class SystemUI { public Context mContext; public abstract void start(); - + protected void onConfigurationChanged(Configuration newConfig) { } diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIService.java b/packages/SystemUI/src/com/android/systemui/SystemUIService.java index 427fe91..18bedf1 100644 --- a/packages/SystemUI/src/com/android/systemui/SystemUIService.java +++ b/packages/SystemUI/src/com/android/systemui/SystemUIService.java @@ -96,6 +96,7 @@ public class SystemUIService extends Service { } mServices[i].mContext = this; Slog.d(TAG, "running: " + mServices[i]); + mServices[i].start(); } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java index fe33b02..8743a90 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java @@ -73,6 +73,7 @@ import android.view.ViewGroup; import android.view.ViewGroup.LayoutParams; import android.view.WindowManager; import android.view.WindowManagerGlobal; +import android.widget.FrameLayout; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.PopupMenu; @@ -124,6 +125,8 @@ public abstract class BaseStatusBar extends SystemUI implements protected int mCurrentUserId = 0; + protected FrameLayout mStatusBarContainer; + // UI-specific methods /** @@ -203,6 +206,8 @@ public abstract class BaseStatusBar extends SystemUI implements mBarService = IStatusBarService.Stub.asInterface( ServiceManager.getService(Context.STATUS_BAR_SERVICE)); + mStatusBarContainer = new FrameLayout(mContext); + // Connect in to the status bar manager service StatusBarIconList iconList = new StatusBarIconList(); ArrayList<IBinder> notificationKeys = new ArrayList<IBinder>(); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java index c82f250..9c947ae 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java @@ -147,6 +147,10 @@ public class NotificationData { return e; } + public void clear() { + mEntries.clear(); + } + /** * Return whether there are any visible items (i.e. items without an error). */ diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java index dbc55c8..3bc3b65 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java @@ -207,6 +207,10 @@ public class StatusBarIconView extends AnimatedImageView { } } + public String getStatusBarSlot() { + return mSlot; + } + @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java index 337aa0d..d21492b 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java @@ -31,6 +31,7 @@ import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.SharedPreferences; +import android.content.res.CustomTheme; import android.content.res.Resources; import android.database.ContentObserver; import android.graphics.Canvas; @@ -53,6 +54,7 @@ import android.service.dreams.DreamService; import android.service.dreams.IDreamManager; import android.util.DisplayMetrics; import android.util.Log; +import android.util.Pair; import android.util.Slog; import android.view.Display; import android.view.Gravity; @@ -70,6 +72,7 @@ import android.view.animation.AnimationUtils; import android.view.animation.DecelerateInterpolator; import android.widget.FrameLayout; import android.widget.ImageView; +import android.widget.FrameLayout; import android.widget.LinearLayout; import android.widget.ScrollView; import android.widget.TextView; @@ -266,6 +269,11 @@ public class PhoneStatusBar extends BaseStatusBar { private Animator mLightsOutAnimation; private Animator mLightsOnAnimation; + // last theme that was applied in order to detect theme change (as opposed + // to some other configuration change). + CustomTheme mCurrentTheme; + private boolean mRecreating = false; + // for disabling the status bar int mDisabled = 0; @@ -326,6 +334,11 @@ public class PhoneStatusBar extends BaseStatusBar { mDreamManager = IDreamManager.Stub.asInterface( ServiceManager.checkService(DreamService.DREAM_SERVICE)); + CustomTheme currentTheme = mContext.getResources().getConfiguration().customTheme; + if (currentTheme != null) { + mCurrentTheme = (CustomTheme)currentTheme.clone(); + } + super.start(); // calls createAndAddWindows() addNavigationBar(); @@ -404,7 +417,7 @@ public class PhoneStatusBar extends BaseStatusBar { try { boolean showNav = mWindowManagerService.hasNavigationBar(); if (DEBUG) Slog.v(TAG, "hasNavigationBar=" + showNav); - if (showNav) { + if (showNav && !mRecreating) { mNavigationBarView = (NavigationBarView) View.inflate(context, R.layout.navigation_bar, null); @@ -425,6 +438,11 @@ public class PhoneStatusBar extends BaseStatusBar { mStatusBarContents = (LinearLayout)mStatusBarView.findViewById(R.id.status_bar_contents); mTickerView = mStatusBarView.findViewById(R.id.ticker); + /* Destroy the old widget before recreating the expanded dialog + to make sure there are no context issues */ + if (mRecreating) + mPowerWidget.destroyWidget(); + mPile = (NotificationRowLayout)mStatusBarWindow.findViewById(R.id.latestItems); mPile.setLayoutTransitionsEnabled(false); mPile.setLongPressListener(getNotificationLongClicker()); @@ -505,7 +523,6 @@ public class PhoneStatusBar extends BaseStatusBar { mTicker = new MyTicker(context, mStatusBarView); - TickerView tickerView = (TickerView)mStatusBarView.findViewById(R.id.tickerText); tickerView.mTicker = mTicker; @@ -696,6 +713,10 @@ public class PhoneStatusBar extends BaseStatusBar { return lp; } + void onBarViewDetached() { + // WindowManagerImpl.getDefault().removeView(mStatusBarWindow); + } + @Override protected void updateSearchPanel() { super.updateSearchPanel(); @@ -806,6 +827,12 @@ public class PhoneStatusBar extends BaseStatusBar { private void repositionNavigationBar() { if (mNavigationBarView == null) return; + CustomTheme newTheme = mContext.getResources().getConfiguration().customTheme; + if (newTheme != null && + (mCurrentTheme == null || !mCurrentTheme.equals(newTheme))) { + // Nevermind, this will be re-created + return; + } prepareNavigationBarView(); mWindowManager.updateViewLayout(mNavigationBarView, getNavigationBarLayoutParams()); @@ -941,7 +968,7 @@ public class PhoneStatusBar extends BaseStatusBar { notification.notification.fullScreenIntent.send(); } catch (PendingIntent.CanceledException e) { } - } else { + } else if (!mRecreating) { // usual case: status bar visible & not immersive // show the ticker if there isn't an intruder too @@ -1362,11 +1389,11 @@ public class PhoneStatusBar extends BaseStatusBar { // Expand the window to encompass the full screen in anticipation of the drag. // This is only possible to do atomically because the status bar is at the top of the screen! - WindowManager.LayoutParams lp = (WindowManager.LayoutParams) mStatusBarWindow.getLayoutParams(); + WindowManager.LayoutParams lp = (WindowManager.LayoutParams) mStatusBarContainer.getLayoutParams(); lp.flags &= ~WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE; lp.flags |= WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM; lp.height = ViewGroup.LayoutParams.MATCH_PARENT; - mWindowManager.updateViewLayout(mStatusBarWindow, lp); + mWindowManager.updateViewLayout(mStatusBarContainer, lp); // Updating the window layout will force an expensive traversal/redraw. // Kick off the reveal animation after this is complete to avoid animation latency. @@ -1640,11 +1667,11 @@ public class PhoneStatusBar extends BaseStatusBar { visibilityChanged(false); // Shrink the window to the size of the status bar only - WindowManager.LayoutParams lp = (WindowManager.LayoutParams) mStatusBarWindow.getLayoutParams(); + WindowManager.LayoutParams lp = (WindowManager.LayoutParams) mStatusBarContainer.getLayoutParams(); lp.height = getStatusBarHeight(); lp.flags |= WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE; lp.flags &= ~WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM; - mWindowManager.updateViewLayout(mStatusBarWindow, lp); + mWindowManager.updateViewLayout(mStatusBarContainer, lp); if ((mDisabled & StatusBarManager.DISABLE_NOTIFICATION_ICONS) == 0) { setNotificationIconVisibility(true, com.android.internal.R.anim.fade_in); @@ -1944,7 +1971,7 @@ public class PhoneStatusBar extends BaseStatusBar { // until status bar window is attached to the window manager, // because... well, what's the point otherwise? And trying to // run a ticker without being attached will crash! - if (n.notification.tickerText != null && mStatusBarWindow.getWindowToken() != null) { + if (n.notification.tickerText != null && mStatusBarContainer.getWindowToken() != null) { if (0 == (mDisabled & (StatusBarManager.DISABLE_NOTIFICATION_ICONS | StatusBarManager.DISABLE_NOTIFICATION_TICKER))) { mTicker.addEntry(n); @@ -2089,7 +2116,6 @@ public class PhoneStatusBar extends BaseStatusBar { private void addStatusBarWindow() { // Put up the view final int height = getStatusBarHeight(); - // Now that the status bar window encompasses the sliding panel and its // translucent backdrop, the entire thing is made TRANSLUCENT and is // hardware-accelerated. @@ -2109,7 +2135,8 @@ public class PhoneStatusBar extends BaseStatusBar { lp.packageName = mContext.getPackageName(); makeStatusBarView(); - mWindowManager.addView(mStatusBarWindow, lp); + mStatusBarContainer.addView(mStatusBarWindow); + mWindowManager.addView(mStatusBarContainer, lp); } void setNotificationIconVisibility(boolean visible, int anim) { @@ -2355,6 +2382,60 @@ public class PhoneStatusBar extends BaseStatusBar { } } + private static void copyNotifications(ArrayList<Pair<IBinder, StatusBarNotification>> dest, + NotificationData source) { + int N = source.size(); + for (int i = 0; i < N; i++) { + NotificationData.Entry entry = source.get(i); + dest.add(Pair.create(entry.key, entry.notification)); + } + } + + private void recreateStatusBar() { + mRecreating = true; + mStatusBarContainer.removeAllViews(); + + // extract icons from the soon-to-be recreated viewgroup. + int nIcons = mStatusIcons.getChildCount(); + ArrayList<StatusBarIcon> icons = new ArrayList<StatusBarIcon>(nIcons); + ArrayList<String> iconSlots = new ArrayList<String>(nIcons); + for (int i = 0; i < nIcons; i++) { + StatusBarIconView iconView = (StatusBarIconView)mStatusIcons.getChildAt(i); + icons.add(iconView.getStatusBarIcon()); + iconSlots.add(iconView.getStatusBarSlot()); + } + + // extract notifications. + int nNotifs = mNotificationData.size(); + ArrayList<Pair<IBinder, StatusBarNotification>> notifications = + new ArrayList<Pair<IBinder, StatusBarNotification>>(nNotifs); + copyNotifications(notifications, mNotificationData); + mNotificationData.clear(); + + makeStatusBarView(); + repositionNavigationBar(); + + // recreate StatusBarIconViews. + for (int i = 0; i < nIcons; i++) { + StatusBarIcon icon = icons.get(i); + String slot = iconSlots.get(i); + addIcon(slot, i, i, icon); + } + + // recreate notifications. + for (int i = 0; i < nNotifs; i++) { + Pair<IBinder, StatusBarNotification> notifData = notifications.get(i); + addNotificationViews(notifData.first, notifData.second); + } + + setAreThereNotifications(); + + mStatusBarContainer.addView(mStatusBarWindow); + + updateExpandedViewPos(EXPANDED_LEAVE_ALONE); + mRecreating = false; + } + /** * Reload some of our resources when the configuration changes. * @@ -2366,14 +2447,23 @@ public class PhoneStatusBar extends BaseStatusBar { final Context context = mContext; final Resources res = context.getResources(); - if (mClearButton instanceof TextView) { - ((TextView)mClearButton).setText(context.getText(R.string.status_bar_clear_all_button)); + // detect theme change. + CustomTheme newTheme = res.getConfiguration().customTheme; + if (newTheme != null && + (mCurrentTheme == null || !mCurrentTheme.equals(newTheme))) { + mCurrentTheme = (CustomTheme)newTheme.clone(); + recreateStatusBar(); + } else { + + if (mClearButton instanceof TextView) { + ((TextView)mClearButton).setText(context.getText(R.string.status_bar_clear_all_button)); + } + loadDimens(); } // Update the QuickSettings container if (mQS != null) mQS.updateResources(); - loadDimens(); } protected void loadDimens() { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java index af6a149..a86a869 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java @@ -84,6 +84,12 @@ public class PhoneStatusBarView extends PanelBar { } @Override + protected void onDetachedFromWindow() { + super.onDetachedFromWindow(); + mBar.onBarViewDetached(); + } + + @Override public boolean panelsEnabled() { return ((mBar.mDisabled & StatusBarManager.DISABLE_EXPAND) == 0); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java index f526f0c..874ca5e 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java @@ -66,6 +66,12 @@ public class StatusBarWindowView extends FrameLayout } @Override + public void dispatchWindowFocusChanged(boolean hasFocus) { + this.setFocusableInTouchMode(hasFocus); + this.requestFocus(); + } + + @Override public boolean dispatchKeyEvent(KeyEvent event) { boolean down = event.getAction() == KeyEvent.ACTION_DOWN; switch (event.getKeyCode()) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java index 86c247a..028528c 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java @@ -29,6 +29,7 @@ import android.content.Intent; import android.content.IntentFilter; import android.content.SharedPreferences; import android.content.res.Configuration; +import android.content.res.CustomTheme; import android.content.res.Resources; import android.graphics.PixelFormat; import android.graphics.Point; @@ -39,6 +40,7 @@ import android.os.IBinder; import android.os.Message; import android.os.RemoteException; import android.text.TextUtils; +import android.util.Pair; import android.util.Slog; import android.view.Display; import android.view.Gravity; @@ -53,6 +55,7 @@ import android.view.ViewGroup.LayoutParams; import android.view.WindowManager; import android.view.accessibility.AccessibilityEvent; import android.widget.ImageView; +import android.widget.FrameLayout; import android.widget.LinearLayout; import android.widget.ScrollView; import android.widget.TextView; @@ -236,6 +239,12 @@ public class TabletStatusBar extends BaseStatusBar implements mWindowManager.addView(sb, lp); } + // last theme that was applied in order to detect theme change (as opposed + // to some other configuration change). + CustomTheme mCurrentTheme; + private boolean mRecreating = false; + + protected void addPanelWindows() { final Context context = mContext; final Resources res = mContext.getResources(); @@ -379,8 +388,49 @@ public class TabletStatusBar extends BaseStatusBar implements super.start(); // will add the main bar view } + private static void copyNotifications(ArrayList<Pair<IBinder, StatusBarNotification>> dest, + NotificationData source) { + int N = source.size(); + for (int i = 0; i < N; i++) { + NotificationData.Entry entry = source.get(i); + dest.add(Pair.create(entry.key, entry.notification)); + } + } + + private void recreateStatusBar() { + mRecreating = true; + mStatusBarContainer.removeAllViews(); + + // extract notifications. + int nNotifs = mNotificationData.size(); + ArrayList<Pair<IBinder, StatusBarNotification>> notifications = + new ArrayList<Pair<IBinder, StatusBarNotification>>(nNotifs); + copyNotifications(notifications, mNotificationData); + mNotificationData.clear(); + + mStatusBarContainer.addView(makeStatusBarView()); + + // recreate notifications. + for (int i = 0; i < nNotifs; i++) { + Pair<IBinder, StatusBarNotification> notifData = notifications.get(i); + addNotificationViews(notifData.first, notifData.second); + } + + setAreThereNotifications(); + + mRecreating = false; + } + + @Override protected void onConfigurationChanged(Configuration newConfig) { + // detect theme change. + CustomTheme newTheme = mContext.getResources().getConfiguration().customTheme; + if (newTheme != null && + (mCurrentTheme == null || !mCurrentTheme.equals(newTheme))) { + mCurrentTheme = (CustomTheme)newTheme.clone(); + recreateStatusBar(); + } loadDimens(); mNotificationPanelParams.height = getNotificationPanelHeight(); mWindowManager.updateViewLayout(mNotificationPanel, mNotificationPanelParams); @@ -443,6 +493,11 @@ public class TabletStatusBar extends BaseStatusBar implements protected View makeStatusBarView() { final Context context = mContext; + CustomTheme currentTheme = mContext.getResources().getConfiguration().customTheme; + if (currentTheme != null) { + mCurrentTheme = (CustomTheme)currentTheme.clone(); + } + loadDimens(); final TabletStatusBarView sb = (TabletStatusBarView)View.inflate( @@ -684,14 +739,14 @@ public class TabletStatusBar extends BaseStatusBar implements public void onBarHeightChanged(int height) { final WindowManager.LayoutParams lp - = (WindowManager.LayoutParams)mStatusBarView.getLayoutParams(); + = (WindowManager.LayoutParams)mStatusBarContainer.getLayoutParams(); if (lp == null) { // haven't been added yet return; } if (lp.height != height) { lp.height = height; - mWindowManager.updateViewLayout(mStatusBarView, lp); + mWindowManager.updateViewLayout(mStatusBarContainer, lp); } } @@ -861,7 +916,7 @@ public class TabletStatusBar extends BaseStatusBar implements notification.notification.fullScreenIntent.send(); } catch (PendingIntent.CanceledException e) { } - } else { + } else if (!mRecreating) { tick(key, notification, true); } |
