From ec0d9449a171d3a6b7e6e344efec6abfcdc7800c Mon Sep 17 00:00:00 2001 From: Hongwei Wang Date: Wed, 22 Dec 2021 16:11:42 -0800 Subject: [PATCH] Add demo for content PiP Bug: 165793661 Video: http://recall/-/aaaaaabFQoRHlzixHdtY/e9Mp5rvxYBrNOdGSUoSXHO Test: manual, see Video Change-Id: I026844cf5eabf30fe553641b36daed6e31e4f893 --- samples/ApiDemos/AndroidManifest.xml | 9 ++++ .../res/layout/picture_in_picture.xml | 8 +-- .../res/layout/picture_in_picture_content.xml | 25 +++++++++ .../apis/app/ContentPictureInPicture.java | 51 +++++++++++++++++++ .../android/apis/app/PictureInPicture.java | 41 +++++++++++++-- 5 files changed, 124 insertions(+), 10 deletions(-) create mode 100644 samples/ApiDemos/res/layout/picture_in_picture_content.xml create mode 100644 samples/ApiDemos/src/com/example/android/apis/app/ContentPictureInPicture.java diff --git a/samples/ApiDemos/AndroidManifest.xml b/samples/ApiDemos/AndroidManifest.xml index 0bac8eaa4..d971ad623 100644 --- a/samples/ApiDemos/AndroidManifest.xml +++ b/samples/ApiDemos/AndroidManifest.xml @@ -299,6 +299,15 @@ + + + - + + + diff --git a/samples/ApiDemos/src/com/example/android/apis/app/ContentPictureInPicture.java b/samples/ApiDemos/src/com/example/android/apis/app/ContentPictureInPicture.java new file mode 100644 index 000000000..eac4307f6 --- /dev/null +++ b/samples/ApiDemos/src/com/example/android/apis/app/ContentPictureInPicture.java @@ -0,0 +1,51 @@ +/* + * 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 com.example.android.apis.app; + +import android.app.Activity; +import android.content.res.Configuration; +import android.os.Bundle; +import android.os.ResultReceiver; + +import com.example.android.apis.R; + +public class ContentPictureInPicture extends Activity { + private ResultReceiver mOnStopReceiver; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.picture_in_picture_content); + mOnStopReceiver = getIntent().getParcelableExtra(PictureInPicture.KEY_ON_STOP_RECEIVER); + } + + @Override + protected void onStop() { + super.onStop(); + if (mOnStopReceiver != null) { + mOnStopReceiver.send(0 /* resultCode */, Bundle.EMPTY); + } + } + + @Override + public void onPictureInPictureModeChanged(boolean isInPictureInPictureMode, + Configuration newConfig) { + if (!isInPictureInPictureMode) { + finish(); + } + } +} diff --git a/samples/ApiDemos/src/com/example/android/apis/app/PictureInPicture.java b/samples/ApiDemos/src/com/example/android/apis/app/PictureInPicture.java index b54631ee5..bb76bf392 100644 --- a/samples/ApiDemos/src/com/example/android/apis/app/PictureInPicture.java +++ b/samples/ApiDemos/src/com/example/android/apis/app/PictureInPicture.java @@ -17,16 +17,21 @@ package com.example.android.apis.app; import android.app.Activity; +import android.app.ActivityOptions; import android.app.PictureInPictureParams; import android.content.Intent; import android.content.res.Configuration; import android.graphics.Rect; import android.os.Bundle; +import android.os.Handler; +import android.os.Looper; +import android.os.ResultReceiver; import android.util.Rational; import android.view.Gravity; import android.view.View; import android.view.WindowManager; import android.widget.CompoundButton; +import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.RadioGroup; import android.widget.Switch; @@ -39,6 +44,19 @@ public class PictureInPicture extends Activity { private static final String EXTRA_ENABLE_SEAMLESS_RESIZE = "seamless_resize"; private static final String EXTRA_CURRENT_POSITION = "current_position"; + private static final int TABLET_BREAK_POINT_DP = 700; + + public static final String KEY_ON_STOP_RECEIVER = "on_stop_receiver"; + private final ResultReceiver mOnStopReceiver = new ResultReceiver( + new Handler(Looper.myLooper())) { + @Override + protected void onReceiveResult(int resultCode, Bundle resultData) { + // Container activity for content-pip has stopped, replace the placeholder + // with actual content in this host activity. + mImageView.setImageResource(R.drawable.sample_1); + } + }; + private final View.OnLayoutChangeListener mOnLayoutChangeListener = (v, oldLeft, oldTop, oldRight, oldBottom, newLeft, newTop, newRight, newBottom) -> { updatePictureInPictureParams(); @@ -51,7 +69,7 @@ public class PictureInPicture extends Activity { (v, id) -> updateContentPosition(id); private LinearLayout mContainer; - private View mImageView; + private ImageView mImageView; private View mControlGroup; private Switch mAutoPipToggle; private Switch mSourceRectHintToggle; @@ -123,13 +141,30 @@ public class PictureInPicture extends Activity { } } + /** + * This is what we expect most host Activity would do to trigger content PiP. + * - Get the bounds of the view to be transferred to content PiP + * - Construct the PictureInPictureParams with source rect hint and aspect ratio from bounds + * - Start the new content PiP container Activity with the ActivityOptions + */ private void enterContentPip() { - // TBD + final Intent intent = new Intent(this, ContentPictureInPicture.class); + intent.putExtra(KEY_ON_STOP_RECEIVER, mOnStopReceiver); + final Rect bounds = new Rect(); + mImageView.getGlobalVisibleRect(bounds); + final PictureInPictureParams params = new PictureInPictureParams.Builder() + .setSourceRectHint(bounds) + .setAspectRatio(new Rational(bounds.width(), bounds.height())) + .build(); + final ActivityOptions opts = ActivityOptions.makeLaunchIntoPip(params); + startActivity(intent, opts.toBundle()); + // Swap the mImageView to placeholder content. + mImageView.setImageResource(R.drawable.black_box); } private void updateLayout(Configuration configuration) { mImageView.addOnLayoutChangeListener(mOnLayoutChangeListener); - final boolean isTablet = configuration.screenWidthDp >= 800; + final boolean isTablet = configuration.smallestScreenWidthDp >= TABLET_BREAK_POINT_DP; final boolean isLandscape = (configuration.orientation == Configuration.ORIENTATION_LANDSCAPE); final boolean isPictureInPicture = isInPictureInPictureMode();