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

Commit 0bdc6ada authored by Chris Göllner's avatar Chris Göllner
Browse files

StatusBarWindowControllerImpl - Use Assisted Injection

For connected displays, we will need StatusBarWindowControllerImpl
instances to have display specific instances of Context and
WindowManager.
Since they can't be injected directly, we can use Assisted Injection.

Test: Build and run
Flag: EXEMPT changing from @Inject to @AssistedInject
Bug: 367592591
Change-Id: I535d94452360a0a6e767bd78136142c53b2f8c32
parent 7b25800a
Loading
Loading
Loading
Loading
+14 −0
Original line number Diff line number Diff line
@@ -113,6 +113,7 @@ import android.view.accessibility.CaptioningManager;
import android.view.inputmethod.InputMethodManager;
import android.view.textclassifier.TextClassificationManager;

import androidx.annotation.NonNull;
import androidx.asynclayoutinflater.view.AsyncLayoutInflater;
import androidx.core.app.NotificationManagerCompat;

@@ -716,6 +717,19 @@ public class FrameworkServicesModule {
                /* isViewCaptureEnabled= */ enableViewCaptureTracing());
    }

    @Provides
    @Singleton
    static ViewCaptureAwareWindowManager.Factory viewCaptureAwareWindowManagerFactory(
            Lazy<ViewCapture> daggerLazyViewCapture) {
        return new ViewCaptureAwareWindowManager.Factory() {
            @NonNull
            @Override
            public ViewCaptureAwareWindowManager create(@NonNull WindowManager windowManager) {
                return provideViewCaptureAwareWindowManager(windowManager, daggerLazyViewCapture);
            }
        };
    }

    @Provides
    @Singleton
    static PermissionManager providePermissionManager(Context context) {
+13 −5
Original line number Diff line number Diff line
@@ -16,6 +16,8 @@

package com.android.systemui.statusbar.dagger

import android.content.Context
import com.android.app.viewcapture.ViewCaptureAwareWindowManager
import com.android.systemui.CoreStartable
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.log.LogBuffer
@@ -63,12 +65,18 @@ abstract class StatusBarModule {

    @Binds abstract fun statusBarInitializer(impl: StatusBarInitializerImpl): StatusBarInitializer

    @Binds
    abstract fun statusBarWindowController(
        impl: StatusBarWindowControllerImpl
    ): StatusBarWindowController

    companion object {

        @Provides
        @SysUISingleton
        fun statusBarWindowController(
            context: Context?,
            viewCaptureAwareWindowManager: ViewCaptureAwareWindowManager?,
            factory: StatusBarWindowControllerImpl.Factory,
        ): StatusBarWindowController {
            return factory.create(context, viewCaptureAwareWindowManager)
        }

        @Provides
        @SysUISingleton
        @OngoingCallLog
+19 −12
Original line number Diff line number Diff line
@@ -28,7 +28,6 @@ import static com.android.systemui.util.leak.RotationUtils.ROTATION_SEASCAPE;
import static com.android.systemui.util.leak.RotationUtils.ROTATION_UPSIDE_DOWN;

import android.content.Context;
import android.content.res.Resources;
import android.graphics.Insets;
import android.graphics.PixelFormat;
import android.graphics.Rect;
@@ -52,23 +51,23 @@ import com.android.app.viewcapture.ViewCaptureAwareWindowManager;
import com.android.internal.policy.SystemBarUtils;
import com.android.systemui.animation.ActivityTransitionAnimator;
import com.android.systemui.animation.DelegateTransitionAnimatorController;
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.fragments.FragmentHostManager;
import com.android.systemui.fragments.FragmentService;
import com.android.systemui.res.R;
import com.android.systemui.statusbar.phone.StatusBarContentInsetsProvider;
import com.android.systemui.statusbar.window.StatusBarWindowModule.InternalWindowViewInflater;
import com.android.systemui.unfold.UnfoldTransitionProgressProvider;
import com.android.systemui.unfold.util.JankMonitorTransitionProgressListener;

import java.util.Optional;
import dagger.assisted.Assisted;
import dagger.assisted.AssistedFactory;
import dagger.assisted.AssistedInject;

import javax.inject.Inject;
import java.util.Optional;

/**
 * Encapsulates all logic for the status bar window state management.
 */
@SysUISingleton
public class StatusBarWindowControllerImpl implements StatusBarWindowController {
    private static final String TAG = "StatusBarWindowController";
    private static final boolean DEBUG = false;
@@ -90,21 +89,20 @@ public class StatusBarWindowControllerImpl implements StatusBarWindowController
    private final WindowManager.LayoutParams mLpChanged;
    private final Binder mInsetsSourceOwner = new Binder();

    @Inject
    @AssistedInject
    public StatusBarWindowControllerImpl(
            Context context,
            @StatusBarWindowModule.InternalWindowView StatusBarWindowView statusBarWindowView,
            ViewCaptureAwareWindowManager viewCaptureAwareWindowManager,
            @Assisted Context context,
            @InternalWindowViewInflater StatusBarWindowViewInflater statusBarWindowViewInflater,
            @Assisted ViewCaptureAwareWindowManager viewCaptureAwareWindowManager,
            IWindowManager iWindowManager,
            StatusBarContentInsetsProvider contentInsetsProvider,
            FragmentService fragmentService,
            @Main Resources resources,
            Optional<UnfoldTransitionProgressProvider> unfoldTransitionProgressProvider) {
        mContext = context;
        mWindowManager = viewCaptureAwareWindowManager;
        mIWindowManager = iWindowManager;
        mContentInsetsProvider = contentInsetsProvider;
        mStatusBarWindowView = statusBarWindowView;
        mStatusBarWindowView = statusBarWindowViewInflater.inflate(context);
        mFragmentService = fragmentService;
        mLaunchAnimationContainer = mStatusBarWindowView.findViewById(
                R.id.status_bar_launch_animation_container);
@@ -354,4 +352,13 @@ public class StatusBarWindowControllerImpl implements StatusBarWindowController
            mLpChanged.forciblyShownTypes &= ~WindowInsets.Type.statusBars();
        }
    }

    @AssistedFactory
    public interface Factory {
        /** Creates a new instance. */
        StatusBarWindowControllerImpl create(
                Context context,
                ViewCaptureAwareWindowManager viewCaptureAwareWindowManager);
    }

}
+17 −28
Original line number Diff line number Diff line
package com.android.systemui.statusbar.window

import android.view.LayoutInflater
import com.android.systemui.res.R
import com.android.systemui.dagger.SysUISingleton
import dagger.Binds
import dagger.Module
import dagger.Provides
import javax.inject.Qualifier

/** Module providing dependencies related to the status bar window. */
@Module
abstract class StatusBarWindowModule {

    /**
     * Provides a [StatusBarWindowView].
     * Binds a [StatusBarWindowViewInflater].
     *
     * Only [StatusBarWindowController] should inject the view.
     * Only [StatusBarWindowControllerImpl] should inject it.
     */
    @Module
    companion object {
        @JvmStatic
        @Provides
    @Binds
    @SysUISingleton
        @InternalWindowView
        fun providesStatusBarWindowView(layoutInflater: LayoutInflater): StatusBarWindowView {
            return layoutInflater.inflate(
                R.layout.super_status_bar,
                /* root= */null
            ) as StatusBarWindowView?
                ?: throw IllegalStateException(
                    "R.layout.super_status_bar could not be properly inflated"
                )
        }
    }
    @InternalWindowViewInflater
    abstract fun providesStatusBarWindowViewInflater(
        inflaterImpl: StatusBarWindowViewInflaterImpl
    ): StatusBarWindowViewInflater

    /**
     * We want [StatusBarWindowView] to be provided to [StatusBarWindowController]'s constructor via
     * dagger so that we can provide a fake window view when testing the controller. However, we wan
     * want *only* the controller to be able to inject the window view.
     * We want [StatusBarWindowViewInflater] to be provided to [StatusBarWindowControllerImpl]'s
     * constructor via dagger so that we can provide a fake window view when testing the controller.
     * However, we wan want *only* the controller to be able to inject the window view.
     *
     * This protected qualifier annotation achieves this. [StatusBarWindowView] can only be injected
     * if it's annotated with [InternalWindowView], and only classes inside this [statusbar.window]
     * package can access the annotation.
     * This protected qualifier annotation achieves this. [StatusBarWindowViewInflater] can only be
     * injected if it's annotated with [InternalWindowViewInflater], and only classes inside this
     * [statusbar.window] package can access the annotation.
     */
    @Retention(AnnotationRetention.BINARY)
    @Qualifier
    protected annotation class InternalWindowView
    protected annotation class InternalWindowViewInflater
}
+42 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2024 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.window

import android.content.Context
import android.view.LayoutInflater
import com.android.systemui.res.R
import javax.inject.Inject

/**
 * Inflates a [StatusBarWindowView]. Exists so that it can be injected into
 * [StatusBarWindowControllerImpl] and be swapped for a fake implementation in tests.
 */
interface StatusBarWindowViewInflater {
    fun inflate(context: Context): StatusBarWindowView
}

class StatusBarWindowViewInflaterImpl @Inject constructor() : StatusBarWindowViewInflater {

    override fun inflate(context: Context): StatusBarWindowView {
        val layoutInflater = LayoutInflater.from(context)
        return layoutInflater.inflate(R.layout.super_status_bar, /* root= */ null)
            as StatusBarWindowView?
            ?: throw IllegalStateException(
                "R.layout.super_status_bar could not be properly inflated"
            )
    }
}