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

Commit 9424af73 authored by Jason Monk's avatar Jason Monk
Browse files

Add support for dagger injection with fragments

Convert NavigationBarFragment as a proof of concept and remove all
references to Dependency from NavigationBarFragment.

Test: atest SystemUITests
Change-Id: I0cdb5bc6ac455fce91e67b9e449cb7b78b1da9a4
parent 27d01a62
Loading
Loading
Loading
Loading
+22 −0
Original line number Diff line number Diff line
@@ -125,6 +125,28 @@ public class Dependency {
}
```

### Using injection with Fragments

Fragments are created as part of the FragmentManager, so they need to be
setup so the manager knows how to create them. To do that, add a method
to com.android.systemui.fragments.FragmentService$FragmentCreator that
returns your fragment class. Thats all thats required, once the method
exists, FragmentService will automatically pick it up and use injection
whenever your fragment needs to be created.

```java
public interface FragmentCreator {
+   NavigationBarFragment createNavigationBar();
}
```

If you need to create your fragment (i.e. for the add or replace transaction),
then the FragmentHostManager can do this for you.

```java
FragmentHostManager.get(view).create(NavigationBarFragment.class);
```

## TODO List

 - Eliminate usages of Depndency#get
+3 −0
Original line number Diff line number Diff line
@@ -28,4 +28,7 @@
-keep class com.android.systemui.plugins.** {
    *;
}
-keep class com.android.systemui.fragments.FragmentService$FragmentCreator {
    *;
}
-keep class androidx.core.app.CoreComponentFactory
+0 −7
Original line number Diff line number Diff line
@@ -44,7 +44,6 @@ import com.android.settingslib.bluetooth.LocalBluetoothManager;
import com.android.systemui.appops.AppOpsController;
import com.android.systemui.appops.AppOpsControllerImpl;
import com.android.systemui.colorextraction.SysuiColorExtractor;
import com.android.systemui.fragments.FragmentService;
import com.android.systemui.keyguard.ScreenLifecycle;
import com.android.systemui.keyguard.WakefulnessLifecycle;
import com.android.systemui.plugins.ActivityStarter;
@@ -403,12 +402,6 @@ public class DependencyProvider {
        return new WakefulnessLifecycle();
    }

    @Singleton
    @Provides
    public FragmentService provideFragmentService() {
        return new FragmentService();
    }

    @Singleton
    @Provides
    public ExtensionController provideExtensionController(Context context) {
+7 −0
Original line number Diff line number Diff line
@@ -30,6 +30,7 @@ import com.android.internal.widget.LockPatternUtils;
import com.android.keyguard.ViewMediatorCallback;
import com.android.systemui.assist.AssistManager;
import com.android.systemui.classifier.FalsingManager;
import com.android.systemui.fragments.FragmentService;
import com.android.systemui.keyguard.DismissCallbackRegistry;
import com.android.systemui.power.EnhancedEstimates;
import com.android.systemui.power.EnhancedEstimatesImpl;
@@ -215,5 +216,11 @@ public class SystemUIFactory {
    public interface SystemUIRootComponent {
        @Singleton
        Dependency.DependencyInjector createDependency();

        /**
         * FragmentCreator generates all Fragments that need injection.
         */
        @Singleton
        FragmentService.FragmentCreator createFragmentCreator();
    }
}
+34 −2
Original line number Diff line number Diff line
@@ -41,6 +41,8 @@ import com.android.systemui.util.leak.LeakDetector;

import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;

@@ -186,6 +188,13 @@ public class FragmentHostManager {
        mFragments.dispatchDestroy();
    }

    /**
     * Creates a fragment that requires injection.
     */
    public <T> T create(Class<T> fragmentCls) {
        return (T) mPlugins.instantiate(mContext, fragmentCls.getName(), null);
    }

    public interface FragmentListener {
        void onFragmentViewCreated(String tag, Fragment fragment);

@@ -294,13 +303,36 @@ public class FragmentHostManager {
        Fragment instantiate(Context context, String className, Bundle arguments) {
            Context extensionContext = mExtensionLookup.get(className);
            if (extensionContext != null) {
                Fragment f = Fragment.instantiate(extensionContext, className, arguments);
                Fragment f = instantiateWithInjections(extensionContext, className, arguments);
                if (f instanceof Plugin) {
                    ((Plugin) f).onCreate(mContext, extensionContext);
                }
                return f;
            }
            return Fragment.instantiate(context, className, arguments);
            return instantiateWithInjections(context, className, arguments);
        }

        private Fragment instantiateWithInjections(Context context, String className,
                Bundle args) {
            Method method = mManager.getInjectionMap().get(className);
            if (method != null) {
                try {
                    Fragment f = (Fragment) method.invoke(mManager.getFragmentCreator());
                    // Setup the args, taken from Fragment#instantiate.
                    if (args != null) {
                        args.setClassLoader(f.getClass().getClassLoader());
                        f.setArguments(args);
                    }
                    return f;
                } catch (IllegalAccessException e) {
                    throw new Fragment.InstantiationException("Unable to instantiate " + className,
                            e);
                } catch (InvocationTargetException e) {
                    throw new Fragment.InstantiationException("Unable to instantiate " + className,
                            e);
                }
            }
            return Fragment.instantiate(context, className, args);
        }
    }

Loading