Merge "Expand SplitContainer if min dimensions not satisfied" into tm-qpr-dev
This commit is contained in:
@@ -24,9 +24,9 @@ import static androidx.window.extensions.embedding.SplitContainer.getFinishSecon
|
|||||||
import static androidx.window.extensions.embedding.SplitContainer.isStickyPlaceholderRule;
|
import static androidx.window.extensions.embedding.SplitContainer.isStickyPlaceholderRule;
|
||||||
import static androidx.window.extensions.embedding.SplitContainer.shouldFinishAssociatedContainerWhenAdjacent;
|
import static androidx.window.extensions.embedding.SplitContainer.shouldFinishAssociatedContainerWhenAdjacent;
|
||||||
import static androidx.window.extensions.embedding.SplitContainer.shouldFinishAssociatedContainerWhenStacked;
|
import static androidx.window.extensions.embedding.SplitContainer.shouldFinishAssociatedContainerWhenStacked;
|
||||||
import static androidx.window.extensions.embedding.SplitPresenter.boundsSmallerThanMinDimensions;
|
import static androidx.window.extensions.embedding.SplitPresenter.RESULT_EXPAND_FAILED_NO_TF_INFO;
|
||||||
import static androidx.window.extensions.embedding.SplitPresenter.getActivityIntentMinDimensionsPair;
|
import static androidx.window.extensions.embedding.SplitPresenter.getActivityIntentMinDimensionsPair;
|
||||||
import static androidx.window.extensions.embedding.SplitPresenter.getMinDimensions;
|
import static androidx.window.extensions.embedding.SplitPresenter.getNonEmbeddedActivityBounds;
|
||||||
import static androidx.window.extensions.embedding.SplitPresenter.shouldShowSideBySide;
|
import static androidx.window.extensions.embedding.SplitPresenter.shouldShowSideBySide;
|
||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
@@ -381,6 +381,7 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
|
|||||||
* in a state that the caller shouldn't handle.
|
* in a state that the caller shouldn't handle.
|
||||||
*/
|
*/
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
|
@GuardedBy("mLock")
|
||||||
boolean resolveActivityToContainer(@NonNull Activity activity, boolean isOnReparent) {
|
boolean resolveActivityToContainer(@NonNull Activity activity, boolean isOnReparent) {
|
||||||
if (isInPictureInPicture(activity) || activity.isFinishing()) {
|
if (isInPictureInPicture(activity) || activity.isFinishing()) {
|
||||||
// We don't embed activity when it is in PIP, or finishing. Return true since we don't
|
// We don't embed activity when it is in PIP, or finishing. Return true since we don't
|
||||||
@@ -581,8 +582,9 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Finds the activity below the given activity. */
|
/** Finds the activity below the given activity. */
|
||||||
|
@VisibleForTesting
|
||||||
@Nullable
|
@Nullable
|
||||||
private Activity findActivityBelow(@NonNull Activity activity) {
|
Activity findActivityBelow(@NonNull Activity activity) {
|
||||||
Activity activityBelow = null;
|
Activity activityBelow = null;
|
||||||
final TaskFragmentContainer container = getContainerWithActivity(activity);
|
final TaskFragmentContainer container = getContainerWithActivity(activity);
|
||||||
if (container != null) {
|
if (container != null) {
|
||||||
@@ -606,6 +608,7 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
|
|||||||
* Checks if there is a rule to split the two activities. If there is one, puts them into split
|
* Checks if there is a rule to split the two activities. If there is one, puts them into split
|
||||||
* and returns {@code true}. Otherwise, returns {@code false}.
|
* and returns {@code true}. Otherwise, returns {@code false}.
|
||||||
*/
|
*/
|
||||||
|
@GuardedBy("mLock")
|
||||||
private boolean putActivitiesIntoSplitIfNecessary(@NonNull Activity primaryActivity,
|
private boolean putActivitiesIntoSplitIfNecessary(@NonNull Activity primaryActivity,
|
||||||
@NonNull Activity secondaryActivity) {
|
@NonNull Activity secondaryActivity) {
|
||||||
final SplitPairRule splitRule = getSplitRule(primaryActivity, secondaryActivity);
|
final SplitPairRule splitRule = getSplitRule(primaryActivity, secondaryActivity);
|
||||||
@@ -616,25 +619,25 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
|
|||||||
primaryActivity);
|
primaryActivity);
|
||||||
final SplitContainer splitContainer = getActiveSplitForContainer(primaryContainer);
|
final SplitContainer splitContainer = getActiveSplitForContainer(primaryContainer);
|
||||||
if (splitContainer != null && primaryContainer == splitContainer.getPrimaryContainer()
|
if (splitContainer != null && primaryContainer == splitContainer.getPrimaryContainer()
|
||||||
&& canReuseContainer(splitRule, splitContainer.getSplitRule())
|
&& canReuseContainer(splitRule, splitContainer.getSplitRule())) {
|
||||||
&& !boundsSmallerThanMinDimensions(primaryContainer.getLastRequestedBounds(),
|
|
||||||
getMinDimensions(primaryActivity))) {
|
|
||||||
// Can launch in the existing secondary container if the rules share the same
|
// Can launch in the existing secondary container if the rules share the same
|
||||||
// presentation.
|
// presentation.
|
||||||
final TaskFragmentContainer secondaryContainer = splitContainer.getSecondaryContainer();
|
final TaskFragmentContainer secondaryContainer = splitContainer.getSecondaryContainer();
|
||||||
if (secondaryContainer == getContainerWithActivity(secondaryActivity)
|
if (secondaryContainer == getContainerWithActivity(secondaryActivity)) {
|
||||||
&& !boundsSmallerThanMinDimensions(secondaryContainer.getLastRequestedBounds(),
|
|
||||||
getMinDimensions(secondaryActivity))) {
|
|
||||||
// The activity is already in the target TaskFragment.
|
// The activity is already in the target TaskFragment.
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
secondaryContainer.addPendingAppearedActivity(secondaryActivity);
|
secondaryContainer.addPendingAppearedActivity(secondaryActivity);
|
||||||
final WindowContainerTransaction wct = new WindowContainerTransaction();
|
final WindowContainerTransaction wct = new WindowContainerTransaction();
|
||||||
wct.reparentActivityToTaskFragment(
|
if (mPresenter.expandSplitContainerIfNeeded(wct, splitContainer, primaryActivity,
|
||||||
secondaryContainer.getTaskFragmentToken(),
|
secondaryActivity, null /* secondaryIntent */)
|
||||||
secondaryActivity.getActivityToken());
|
!= RESULT_EXPAND_FAILED_NO_TF_INFO) {
|
||||||
mPresenter.applyTransaction(wct);
|
wct.reparentActivityToTaskFragment(
|
||||||
return true;
|
secondaryContainer.getTaskFragmentToken(),
|
||||||
|
secondaryActivity.getActivityToken());
|
||||||
|
mPresenter.applyTransaction(wct);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// Create new split pair.
|
// Create new split pair.
|
||||||
mPresenter.createNewSplitContainer(primaryActivity, secondaryActivity, splitRule);
|
mPresenter.createNewSplitContainer(primaryActivity, secondaryActivity, splitRule);
|
||||||
@@ -792,6 +795,7 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
|
|||||||
* Returns a container for the new activity intent to launch into as splitting with the primary
|
* Returns a container for the new activity intent to launch into as splitting with the primary
|
||||||
* activity.
|
* activity.
|
||||||
*/
|
*/
|
||||||
|
@GuardedBy("mLock")
|
||||||
@Nullable
|
@Nullable
|
||||||
private TaskFragmentContainer getSecondaryContainerForSplitIfAny(
|
private TaskFragmentContainer getSecondaryContainerForSplitIfAny(
|
||||||
@NonNull WindowContainerTransaction wct, @NonNull Activity primaryActivity,
|
@NonNull WindowContainerTransaction wct, @NonNull Activity primaryActivity,
|
||||||
@@ -805,16 +809,12 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
|
|||||||
if (splitContainer != null && existingContainer == splitContainer.getPrimaryContainer()
|
if (splitContainer != null && existingContainer == splitContainer.getPrimaryContainer()
|
||||||
&& (canReuseContainer(splitRule, splitContainer.getSplitRule())
|
&& (canReuseContainer(splitRule, splitContainer.getSplitRule())
|
||||||
// TODO(b/231845476) we should always respect clearTop.
|
// TODO(b/231845476) we should always respect clearTop.
|
||||||
|| !respectClearTop)) {
|
|| !respectClearTop)
|
||||||
final Rect secondaryBounds = splitContainer.getSecondaryContainer()
|
&& mPresenter.expandSplitContainerIfNeeded(wct, splitContainer, primaryActivity,
|
||||||
.getLastRequestedBounds();
|
null /* secondaryActivity */, intent) != RESULT_EXPAND_FAILED_NO_TF_INFO) {
|
||||||
if (secondaryBounds.isEmpty()
|
// Can launch in the existing secondary container if the rules share the same
|
||||||
|| !boundsSmallerThanMinDimensions(secondaryBounds,
|
// presentation.
|
||||||
getMinDimensions(intent))) {
|
return splitContainer.getSecondaryContainer();
|
||||||
// Can launch in the existing secondary container if the rules share the same
|
|
||||||
// presentation.
|
|
||||||
return splitContainer.getSecondaryContainer();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// Create a new TaskFragment to split with the primary activity for the new activity.
|
// Create a new TaskFragment to split with the primary activity for the new activity.
|
||||||
return mPresenter.createNewSplitWithEmptySideContainer(wct, primaryActivity, intent,
|
return mPresenter.createNewSplitWithEmptySideContainer(wct, primaryActivity, intent,
|
||||||
@@ -868,6 +868,7 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
|
|||||||
* if needed.
|
* if needed.
|
||||||
* @param taskId parent Task of the new TaskFragment.
|
* @param taskId parent Task of the new TaskFragment.
|
||||||
*/
|
*/
|
||||||
|
@GuardedBy("mLock")
|
||||||
TaskFragmentContainer newContainer(@Nullable Activity pendingAppearedActivity,
|
TaskFragmentContainer newContainer(@Nullable Activity pendingAppearedActivity,
|
||||||
@Nullable Intent pendingAppearedIntent, @NonNull Activity activityInTask, int taskId) {
|
@Nullable Intent pendingAppearedIntent, @NonNull Activity activityInTask, int taskId) {
|
||||||
if (activityInTask == null) {
|
if (activityInTask == null) {
|
||||||
@@ -881,7 +882,7 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
|
|||||||
pendingAppearedIntent, taskContainer, this);
|
pendingAppearedIntent, taskContainer, this);
|
||||||
if (!taskContainer.isTaskBoundsInitialized()) {
|
if (!taskContainer.isTaskBoundsInitialized()) {
|
||||||
// Get the initial bounds before the TaskFragment has appeared.
|
// Get the initial bounds before the TaskFragment has appeared.
|
||||||
final Rect taskBounds = SplitPresenter.getTaskBoundsFromActivity(activityInTask);
|
final Rect taskBounds = getNonEmbeddedActivityBounds(activityInTask);
|
||||||
if (!taskContainer.setTaskBounds(taskBounds)) {
|
if (!taskContainer.setTaskBounds(taskBounds)) {
|
||||||
Log.w(TAG, "Can't find bounds from activity=" + activityInTask);
|
Log.w(TAG, "Can't find bounds from activity=" + activityInTask);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -65,6 +65,41 @@ class SplitPresenter extends JetpackTaskFragmentOrganizer {
|
|||||||
})
|
})
|
||||||
private @interface Position {}
|
private @interface Position {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Result of {@link #expandSplitContainerIfNeeded(WindowContainerTransaction, SplitContainer,
|
||||||
|
* Activity, Activity, Intent)}.
|
||||||
|
* No need to expand the splitContainer because screen is big enough to
|
||||||
|
* {@link #shouldShowSideBySide(Rect, SplitRule, Pair)} and minimum dimensions is satisfied.
|
||||||
|
*/
|
||||||
|
static final int RESULT_NOT_EXPANDED = 0;
|
||||||
|
/**
|
||||||
|
* Result of {@link #expandSplitContainerIfNeeded(WindowContainerTransaction, SplitContainer,
|
||||||
|
* Activity, Activity, Intent)}.
|
||||||
|
* The splitContainer should be expanded. It is usually because minimum dimensions is not
|
||||||
|
* satisfied.
|
||||||
|
* @see #shouldShowSideBySide(Rect, SplitRule, Pair)
|
||||||
|
*/
|
||||||
|
static final int RESULT_EXPANDED = 1;
|
||||||
|
/**
|
||||||
|
* Result of {@link #expandSplitContainerIfNeeded(WindowContainerTransaction, SplitContainer,
|
||||||
|
* Activity, Activity, Intent)}.
|
||||||
|
* The splitContainer should be expanded, but the client side hasn't received
|
||||||
|
* {@link android.window.TaskFragmentInfo} yet. Fallback to create new expanded SplitContainer
|
||||||
|
* instead.
|
||||||
|
*/
|
||||||
|
static final int RESULT_EXPAND_FAILED_NO_TF_INFO = 2;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Result of {@link #expandSplitContainerIfNeeded(WindowContainerTransaction, SplitContainer,
|
||||||
|
* Activity, Activity, Intent)}
|
||||||
|
*/
|
||||||
|
@IntDef(value = {
|
||||||
|
RESULT_NOT_EXPANDED,
|
||||||
|
RESULT_EXPANDED,
|
||||||
|
RESULT_EXPAND_FAILED_NO_TF_INFO,
|
||||||
|
})
|
||||||
|
private @interface ResultCode {}
|
||||||
|
|
||||||
private final SplitController mController;
|
private final SplitController mController;
|
||||||
|
|
||||||
SplitPresenter(@NonNull Executor executor, SplitController controller) {
|
SplitPresenter(@NonNull Executor executor, SplitController controller) {
|
||||||
@@ -396,6 +431,44 @@ class SplitPresenter extends JetpackTaskFragmentOrganizer {
|
|||||||
super.updateWindowingMode(wct, fragmentToken, windowingMode);
|
super.updateWindowingMode(wct, fragmentToken, windowingMode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Expands the split container if the current split bounds are smaller than the Activity or
|
||||||
|
* Intent that is added to the container.
|
||||||
|
*
|
||||||
|
* @return the {@link ResultCode} based on {@link #shouldShowSideBySide(Rect, SplitRule, Pair)}
|
||||||
|
* and if {@link android.window.TaskFragmentInfo} has reported to the client side.
|
||||||
|
*/
|
||||||
|
@ResultCode
|
||||||
|
int expandSplitContainerIfNeeded(@NonNull WindowContainerTransaction wct,
|
||||||
|
@NonNull SplitContainer splitContainer, @NonNull Activity primaryActivity,
|
||||||
|
@Nullable Activity secondaryActivity, @Nullable Intent secondaryIntent) {
|
||||||
|
if (secondaryActivity == null && secondaryIntent == null) {
|
||||||
|
throw new IllegalArgumentException("Either secondaryActivity or secondaryIntent must be"
|
||||||
|
+ " non-null.");
|
||||||
|
}
|
||||||
|
final Rect taskBounds = getParentContainerBounds(primaryActivity);
|
||||||
|
final Pair<Size, Size> minDimensionsPair;
|
||||||
|
if (secondaryActivity != null) {
|
||||||
|
minDimensionsPair = getActivitiesMinDimensionsPair(primaryActivity, secondaryActivity);
|
||||||
|
} else {
|
||||||
|
minDimensionsPair = getActivityIntentMinDimensionsPair(primaryActivity,
|
||||||
|
secondaryIntent);
|
||||||
|
}
|
||||||
|
// Expand the splitContainer if minimum dimensions are not satisfied.
|
||||||
|
if (!shouldShowSideBySide(taskBounds, splitContainer.getSplitRule(), minDimensionsPair)) {
|
||||||
|
// If the client side hasn't received TaskFragmentInfo yet, we can't change TaskFragment
|
||||||
|
// bounds. Return failure to create a new SplitContainer which fills task bounds.
|
||||||
|
if (splitContainer.getPrimaryContainer().getInfo() == null
|
||||||
|
|| splitContainer.getSecondaryContainer().getInfo() == null) {
|
||||||
|
return RESULT_EXPAND_FAILED_NO_TF_INFO;
|
||||||
|
}
|
||||||
|
expandTaskFragment(wct, splitContainer.getPrimaryContainer().getTaskFragmentToken());
|
||||||
|
expandTaskFragment(wct, splitContainer.getSecondaryContainer().getTaskFragmentToken());
|
||||||
|
return RESULT_EXPANDED;
|
||||||
|
}
|
||||||
|
return RESULT_NOT_EXPANDED;
|
||||||
|
}
|
||||||
|
|
||||||
static boolean shouldShowSideBySide(@NonNull Rect parentBounds, @NonNull SplitRule rule) {
|
static boolean shouldShowSideBySide(@NonNull Rect parentBounds, @NonNull SplitRule rule) {
|
||||||
return shouldShowSideBySide(parentBounds, rule, null /* minimumDimensionPair */);
|
return shouldShowSideBySide(parentBounds, rule, null /* minimumDimensionPair */);
|
||||||
}
|
}
|
||||||
@@ -565,11 +638,19 @@ class SplitPresenter extends JetpackTaskFragmentOrganizer {
|
|||||||
if (container != null) {
|
if (container != null) {
|
||||||
return getParentContainerBounds(container);
|
return getParentContainerBounds(container);
|
||||||
}
|
}
|
||||||
return getTaskBoundsFromActivity(activity);
|
// Obtain bounds from Activity instead because the Activity hasn't been embedded yet.
|
||||||
|
return getNonEmbeddedActivityBounds(activity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Obtains the bounds from a non-embedded Activity.
|
||||||
|
* <p>
|
||||||
|
* Note that callers should use {@link #getParentContainerBounds(Activity)} instead for most
|
||||||
|
* cases unless we want to obtain task bounds before
|
||||||
|
* {@link TaskContainer#isTaskBoundsInitialized()}.
|
||||||
|
*/
|
||||||
@NonNull
|
@NonNull
|
||||||
static Rect getTaskBoundsFromActivity(@NonNull Activity activity) {
|
static Rect getNonEmbeddedActivityBounds(@NonNull Activity activity) {
|
||||||
final WindowConfiguration windowConfiguration =
|
final WindowConfiguration windowConfiguration =
|
||||||
activity.getResources().getConfiguration().windowConfiguration;
|
activity.getResources().getConfiguration().windowConfiguration;
|
||||||
if (!activity.isInMultiWindowMode()) {
|
if (!activity.isInMultiWindowMode()) {
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ import static org.mockito.Mockito.mock;
|
|||||||
import android.annotation.NonNull;
|
import android.annotation.NonNull;
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
import android.content.pm.ActivityInfo;
|
||||||
import android.content.res.Configuration;
|
import android.content.res.Configuration;
|
||||||
import android.graphics.Point;
|
import android.graphics.Point;
|
||||||
import android.graphics.Rect;
|
import android.graphics.Rect;
|
||||||
@@ -57,13 +58,21 @@ public class EmbeddingTestUtils {
|
|||||||
/** Creates a rule to always split the given activity and the given intent. */
|
/** Creates a rule to always split the given activity and the given intent. */
|
||||||
static SplitRule createSplitRule(@NonNull Activity primaryActivity,
|
static SplitRule createSplitRule(@NonNull Activity primaryActivity,
|
||||||
@NonNull Intent secondaryIntent) {
|
@NonNull Intent secondaryIntent) {
|
||||||
|
return createSplitRule(primaryActivity, secondaryIntent, true /* clearTop */);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Creates a rule to always split the given activity and the given intent. */
|
||||||
|
static SplitRule createSplitRule(@NonNull Activity primaryActivity,
|
||||||
|
@NonNull Intent secondaryIntent, boolean clearTop) {
|
||||||
final Pair<Activity, Intent> targetPair = new Pair<>(primaryActivity, secondaryIntent);
|
final Pair<Activity, Intent> targetPair = new Pair<>(primaryActivity, secondaryIntent);
|
||||||
return new SplitPairRule.Builder(
|
return new SplitPairRule.Builder(
|
||||||
activityPair -> false,
|
activityPair -> false,
|
||||||
targetPair::equals,
|
targetPair::equals,
|
||||||
w -> true)
|
w -> true)
|
||||||
.setSplitRatio(SPLIT_RATIO)
|
.setSplitRatio(SPLIT_RATIO)
|
||||||
.setShouldClearTop(true)
|
.setShouldClearTop(clearTop)
|
||||||
|
.setFinishPrimaryWithSecondary(DEFAULT_FINISH_PRIMARY_WITH_SECONDARY)
|
||||||
|
.setFinishSecondaryWithPrimary(DEFAULT_FINISH_SECONDARY_WITH_PRIMARY)
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -75,6 +84,14 @@ public class EmbeddingTestUtils {
|
|||||||
true /* clearTop */);
|
true /* clearTop */);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Creates a rule to always split the given activities. */
|
||||||
|
static SplitRule createSplitRule(@NonNull Activity primaryActivity,
|
||||||
|
@NonNull Activity secondaryActivity, boolean clearTop) {
|
||||||
|
return createSplitRule(primaryActivity, secondaryActivity,
|
||||||
|
DEFAULT_FINISH_PRIMARY_WITH_SECONDARY, DEFAULT_FINISH_SECONDARY_WITH_PRIMARY,
|
||||||
|
clearTop);
|
||||||
|
}
|
||||||
|
|
||||||
/** Creates a rule to always split the given activities with the given finish behaviors. */
|
/** Creates a rule to always split the given activities with the given finish behaviors. */
|
||||||
static SplitRule createSplitRule(@NonNull Activity primaryActivity,
|
static SplitRule createSplitRule(@NonNull Activity primaryActivity,
|
||||||
@NonNull Activity secondaryActivity, int finishPrimaryWithSecondary,
|
@NonNull Activity secondaryActivity, int finishPrimaryWithSecondary,
|
||||||
@@ -105,4 +122,12 @@ public class EmbeddingTestUtils {
|
|||||||
false /* isTaskFragmentClearedForPip */,
|
false /* isTaskFragmentClearedForPip */,
|
||||||
new Point());
|
new Point());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static ActivityInfo createActivityInfoWithMinDimensions() {
|
||||||
|
ActivityInfo aInfo = new ActivityInfo();
|
||||||
|
final Rect primaryBounds = getSplitBounds(true /* isPrimary */);
|
||||||
|
aInfo.windowLayout = new ActivityInfo.WindowLayout(0, 0, 0, 0, 0,
|
||||||
|
primaryBounds.width() + 1, primaryBounds.height() + 1);
|
||||||
|
return aInfo;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
|
|||||||
import static androidx.window.extensions.embedding.EmbeddingTestUtils.SPLIT_RATIO;
|
import static androidx.window.extensions.embedding.EmbeddingTestUtils.SPLIT_RATIO;
|
||||||
import static androidx.window.extensions.embedding.EmbeddingTestUtils.TASK_BOUNDS;
|
import static androidx.window.extensions.embedding.EmbeddingTestUtils.TASK_BOUNDS;
|
||||||
import static androidx.window.extensions.embedding.EmbeddingTestUtils.TASK_ID;
|
import static androidx.window.extensions.embedding.EmbeddingTestUtils.TASK_ID;
|
||||||
|
import static androidx.window.extensions.embedding.EmbeddingTestUtils.createActivityInfoWithMinDimensions;
|
||||||
import static androidx.window.extensions.embedding.EmbeddingTestUtils.createMockTaskFragmentInfo;
|
import static androidx.window.extensions.embedding.EmbeddingTestUtils.createMockTaskFragmentInfo;
|
||||||
import static androidx.window.extensions.embedding.EmbeddingTestUtils.createSplitRule;
|
import static androidx.window.extensions.embedding.EmbeddingTestUtils.createSplitRule;
|
||||||
import static androidx.window.extensions.embedding.EmbeddingTestUtils.getSplitBounds;
|
import static androidx.window.extensions.embedding.EmbeddingTestUtils.getSplitBounds;
|
||||||
@@ -34,6 +35,7 @@ import static com.google.common.truth.Truth.assertWithMessage;
|
|||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.junit.Assert.assertFalse;
|
import static org.junit.Assert.assertFalse;
|
||||||
|
import static org.junit.Assert.assertNotEquals;
|
||||||
import static org.junit.Assert.assertNotNull;
|
import static org.junit.Assert.assertNotNull;
|
||||||
import static org.junit.Assert.assertNull;
|
import static org.junit.Assert.assertNull;
|
||||||
import static org.junit.Assert.assertThrows;
|
import static org.junit.Assert.assertThrows;
|
||||||
@@ -435,6 +437,50 @@ public class SplitControllerTest {
|
|||||||
assertTrue(container.areLastRequestedBoundsEqual(null));
|
assertTrue(container.areLastRequestedBoundsEqual(null));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testResolveStartActivityIntent_shouldExpandSplitContainer() {
|
||||||
|
final Intent intent = new Intent().setComponent(
|
||||||
|
new ComponentName(ApplicationProvider.getApplicationContext(),
|
||||||
|
MinimumDimensionActivity.class));
|
||||||
|
setupSplitRule(mActivity, intent, false /* clearTop */);
|
||||||
|
final Activity secondaryActivity = createMockActivity();
|
||||||
|
addSplitTaskFragments(mActivity, secondaryActivity, false /* clearTop */);
|
||||||
|
|
||||||
|
final TaskFragmentContainer container = mSplitController.resolveStartActivityIntent(
|
||||||
|
mTransaction, TASK_ID, intent, mActivity);
|
||||||
|
final TaskFragmentContainer primaryContainer = mSplitController.getContainerWithActivity(
|
||||||
|
mActivity);
|
||||||
|
|
||||||
|
assertNotNull(mSplitController.getActiveSplitForContainers(primaryContainer, container));
|
||||||
|
assertTrue(primaryContainer.areLastRequestedBoundsEqual(null));
|
||||||
|
assertTrue(container.areLastRequestedBoundsEqual(null));
|
||||||
|
assertEquals(container, mSplitController.getContainerWithActivity(secondaryActivity));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testResolveStartActivityIntent_noInfo_shouldCreateSplitContainer() {
|
||||||
|
final Intent intent = new Intent().setComponent(
|
||||||
|
new ComponentName(ApplicationProvider.getApplicationContext(),
|
||||||
|
MinimumDimensionActivity.class));
|
||||||
|
setupSplitRule(mActivity, intent, false /* clearTop */);
|
||||||
|
final Activity secondaryActivity = createMockActivity();
|
||||||
|
addSplitTaskFragments(mActivity, secondaryActivity, false /* clearTop */);
|
||||||
|
|
||||||
|
final TaskFragmentContainer secondaryContainer = mSplitController
|
||||||
|
.getContainerWithActivity(secondaryActivity);
|
||||||
|
secondaryContainer.mInfo = null;
|
||||||
|
|
||||||
|
final TaskFragmentContainer container = mSplitController.resolveStartActivityIntent(
|
||||||
|
mTransaction, TASK_ID, intent, mActivity);
|
||||||
|
final TaskFragmentContainer primaryContainer = mSplitController.getContainerWithActivity(
|
||||||
|
mActivity);
|
||||||
|
|
||||||
|
assertNotNull(mSplitController.getActiveSplitForContainers(primaryContainer, container));
|
||||||
|
assertTrue(primaryContainer.areLastRequestedBoundsEqual(null));
|
||||||
|
assertTrue(container.areLastRequestedBoundsEqual(null));
|
||||||
|
assertNotEquals(container, secondaryContainer);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testPlaceActivityInTopContainer() {
|
public void testPlaceActivityInTopContainer() {
|
||||||
mSplitController.placeActivityInTopContainer(mActivity);
|
mSplitController.placeActivityInTopContainer(mActivity);
|
||||||
@@ -787,11 +833,7 @@ public class SplitControllerTest {
|
|||||||
final Activity activityBelow = createMockActivity();
|
final Activity activityBelow = createMockActivity();
|
||||||
setupSplitRule(mActivity, activityBelow);
|
setupSplitRule(mActivity, activityBelow);
|
||||||
|
|
||||||
ActivityInfo aInfo = new ActivityInfo();
|
doReturn(createActivityInfoWithMinDimensions()).when(mActivity).getActivityInfo();
|
||||||
final Rect primaryBounds = getSplitBounds(true /* isPrimary */);
|
|
||||||
aInfo.windowLayout = new ActivityInfo.WindowLayout(0, 0, 0, 0, 0,
|
|
||||||
primaryBounds.width() + 1, primaryBounds.height() + 1);
|
|
||||||
doReturn(aInfo).when(mActivity).getActivityInfo();
|
|
||||||
|
|
||||||
final TaskFragmentContainer container = mSplitController.newContainer(activityBelow,
|
final TaskFragmentContainer container = mSplitController.newContainer(activityBelow,
|
||||||
TASK_ID);
|
TASK_ID);
|
||||||
@@ -810,17 +852,12 @@ public class SplitControllerTest {
|
|||||||
final Activity activityBelow = createMockActivity();
|
final Activity activityBelow = createMockActivity();
|
||||||
setupSplitRule(activityBelow, mActivity);
|
setupSplitRule(activityBelow, mActivity);
|
||||||
|
|
||||||
ActivityInfo aInfo = new ActivityInfo();
|
doReturn(createActivityInfoWithMinDimensions()).when(mActivity).getActivityInfo();
|
||||||
final Rect secondaryBounds = getSplitBounds(false /* isPrimary */);
|
|
||||||
aInfo.windowLayout = new ActivityInfo.WindowLayout(0, 0, 0, 0, 0,
|
|
||||||
secondaryBounds.width() + 1, secondaryBounds.height() + 1);
|
|
||||||
doReturn(aInfo).when(mActivity).getActivityInfo();
|
|
||||||
|
|
||||||
final TaskFragmentContainer container = mSplitController.newContainer(activityBelow,
|
final TaskFragmentContainer container = mSplitController.newContainer(activityBelow,
|
||||||
TASK_ID);
|
TASK_ID);
|
||||||
container.addPendingAppearedActivity(mActivity);
|
container.addPendingAppearedActivity(mActivity);
|
||||||
|
|
||||||
// Allow to split as primary.
|
|
||||||
boolean result = mSplitController.resolveActivityToContainer(mActivity,
|
boolean result = mSplitController.resolveActivityToContainer(mActivity,
|
||||||
false /* isOnReparent */);
|
false /* isOnReparent */);
|
||||||
|
|
||||||
@@ -828,6 +865,29 @@ public class SplitControllerTest {
|
|||||||
assertSplitPair(activityBelow, mActivity, true /* matchParentBounds */);
|
assertSplitPair(activityBelow, mActivity, true /* matchParentBounds */);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Suppress GuardedBy warning on unit tests
|
||||||
|
@SuppressWarnings("GuardedBy")
|
||||||
|
@Test
|
||||||
|
public void testResolveActivityToContainer_minDimensions_shouldExpandSplitContainer() {
|
||||||
|
final Activity primaryActivity = createMockActivity();
|
||||||
|
final Activity secondaryActivity = createMockActivity();
|
||||||
|
addSplitTaskFragments(primaryActivity, secondaryActivity, false /* clearTop */);
|
||||||
|
|
||||||
|
setupSplitRule(primaryActivity, mActivity, false /* clearTop */);
|
||||||
|
doReturn(createActivityInfoWithMinDimensions()).when(mActivity).getActivityInfo();
|
||||||
|
doReturn(secondaryActivity).when(mSplitController).findActivityBelow(eq(mActivity));
|
||||||
|
|
||||||
|
clearInvocations(mSplitPresenter);
|
||||||
|
boolean result = mSplitController.resolveActivityToContainer(mActivity,
|
||||||
|
false /* isOnReparent */);
|
||||||
|
|
||||||
|
assertTrue(result);
|
||||||
|
assertSplitPair(primaryActivity, mActivity, true /* matchParentBounds */);
|
||||||
|
assertEquals(mSplitController.getContainerWithActivity(secondaryActivity),
|
||||||
|
mSplitController.getContainerWithActivity(mActivity));
|
||||||
|
verify(mSplitPresenter, never()).createNewSplitContainer(any(), any(), any());
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testResolveActivityToContainer_inUnknownTaskFragment() {
|
public void testResolveActivityToContainer_inUnknownTaskFragment() {
|
||||||
doReturn(new Binder()).when(mSplitController).getInitialTaskFragmentToken(mActivity);
|
doReturn(new Binder()).when(mSplitController).getInitialTaskFragmentToken(mActivity);
|
||||||
@@ -944,23 +1004,41 @@ public class SplitControllerTest {
|
|||||||
/** Setups a rule to always split the given activities. */
|
/** Setups a rule to always split the given activities. */
|
||||||
private void setupSplitRule(@NonNull Activity primaryActivity,
|
private void setupSplitRule(@NonNull Activity primaryActivity,
|
||||||
@NonNull Intent secondaryIntent) {
|
@NonNull Intent secondaryIntent) {
|
||||||
final SplitRule splitRule = createSplitRule(primaryActivity, secondaryIntent);
|
setupSplitRule(primaryActivity, secondaryIntent, true /* clearTop */);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Setups a rule to always split the given activities. */
|
||||||
|
private void setupSplitRule(@NonNull Activity primaryActivity,
|
||||||
|
@NonNull Intent secondaryIntent, boolean clearTop) {
|
||||||
|
final SplitRule splitRule = createSplitRule(primaryActivity, secondaryIntent, clearTop);
|
||||||
mSplitController.setEmbeddingRules(Collections.singleton(splitRule));
|
mSplitController.setEmbeddingRules(Collections.singleton(splitRule));
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Setups a rule to always split the given activities. */
|
/** Setups a rule to always split the given activities. */
|
||||||
private void setupSplitRule(@NonNull Activity primaryActivity,
|
private void setupSplitRule(@NonNull Activity primaryActivity,
|
||||||
@NonNull Activity secondaryActivity) {
|
@NonNull Activity secondaryActivity) {
|
||||||
final SplitRule splitRule = createSplitRule(primaryActivity, secondaryActivity);
|
setupSplitRule(primaryActivity, secondaryActivity, true /* clearTop */);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Setups a rule to always split the given activities. */
|
||||||
|
private void setupSplitRule(@NonNull Activity primaryActivity,
|
||||||
|
@NonNull Activity secondaryActivity, boolean clearTop) {
|
||||||
|
final SplitRule splitRule = createSplitRule(primaryActivity, secondaryActivity, clearTop);
|
||||||
mSplitController.setEmbeddingRules(Collections.singleton(splitRule));
|
mSplitController.setEmbeddingRules(Collections.singleton(splitRule));
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Adds a pair of TaskFragments as split for the given activities. */
|
/** Adds a pair of TaskFragments as split for the given activities. */
|
||||||
private void addSplitTaskFragments(@NonNull Activity primaryActivity,
|
private void addSplitTaskFragments(@NonNull Activity primaryActivity,
|
||||||
@NonNull Activity secondaryActivity) {
|
@NonNull Activity secondaryActivity) {
|
||||||
|
addSplitTaskFragments(primaryActivity, secondaryActivity, true /* clearTop */);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Adds a pair of TaskFragments as split for the given activities. */
|
||||||
|
private void addSplitTaskFragments(@NonNull Activity primaryActivity,
|
||||||
|
@NonNull Activity secondaryActivity, boolean clearTop) {
|
||||||
registerSplitPair(createMockTaskFragmentContainer(primaryActivity),
|
registerSplitPair(createMockTaskFragmentContainer(primaryActivity),
|
||||||
createMockTaskFragmentContainer(secondaryActivity),
|
createMockTaskFragmentContainer(secondaryActivity),
|
||||||
createSplitRule(primaryActivity, secondaryActivity));
|
createSplitRule(primaryActivity, secondaryActivity, clearTop));
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Registers the two given TaskFragments as split pair. */
|
/** Registers the two given TaskFragments as split pair. */
|
||||||
@@ -1011,16 +1089,18 @@ public class SplitControllerTest {
|
|||||||
if (primaryContainer.mInfo != null) {
|
if (primaryContainer.mInfo != null) {
|
||||||
final Rect primaryBounds = matchParentBounds ? new Rect()
|
final Rect primaryBounds = matchParentBounds ? new Rect()
|
||||||
: getSplitBounds(true /* isPrimary */);
|
: getSplitBounds(true /* isPrimary */);
|
||||||
|
final int windowingMode = matchParentBounds ? WINDOWING_MODE_UNDEFINED
|
||||||
|
: WINDOWING_MODE_MULTI_WINDOW;
|
||||||
assertTrue(primaryContainer.areLastRequestedBoundsEqual(primaryBounds));
|
assertTrue(primaryContainer.areLastRequestedBoundsEqual(primaryBounds));
|
||||||
assertTrue(primaryContainer.isLastRequestedWindowingModeEqual(
|
assertTrue(primaryContainer.isLastRequestedWindowingModeEqual(windowingMode));
|
||||||
WINDOWING_MODE_MULTI_WINDOW));
|
|
||||||
}
|
}
|
||||||
if (secondaryContainer.mInfo != null) {
|
if (secondaryContainer.mInfo != null) {
|
||||||
final Rect secondaryBounds = matchParentBounds ? new Rect()
|
final Rect secondaryBounds = matchParentBounds ? new Rect()
|
||||||
: getSplitBounds(false /* isPrimary */);
|
: getSplitBounds(false /* isPrimary */);
|
||||||
|
final int windowingMode = matchParentBounds ? WINDOWING_MODE_UNDEFINED
|
||||||
|
: WINDOWING_MODE_MULTI_WINDOW;
|
||||||
assertTrue(secondaryContainer.areLastRequestedBoundsEqual(secondaryBounds));
|
assertTrue(secondaryContainer.areLastRequestedBoundsEqual(secondaryBounds));
|
||||||
assertTrue(secondaryContainer.isLastRequestedWindowingModeEqual(
|
assertTrue(secondaryContainer.isLastRequestedWindowingModeEqual(windowingMode));
|
||||||
WINDOWING_MODE_MULTI_WINDOW));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,11 +20,16 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
|
|||||||
|
|
||||||
import static androidx.window.extensions.embedding.EmbeddingTestUtils.TASK_BOUNDS;
|
import static androidx.window.extensions.embedding.EmbeddingTestUtils.TASK_BOUNDS;
|
||||||
import static androidx.window.extensions.embedding.EmbeddingTestUtils.TASK_ID;
|
import static androidx.window.extensions.embedding.EmbeddingTestUtils.TASK_ID;
|
||||||
|
import static androidx.window.extensions.embedding.EmbeddingTestUtils.createActivityInfoWithMinDimensions;
|
||||||
|
import static androidx.window.extensions.embedding.EmbeddingTestUtils.createMockTaskFragmentInfo;
|
||||||
import static androidx.window.extensions.embedding.EmbeddingTestUtils.createSplitRule;
|
import static androidx.window.extensions.embedding.EmbeddingTestUtils.createSplitRule;
|
||||||
import static androidx.window.extensions.embedding.EmbeddingTestUtils.getSplitBounds;
|
import static androidx.window.extensions.embedding.EmbeddingTestUtils.getSplitBounds;
|
||||||
import static androidx.window.extensions.embedding.SplitPresenter.POSITION_END;
|
import static androidx.window.extensions.embedding.SplitPresenter.POSITION_END;
|
||||||
import static androidx.window.extensions.embedding.SplitPresenter.POSITION_FILL;
|
import static androidx.window.extensions.embedding.SplitPresenter.POSITION_FILL;
|
||||||
import static androidx.window.extensions.embedding.SplitPresenter.POSITION_START;
|
import static androidx.window.extensions.embedding.SplitPresenter.POSITION_START;
|
||||||
|
import static androidx.window.extensions.embedding.SplitPresenter.RESULT_EXPANDED;
|
||||||
|
import static androidx.window.extensions.embedding.SplitPresenter.RESULT_EXPAND_FAILED_NO_TF_INFO;
|
||||||
|
import static androidx.window.extensions.embedding.SplitPresenter.RESULT_NOT_EXPANDED;
|
||||||
import static androidx.window.extensions.embedding.SplitPresenter.getBoundsForPosition;
|
import static androidx.window.extensions.embedding.SplitPresenter.getBoundsForPosition;
|
||||||
import static androidx.window.extensions.embedding.SplitPresenter.getMinDimensions;
|
import static androidx.window.extensions.embedding.SplitPresenter.getMinDimensions;
|
||||||
import static androidx.window.extensions.embedding.SplitPresenter.shouldShowSideBySide;
|
import static androidx.window.extensions.embedding.SplitPresenter.shouldShowSideBySide;
|
||||||
@@ -34,6 +39,7 @@ import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
|
|||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.junit.Assert.assertFalse;
|
import static org.junit.Assert.assertFalse;
|
||||||
|
import static org.junit.Assert.assertThrows;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
import static org.mockito.ArgumentMatchers.any;
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
import static org.mockito.ArgumentMatchers.anyInt;
|
import static org.mockito.ArgumentMatchers.anyInt;
|
||||||
@@ -49,6 +55,7 @@ import android.content.pm.ActivityInfo;
|
|||||||
import android.content.res.Configuration;
|
import android.content.res.Configuration;
|
||||||
import android.content.res.Resources;
|
import android.content.res.Resources;
|
||||||
import android.graphics.Rect;
|
import android.graphics.Rect;
|
||||||
|
import android.os.IBinder;
|
||||||
import android.platform.test.annotations.Presubmit;
|
import android.platform.test.annotations.Presubmit;
|
||||||
import android.util.Pair;
|
import android.util.Pair;
|
||||||
import android.util.Size;
|
import android.util.Size;
|
||||||
@@ -195,6 +202,52 @@ public class SplitPresenterTest {
|
|||||||
splitRule, mActivity, minDimensionsPair));
|
splitRule, mActivity, minDimensionsPair));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testExpandSplitContainerIfNeeded() {
|
||||||
|
SplitContainer splitContainer = mock(SplitContainer.class);
|
||||||
|
Activity secondaryActivity = createMockActivity();
|
||||||
|
SplitRule splitRule = createSplitRule(mActivity, secondaryActivity);
|
||||||
|
TaskFragmentContainer primaryTf = mController.newContainer(mActivity, TASK_ID);
|
||||||
|
TaskFragmentContainer secondaryTf = mController.newContainer(secondaryActivity, TASK_ID);
|
||||||
|
doReturn(splitRule).when(splitContainer).getSplitRule();
|
||||||
|
doReturn(primaryTf).when(splitContainer).getPrimaryContainer();
|
||||||
|
doReturn(secondaryTf).when(splitContainer).getSecondaryContainer();
|
||||||
|
|
||||||
|
assertThrows(IllegalArgumentException.class, () ->
|
||||||
|
mPresenter.expandSplitContainerIfNeeded(mTransaction, splitContainer, mActivity,
|
||||||
|
null /* secondaryActivity */, null /* secondaryIntent */));
|
||||||
|
|
||||||
|
assertEquals(RESULT_NOT_EXPANDED, mPresenter.expandSplitContainerIfNeeded(mTransaction,
|
||||||
|
splitContainer, mActivity, secondaryActivity, null /* secondaryIntent */));
|
||||||
|
verify(mPresenter, never()).expandTaskFragment(any(), any());
|
||||||
|
|
||||||
|
doReturn(createActivityInfoWithMinDimensions()).when(secondaryActivity).getActivityInfo();
|
||||||
|
assertEquals(RESULT_EXPAND_FAILED_NO_TF_INFO, mPresenter.expandSplitContainerIfNeeded(
|
||||||
|
mTransaction, splitContainer, mActivity, secondaryActivity,
|
||||||
|
null /* secondaryIntent */));
|
||||||
|
|
||||||
|
primaryTf.setInfo(createMockTaskFragmentInfo(primaryTf, mActivity));
|
||||||
|
secondaryTf.setInfo(createMockTaskFragmentInfo(secondaryTf, secondaryActivity));
|
||||||
|
|
||||||
|
assertEquals(RESULT_EXPANDED, mPresenter.expandSplitContainerIfNeeded(mTransaction,
|
||||||
|
splitContainer, mActivity, secondaryActivity, null /* secondaryIntent */));
|
||||||
|
verify(mPresenter).expandTaskFragment(eq(mTransaction),
|
||||||
|
eq(primaryTf.getTaskFragmentToken()));
|
||||||
|
verify(mPresenter).expandTaskFragment(eq(mTransaction),
|
||||||
|
eq(secondaryTf.getTaskFragmentToken()));
|
||||||
|
|
||||||
|
clearInvocations(mPresenter);
|
||||||
|
|
||||||
|
assertEquals(RESULT_EXPANDED, mPresenter.expandSplitContainerIfNeeded(mTransaction,
|
||||||
|
splitContainer, mActivity, null /* secondaryActivity */,
|
||||||
|
new Intent(ApplicationProvider.getApplicationContext(),
|
||||||
|
MinimumDimensionActivity.class)));
|
||||||
|
verify(mPresenter).expandTaskFragment(eq(mTransaction),
|
||||||
|
eq(primaryTf.getTaskFragmentToken()));
|
||||||
|
verify(mPresenter).expandTaskFragment(eq(mTransaction),
|
||||||
|
eq(secondaryTf.getTaskFragmentToken()));
|
||||||
|
}
|
||||||
|
|
||||||
private Activity createMockActivity() {
|
private Activity createMockActivity() {
|
||||||
final Activity activity = mock(Activity.class);
|
final Activity activity = mock(Activity.class);
|
||||||
final Configuration activityConfig = new Configuration();
|
final Configuration activityConfig = new Configuration();
|
||||||
@@ -203,6 +256,7 @@ public class SplitPresenterTest {
|
|||||||
doReturn(mActivityResources).when(activity).getResources();
|
doReturn(mActivityResources).when(activity).getResources();
|
||||||
doReturn(activityConfig).when(mActivityResources).getConfiguration();
|
doReturn(activityConfig).when(mActivityResources).getConfiguration();
|
||||||
doReturn(new ActivityInfo()).when(activity).getActivityInfo();
|
doReturn(new ActivityInfo()).when(activity).getActivityInfo();
|
||||||
|
doReturn(mock(IBinder.class)).when(activity).getActivityToken();
|
||||||
return activity;
|
return activity;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user