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

Commit ea54e8a7 authored by Jason Monk's avatar Jason Monk
Browse files

Sysui: Add support for view injection

Test: Existing tests pass
Change-Id: Ic6931ebec38ca9514e9368239dd9502ae2dee33c
parent b34e8528
Loading
Loading
Loading
Loading
+46 −0
Original line number Original line Diff line number Diff line
@@ -147,6 +147,52 @@ then the FragmentHostManager can do this for you.
FragmentHostManager.get(view).create(NavigationBarFragment.class);
FragmentHostManager.get(view).create(NavigationBarFragment.class);
```
```


### Using injection with Views

Generally, you shouldn't need to inject for a view, as the view should
be relatively self contained and logic that requires injection should be
moved to a higher level construct such as a Fragment or a top-level SystemUI
component, see above for how to do injection for both of which.

Still here? Yeah, ok, sysui has a lot of pre-existing views that contain a
lot of code that could benefit from injection and will need to be migrated
off from Dependency#get uses. Similar to how fragments are injected, the view
needs to be added to the interface
com.android.systemui.util.InjectionInflationController$ViewInstanceCreator.

```java
public interface ViewInstanceCreator {
+   QuickStatusBarHeader createQsHeader();
}
```

Presumably you need to inflate that view from XML (otherwise why do you
need anything special? see earlier sections about generic injection). To obtain
an inflater that supports injected objects, call InjectionInflationController#injectable,
which will wrap the inflater it is passed in one that can create injected
objects when needed.

```java
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
        Bundle savedInstanceState) {
    return mInjectionInflater.injectable(inflater).inflate(R.layout.my_layout, container, false);
}
```

There is one other important thing to note about injecting with views. SysUI
already has a Context in its global dagger component, so if you simply inject
a Context, you will not get the one that the view should have with proper
theming. Because of this, always ensure to tag views that have @Inject with
the @Named view context.

```java
public CustomView(@Named(VIEW_CONTEXT) Context themedViewContext, AttributeSet attrs,
        OtherCustomDependency something) {
    ...
}
```

## TODO List
## TODO List


 - Eliminate usages of Depndency#get
 - Eliminate usages of Depndency#get
+3 −0
Original line number Original line Diff line number Diff line
@@ -31,4 +31,7 @@
-keep class com.android.systemui.fragments.FragmentService$FragmentCreator {
-keep class com.android.systemui.fragments.FragmentService$FragmentCreator {
    *;
    *;
}
}
-keep class com.android.systemui.util.InjectionInflationController$ViewInstanceCreator {
    *;
}
-keep class androidx.core.app.CoreComponentFactory
-keep class androidx.core.app.CoreComponentFactory
+0 −2
Original line number Original line Diff line number Diff line
@@ -33,7 +33,6 @@ import android.os.Process;
import android.os.ServiceManager;
import android.os.ServiceManager;
import android.os.UserHandle;
import android.os.UserHandle;
import android.util.DisplayMetrics;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.IWindowManager;
import android.view.IWindowManager;
import android.view.WindowManagerGlobal;
import android.view.WindowManagerGlobal;


@@ -470,7 +469,6 @@ public class DependencyProvider {
    @Singleton
    @Singleton
    @Provides
    @Provides
    public UiOffloadThread provideUiOffloadThread() {
    public UiOffloadThread provideUiOffloadThread() {
        Log.d("TestTest", "provideUiOffloadThread");
        return new UiOffloadThread();
        return new UiOffloadThread();
    }
    }


+6 −1
Original line number Original line Diff line number Diff line
@@ -42,7 +42,6 @@ import com.android.systemui.statusbar.NotificationLockscreenUserManagerImpl;
import com.android.systemui.statusbar.ScrimView;
import com.android.systemui.statusbar.ScrimView;
import com.android.systemui.statusbar.notification.NotificationData;
import com.android.systemui.statusbar.notification.NotificationData;
import com.android.systemui.statusbar.notification.NotificationEntryManager;
import com.android.systemui.statusbar.notification.NotificationEntryManager;
import com.android.systemui.statusbar.notification.NotificationRowBinder;
import com.android.systemui.statusbar.phone.DozeParameters;
import com.android.systemui.statusbar.phone.DozeParameters;
import com.android.systemui.statusbar.phone.KeyguardBouncer;
import com.android.systemui.statusbar.phone.KeyguardBouncer;
import com.android.systemui.statusbar.phone.KeyguardEnvironmentImpl;
import com.android.systemui.statusbar.phone.KeyguardEnvironmentImpl;
@@ -55,6 +54,7 @@ import com.android.systemui.statusbar.phone.StatusBar;
import com.android.systemui.statusbar.phone.StatusBarIconController;
import com.android.systemui.statusbar.phone.StatusBarIconController;
import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
import com.android.systemui.statusbar.policy.DeviceProvisionedController;
import com.android.systemui.statusbar.policy.DeviceProvisionedController;
import com.android.systemui.util.InjectionInflationController;
import com.android.systemui.volume.VolumeDialogComponent;
import com.android.systemui.volume.VolumeDialogComponent;


import java.util.function.Consumer;
import java.util.function.Consumer;
@@ -223,5 +223,10 @@ public class SystemUIFactory {
         */
         */
        @Singleton
        @Singleton
        FragmentService.FragmentCreator createFragmentCreator();
        FragmentService.FragmentCreator createFragmentCreator();

        /**
         * ViewCreator generates all Views that need injection.
         */
        InjectionInflationController.ViewCreator createViewCreator();
    }
    }
}
}
+7 −2
Original line number Original line Diff line number Diff line
@@ -45,6 +45,7 @@ import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.notification.stack.StackStateAnimator;
import com.android.systemui.statusbar.notification.stack.StackStateAnimator;
import com.android.systemui.statusbar.phone.NotificationsQuickSettingsContainer;
import com.android.systemui.statusbar.phone.NotificationsQuickSettingsContainer;
import com.android.systemui.statusbar.policy.RemoteInputQuickSettingsDisabler;
import com.android.systemui.statusbar.policy.RemoteInputQuickSettingsDisabler;
import com.android.systemui.util.InjectionInflationController;


import javax.inject.Inject;
import javax.inject.Inject;


@@ -76,16 +77,20 @@ public class QSFragment extends Fragment implements QS, CommandQueue.Callbacks {
    private boolean mQsDisabled;
    private boolean mQsDisabled;


    private final RemoteInputQuickSettingsDisabler mRemoteInputQuickSettingsDisabler;
    private final RemoteInputQuickSettingsDisabler mRemoteInputQuickSettingsDisabler;
    private final InjectionInflationController mInjectionInflater;


    @Inject
    @Inject
    public QSFragment(RemoteInputQuickSettingsDisabler remoteInputQsDisabler) {
    public QSFragment(RemoteInputQuickSettingsDisabler remoteInputQsDisabler,
            InjectionInflationController injectionInflater) {
        mRemoteInputQuickSettingsDisabler = remoteInputQsDisabler;
        mRemoteInputQuickSettingsDisabler = remoteInputQsDisabler;
        mInjectionInflater = injectionInflater;
    }
    }


    @Override
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
            Bundle savedInstanceState) {
            Bundle savedInstanceState) {
        inflater = inflater.cloneInContext(new ContextThemeWrapper(getContext(), R.style.qs_theme));
        inflater = mInjectionInflater.injectable(
                inflater.cloneInContext(new ContextThemeWrapper(getContext(), R.style.qs_theme)));
        return inflater.inflate(R.layout.qs_panel, container, false);
        return inflater.inflate(R.layout.qs_panel, container, false);
    }
    }


Loading