Merge "Remove Dependency#get from fragments package." into tm-qpr-dev

This commit is contained in:
Dave Mankoff
2023-01-28 15:36:16 +00:00
committed by Android (Google) Code Review
10 changed files with 97 additions and 45 deletions

View File

@@ -37,9 +37,14 @@ public class ExtensionFragmentListener<T extends FragmentBase> implements Consum
private final int mId;
private String mOldClass;
private ExtensionFragmentListener(View view, String tag, int id, Extension<T> extension) {
private ExtensionFragmentListener(
FragmentService fragmentService,
View view,
String tag,
int id,
Extension<T> extension) {
mTag = tag;
mFragmentHostManager = FragmentHostManager.get(view);
mFragmentHostManager = fragmentService.getFragmentHostManager(view);
mExtension = extension;
mId = id;
mFragmentHostManager.getFragmentManager().beginTransaction()
@@ -61,8 +66,13 @@ public class ExtensionFragmentListener<T extends FragmentBase> implements Consum
mExtension.clearItem(true);
}
public static <T> void attachExtensonToFragment(View view, String tag, int id,
public static <T> void attachExtensonToFragment(
FragmentService fragmentService,
View view,
String tag,
int id,
Extension<T> extension) {
extension.addCallback(new ExtensionFragmentListener(view, tag, id, extension));
extension.addCallback(
new ExtensionFragmentListener(fragmentService, view, tag, id, extension));
}
}

View File

@@ -36,7 +36,6 @@ import android.view.View;
import androidx.annotation.NonNull;
import com.android.settingslib.applications.InterestingConfigChanges;
import com.android.systemui.Dependency;
import com.android.systemui.plugins.Plugin;
import com.android.systemui.util.leak.LeakDetector;
@@ -46,12 +45,17 @@ import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.HashMap;
import dagger.assisted.Assisted;
import dagger.assisted.AssistedFactory;
import dagger.assisted.AssistedInject;
public class FragmentHostManager {
private final Handler mHandler = new Handler(Looper.getMainLooper());
private final Context mContext;
private final HashMap<String, ArrayList<FragmentListener>> mListeners = new HashMap<>();
private final View mRootView;
private final LeakDetector mLeakDetector;
private final InterestingConfigChanges mConfigChanges = new InterestingConfigChanges(
ActivityInfo.CONFIG_FONT_SCALE | ActivityInfo.CONFIG_LOCALE
| ActivityInfo.CONFIG_ASSETS_PATHS);
@@ -61,14 +65,24 @@ public class FragmentHostManager {
private FragmentController mFragments;
private FragmentLifecycleCallbacks mLifecycleCallbacks;
FragmentHostManager(FragmentService manager, View rootView) {
@AssistedInject
FragmentHostManager(
@Assisted View rootView,
FragmentService manager,
LeakDetector leakDetector) {
mContext = rootView.getContext();
mManager = manager;
mRootView = rootView;
mLeakDetector = leakDetector;
mConfigChanges.applyNewConfig(mContext.getResources());
createFragmentHost(null);
}
@AssistedFactory
public interface Factory {
FragmentHostManager create(View rootView);
}
private void createFragmentHost(Parcelable savedState) {
mFragments = FragmentController.createController(new HostCallbacks());
mFragments.attachHost(null);
@@ -86,7 +100,7 @@ public class FragmentHostManager {
@Override
public void onFragmentDestroyed(FragmentManager fm, Fragment f) {
Dependency.get(LeakDetector.class).trackGarbage(f);
mLeakDetector.trackGarbage(f);
}
};
mFragments.getFragmentManager().registerFragmentLifecycleCallbacks(mLifecycleCallbacks,
@@ -211,19 +225,6 @@ public class FragmentHostManager {
}
}
public static FragmentHostManager get(View view) {
try {
return Dependency.get(FragmentService.class).getFragmentHostManager(view);
} catch (ClassCastException e) {
// TODO: Some auto handling here?
throw e;
}
}
public static void removeAndDestroy(View view) {
Dependency.get(FragmentService.class).removeAndDestroy(view);
}
public void reloadFragments() {
Trace.beginSection("FrargmentHostManager#reloadFragments");
// Save the old state.

View File

@@ -53,6 +53,7 @@ public class FragmentService implements Dumpable {
*/
private final ArrayMap<String, FragmentInstantiationInfo> mInjectionMap = new ArrayMap<>();
private final Handler mHandler = new Handler();
private final FragmentHostManager.Factory mFragmentHostManagerFactory;
private ConfigurationController.ConfigurationListener mConfigurationListener =
new ConfigurationController.ConfigurationListener() {
@@ -67,8 +68,10 @@ public class FragmentService implements Dumpable {
@Inject
public FragmentService(
FragmentCreator.Factory fragmentCreatorFactory,
FragmentHostManager.Factory fragmentHostManagerFactory,
ConfigurationController configurationController,
DumpManager dumpManager) {
mFragmentHostManagerFactory = fragmentHostManagerFactory;
addFragmentInstantiationProvider(fragmentCreatorFactory.build());
configurationController.addCallback(mConfigurationListener);
@@ -152,7 +155,7 @@ public class FragmentService implements Dumpable {
public FragmentHostState(View view) {
mView = view;
mFragmentHostManager = new FragmentHostManager(FragmentService.this, mView);
mFragmentHostManager = mFragmentHostManagerFactory.create(mView);
}
public void sendConfigurationChange(Configuration newConfig) {

View File

@@ -31,6 +31,7 @@ import com.android.systemui.R
import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.flags.FeatureFlags
import com.android.systemui.flags.Flags
import com.android.systemui.fragments.FragmentService
import com.android.systemui.navigationbar.NavigationModeController
import com.android.systemui.plugins.qs.QS
import com.android.systemui.plugins.qs.QSContainerController
@@ -54,6 +55,7 @@ class NotificationsQSContainerController @Inject constructor(
private val largeScreenShadeHeaderController: LargeScreenShadeHeaderController,
private val shadeExpansionStateManager: ShadeExpansionStateManager,
private val featureFlags: FeatureFlags,
private val fragmentService: FragmentService,
@Main private val delayableExecutor: DelayableExecutor
) : ViewController<NotificationsQuickSettingsContainer>(view), QSContainerController {
@@ -128,6 +130,7 @@ class NotificationsQSContainerController @Inject constructor(
mView.setInsetsChangedListener(delayedInsetSetter)
mView.setQSFragmentAttachedListener { qs: QS -> qs.setContainerController(this) }
mView.setConfigurationChangedListener { updateResources() }
fragmentService.getFragmentHostManager(mView).addTagListener(QS.TAG, mView)
}
override fun onViewDetached() {
@@ -136,6 +139,7 @@ class NotificationsQSContainerController @Inject constructor(
mView.removeOnInsetsChangedListener()
mView.removeQSFragmentAttachedListener()
mView.setConfigurationChangedListener(null)
fragmentService.getFragmentHostManager(mView).removeTagListener(QS.TAG, mView)
}
fun updateResources() {

View File

@@ -29,7 +29,6 @@ import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.constraintlayout.widget.ConstraintSet;
import com.android.systemui.R;
import com.android.systemui.fragments.FragmentHostManager;
import com.android.systemui.fragments.FragmentHostManager.FragmentListener;
import com.android.systemui.plugins.qs.QS;
import com.android.systemui.statusbar.notification.AboveShelfObserver;
@@ -132,18 +131,6 @@ public class NotificationsQuickSettingsContainer extends ConstraintLayout
mQSFragmentAttachedListener = qs -> {};
}
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
FragmentHostManager.get(this).addTagListener(QS.TAG, this);
}
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
FragmentHostManager.get(this).removeTagListener(QS.TAG, this);
}
@Override
public WindowInsets onApplyWindowInsets(WindowInsets insets) {
mInsetsChangedListener.accept(insets);

View File

@@ -1306,8 +1306,13 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces {
// Set up the quick settings tile panel
final View container = mNotificationShadeWindowView.findViewById(R.id.qs_frame);
if (container != null) {
FragmentHostManager fragmentHostManager = FragmentHostManager.get(container);
ExtensionFragmentListener.attachExtensonToFragment(container, QS.TAG, R.id.qs_frame,
FragmentHostManager fragmentHostManager =
mFragmentService.getFragmentHostManager(container);
ExtensionFragmentListener.attachExtensonToFragment(
mFragmentService,
container,
QS.TAG,
R.id.qs_frame,
mExtensionController
.newExtension(QS.class)
.withPlugin(QS.class)
@@ -1478,7 +1483,9 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces {
}
protected QS createDefaultQSFragment() {
return FragmentHostManager.get(mNotificationShadeWindowView).create(QSFragment.class);
return mFragmentService
.getFragmentHostManager(mNotificationShadeWindowView)
.create(QSFragment.class);
}
private void setUpPresenter() {

View File

@@ -48,6 +48,7 @@ import com.android.systemui.animation.DelegateLaunchAnimatorController;
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.statusbar.phone.StatusBarContentInsetsProvider;
import com.android.systemui.unfold.UnfoldTransitionProgressProvider;
import com.android.systemui.unfold.util.JankMonitorTransitionProgressListener;
@@ -73,6 +74,7 @@ public class StatusBarWindowController {
private boolean mIsAttached;
private final ViewGroup mStatusBarWindowView;
private final FragmentService mFragmentService;
// The container in which we should run launch animations started from the status bar and
// expanding into the opening window.
private final ViewGroup mLaunchAnimationContainer;
@@ -86,6 +88,7 @@ public class StatusBarWindowController {
WindowManager windowManager,
IWindowManager iWindowManager,
StatusBarContentInsetsProvider contentInsetsProvider,
FragmentService fragmentService,
@Main Resources resources,
Optional<UnfoldTransitionProgressProvider> unfoldTransitionProgressProvider) {
mContext = context;
@@ -93,6 +96,7 @@ public class StatusBarWindowController {
mIWindowManager = iWindowManager;
mContentInsetsProvider = contentInsetsProvider;
mStatusBarWindowView = statusBarWindowView;
mFragmentService = fragmentService;
mLaunchAnimationContainer = mStatusBarWindowView.findViewById(
R.id.status_bar_launch_animation_container);
mLpChanged = new WindowManager.LayoutParams();
@@ -157,7 +161,7 @@ public class StatusBarWindowController {
/** Returns a fragment host manager for the status bar window view. */
public FragmentHostManager getFragmentHostManager() {
return FragmentHostManager.get(mStatusBarWindowView);
return mFragmentService.getFragmentHostManager(mStatusBarWindowView);
}
/**

View File

@@ -28,8 +28,9 @@ import androidx.preference.Preference;
import androidx.preference.PreferenceScreen;
import com.android.settingslib.Utils;
import com.android.systemui.Dependency;
import com.android.systemui.R;
import com.android.systemui.fragments.FragmentHostManager;
import com.android.systemui.fragments.FragmentService;
import java.util.Objects;
@@ -74,7 +75,7 @@ public class RadioListPreference extends CustomListPreference {
RadioFragment f = new RadioFragment();
f.setPreference(this);
FragmentHostManager.get(v).getFragmentManager()
Dependency.get(FragmentService.class).getFragmentHostManager(v).getFragmentManager()
.beginTransaction()
.add(android.R.id.content, f)
.commit();
@@ -86,8 +87,10 @@ public class RadioListPreference extends CustomListPreference {
Bundle savedInstanceState) {
super.onDialogStateRestored(fragment, dialog, savedInstanceState);
View view = dialog.findViewById(R.id.content);
RadioFragment radioFragment = (RadioFragment) FragmentHostManager.get(view)
.getFragmentManager().findFragmentById(R.id.content);
RadioFragment radioFragment = (RadioFragment) Dependency.get(FragmentService.class)
.getFragmentHostManager(view)
.getFragmentManager()
.findFragmentById(R.id.content);
if (radioFragment != null) {
radioFragment.setPreference(this);
}

View File

@@ -14,6 +14,7 @@ import org.junit.Test
@SmallTest
class FragmentServiceTest : SysuiTestCase() {
private val fragmentCreator = TestFragmentCreator()
private val fragmenetHostManagerFactory: FragmentHostManager.Factory = mock()
private val fragmentCreatorFactory = FragmentService.FragmentCreator.Factory { fragmentCreator }
private lateinit var fragmentService: FragmentService
@@ -24,7 +25,13 @@ class FragmentServiceTest : SysuiTestCase() {
Looper.prepare()
}
fragmentService = FragmentService(fragmentCreatorFactory, mock(), DumpManager())
fragmentService =
FragmentService(
fragmentCreatorFactory,
fragmenetHostManagerFactory,
mock(),
DumpManager()
)
}
@Test

View File

@@ -13,8 +13,11 @@ import androidx.test.filters.SmallTest
import com.android.systemui.R
import com.android.systemui.SysuiTestCase
import com.android.systemui.flags.FeatureFlags
import com.android.systemui.fragments.FragmentHostManager
import com.android.systemui.fragments.FragmentService
import com.android.systemui.navigationbar.NavigationModeController
import com.android.systemui.navigationbar.NavigationModeController.ModeChangedListener
import com.android.systemui.plugins.qs.QS
import com.android.systemui.recents.OverviewProxyService
import com.android.systemui.recents.OverviewProxyService.OverviewProxyListener
import com.android.systemui.util.concurrency.FakeExecutor
@@ -29,6 +32,7 @@ import org.mockito.Captor
import org.mockito.Mock
import org.mockito.Mockito
import org.mockito.Mockito.RETURNS_DEEP_STUBS
import org.mockito.Mockito.any
import org.mockito.Mockito.anyInt
import org.mockito.Mockito.doNothing
import org.mockito.Mockito.eq
@@ -69,6 +73,10 @@ class NotificationQSContainerControllerTest : SysuiTestCase() {
private lateinit var shadeExpansionStateManager: ShadeExpansionStateManager
@Mock
private lateinit var featureFlags: FeatureFlags
@Mock
private lateinit var fragmentService: FragmentService
@Mock
private lateinit var fragmentHostManager: FragmentHostManager
@Captor
lateinit var navigationModeCaptor: ArgumentCaptor<ModeChangedListener>
@Captor
@@ -77,6 +85,8 @@ class NotificationQSContainerControllerTest : SysuiTestCase() {
lateinit var windowInsetsCallbackCaptor: ArgumentCaptor<Consumer<WindowInsets>>
@Captor
lateinit var constraintSetCaptor: ArgumentCaptor<ConstraintSet>
@Captor
lateinit var attachStateListenerCaptor: ArgumentCaptor<View.OnAttachStateChangeListener>
private lateinit var controller: NotificationsQSContainerController
private lateinit var navigationModeCallback: ModeChangedListener
@@ -91,8 +101,10 @@ class NotificationQSContainerControllerTest : SysuiTestCase() {
mContext.ensureTestableResources()
whenever(notificationsQSContainer.context).thenReturn(mContext)
whenever(notificationsQSContainer.resources).thenReturn(mContext.resources)
whenever(fragmentService.getFragmentHostManager(any())).thenReturn(fragmentHostManager)
fakeSystemClock = FakeSystemClock()
delayableExecutor = FakeExecutor(fakeSystemClock)
controller = NotificationsQSContainerController(
notificationsQSContainer,
navigationModeController,
@@ -100,6 +112,7 @@ class NotificationQSContainerControllerTest : SysuiTestCase() {
largeScreenShadeHeaderController,
shadeExpansionStateManager,
featureFlags,
fragmentService,
delayableExecutor
)
@@ -114,9 +127,10 @@ class NotificationQSContainerControllerTest : SysuiTestCase() {
doNothing().`when`(notificationsQSContainer)
.setInsetsChangedListener(windowInsetsCallbackCaptor.capture())
doNothing().`when`(notificationsQSContainer).applyConstraints(constraintSetCaptor.capture())
doNothing().`when`(notificationsQSContainer)
.addOnAttachStateChangeListener(attachStateListenerCaptor.capture())
controller.init()
controller.onViewAttached()
attachStateListenerCaptor.value.onViewAttachedToWindow(notificationsQSContainer)
navigationModeCallback = navigationModeCaptor.value
taskbarVisibilityCallback = taskbarVisibilityCaptor.value
@@ -385,6 +399,7 @@ class NotificationQSContainerControllerTest : SysuiTestCase() {
largeScreenShadeHeaderController,
shadeExpansionStateManager,
featureFlags,
fragmentService,
delayableExecutor
)
controller.updateConstraints()
@@ -426,6 +441,17 @@ class NotificationQSContainerControllerTest : SysuiTestCase() {
verify(largeScreenShadeHeaderController).startCustomizingAnimation(false, 100L)
}
@Test
fun testTagListenerAdded() {
verify(fragmentHostManager).addTagListener(eq(QS.TAG), eq(notificationsQSContainer))
}
@Test
fun testTagListenerRemoved() {
attachStateListenerCaptor.value.onViewDetachedFromWindow(notificationsQSContainer)
verify(fragmentHostManager).removeTagListener(eq(QS.TAG), eq(notificationsQSContainer))
}
private fun disableSplitShade() {
setSplitShadeEnabled(false)
}