• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.example.android.apis.app;
18 
19 import android.app.Activity;
20 import android.app.PictureInPictureParams;
21 import android.content.pm.ActivityInfo;
22 import android.content.res.Configuration;
23 import android.graphics.Rect;
24 import android.os.Bundle;
25 import android.util.Rational;
26 import android.view.Gravity;
27 import android.view.View;
28 import android.view.WindowManager;
29 import android.widget.CompoundButton;
30 import android.widget.LinearLayout;
31 import android.widget.Switch;
32 
33 import com.example.android.apis.R;
34 
35 public class PictureInPictureAutoEnter extends Activity {
36     private final View.OnLayoutChangeListener mOnLayoutChangeListener =
37             (v, oldLeft, oldTop, oldRight, oldBottom, newLeft, newTop, newRight, newBottom) -> {
38                 updatePictureInPictureParams();
39             };
40 
41     private final CompoundButton.OnCheckedChangeListener mOnCheckedChangeListener =
42             (v, isChecked) -> updatePictureInPictureParams();
43 
44     private View mImageView;
45     private View mButtonView;
46     private Switch mSwitchView;
47 
48     @Override
onCreate(Bundle savedInstanceState)49     protected void onCreate(Bundle savedInstanceState) {
50         super.onCreate(savedInstanceState);
51         setContentView(R.layout.picture_in_picture_auto_enter);
52 
53         mImageView = findViewById(R.id.image);
54         mImageView.addOnLayoutChangeListener(mOnLayoutChangeListener);
55         mButtonView = findViewById(R.id.change_orientation);
56         mButtonView.setOnClickListener((v) -> {
57             final int orientation = getResources().getConfiguration().orientation;
58             if (orientation == Configuration.ORIENTATION_LANDSCAPE) {
59                 setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
60             } else {
61                 setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
62             }
63         });
64         mSwitchView = findViewById(R.id.source_rect_hint_toggle);
65         mSwitchView.setOnCheckedChangeListener(mOnCheckedChangeListener);
66 
67         // there is a bug that setSourceRectHint(null) does not clear the source rect hint
68         // once there is a non-null source rect hint ever been set. set this to false by default
69         // therefore this demo activity can be used for testing autoEnterPip behavior without
70         // source rect hint when launched for the first time.
71         mSwitchView.setChecked(false);
72 
73         updateLayout(getResources().getConfiguration());
74     }
75 
76     @Override
onConfigurationChanged(Configuration newConfiguration)77     public void onConfigurationChanged(Configuration newConfiguration) {
78         super.onConfigurationChanged(newConfiguration);
79         updateLayout(newConfiguration);
80     }
81 
updateLayout(Configuration configuration)82     private void updateLayout(Configuration configuration) {
83         final boolean isLandscape =
84                 (configuration.orientation == Configuration.ORIENTATION_LANDSCAPE);
85         final boolean isPictureInPicture = isInPictureInPictureMode();
86         mButtonView.setVisibility((isPictureInPicture || isLandscape) ? View.GONE : View.VISIBLE);
87         mSwitchView.setVisibility((isPictureInPicture || isLandscape) ? View.GONE: View.VISIBLE);
88         final LinearLayout.LayoutParams layoutParams;
89         if (isPictureInPicture) {
90             layoutParams = new LinearLayout.LayoutParams(
91                     LinearLayout.LayoutParams.MATCH_PARENT,
92                     LinearLayout.LayoutParams.MATCH_PARENT);
93             layoutParams.gravity = Gravity.NO_GRAVITY;
94         } else {
95             // Toggle the fullscreen mode as well.
96             // TODO(b/188001699) switch to use insets controller once the bug is fixed.
97             final View decorView = getWindow().getDecorView();
98             final int systemUiNavigationBarFlags = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
99                     | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
100             if (isLandscape) {
101                 layoutParams = new LinearLayout.LayoutParams(
102                         LinearLayout.LayoutParams.WRAP_CONTENT,
103                         LinearLayout.LayoutParams.MATCH_PARENT);
104                 layoutParams.gravity = Gravity.CENTER_HORIZONTAL;
105                 getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
106                         WindowManager.LayoutParams.FLAG_FULLSCREEN);
107                 decorView.setSystemUiVisibility(decorView.getSystemUiVisibility()
108                         | systemUiNavigationBarFlags);
109             } else {
110                 layoutParams = new LinearLayout.LayoutParams(
111                         LinearLayout.LayoutParams.MATCH_PARENT,
112                         LinearLayout.LayoutParams.WRAP_CONTENT);
113                 layoutParams.gravity = Gravity.NO_GRAVITY;
114                 getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
115                 decorView.setSystemUiVisibility(decorView.getSystemUiVisibility()
116                         & ~systemUiNavigationBarFlags);
117             }
118         }
119         mImageView.addOnLayoutChangeListener(mOnLayoutChangeListener);
120         mImageView.setLayoutParams(layoutParams);
121     }
122 
updatePictureInPictureParams()123     private void updatePictureInPictureParams() {
124         mImageView.removeOnLayoutChangeListener(mOnLayoutChangeListener);
125         // do not bother PictureInPictureParams update when it's already in pip mode.
126         if (isInPictureInPictureMode()) return;
127         final Rect imageViewRect = new Rect();
128         mImageView.getGlobalVisibleRect(imageViewRect);
129         // bail early if mImageView has not been measured yet
130         if (imageViewRect.isEmpty()) return;
131         final Rect sourceRectHint = mSwitchView.isChecked() ? new Rect(imageViewRect) : null;
132         final PictureInPictureParams.Builder builder = new PictureInPictureParams.Builder()
133                 .setAutoEnterEnabled(true)
134                 .setAspectRatio(new Rational(imageViewRect.width(), imageViewRect.height()))
135                 .setSourceRectHint(sourceRectHint);
136         setPictureInPictureParams(builder.build());
137     }
138 }
139