Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a478f39e authored by Josh Guilfoyle's avatar Josh Guilfoyle
Browse files

Hack to update status bar service drawables on theme change.

The status bar UI is running in a service which doesn't have the typical
activity lifecycle to trigger a View reinflation that is normally used
to apply a theme.  Manual reinflation is tricky for the status bar
because of hacks in the PhoneWindowManager which attach to the initial
status bar view added to it (it apparently cannot be removed in a stable
fashion).  More research is needed to solve this issue properly.
parent 3dc4cedd
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -24,7 +24,7 @@
    android:descendantFocusability="afterDescendants"
    >

    <LinearLayout
    <LinearLayout android:id="@+id/exp_view_lin_layout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
+1 −1
Original line number Diff line number Diff line
@@ -14,7 +14,7 @@
            >
    </com.android.systemui.statusbar.LatestItemView>

    <View
    <View android:id="@+id/separator"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@drawable/divider_horizontal_light_opaque"
+24 −0
Original line number Diff line number Diff line
@@ -67,6 +67,30 @@ public class StatusBarIconView extends AnimatedImageView {
        return a.equals(b);
    }

    /**
     * Refresh resources that might have changed due to a configuration change.
     */
    public void updateResources() {
        StatusBarIcon icon = mIcon;
        if (icon != null) {
            Drawable drawable = getIcon(icon);
            if (drawable != null) {
                setImageDrawable(drawable);
            }

            if (icon.number > 0) {
                mNumberBackground = getContext().getResources().getDrawable(
                        R.drawable.ic_notification_overlay);
                placeNumber();
            } else {
                mNumberBackground = null;
                mNumberText = null;
            }

            invalidate();
        }
    }

    /**
     * Returns whether the set succeeded.
     */
+71 −0
Original line number Diff line number Diff line
@@ -34,6 +34,7 @@ import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.content.res.CustomTheme;
import android.content.res.Resources;
import android.graphics.PixelFormat;
import android.graphics.Rect;
@@ -106,6 +107,10 @@ public class StatusBarService extends Service implements CommandQueue.Callbacks
    H mHandler = new H();
    Object mQueueLock = new Object();

    // last theme that was applied in order to detect theme change (as opposed
    // to some other configuration change).
    CustomTheme mCurrentTheme;

    // icons
    LinearLayout mIcons;
    IconMerger mNotificationIcons;
@@ -1458,6 +1463,15 @@ public class StatusBarService extends Service implements CommandQueue.Callbacks
    void updateResources() {
        Resources res = getResources();

        // detect theme change.
        boolean themeChanged = false;
        CustomTheme newTheme = res.getConfiguration().customTheme;
        if (newTheme != null &&
                (mCurrentTheme == null || !mCurrentTheme.equals(newTheme))) {
            mCurrentTheme = (CustomTheme)newTheme.clone();
            themeChanged = true;
        }

        mClearButton.setText(getText(R.string.status_bar_clear_all_button));
        mOngoingTitle.setText(getText(R.string.status_bar_ongoing_events_title));
        mLatestTitle.setText(getText(R.string.status_bar_latest_events_title));
@@ -1465,6 +1479,63 @@ public class StatusBarService extends Service implements CommandQueue.Callbacks

        mEdgeBorder = res.getDimensionPixelSize(R.dimen.status_bar_edge_ignore);

        /*
         * HACK: Attempt to re-apply views that could have changed from a theme.
         * This will be replaced with a better solution reinflating the
         * necessary views.
         */
        if (themeChanged) {
            // XXX: If this changes in the XML, it must also change here.
            mStatusBarView.setBackgroundDrawable(res.getDrawable(R.drawable.statusbar_background));
            mDateView.setBackgroundDrawable(res.getDrawable(R.drawable.statusbar_background));
            ((ImageView)mCloseView.getChildAt(0)).setImageDrawable(res.getDrawable(R.drawable.status_bar_close_on));
            mExpandedView.findViewById(R.id.exp_view_lin_layout).setBackgroundDrawable(res.getDrawable(R.drawable.title_bar_portrait));
            mClearButton.setBackgroundDrawable(res.getDrawable(android.R.drawable.btn_default_small));

            // Update icons.
            ArrayList<ViewGroup> iconViewGroups = new ArrayList<ViewGroup>();
            iconViewGroups.add(mStatusIcons);
            iconViewGroups.add(mNotificationIcons);

            for (ViewGroup iconViewGroup: iconViewGroups) {
                int nIcons = iconViewGroup.getChildCount();
                for (int i = 0; i < nIcons; i++) {
                    StatusBarIconView iconView = (StatusBarIconView)iconViewGroup.getChildAt(i);
                    iconView.updateResources();
                }
            }

            // Re-apply notifications.
            ArrayList<NotificationData> notifGroups = new ArrayList<NotificationData>();
            notifGroups.add(mOngoing);
            notifGroups.add(mLatest);
            ArrayList<ViewGroup> notifViewGroups = new ArrayList<ViewGroup>();
            notifViewGroups.add(mOngoingItems);
            notifViewGroups.add(mLatestItems);

            int nNotifGroups = notifGroups.size();
            for (int i = 0; i < nNotifGroups; i++) {
                NotificationData notifGroup = notifGroups.get(i);
                ViewGroup notifViewGroup = notifViewGroups.get(i);
                int nViews = notifViewGroup.getChildCount();
                if (nViews != notifGroup.size()) {
                    throw new IllegalStateException("unexpected mismatch between number of notification views and items");
                }
                for (int j = 0; j < nViews; j++) {
                    ViewGroup container = (ViewGroup)notifViewGroup.getChildAt(j);
                    NotificationData.Entry entry = notifGroup.getEntryAt(j);
                    updateNotification(entry.key, entry.notification);

                    // XXX: If this changes in XML, it must also change here.
                    container.findViewById(R.id.separator).setBackgroundDrawable(res.getDrawable(R.drawable.divider_horizontal_light_opaque));
                    container.findViewById(R.id.content).setBackgroundDrawable(res.getDrawable(android.R.drawable.status_bar_item_background));
                }
            }

            // Recalculate the position of the sliding windows and the titles.
            updateExpandedViewPos(EXPANDED_LEAVE_ALONE);
        }

        if (false) Slog.v(TAG, "updateResources");
    }