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

Commit d6784fe2 authored by Christian Göllner's avatar Christian Göllner
Browse files

Create StatusBarBoundsProvider which provided bounds of the left and right side icons

+ Returns visible bounds.
+ Notifies listeners about changes in bounds.

Test: Manually
Test: StatusBarBoundsProviderTest.kt
Fixes: 237270155
Change-Id: If2fda6f73a1c42b5976039f195d9c73dffe98334
parent c9358c61
Loading
Loading
Loading
Loading
+92 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2022 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.phone

import android.graphics.Rect
import android.view.View
import com.android.systemui.statusbar.phone.fragment.dagger.StatusBarFragmentComponent
import com.android.systemui.statusbar.phone.fragment.dagger.StatusBarFragmentModule.END_SIDE_CONTENT
import com.android.systemui.statusbar.phone.fragment.dagger.StatusBarFragmentModule.START_SIDE_CONTENT
import com.android.systemui.statusbar.phone.fragment.dagger.StatusBarFragmentScope
import com.android.systemui.util.boundsOnScreen
import javax.inject.Inject
import javax.inject.Named

/** Provides various bounds within the status bar. */
@StatusBarFragmentScope
class StatusBarBoundsProvider
@Inject
constructor(
    private val changeListeners: Set<@JvmSuppressWildcards BoundsChangeListener>,
    @Named(START_SIDE_CONTENT) private val startSideContent: View,
    @Named(END_SIDE_CONTENT) private val endSideContent: View,
) : StatusBarFragmentComponent.Startable {

    interface BoundsChangeListener {
        fun onStatusBarBoundsChanged()
    }

    private var previousBounds =
        BoundsPair(start = startSideContent.boundsOnScreen, end = endSideContent.boundsOnScreen)

    private val layoutListener =
        View.OnLayoutChangeListener { _, _, _, _, _, _, _, _, _ ->
            val newBounds = BoundsPair(start = visibleStartSideBounds, end = visibleEndSideBounds)
            if (previousBounds != newBounds) {
                previousBounds = newBounds
                changeListeners.forEach { it.onStatusBarBoundsChanged() }
            }
        }

    override fun start() {
        startSideContent.addOnLayoutChangeListener(layoutListener)
        endSideContent.addOnLayoutChangeListener(layoutListener)
    }

    override fun stop() {
        startSideContent.removeOnLayoutChangeListener(layoutListener)
        endSideContent.removeOnLayoutChangeListener(layoutListener)
    }

    /**
     * Returns the bounds of the end side of the status bar that are visible to the user. The end
     * side is right when in LTR and is left when in RTL.
     *
     * Note that even though the layout might be larger, here we only return the bounds for what is
     * visible to the user.
     *
     * The end side of the status bar contains the multi-user switcher and status icons such as
     * wi-fi, battery, etc
     */
    val visibleEndSideBounds: Rect
        get() = endSideContent.boundsOnScreen

    /**
     * Returns the bounds of the start side of the status bar that are visible to the user. The
     * start side is left when in LTR and is right when in RTL.
     *
     * Note that even though the layout might be larger, here we only return the bounds for what is
     * visible to the user.
     *
     * The start side of the status bar contains the operator name, clock, on-going call chip, and
     * notifications.
     */
    val visibleStartSideBounds: Rect
        get() = startSideContent.boundsOnScreen
}

private data class BoundsPair(val start: Rect, val end: Rect)
+5 −2
Original line number Diff line number Diff line
@@ -30,6 +30,7 @@ import com.android.systemui.battery.BatteryMeterViewController;
import com.android.systemui.biometrics.AuthRippleView;
import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.dump.DumpManager;
import com.android.systemui.flags.FeatureFlags;
import com.android.systemui.flags.Flags;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
@@ -269,7 +270,8 @@ public abstract class StatusBarViewModule {
            CollapsedStatusBarFragmentLogger collapsedStatusBarFragmentLogger,
            OperatorNameViewController.Factory operatorNameViewControllerFactory,
            SecureSettings secureSettings,
            @Main Executor mainExecutor
            @Main Executor mainExecutor,
            DumpManager dumpManager
    ) {
        return new CollapsedStatusBarFragment(statusBarFragmentComponentFactory,
                ongoingCallController,
@@ -289,7 +291,8 @@ public abstract class StatusBarViewModule {
                collapsedStatusBarFragmentLogger,
                operatorNameViewControllerFactory,
                secureSettings,
                mainExecutor);
                mainExecutor,
                dumpManager);
    }

    /**
+47 −2
Original line number Diff line number Diff line
@@ -34,6 +34,8 @@ import android.os.Parcelable;
import android.os.UserHandle;
import android.provider.Settings;
import android.telephony.SubscriptionManager;
import android.util.ArrayMap;
import android.util.IndentingPrintWriter;
import android.util.SparseArray;
import android.view.LayoutInflater;
import android.view.View;
@@ -43,9 +45,11 @@ import android.widget.LinearLayout;

import androidx.annotation.VisibleForTesting;

import com.android.systemui.Dumpable;
import com.android.systemui.R;
import com.android.systemui.animation.Interpolators;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.dump.DumpManager;
import com.android.systemui.flags.FeatureFlags;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.shade.NotificationPanelViewController;
@@ -66,6 +70,7 @@ import com.android.systemui.statusbar.phone.StatusBarIconController;
import com.android.systemui.statusbar.phone.StatusBarIconController.DarkIconManager;
import com.android.systemui.statusbar.phone.StatusBarLocationPublisher;
import com.android.systemui.statusbar.phone.fragment.dagger.StatusBarFragmentComponent;
import com.android.systemui.statusbar.phone.fragment.dagger.StatusBarFragmentComponent.Startable;
import com.android.systemui.statusbar.phone.ongoingcall.OngoingCallController;
import com.android.systemui.statusbar.phone.ongoingcall.OngoingCallListener;
import com.android.systemui.statusbar.phone.panelstate.PanelExpansionStateManager;
@@ -76,9 +81,12 @@ import com.android.systemui.util.CarrierConfigTracker.CarrierConfigChangedListen
import com.android.systemui.util.CarrierConfigTracker.DefaultDataSubscriptionChangedListener;
import com.android.systemui.util.settings.SecureSettings;

import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.Executor;

/**
@@ -89,7 +97,7 @@ import java.util.concurrent.Executor;
@SuppressLint("ValidFragment")
public class CollapsedStatusBarFragment extends Fragment implements CommandQueue.Callbacks,
        StatusBarStateController.StateListener,
        SystemStatusAnimationCallback {
        SystemStatusAnimationCallback, Dumpable {

    public static final String TAG = "CollapsedStatusBarFragment";
    private static final String EXTRA_PANEL_STATE = "panel_state";
@@ -124,8 +132,10 @@ public class CollapsedStatusBarFragment extends Fragment implements CommandQueue
    private final StatusBarHideIconsForBouncerManager mStatusBarHideIconsForBouncerManager;
    private final SecureSettings mSecureSettings;
    private final Executor mMainExecutor;
    private final DumpManager mDumpManager;

    private List<String> mBlockedIcons = new ArrayList<>();
    private Map<Startable, Startable.State> mStartableStates = new ArrayMap<>();

    private SignalCallback mSignalCallback = new SignalCallback() {
        @Override
@@ -185,7 +195,8 @@ public class CollapsedStatusBarFragment extends Fragment implements CommandQueue
            CollapsedStatusBarFragmentLogger collapsedStatusBarFragmentLogger,
            OperatorNameViewController.Factory operatorNameViewControllerFactory,
            SecureSettings secureSettings,
            @Main Executor mainExecutor
            @Main Executor mainExecutor,
            DumpManager dumpManager
    ) {
        mStatusBarFragmentComponentFactory = statusBarFragmentComponentFactory;
        mOngoingCallController = ongoingCallController;
@@ -206,6 +217,7 @@ public class CollapsedStatusBarFragment extends Fragment implements CommandQueue
        mOperatorNameViewControllerFactory = operatorNameViewControllerFactory;
        mSecureSettings = secureSettings;
        mMainExecutor = mainExecutor;
        mDumpManager = dumpManager;
    }

    @Override
@@ -217,8 +229,15 @@ public class CollapsedStatusBarFragment extends Fragment implements CommandQueue
    @Override
    public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        mDumpManager.registerDumpable(getClass().getSimpleName(), this);
        mStatusBarFragmentComponent = mStatusBarFragmentComponentFactory.create(this);
        mStatusBarFragmentComponent.init();
        mStartableStates.clear();
        for (Startable startable : mStatusBarFragmentComponent.getStartables()) {
            mStartableStates.put(startable, Startable.State.STARTING);
            startable.start();
            mStartableStates.put(startable, Startable.State.STARTED);
        }

        mStatusBar = (PhoneStatusBarView) view;
        View contents = mStatusBar.findViewById(R.id.status_bar_contents);
@@ -321,6 +340,13 @@ public class CollapsedStatusBarFragment extends Fragment implements CommandQueue
        }
        mCarrierConfigTracker.removeCallback(mCarrierConfigCallback);
        mCarrierConfigTracker.removeDataSubscriptionChangedListener(mDefaultDataListener);

        for (Startable startable : mStatusBarFragmentComponent.getStartables()) {
            mStartableStates.put(startable, Startable.State.STOPPING);
            startable.stop();
            mStartableStates.put(startable, Startable.State.STOPPED);
        }
        mDumpManager.unregisterDumpable(getClass().getSimpleName());
    }

    /** Initializes views related to the notification icon area. */
@@ -670,4 +696,23 @@ public class CollapsedStatusBarFragment extends Fragment implements CommandQueue
                    updateStatusBarLocation(left, right);
                }
            };

    @Override
    public void dump(PrintWriter printWriter, String[] args) {
        IndentingPrintWriter pw = new IndentingPrintWriter(printWriter, /* singleIndent= */"  ");
        StatusBarFragmentComponent component = mStatusBarFragmentComponent;
        if (component == null) {
            pw.println("StatusBarFragmentComponent is null");
        } else {
            Set<Startable> startables = component.getStartables();
            pw.println("Startables: " + startables.size());
            pw.increaseIndent();
            for (Startable startable : startables) {
                Startable.State startableState = mStartableStates.getOrDefault(startable,
                        Startable.State.NONE);
                pw.println(startable + ", state: " + startableState);
            }
            pw.decreaseIndent();
        }
    }
}
+25 −1
Original line number Diff line number Diff line
@@ -23,9 +23,12 @@ import com.android.systemui.statusbar.phone.LightsOutNotifController;
import com.android.systemui.statusbar.phone.PhoneStatusBarTransitions;
import com.android.systemui.statusbar.phone.PhoneStatusBarView;
import com.android.systemui.statusbar.phone.PhoneStatusBarViewController;
import com.android.systemui.statusbar.phone.StatusBarBoundsProvider;
import com.android.systemui.statusbar.phone.StatusBarDemoMode;
import com.android.systemui.statusbar.phone.fragment.CollapsedStatusBarFragment;

import java.util.Set;

import dagger.BindsInstance;
import dagger.Subcomponent;

@@ -41,7 +44,10 @@ import dagger.Subcomponent;
 * should be included here or in {@link StatusBarFragmentModule}.
 */

@Subcomponent(modules = {StatusBarFragmentModule.class})
@Subcomponent(modules = {
        StatusBarFragmentModule.class,
        StatusBarStartablesModule.class
})
@StatusBarFragmentScope
public interface StatusBarFragmentComponent {
    /** Simple factory. */
@@ -51,6 +57,18 @@ public interface StatusBarFragmentComponent {
                @BindsInstance CollapsedStatusBarFragment collapsedStatusBarFragment);
    }

    /**
     * Performs initialization logic after {@link StatusBarFragmentComponent} has been constructed.
     */
    interface Startable {
        void start();
        void stop();

        enum State {
            NONE, STARTING, STARTED, STOPPING, STOPPED
        }
    }

    /**
     * Initialize anything extra for the component. Must be called after the component is created.
     */
@@ -92,4 +110,10 @@ public interface StatusBarFragmentComponent {
    /** */
    @StatusBarFragmentScope
    PhoneStatusBarTransitions getPhoneStatusBarTransitions();

    /** */
    Set<Startable> getStartables();

    /** */
    StatusBarBoundsProvider getBoundsProvider();
}
+25 −0
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@ import com.android.systemui.statusbar.HeadsUpStatusBarView;
import com.android.systemui.statusbar.phone.PhoneStatusBarTransitions;
import com.android.systemui.statusbar.phone.PhoneStatusBarView;
import com.android.systemui.statusbar.phone.PhoneStatusBarViewController;
import com.android.systemui.statusbar.phone.StatusBarBoundsProvider;
import com.android.systemui.statusbar.phone.fragment.CollapsedStatusBarFragment;
import com.android.systemui.statusbar.phone.userswitcher.StatusBarUserSwitcherContainer;
import com.android.systemui.statusbar.phone.userswitcher.StatusBarUserSwitcherController;
@@ -34,12 +35,14 @@ import com.android.systemui.statusbar.policy.Clock;
import com.android.systemui.statusbar.window.StatusBarWindowController;

import java.util.Optional;
import java.util.Set;

import javax.inject.Named;

import dagger.Binds;
import dagger.Module;
import dagger.Provides;
import dagger.multibindings.Multibinds;

/** Dagger module for {@link StatusBarFragmentComponent}. */
@Module
@@ -48,6 +51,8 @@ public interface StatusBarFragmentModule {
    String LIGHTS_OUT_NOTIF_VIEW = "lights_out_notif_view";
    String OPERATOR_NAME_VIEW = "operator_name_view";
    String OPERATOR_NAME_FRAME_VIEW = "operator_name_frame_view";
    String START_SIDE_CONTENT = "start_side_content";
    String END_SIDE_CONTENT = "end_side_content";

    /** */
    @Provides
@@ -65,6 +70,22 @@ public interface StatusBarFragmentModule {
        return view.findViewById(R.id.battery);
    }

    /** */
    @Provides
    @StatusBarFragmentScope
    @Named(START_SIDE_CONTENT)
    static View startSideContent(@RootView PhoneStatusBarView view) {
        return view.findViewById(R.id.status_bar_start_side_content);
    }

    /** */
    @Provides
    @StatusBarFragmentScope
    @Named(END_SIDE_CONTENT)
    static View endSideContent(@RootView PhoneStatusBarView view) {
        return view.findViewById(R.id.status_bar_end_side_content);
    }

    /** */
    @Provides
    @StatusBarFragmentScope
@@ -138,4 +159,8 @@ public interface StatusBarFragmentModule {
    static HeadsUpStatusBarView providesHeasdUpStatusBarView(@RootView PhoneStatusBarView view) {
        return view.findViewById(R.id.heads_up_status_bar_view);
    }

    /** */
    @Multibinds
    Set<StatusBarBoundsProvider.BoundsChangeListener> boundsChangeListeners();
}
Loading