Update split controller to latest extension interface

Bug: 190433398
Bug: 190433972
Test: Manual
Change-Id: I215bd5925f35c2a798b7f82ac8753d86cf9b594c
This commit is contained in:
Andrii Kulian
2021-07-22 18:58:25 -07:00
parent dfb851d740
commit ce4afed050
8 changed files with 193 additions and 164 deletions

View File

@@ -749,7 +749,8 @@ public class Instrumentation {
* @see #onStartActivity(Intent)
* @hide
*/
public ActivityResult onStartActivity(Context who, Intent intent, Bundle options) {
public ActivityResult onStartActivity(@NonNull Context who, @NonNull Intent intent,
@NonNull Bundle options) {
return onStartActivity(intent);
}

View File

@@ -18,6 +18,10 @@ package androidx.window.extensions;
import android.content.Context;
import androidx.annotation.NonNull;
import androidx.window.extensions.embedding.ActivityEmbeddingComponent;
import androidx.window.extensions.organizer.EmbeddingExtensionImpl;
/**
* Provider class that will instantiate the library implementation. It must be included in the
* vendor library, and the vendor implementation must match the signature of this class.
@@ -31,6 +35,12 @@ public class ExtensionProvider {
return new SampleExtensionImpl(context);
}
/** Provides a reference implementation of {@link ActivityEmbeddingComponent}. */
public static ActivityEmbeddingComponent getActivityEmbeddingExtensionImpl(
@NonNull Context context) {
return new EmbeddingExtensionImpl();
}
/**
* The support library will use this method to check API version compatibility.
* @return API version string in MAJOR.MINOR.PATCH-description format.

View File

@@ -23,19 +23,15 @@ import static androidx.window.util.ExtensionHelper.transformToWindowSpaceRect;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.Rect;
import android.os.Bundle;
import android.util.Log;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.window.common.DeviceStateManagerPostureProducer;
import androidx.window.common.DisplayFeature;
import androidx.window.common.ResourceConfigDisplayFeatureProducer;
import androidx.window.common.SettingsDevicePostureProducer;
import androidx.window.common.SettingsDisplayFeatureProducer;
import androidx.window.extensions.organizer.SplitController;
import androidx.window.util.DataProducer;
import androidx.window.util.PriorityDataProducer;
@@ -60,8 +56,6 @@ class SampleExtensionImpl extends StubExtension {
private final SettingsDisplayFeatureProducer mSettingsDisplayFeatureProducer;
private final DataProducer<List<DisplayFeature>> mDisplayFeatureProducer;
private final SplitController mSplitController;
SampleExtensionImpl(Context context) {
mSettingsDevicePostureProducer = new SettingsDevicePostureProducer(context);
mDevicePostureProducer = new PriorityDataProducer<>(List.of(
@@ -77,8 +71,6 @@ class SampleExtensionImpl extends StubExtension {
mDevicePostureProducer.addDataChangedCallback(this::onDisplayFeaturesChanged);
mDisplayFeatureProducer.addDataChangedCallback(this::onDisplayFeaturesChanged);
mSplitController = new SplitController();
}
private int getFeatureState(DisplayFeature feature) {
@@ -142,28 +134,4 @@ class SampleExtensionImpl extends StubExtension {
onDisplayFeaturesChanged();
}
@Override
public void setSplitRules(@NonNull List<ExtensionSplitRule> splitRules) {
mSplitController.setSplitRules(splitRules);
}
@Override
@NonNull
public List<ExtensionSplitRule> getSplitRules() {
return new ArrayList<>(mSplitController.getSplitRules());
}
@Override
public void setSplitOrganizerCallback(@Nullable SplitOrganizerCallback callback) {
mSplitController.setSplitOrganizerCallback(callback);
}
@Override
public void startActivityToSide(@NonNull Activity launchingActivity, @NonNull Intent intent,
@Nullable Bundle options, @NonNull ExtensionSplitPairRule splitPairRule,
int startRequestId) {
mSplitController.startActivityToSide(launchingActivity, intent, options, splitPairRule,
startRequestId);
}
}

View File

@@ -0,0 +1,48 @@
/*
* Copyright (C) 2021 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 androidx.window.extensions.organizer;
import androidx.annotation.NonNull;
import androidx.window.extensions.embedding.ActivityEmbeddingComponent;
import androidx.window.extensions.embedding.EmbeddingRule;
import androidx.window.extensions.embedding.SplitInfo;
import java.util.List;
import java.util.Set;
import java.util.function.Consumer;
/**
* Reference implementation of the activity embedding interface defined in WM Jetpack.
*/
public class EmbeddingExtensionImpl implements ActivityEmbeddingComponent {
private final SplitController mSplitController;
public EmbeddingExtensionImpl() {
mSplitController = new SplitController();
}
@Override
public void setEmbeddingRules(@NonNull Set<EmbeddingRule> rules) {
mSplitController.setEmbeddingRules(rules);
}
@Override
public void setEmbeddingCallback(@NonNull Consumer<List<SplitInfo>> consumer) {
mSplitController.setEmbeddingCallback(consumer);
}
}

View File

@@ -19,7 +19,9 @@ package androidx.window.extensions.organizer;
import android.annotation.NonNull;
import android.app.Activity;
import androidx.window.extensions.ExtensionSplitPairRule;
import androidx.window.extensions.embedding.SplitPairRule;
import androidx.window.extensions.embedding.SplitPlaceholderRule;
import androidx.window.extensions.embedding.SplitRule;
/**
* Client-side descriptor of a split that holds two containers.
@@ -27,20 +29,26 @@ import androidx.window.extensions.ExtensionSplitPairRule;
class SplitContainer {
private final TaskFragmentContainer mPrimaryContainer;
private final TaskFragmentContainer mSecondaryContainer;
private final ExtensionSplitPairRule mSplitPairRule;
private final SplitRule mSplitRule;
SplitContainer(@NonNull TaskFragmentContainer primaryContainer,
@NonNull Activity primaryActivity,
@NonNull TaskFragmentContainer secondaryContainer,
@NonNull ExtensionSplitPairRule splitPairRule) {
@NonNull SplitRule splitRule) {
mPrimaryContainer = primaryContainer;
mSecondaryContainer = secondaryContainer;
mSplitPairRule = splitPairRule;
mSplitRule = splitRule;
if (mSplitPairRule.finishPrimaryWithSecondary || mSplitPairRule.useAsPlaceholder) {
final boolean isPlaceholderContainer = isPlaceholderContainer();
final boolean shouldFinishPrimaryWithSecondary = (mSplitRule instanceof SplitPairRule)
&& ((SplitPairRule) mSplitRule).shouldFinishPrimaryWithSecondary();
final boolean shouldFinishSecondaryWithPrimary = (mSplitRule instanceof SplitPairRule)
&& ((SplitPairRule) mSplitRule).shouldFinishSecondaryWithPrimary();
if (shouldFinishPrimaryWithSecondary || isPlaceholderContainer) {
mSecondaryContainer.addActivityToFinishOnExit(primaryActivity);
}
if (mSplitPairRule.finishSecondaryWithPrimary || mSplitPairRule.useAsPlaceholder) {
if (shouldFinishSecondaryWithPrimary || isPlaceholderContainer) {
mPrimaryContainer.addContainerToFinishOnExit(mSecondaryContainer);
}
}
@@ -56,7 +64,11 @@ class SplitContainer {
}
@NonNull
ExtensionSplitPairRule getSplitPairRule() {
return mSplitPairRule;
SplitRule getSplitRule() {
return mSplitRule;
}
boolean isPlaceholderContainer() {
return (mSplitRule instanceof SplitPlaceholderRule);
}
}

View File

@@ -24,7 +24,6 @@ import android.app.ActivityOptions;
import android.app.ActivityThread;
import android.app.Application.ActivityLifecycleCallbacks;
import android.app.Instrumentation;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.res.Configuration;
@@ -32,20 +31,24 @@ import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.util.Pair;
import android.window.TaskFragmentAppearedInfo;
import android.window.TaskFragmentInfo;
import android.window.WindowContainerTransaction;
import androidx.window.extensions.ExtensionInterface.SplitOrganizerCallback;
import androidx.window.extensions.ExtensionSplitActivityRule;
import androidx.window.extensions.ExtensionSplitInfo;
import androidx.window.extensions.ExtensionSplitPairRule;
import androidx.window.extensions.ExtensionSplitRule;
import androidx.window.extensions.ExtensionTaskFragment;
import androidx.window.extensions.embedding.ActivityRule;
import androidx.window.extensions.embedding.EmbeddingRule;
import androidx.window.extensions.embedding.SplitInfo;
import androidx.window.extensions.embedding.SplitPairRule;
import androidx.window.extensions.embedding.SplitPlaceholderRule;
import androidx.window.extensions.embedding.SplitRule;
import androidx.window.extensions.embedding.TaskFragment;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.concurrent.Executor;
import java.util.function.Consumer;
/**
* Main controller class that manages split states and presentation.
@@ -55,12 +58,12 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
private final SplitPresenter mPresenter;
// Currently applied split configuration.
private final List<ExtensionSplitRule> mSplitRules = new ArrayList<>();
private final List<EmbeddingRule> mSplitRules = new ArrayList<>();
private final List<TaskFragmentContainer> mContainers = new ArrayList<>();
private final List<SplitContainer> mSplitContainers = new ArrayList<>();
// Callback to Jetpack to notify about changes to split states.
private SplitOrganizerCallback mSplitOrganizerCallback;
private @NonNull Consumer<List<SplitInfo>> mEmbeddingCallback;
public SplitController() {
mPresenter = new SplitPresenter(new MainThreadExecutor(), this);
@@ -73,13 +76,14 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
instrumentation.addMonitor(new ActivityStartMonitor());
}
public void setSplitRules(@NonNull List<ExtensionSplitRule> splitRules) {
/** Updates the embedding rules applied to future activity launches. */
public void setEmbeddingRules(@NonNull Set<EmbeddingRule> rules) {
mSplitRules.clear();
mSplitRules.addAll(splitRules);
mSplitRules.addAll(rules);
}
@NonNull
public List<ExtensionSplitRule> getSplitRules() {
public List<EmbeddingRule> getSplitRules() {
return mSplitRules;
}
@@ -87,22 +91,20 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
* Starts an activity to side of the launchingActivity with the provided split config.
*/
public void startActivityToSide(@NonNull Activity launchingActivity, @NonNull Intent intent,
@Nullable Bundle options, @NonNull ExtensionSplitPairRule splitPairRule,
int startRequestId) {
@Nullable Bundle options, @NonNull SplitRule sideRule,
@NonNull Consumer<Exception> failureCallback) {
try {
mPresenter.startActivityToSide(launchingActivity, intent, options, splitPairRule);
mPresenter.startActivityToSide(launchingActivity, intent, options, sideRule);
} catch (Exception e) {
if (mSplitOrganizerCallback != null && startRequestId != -1) {
mSplitOrganizerCallback.onActivityFailedToStartInContainer(startRequestId, e);
}
failureCallback.accept(e);
}
}
/**
* Registers the split organizer callback to notify about changes to active splits.
*/
public void setSplitOrganizerCallback(@NonNull SplitOrganizerCallback callback) {
mSplitOrganizerCallback = callback;
public void setEmbeddingCallback(@NonNull Consumer<List<SplitInfo>> callback) {
mEmbeddingCallback = callback;
updateCallbackIfNecessary();
}
@@ -160,14 +162,12 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
*/
// TODO(b/190433398): Break down into smaller functions.
void onActivityCreated(@NonNull Activity launchedActivity) {
final ComponentName componentName = launchedActivity.getComponentName();
final List<ExtensionSplitRule> splitRules = getSplitRules();
final List<EmbeddingRule> splitRules = getSplitRules();
final TaskFragmentContainer currentContainer = getContainerWithActivity(
launchedActivity.getActivityToken(), launchedActivity);
// Check if the activity is configured to always be expanded.
if (shouldExpand(componentName, splitRules)) {
if (shouldExpand(launchedActivity, splitRules)) {
if (shouldContainerBeExpanded(currentContainer)) {
// Make sure that the existing container is expanded
mPresenter.expandTaskFragment(currentContainer.getTaskFragmentToken());
@@ -224,8 +224,8 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
}
}
final ExtensionSplitPairRule splitPairRule = getSplitRule(
activityBelow.getComponentName(), componentName, splitRules);
final SplitPairRule splitPairRule = getSplitRule(activityBelow, launchedActivity,
splitRules);
if (splitPairRule == null) {
return;
}
@@ -302,11 +302,12 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
void registerSplit(@NonNull WindowContainerTransaction wct,
@NonNull TaskFragmentContainer primaryContainer, @NonNull Activity primaryActivity,
@NonNull TaskFragmentContainer secondaryContainer,
@NonNull ExtensionSplitPairRule splitPairRule) {
removeExistingSecondaryContainers(wct, primaryContainer);
@NonNull SplitRule splitRule) {
if (splitRule instanceof SplitPairRule && ((SplitPairRule) splitRule).shouldClearTop()) {
removeExistingSecondaryContainers(wct, primaryContainer);
}
SplitContainer splitContainer = new SplitContainer(primaryContainer, primaryActivity,
secondaryContainer, splitPairRule);
secondaryContainer, splitRule);
mSplitContainers.add(splitContainer);
}
@@ -456,22 +457,20 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
}
// Check if there is enough space for launch
final ExtensionSplitPairRule placeholderRule = getPlaceholderRule(
activity.getComponentName());
final SplitPlaceholderRule placeholderRule = getPlaceholderRule(activity);
if (placeholderRule == null || !mPresenter.shouldShowSideBySide(
mPresenter.getParentContainerBounds(activity), placeholderRule)) {
return false;
}
Intent placeholderIntent = new Intent();
placeholderIntent.setComponent(placeholderRule.secondaryActivityName);
// TODO(b/190433398): Handle failed request
startActivityToSide(activity, placeholderIntent, null, placeholderRule, -1);
startActivityToSide(activity, placeholderRule.getPlaceholderIntent(), null,
placeholderRule, null);
return true;
}
private boolean dismissPlaceholderIfNecessary(@NonNull SplitContainer splitContainer) {
if (!splitContainer.getSplitPairRule().useAsPlaceholder) {
if (!splitContainer.isPlaceholderContainer()) {
return false;
}
@@ -488,15 +487,14 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
* Returns the rule to launch a placeholder for the activity with the provided component name
* if it is configured in the split config.
*/
private ExtensionSplitPairRule getPlaceholderRule(@NonNull ComponentName componentName) {
for (ExtensionSplitRule rule : mSplitRules) {
if (!(rule instanceof ExtensionSplitPairRule)) {
private SplitPlaceholderRule getPlaceholderRule(@NonNull Activity activity) {
for (EmbeddingRule rule : mSplitRules) {
if (!(rule instanceof SplitPlaceholderRule)) {
continue;
}
ExtensionSplitPairRule pairRule = (ExtensionSplitPairRule) rule;
if (componentName.equals(pairRule.primaryActivityName)
&& pairRule.useAsPlaceholder) {
return pairRule;
SplitPlaceholderRule placeholderRule = (SplitPlaceholderRule) rule;
if (placeholderRule.getActivityPredicate().test(activity)) {
return placeholderRule;
}
}
return null;
@@ -506,27 +504,27 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
* Notifies listeners about changes to split states if necessary.
*/
private void updateCallbackIfNecessary() {
if (mSplitOrganizerCallback == null) {
if (mEmbeddingCallback == null) {
return;
}
// TODO(b/190433398): Check if something actually changed
mSplitOrganizerCallback.onSplitInfoChanged(getActiveSplitStates());
mEmbeddingCallback.accept(getActiveSplitStates());
}
/**
* Returns a list of descriptors for currently active split states.
*/
private List<ExtensionSplitInfo> getActiveSplitStates() {
List<ExtensionSplitInfo> splitStates = new ArrayList<>();
private List<SplitInfo> getActiveSplitStates() {
List<SplitInfo> splitStates = new ArrayList<>();
for (SplitContainer container : mSplitContainers) {
ExtensionTaskFragment primaryContainer =
new ExtensionTaskFragment(
TaskFragment primaryContainer =
new TaskFragment(
container.getPrimaryContainer().collectActivities());
ExtensionTaskFragment secondaryContainer =
new ExtensionTaskFragment(
TaskFragment secondaryContainer =
new TaskFragment(
container.getSecondaryContainer().collectActivities());
ExtensionSplitInfo splitState = new ExtensionSplitInfo(primaryContainer,
secondaryContainer, container.getSplitPairRule().splitRatio);
SplitInfo splitState = new SplitInfo(primaryContainer,
secondaryContainer, container.getSplitRule().getSplitRatio());
splitStates.add(splitState);
}
return splitStates;
@@ -550,23 +548,41 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
}
/**
* Returns a split rule for the provided pair of component names if available.
* Returns a split rule for the provided pair of primary activity and secondary activity intent
* if available.
*/
@Nullable
private static ExtensionSplitPairRule getSplitRule(@NonNull ComponentName primaryActivityName,
@NonNull ComponentName secondaryActivityName,
@NonNull List<ExtensionSplitRule> splitRules) {
if (splitRules == null || primaryActivityName == null || secondaryActivityName == null) {
return null;
}
for (ExtensionSplitRule rule : splitRules) {
if (!(rule instanceof ExtensionSplitPairRule)) {
private static SplitPairRule getSplitRule(@NonNull Activity primaryActivity,
@NonNull Intent secondaryActivityIntent, @NonNull List<EmbeddingRule> splitRules) {
for (EmbeddingRule rule : splitRules) {
if (!(rule instanceof SplitPairRule)) {
continue;
}
ExtensionSplitPairRule pairRule = (ExtensionSplitPairRule) rule;
if (match(secondaryActivityName, pairRule.secondaryActivityName)
&& match(primaryActivityName, pairRule.primaryActivityName)) {
SplitPairRule pairRule = (SplitPairRule) rule;
if (pairRule.getActivityIntentPredicate().test(
new Pair(primaryActivity, secondaryActivityIntent))) {
return pairRule;
}
}
return null;
}
/**
* Returns a split rule for the provided pair of primary and secondary activities if available.
*/
@Nullable
private static SplitPairRule getSplitRule(@NonNull Activity primaryActivity,
@NonNull Activity secondaryActivity, @NonNull List<EmbeddingRule> splitRules) {
for (EmbeddingRule rule : splitRules) {
if (!(rule instanceof SplitPairRule)) {
continue;
}
SplitPairRule pairRule = (SplitPairRule) rule;
final Intent intent = secondaryActivity.getIntent();
if (pairRule.getActivityPairPredicate().test(
new Pair(primaryActivity, secondaryActivity))
&& (intent == null || pairRule.getActivityIntentPredicate().test(
new Pair(primaryActivity, intent)))) {
return pairRule;
}
}
@@ -587,55 +603,26 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
* Returns {@code true} if an Activity with the provided component name should always be
* expanded to occupy full task bounds. Such activity must not be put in a split.
*/
private static boolean shouldExpand(@NonNull ComponentName componentName,
List<ExtensionSplitRule> splitRules) {
private static boolean shouldExpand(@NonNull Activity activity,
List<EmbeddingRule> splitRules) {
if (splitRules == null) {
return false;
}
for (ExtensionSplitRule rule : splitRules) {
if (!(rule instanceof ExtensionSplitActivityRule)) {
for (EmbeddingRule rule : splitRules) {
if (!(rule instanceof ActivityRule)) {
continue;
}
ExtensionSplitActivityRule activityRule = (ExtensionSplitActivityRule) rule;
if (match(componentName, activityRule.activityName)
&& activityRule.alwaysExpand) {
ActivityRule activityRule = (ActivityRule) rule;
if (!activityRule.shouldAlwaysExpand()) {
continue;
}
if (activityRule.getActivityPredicate().test(activity)) {
return true;
}
}
return false;
}
/** Match check allowing wildcards for activity class name but not package name. */
private static boolean match(@NonNull ComponentName activityComponent,
@NonNull ComponentName ruleComponent) {
if (activityComponent.toString().contains("*")) {
throw new IllegalArgumentException("Wildcard can only be part of the rule.");
}
final boolean packagesMatch =
activityComponent.getPackageName().equals(ruleComponent.getPackageName());
final boolean classesMatch =
activityComponent.getClassName().equals(ruleComponent.getClassName());
return packagesMatch && (classesMatch
|| wildcardMatch(activityComponent.getClassName(), ruleComponent.getClassName()));
}
/**
* Checks if the provided name matches the pattern.
*/
private static boolean wildcardMatch(@NonNull String name, @NonNull String pattern) {
if (!pattern.contains("*")) {
return false;
}
if (pattern.equals("*")) {
return true;
}
if (pattern.indexOf("*") != pattern.lastIndexOf("*") || !pattern.endsWith("*")) {
throw new IllegalArgumentException(
"Name pattern with a wildcard must only contain a single * in the end");
}
return name.startsWith(pattern.substring(0, pattern.length() - 1));
}
private final class LifecycleCallbacks implements ActivityLifecycleCallbacks {
@Override
@@ -698,8 +685,8 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
private class ActivityStartMonitor extends Instrumentation.ActivityMonitor {
@Override
public Instrumentation.ActivityResult onStartActivity(Context who, Intent intent,
Bundle options) {
public Instrumentation.ActivityResult onStartActivity(@NonNull Context who,
@NonNull Intent intent, @NonNull Bundle options) {
// TODO(b/190433398): Check if the activity is configured to always be expanded.
// Check if activity should be put in a split with the activity that launched it.
@@ -722,8 +709,8 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
*/
private boolean setLaunchingToSideContainer(Activity launchingActivity, Intent intent,
Bundle options) {
final ExtensionSplitPairRule splitPairRule = getSplitRule(
launchingActivity.getComponentName(), intent.getComponent(), getSplitRules());
final SplitPairRule splitPairRule = getSplitRule(launchingActivity, intent,
getSplitRules());
if (splitPairRule == null) {
return false;
}
@@ -770,8 +757,8 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
return;
}
final ExtensionSplitPairRule splitPairRule = getSplitRule(
primaryActivity.getComponentName(), intent.getComponent(), getSplitRules());
final SplitPairRule splitPairRule = getSplitRule(primaryActivity, intent,
getSplitRules());
if (splitPairRule == null) {
return;
}

View File

@@ -24,13 +24,16 @@ import android.content.res.Configuration;
import android.graphics.Rect;
import android.os.Bundle;
import android.os.IBinder;
import android.view.WindowInsets;
import android.view.WindowMetrics;
import android.window.TaskFragmentCreationParams;
import android.window.WindowContainerTransaction;
import androidx.annotation.IntDef;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.window.extensions.ExtensionSplitPairRule;
import androidx.window.extensions.embedding.SplitPairRule;
import androidx.window.extensions.embedding.SplitRule;
import java.util.concurrent.Executor;
@@ -89,7 +92,7 @@ class SplitPresenter extends JetpackTaskFragmentOrganizer {
* @return The newly created secondary container.
*/
TaskFragmentContainer createNewSplitWithEmptySideContainer(@NonNull Activity primaryActivity,
@NonNull ExtensionSplitPairRule rule) {
@NonNull SplitPairRule rule) {
final WindowContainerTransaction wct = new WindowContainerTransaction();
final Rect parentBounds = getParentContainerBounds(primaryActivity);
@@ -128,7 +131,7 @@ class SplitPresenter extends JetpackTaskFragmentOrganizer {
* @param rule The split rule to be applied to the container.
*/
void createNewSplitContainer(@NonNull Activity primaryActivity,
@NonNull Activity secondaryActivity, @NonNull ExtensionSplitPairRule rule) {
@NonNull Activity secondaryActivity, @NonNull SplitPairRule rule) {
final WindowContainerTransaction wct = new WindowContainerTransaction();
final Rect parentBounds = getParentContainerBounds(primaryActivity);
@@ -192,7 +195,7 @@ class SplitPresenter extends JetpackTaskFragmentOrganizer {
* @param rule The split rule to be applied to the container.
*/
void startActivityToSide(@NonNull Activity launchingActivity, @NonNull Intent activityIntent,
@Nullable Bundle activityOptions, @NonNull ExtensionSplitPairRule rule) {
@Nullable Bundle activityOptions, @NonNull SplitRule rule) {
final Rect parentBounds = getParentContainerBounds(launchingActivity);
final Rect primaryRectBounds = getBoundsForPosition(POSITION_LEFT, parentBounds, rule);
final Rect secondaryRectBounds = getBoundsForPosition(POSITION_RIGHT, parentBounds, rule);
@@ -227,7 +230,7 @@ class SplitPresenter extends JetpackTaskFragmentOrganizer {
@NonNull WindowContainerTransaction wct) {
// Getting the parent bounds using the updated container - it will have the recent value.
final Rect parentBounds = getParentContainerBounds(updatedContainer);
final ExtensionSplitPairRule rule = splitContainer.getSplitPairRule();
final SplitRule rule = splitContainer.getSplitRule();
final Rect primaryRectBounds = getBoundsForPosition(POSITION_LEFT, parentBounds, rule);
final Rect secondaryRectBounds = getBoundsForPosition(POSITION_RIGHT, parentBounds, rule);
@@ -273,24 +276,24 @@ class SplitPresenter extends JetpackTaskFragmentOrganizer {
boolean shouldShowSideBySide(@NonNull SplitContainer splitContainer) {
final Rect parentBounds = getParentContainerBounds(splitContainer.getPrimaryContainer());
return shouldShowSideBySide(parentBounds, splitContainer.getSplitPairRule());
return shouldShowSideBySide(parentBounds, splitContainer.getSplitRule());
}
boolean shouldShowSideBySide(@Nullable Rect parentBounds,
@NonNull ExtensionSplitPairRule rule) {
return parentBounds != null && parentBounds.width() >= rule.minWidth
// TODO(b/190433398): Consider proper smallest width computation.
&& Math.min(parentBounds.width(), parentBounds.height()) >= rule.minSmallestWidth;
boolean shouldShowSideBySide(@Nullable Rect parentBounds, @NonNull SplitRule rule) {
// TODO(b/190433398): Supply correct insets.
final WindowMetrics parentMetrics = new WindowMetrics(parentBounds,
new WindowInsets(new Rect()));
return rule.getParentWindowMetricsPredicate().test(parentMetrics);
}
@NonNull
private Rect getBoundsForPosition(@Position int position, @NonNull Rect parentBounds,
@NonNull ExtensionSplitPairRule rule) {
@NonNull SplitRule rule) {
if (!shouldShowSideBySide(parentBounds, rule)) {
return new Rect();
}
float splitRatio = rule.splitRatio;
float splitRatio = rule.getSplitRatio();
switch (position) {
case POSITION_LEFT:
return new Rect(