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

Commit 3743d28e authored by Winson Chung's avatar Winson Chung
Browse files

Prevent clobbering of activity options bundle when merging

- RemoteViews specify an ActivityOptions when calling startIntentSender()
  (for click handling), but if the PendingIntent being started also has an
  ActivityOptions, the merging of the two options will fail since the
  ActivityOptions properties are always written into the bundle (regardless
  of whether they are actually set).  Instead, only write non-default
  values to the bundle (the defaults will be read out if not set when
  restoring the options from the bundle anyways).

Bug: 72459081
Test: atest FrameworksServicesTests:ActivityOptionsTest

change-id: i1d6718d9db4b3f7056412c5b4c5347a19ffa7c09
parent 0c16e74b
Loading
Loading
Loading
Loading
+36 −14
Original line number Diff line number Diff line
@@ -302,7 +302,6 @@ public class ActivityOptions {
    private int mResultCode;
    private int mExitCoordinatorIndex;
    private PendingIntent mUsageTimeReport;
    private boolean mLockTaskMode = false;
    private int mLaunchDisplayId = INVALID_DISPLAY;
    @WindowConfiguration.WindowingMode
    private int mLaunchWindowingMode = WINDOWING_MODE_UNDEFINED;
@@ -310,6 +309,7 @@ public class ActivityOptions {
    private int mLaunchActivityType = ACTIVITY_TYPE_UNDEFINED;
    private int mLaunchTaskId = -1;
    private int mSplitScreenCreateMode = SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT;
    private boolean mLockTaskMode = false;
    private boolean mDisallowEnterPictureInPictureWhileLaunching;
    private boolean mTaskOverlay;
    private boolean mTaskOverlayCanResume;
@@ -946,7 +946,7 @@ public class ActivityOptions {
            mAnimationFinishedListener = IRemoteCallback.Stub.asInterface(
                    opts.getBinder(KEY_ANIMATION_FINISHED_LISTENER));
        }
        mRotationAnimationHint = opts.getInt(KEY_ROTATION_ANIMATION_HINT);
        mRotationAnimationHint = opts.getInt(KEY_ROTATION_ANIMATION_HINT, -1);
        mAppVerificationBundle = opts.getBundle(KEY_INSTANT_APP_VERIFICATION_BUNDLE);
        if (opts.containsKey(KEY_SPECS_FUTURE)) {
            mSpecsFuture = IAppTransitionAnimationSpecsFuture.Stub.asInterface(opts.getBinder(
@@ -1442,17 +1442,37 @@ public class ActivityOptions {
                b.putInt(KEY_EXIT_COORDINATOR_INDEX, mExitCoordinatorIndex);
                break;
        }
        if (mLockTaskMode) {
            b.putBoolean(KEY_LOCK_TASK_MODE, mLockTaskMode);
        }
        if (mLaunchDisplayId != INVALID_DISPLAY) {
            b.putInt(KEY_LAUNCH_DISPLAY_ID, mLaunchDisplayId);
        }
        if (mLaunchWindowingMode != WINDOWING_MODE_UNDEFINED) {
            b.putInt(KEY_LAUNCH_WINDOWING_MODE, mLaunchWindowingMode);
        }
        if (mLaunchActivityType != ACTIVITY_TYPE_UNDEFINED) {
            b.putInt(KEY_LAUNCH_ACTIVITY_TYPE, mLaunchActivityType);
        }
        if (mLaunchTaskId != -1) {
            b.putInt(KEY_LAUNCH_TASK_ID, mLaunchTaskId);
        }
        if (mTaskOverlay) {
            b.putBoolean(KEY_TASK_OVERLAY, mTaskOverlay);
        }
        if (mTaskOverlayCanResume) {
            b.putBoolean(KEY_TASK_OVERLAY_CAN_RESUME, mTaskOverlayCanResume);
        }
        if (mAvoidMoveToFront) {
            b.putBoolean(KEY_AVOID_MOVE_TO_FRONT, mAvoidMoveToFront);
        }
        if (mSplitScreenCreateMode != SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT) {
            b.putInt(KEY_SPLIT_SCREEN_CREATE_MODE, mSplitScreenCreateMode);
        }
        if (mDisallowEnterPictureInPictureWhileLaunching) {
            b.putBoolean(KEY_DISALLOW_ENTER_PICTURE_IN_PICTURE_WHILE_LAUNCHING,
                    mDisallowEnterPictureInPictureWhileLaunching);
        }
        if (mAnimSpecs != null) {
            b.putParcelableArray(KEY_ANIM_SPECS, mAnimSpecs);
        }
@@ -1462,7 +1482,9 @@ public class ActivityOptions {
        if (mSpecsFuture != null) {
            b.putBinder(KEY_SPECS_FUTURE, mSpecsFuture.asBinder());
        }
        if (mRotationAnimationHint != -1) {
            b.putInt(KEY_ROTATION_ANIMATION_HINT, mRotationAnimationHint);
        }
        if (mAppVerificationBundle != null) {
            b.putBundle(KEY_INSTANT_APP_VERIFICATION_BUNDLE, mAppVerificationBundle);
        }
+76 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2018 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.server.am;

import static android.app.ActivityTaskManager.SPLIT_SCREEN_CREATE_MODE_BOTTOM_OR_RIGHT;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
import static android.view.WindowManager.LayoutParams.ROTATION_ANIMATION_ROTATE;
import static org.junit.Assert.assertEquals;

import android.app.ActivityOptions;
import android.os.Bundle;
import android.os.Debug;
import android.platform.test.annotations.Presubmit;
import android.support.test.filters.FlakyTest;
import android.support.test.filters.MediumTest;
import android.support.test.runner.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;


/**
 * atest FrameworksServicesTests:ActivityOptionsTest
 */
@MediumTest
@Presubmit
@RunWith(AndroidJUnit4.class)
public class ActivityOptionsTest {

    @Test
    public void testMerge_NoClobber() {
        // Construct some options with set values
        ActivityOptions opts = ActivityOptions.makeBasic();
        opts.setLaunchDisplayId(Integer.MAX_VALUE);
        opts.setLaunchActivityType(ACTIVITY_TYPE_STANDARD);
        opts.setLaunchWindowingMode(WINDOWING_MODE_FULLSCREEN);
        opts.setAvoidMoveToFront();
        opts.setLaunchTaskId(Integer.MAX_VALUE);
        opts.setLockTaskEnabled(true);
        opts.setRotationAnimationHint(ROTATION_ANIMATION_ROTATE);
        opts.setTaskOverlay(true, true);
        opts.setSplitScreenCreateMode(SPLIT_SCREEN_CREATE_MODE_BOTTOM_OR_RIGHT);
        Bundle optsBundle = opts.toBundle();

        // Try and merge the constructed options with a new set of options
        optsBundle.putAll(ActivityOptions.makeBasic().toBundle());

        // Ensure the set values are not clobbered
        ActivityOptions restoredOpts = ActivityOptions.fromBundle(optsBundle);
        assertEquals(Integer.MAX_VALUE, restoredOpts.getLaunchDisplayId());
        assertEquals(ACTIVITY_TYPE_STANDARD, restoredOpts.getLaunchActivityType());
        assertEquals(WINDOWING_MODE_FULLSCREEN, restoredOpts.getLaunchWindowingMode());
        assertEquals(true, restoredOpts.getAvoidMoveToFront());
        assertEquals(Integer.MAX_VALUE, restoredOpts.getLaunchTaskId());
        assertEquals(true, restoredOpts.getLockTaskMode());
        assertEquals(ROTATION_ANIMATION_ROTATE, restoredOpts.getRotationAnimationHint());
        assertEquals(true, restoredOpts.getTaskOverlay());
        assertEquals(true, restoredOpts.canTaskOverlayResume());
        assertEquals(SPLIT_SCREEN_CREATE_MODE_BOTTOM_OR_RIGHT,
                restoredOpts.getSplitScreenCreateMode());
    }
}