From 18953f7509f92ee224b5e5a9910acdbc1abbe466 Mon Sep 17 00:00:00 2001 From: Mark Renouf Date: Fri, 23 Feb 2024 13:30:56 -0500 Subject: Creates ChooserHelper, a peer class for code cleanup This is a peer class to ChooserActivity to incrementally assume the tasks of initialization. Code moved through this class will have carefully controlled rules (documented in the class) for control and data flow to prevent additional tangles. This commit makes only a single control flow change, forwarding the call to ChooserActivity#init through this class. This makes no change to functionality yet, but provides a hook for following CLs. Bug: 309960444 Test: atest com.android.intentresolver Change-Id: I4d895adb00a09a9d18117639b2d85e3fe880e067 --- .../android/intentresolver/v2/ChooserActivity.java | 8 ++- .../com/android/intentresolver/v2/ChooserHelper.kt | 81 ++++++++++++++++++++++ 2 files changed, 87 insertions(+), 2 deletions(-) create mode 100644 java/src/com/android/intentresolver/v2/ChooserHelper.kt (limited to 'java/src') diff --git a/java/src/com/android/intentresolver/v2/ChooserActivity.java b/java/src/com/android/intentresolver/v2/ChooserActivity.java index 3d8bfac5..3c9a4247 100644 --- a/java/src/com/android/intentresolver/v2/ChooserActivity.java +++ b/java/src/com/android/intentresolver/v2/ChooserActivity.java @@ -273,6 +273,7 @@ public class ChooserActivity extends Hilt_ChooserActivity implements private static final int SCROLL_STATUS_SCROLLING_VERTICAL = 1; private static final int SCROLL_STATUS_SCROLLING_HORIZONTAL = 2; + @Inject public ChooserHelper mChooserHelper; @Inject public ActivityModel mActivityModel; @Inject public FeatureFlags mFeatureFlags; @Inject public android.service.chooser.FeatureFlags mChooserServiceFeatureFlags; @@ -354,7 +355,11 @@ public class ChooserActivity extends Hilt_ChooserActivity implements protected final void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Log.i(TAG, "onCreate"); - Log.i(TAG, "activityLaunch=" + mActivityModel.toString()); + Log.i(TAG, "mActivityModel=" + mActivityModel.toString()); + + // The postInit hook is invoked when this function returns, via Lifecycle. + mChooserHelper.setPostCreateCallback(this::init); + int callerUid = mActivityModel.getLaunchedFromUid(); if (callerUid < 0 || UserHandle.isIsolated(callerUid)) { Log.e(TAG, "Can't start a resolver from uid " + callerUid); @@ -374,7 +379,6 @@ public class ChooserActivity extends Hilt_ChooserActivity implements .create(mActivityModel.getLaunchedFromUid(), chosenComponentSender); } mLogic = createActivityLogic(); - init(); } private void init() { diff --git a/java/src/com/android/intentresolver/v2/ChooserHelper.kt b/java/src/com/android/intentresolver/v2/ChooserHelper.kt new file mode 100644 index 00000000..17bc2731 --- /dev/null +++ b/java/src/com/android/intentresolver/v2/ChooserHelper.kt @@ -0,0 +1,81 @@ +/* + * 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.intentresolver.v2 + +import android.app.Activity +import androidx.activity.ComponentActivity +import androidx.lifecycle.DefaultLifecycleObserver +import androidx.lifecycle.LifecycleOwner +import dagger.hilt.android.scopes.ActivityScoped +import javax.inject.Inject + +/** + * __Purpose__ + * + * Cleanup aid. Provides a pathway to cleaner code. + * + * __Incoming References__ + * + * For use by ChooserActivity only; must not be accessed by any code outside of ChooserActivity. + * This prevents circular dependencies and coupling, and maintains unidirectional flow. This is + * important for maintaining a migration path towards healthier architecture. + * + * __Outgoing References__ + * + * _ChooserActivity_ + * + * This class must only reference it's host as Activity/ComponentActivity; no down-cast to + * [ChooserActivity]. Other components should be passed in and not pulled from other places. This + * prevents circular dependencies from forming. + * + * _Elsewhere_ + * + * Where possible, Singleton and ActivityScoped dependencies should be injected here instead of + * referenced from an existing location. If not available for injection, the value should be + * constructed here, then provided to where it is needed. If existing objects from ChooserActivity + * are required, supply a factory interface which satisfies the necessary dependencies and use it + * during construction. + */ + +@ActivityScoped +class ChooserHelper @Inject constructor( + hostActivity: Activity, +) : DefaultLifecycleObserver { + // This is guaranteed by Hilt, since only a ComponentActivity is injectable. + private val activity: ComponentActivity = hostActivity as ComponentActivity + + private var activityPostCreate: Runnable? = null + + init { + activity.lifecycle.addObserver(this) + } + + /** + * Provides a optional callback to setup state which is not yet possible to do without circular + * dependencies or by moving more code. + */ + fun setPostCreateCallback(onPostCreate: Runnable) { + activityPostCreate = onPostCreate + } + + /** + * Invoked by Lifecycle, after Activity.onCreate() _returns_. + */ + override fun onCreate(owner: LifecycleOwner) { + activityPostCreate?.run() + } +} \ No newline at end of file -- cgit v1.2.3-59-g8ed1b